Доступ к элементам структуры
Для обращения к отдельным элементам структуры используются операторы: . и ->.
Доступ к элементам структуры может иметь следующее формальное описание:
переменная_структурного_типа.элемент_структуры=значение;
имя_структурного_типа *указатель_структуры=& переменная_структурного_типа;
указатель_структуры->элемент_структуры=значение;
Например:
struct structA {
char c1;
char s1[4];
float f1;} aS1, *prtaS1=&aS1; // aS1 - переменная структурного типа
// prtaS1 - указатель на структуру aS1
struct structB {
struct structA aS2; // Вложенная структура
} bS1, *prtbS1=&bS1;
aS1.c1= 'Е'; // Доступ к элементу c1 структуры aS1
prtaS1->c1= 'Е'; // Доступ к элементу c1 через указатель prtaS1
(*prtaS1).c1= 'Е'; // Доступ к элементу c1
(prtbS1->aS2).c1='Е'; // Доступ к элементу вложенной структуры
Массив структур
Процесс описания массива структур совершенно аналогичен описанию любого другого типа массива:
struct book libry[MAXBKS];
Этот оператор объявляет libry массивом, состоящим из MAXBKS-элементов. Каждый элемент массива представляет собой структуру типа book. Таким образом, libry[0] является book-структурой, libry[1] - второй book-структурой и т.д.
Доступ к элементу массива структурного типа имеет следующий формальный синтаксис:
имя_массива[индекс_элемента_массива].элемент_структуры
При определении элементов массива структур мы применяем те же самые правила, которые используются для отдельных структур: сопровождаем имя структуры операцией получения элемента и имени элемента:
libry[0].value value - первый элемент массива
libry[4].title title - пятый элемент массива
При использовании указателей на массив структур следует сначала присвоить указателю адрес первого элемента массива, а затем реализовывать доступ к элементам массива, изменяя этот указатель адреса.
Например:
struct structA {
int i; char c;} sA[4], *psA;
psA=&sA[0];
…
cout<<psA->i; // Доступ к первому элементу массива структур
psA++; // Переход ко второму элементу массива
// Эквивалентно записи: psA=&sA[1];
cout<<psA->i;
Передача структур в качестве параметров
Переменные структурного типа и элементы структуры можно передавать в функции в качестве параметров.
Передача параметров может выполняться:
по ссылке или указателю;
по значению.
При передаче параметра по указателю передается только указатель на структуру, при передаче по значению в стек копируется все содержание структуры.
Например:
struct structA {
int i; char c;} sA, *psA=&sA;
void F1(struct structA sA); // Передача параметров по значению
void F2(struct structA *psA); // Передача параметров по указателю
void F3(struct structA &sA); // Передача параметров по ссылке
…
void F2(struct structA *psA) {
psA->i =10; } // Доступ к элементу структуры
При большой вложенности вызовов и использовании большого числа структур или их значительных размерах вызов по значению может привести к переполнению стека.
Функция может возвращать значение структурного типа или типа указателя на структуру.
Например:
struct structA { int i; char с;};
struct structA Function3(void); // Функция возвращает значение структурного типа
struct structA *Function4(void); // Функция возвращает указатель на структуру
Пример использования структуры
Пусть требуется составить перечень музыкальных компакт-дисков. Достаточной для поиска диска в коллекции является следующая информация:
– название альбома;
– исполнитель;
– количество композиций;
– цена;
– дата покупки.
Итак, получено пять элементов будущей структуры. Теперь необходимо определить тип данных для каждого члена создаваемого структурированного типа. Название альбома и имя исполнителя будут описываться массивом символьных переменных. Поскольку нельзя знать заранее количество символов, входящих в эти поля, следовательно, в структуре будет храниться указатель на символьный массив. Количество композиций определяется целочисленной переменной, для хранения значения цены можно использовать число с плавающей запятой. Дата покупки определяется символьным массивом, состоящим из восьми элементов. Для наглядности вышесказанное представлено в виде таблицы:
Имя элемента |
Соответствующий тип данных |
Название альбома Исполнитель Количество композиций Цена Дата покупки |
Символьный массив неизвестного размера (char *) Символьный массив неизвестного размера (char *) Целочисленная переменная (int) Переменная с плавающей запятой (float) Символьный массив (char [8]) |
Подобное представление при программировании структуры значительно упрощает и ускоряет написание программы.
Определение структуры для хранения сведений о музыкальной коллекции, описанной выше, будет выглядеть следующим образом:
struct CD_collection
{
char * title;
char * artist;
int num_songs;
float price;
char date_purchased [8];
} cd1, cd2, cd3;
Определенный структурный тип имеет имя - CD_collection, он содержит пять членов структуры title, artist, num_songs, price и date_purchased. Здесь же объявлены три переменные - cd1, cd2, cd3 формата CD_collection.
Как и при работе с обычными переменными после объявления структуры необходимо заполнить её данными. Самый простой способ заключается в одновременном декларировании и инициализации структуры. Чтобы пояснить сказанное, ниже приведен пример:
struct CD_collection
{
char title [14];
char artist [18];
int num_songs;
float price;
char date_purchased [8];
} CD1 = { "Marilyn Manson", "Mechanical Animals", 14, 11.95, "11/12/01" };
В данном случае нам точно известны размеры символьных массивов, поэтому при декларировании структуры количество элементов полей title и artist заданы точно.
Программа заполняет структурную переменную с именем Top_CD и выводит значения её полей на экран.
#include <stdio.h>
#include <string.h>
#include <conio.h>
struct CD_collection // Объявление структуры
{
char * title;
char * artist;
int num_songs;
float price;
char date_purchased [8];
};
void main()
{
CD_collection Top_CD; // Объявление новой переменной
Top_CD.title = new char [17]; // Выделение памяти под заголовок
Top_CD.artist = new char [10]; // Выделение памяти под имя исполнителя
Top_CD.title = "The Sinister Urge";
Top_CD.artist = "Rob Zombie";
Top_CD.num_songs = 10;
Top_CD.price = 10.75;
strcpy(Top_CD.date_purchased,"26/12/06"); // Копировать дату в строку
printf("/n Диск №1: /n Название диска: %s/n Исполнитель: %s/n Кол-во песен: %d /n Цена: %f /n Дата покупки: %s", Top_CD.title, Top_CD.artist, Top_CD.num_songs, Top_CD.price, Top_CD.date_purchased);
getch();
}