Под структурой в языке С понимается набор одной или большего числа переменных, возможно имеющих различный тип и объединенных под единым именем, называемым именем структуры. Описание структуры имеет следующий вид
struct
{
тип поле1;
тип поле2;
…
} идентификатор1, идентификатор2, …;
В результате такого описания будут созданы переменные с именами идентификатор1, идентификатор2 и т.д. Каждая такая переменная будет содержать несколько значений. Каждое значение хранится в параметре поле, а каждое поле может иметь собственный тип. Поля одного типа могут объединяться в списке, как при описании переменных
struct
{
тип поле1, поле2, поле3;
тип поле4;
…
} идентификатор1, идентификатор2, …;
В примере описана структура данных для работы с датой
struct
{
int year, month, day;
char week_day[3];
char month_name[10];
bool work_day;
} date;
Такое описание создаст переменную date. Переменная используется для хранения даты и содержит такие значения:
· год в числовом формате, например 2009;
· месяц в числовом формате, например 10 (октябрь);
|
|
· число месяца, например 16;
· название для недели в формате "Пн", "Вт", "Ср" и т.д.;
· название месяца в формате "Январь", "Февраль", "Март" и т.д.;
· поле логического типа, которое равно true, если день является рабочим и false, если выходным.
На Рис. 44 схематически представлено хранение в памяти переменной date. Размер, который занимает структурированная переменная, равен сумме размеров составляющих ее полей.
Рис. 44
Доступ к полям структуры имеет такой синтаксис
идентификатор.поле
Для работы с описанной выше переменной date в программе можно выполнять любые операции, как с обычной переменной, указывая при этом необходимые поля.
date.year = 2010;
date.workday = true;
strcpy(date.week_day, “Пт”);
cout << date.month_name << ‘\n’;
Отдельные структуры с произвольным общим шаблоном, как и обычные переменные любого типа, могут быть объединены в массивы фиксированной длины. Описания массивов структур в программе строятся на той же самой синтаксической основе, что и описания обычных массивов.
struct
{
int num;
char fio[30];
float weght;
int math, phiz, alg;
} ap17a[21], ap17b[18], ap57[23];
В примере созданы массивы для хранения списков студентов трех групп. Размер каждого массива соответствует фактическому количеству студентов в группе. Элементы всех массивов имеют одинаковый шаблон, и каждый элемент содержит информацию об одном студенте:
· номер студента по списку в журнале – поле num;
· фамилию студента – поле fio;
· вес студента – поле weight;
· оценки по математике, физике и программированию за последнюю сессию – поля math, phiz и alg соответственно.
Можно найти средний вес студентов группы АП-17Б
|
|
float aver_weight = 0.f;
for(int j = 0; j < 18; ++j)
aver_weight += ap17b[i].weight;
aver_weight /= 18;
Этот простейший способ определения структур требует всякий раз повторять шаблон структуры в каждом новом описании, даже если эти описания определяют структуры с одной и той же общей схемой. Чтобы избежать такого повторения, язык С предоставляет возможность снабдить шаблон создаваемой структуры некоторым именем, которое называется тег структуры. Синтаксис описания структуры с тегом таков
struct тег
{
тип поле1;
тип поле2;
…
} идентификатор1, идентификатор2;
В этом случае структура получит имя, и буду описаны переменные этой структуры. После такого определения в программе, тег структуры может быть использован как синтаксический эквивалент имени типа данных для описания переменных.
struct тег идентификатор3;
Переменная идентификатор3 будет иметь те же поля, что и переменные идентификатор1 и идентификатор2. В программе можно выполнить просто описание тега структуры без описания переменных. Переменные могут быть описаны позднее. Также можно опустить ключевое слово struct при описание структурированных переменных с помощью тега.
struct тег
{
тип поле1;
тип поле2;
…
};
тег идентификатор1, идентификатор2, идентификатор3;
В примере определена структура для описания точки в трехмерной системе координат массив из 10 таких точек:
struct point3d
{
double x, y, z;
};
point3d points[10];
Отдельно необходимо рассмотреть работу со структурами с использованием указателей. Такая необходимость может возникнуть, например, при передаче в функцию параметра через указатель. Если структурированная переменная является указателем, то синтаксис доступа к полям этой переменной следующий
(*указатель).поле
Также имеется альтернативный синтаксис этой операции, который используется чаще
указатель->поле
В примере реализована функция, которая позволяет заполнить описанную выше структуру даты.
struct s_date
{
int year, month, day;
char week_day[3];
char month_name[10];
bool work_day;
};
void set_date(int _y, int _m, int _d, char *pwd, _char *_pmn, bool _wd, s_date *d)
{
d->year = _y;
d->month = _m;
d->day = _d;
strcpy(d->week_day, _pwd);
strcpy(d->month_name, _pmn);
d->work_day = _wd;
}
void main()
{
s_date date;
set_date(2009, 12, 30, “Ср”, “Декабрь”, true, &date);
…
}
Структура определена с использованием тега s_date. Это сделано для того, чтобы описание структуры было глобальным и его можно было использовать как в основной программе, так и в функциях. Переменная date описана в основной программе. Далее вызывается функция set_date() и в нее передается адрес переменной date. Формальным параметром, который соответствует переменной date, является указатель d. Собственно в функции set_date() значения формальных параметров присваиваются соответствующим полям структуры.