7.2 Анонимные структуры. Присваивание структурных переменных
Если в каком-либо блоке программы временно необходима только одна структурная переменная того или иного типа, то нет необходимости в использовании имени структуры. Такие структуры называются анонимными или безымянными и объявляются следующим образом:
struct {
float A;
double B;
int C[2];
} V;
Таким образом, в объявлении структуры может отсутствовать либо имя структурированного типа, либо список структурных переменных, но не оба одновременно.
Информация, содержащаяся в одной структурной переменной, может быть присвоена другой структурной переменной того же типа с помощью операции присваивания, то есть не нужно присваивать значение каждого поля по отдельности (что очень удобно). Следующая программа демонстрирует присваивание структурных переменных:
#include <stdio.h>
struct MyType {
float A;
double B;
int C[2];
};
void main()
{
MyType V1, V2;
// заполнение полей переменной V1
V1.A = 0.5;
V1.B = 3.6;
V1.C[0] = 45;
V1.C[1] = 90;
V2 = V1; // присваивание структурных переменных
// вывод полей переменной V2
printf ( " %f ", V2.A );
printf ( " %lf ", V2.B );
for( int i = 0; i < 2; i++ )
printf ( " %d ", V2.C[i] );
}
После присваивания поля переменой V2 будут содержать те же значения, что и поля переменной V1. Программа выдаст на экран:
0.5 3.6 45 90
7.3 Массивы структур
Довольно часто структуры используются именно в виде массивов структур. Для объявления такого массива следует сначала определить саму структуру, а затем объявить массив переменных данного типа. Например, для объявления массива структур типа MyType следует написать:
const int Nmax = 10;
// объявление структуры
struct MyType {
float A;
double B;
int C[2];
};
// объявление массива структур
MyType Mas[Nmax];
В результате получаем массив структур из 10 элементов, каждый из которых имеет тот же вид, что и переменная V в предыдущих примерах:
Для доступа к отдельным элементам массива структур используется операция индексации как и для массивов стандартных типов данных. Она имеет следующий синтаксис:
ИмяМассиваСтруктур [номер элемента] . ИмяПоля
Ниже приведён блок ввода массива структур с клавиатуры с выводом на экран подсказки для каждого поля:
for( int i = 0; i < Nmax; i++ )
{
printf ( " A = " );
scanf ( "%f", &Mas[i].A );
printf ( " B = " );
scanf ( "%lf", &Mas[i].B );
for( int j = ; j < 2; j++ )
{
printf ( " C[%d] = ", i+1 );
scanf ( "%d", &Mas[i].C[j] );
}
}
Выражение Mas[i].C[j] означает обращение к j-му элементу массива C, который является полем структурной переменной Mas[i].
Как и массивы стандартных типов, массивы структур индексируются с нуля.
7.4 Вложенные структуры
Иногда поля структуры сами являются структурными переменными. Такие поля называются вложенными. Так, например, необходимо описать с помощью структуры параметры человека. Поле FIO будет содержать вложенные поля: Fam – фамилия, Imya – имя и Otch – отчество. А поле даты рождения DataR будет содержать вложенные поля: Den – день, Mes – месяц и God – год.
При создании подобных структур необходимо соблюдать порядок объявления типов. Сначала объявляются типы вложенных полей, а затем уже общий тип, который содержит вложенные поля, например:
struct TypeFIO { // тип фамилии, имени и отчества
char Fam[20];
char Imya[20];
char Otch[20];
};
struct TypeData { // тип даты
int Den;
int Mes;
int God;
};
struct TypePerson { // тип человека
TypeFIO FIO; // поле фамилии, имени, отчества (вложенное)
TypeData DataR; // поле даты рождения (вложенное)
int Ves; // поле веса
int Rost; // поле роста
};
Теперь можно создавать структурные переменные типа TypePerson, например:
TypePerson P;
В результате будет создана переменная следующего вида:
Синтаксис доступа к вложенным полям структурной переменой:
ИмяСтруктурной Переменной . ИмяПоля . ИмяВложенногоПоля
Опишем блок ввода полей переменной P с клавиатуры с выдачей подсказки на экран:
printf ( " Fam " );
scanf ( "%s", P.FIO.Fam );
printf ( " Imya " );
scanf ( "%s", P.FIO.Imya );
printf ( " Otch " );
scanf ( "%s", P.FIO.Otch );
printf ( " Den " );
scanf ( "%d", &P.DataR.Den );
printf ( " Mes " );
scanf ( "%d", &P.DataR.Mes );
printf ( " God " );
scanf ( "%d", &P.DataR.God );
printf ( " Ves " );
scanf ( "%d", &P.Ves );
printf ( " Rost " );
scanf ( "%d", &P.Rost );
Поскольку поля Ves и Rost являются обычными полями, то при обращении к ним операция «точка» использовалась только один раз. Для доступа к остальным полям, которые являются вложенными, операция «точка» использовалась дважды.
