Операции над структурными переменными
Поля структурной переменной могут использоваться в выражениях и операторахв контексте их типа,в том числе и операторах ввода-вывода.Так же, как и для обычных операндов, действуют правила преобразования типов при смешивании операндов-полей разных типов. Например:
if (strcmp(first_book.name, “Mitchel M.”) == 0)…….
if(first_book.year%4==0)…
first_book.name[0] = lower(first_book.name[0]);
strcpy (first_book. name, “Mitchel M.”); //поле-строка получает значение !!!!!
strcpy (first_book. title,“Unesennie vetrom”);
cin >> child_book.title;//поле- строка получает значение !!!!!
first_book. year = 2007;
cin >> first_book. price;
Определить адрес структурной переменной или ее поля можно обычной операцией взятия адреса.
Непосредственно сравнивать две структурные переменные (даже одного типа) нельзя. Сравнивать можно только члены структур. Например:
struct { int a;
int b;
} v1, v2;
if ((v1.a == v2.a) && (v1.b == v2.b)) cout << “переменные равны”;
К структурным переменным, определенным с помощью одного и того же шаблона, применим оператор присваивания.!!! После его выполнения значения полей структурных переменных будут равны. Например:
first_book = child_book;
first_book = child_book = dog_book;
!!! Для определения прямоугольных областей можно использовать предопределенную в заголовочном файле windows.h структуру RECT, соответствующую приведенной выше структуреRectangle:
#include <windows.h>
RECT r1, r2 = { 2, 6, 4, 2 }, r3;
r1.left = 1;
r1.top = 5;
r1.right = 3;
r1.bottom = 1;
r3 = r1;
cout<< r3.left << endl;
При присваивании, байты памяти,выделенныеправой структурной переменной, копируются в память, выделенную компилятором для структурной переменной этого же типа, стоящей слева. Это так называемое поверхностное копирование.
НО!!! Поверхностное копирование полей-указателей может стать источником ошибок в дальнейшей работе.Если в структуре есть поля-указатели, то после присваивания будет существовать больше одной структурной переменной, поля которой указывают на одну и ту же область памяти.!!!
Если два структурных типа «закольцованы» (поля одного структурного типа объявляются через другой структурный тип и наоборот):
structA { B *pb;};
structB { A *pa;};
то допустимо использовать предварительное неполное определение любого из типов:
structB; // предварительное неполное определение типа B;
structA { B *pb;};
structB { A *pa;};
В данном случае предварительное неполное определение структурного типа B допустимо использовать в определении структурного типа A, так как определение указателя pb на структуру типа B не требует сведений о размере структуры типа B.
При обращении к элементам структуры с помощью указателя нужно учитывать приоритет операций. Для изменения порядка действий необходимо использовать явные скобки.
Выражение (*ptr_date).year представляет собой обращение к элементу year структуры, связанной с указателем ptr_date. Нельзя опускать скобки в этом выражении, так как приоритет операции точка (.) выше, чем операции доступ по указателю (*).
Для вложенных структур доступ к полям структурной переменной через указатель реализуется следующим образом: p->q->mem, что равносильно (p->q) -> mem (поскольку операции -> и . выполняются слева направо). Аналогично, выражение
stud. birthdate. month означает (stud. birthdate). month.
Массив структур
Определим шаблон структурыdata, содержащий информацию о дне рождения (год, месяц, день), и структурные переменные masha_data и sasha_data с информацией о днях рождения Маши и Саши:
struct data
{
int year; //год
unsigned mes; //месяц
unsigned day; //день
};
data masha_data, sasha_data;
Тогда:
masha_data.day //доступ к полю «день рождения» Маши
sasha_data.year //доступ к полю «год рождения» Саши
masha_data (вся информация о дате рождения Маши),
sasha_data (вся информация о дате рождения Саши).
Для данного структурного типа опишем массив структур person_data:
data person_data [20];
Тогда:
person_data – информация о датах рождения всей группы (массива людей из двадцати человек);
person_data[i] – информация о дате рождения (i+1) – го члена группы (i – ый элемент массива);
person_data[i]. mes – месяц рождения (i+1) – го члена группы;
Определим структурный тип (шаблон структуры) mash с информацией о владельце автомобиля: номер, марка автомобиля, фамилия и адрес владельца.
struct Auto
{int nomer ; //номер автомобиля
char marka[20]; //марка автомобиля
char fio[40]; //фамилия владельца
char adres[60] //адрес владельца
};
Automers, volvo, alfa_r [5], *mazda,person_list [20]; //определение структурных переменных
mers.marka–доступ к полю «марка» автомобиля mers
mers– вся информация о владельце автомобиля mers
volvo.fio[0]–первая буква фамилии владельца автомобиля volvo
alfa_r [1].adres[0]– первый символ адреса второго элемента массива владельцев alfa_r
person_list– информация о всех владельцах автомобилей (массив из двадцати наборов данных);
person_list[i] – информация о владельце (i+1) –го автомобиля (i –ый элемент в наборе данных);
person_list[i].fio– фамилия владельца (i+1) –го автомобиля;
person_list[i].fio[j]–j-ая буква в фамилии владельца (i+1) –го автомобиля
Расположение массива структур в памяти:
person_list | |||||
1-ый владелец: person_ list [0] | 2-ой владелец: person_list [1] | … | i-ый владелец: person_list [i-1] | ... | 20-ый владелец: person_list [19] |
nomer(4 байта) marka(20 байт) fio(40 байт) adres(60 байт) | nomer marka Adres Adre s adres | … | nomer marka fio О adres | … | ОООООООО ОООООООО ОOОООООО ОООООООО ОООООООО |
person_list [1]. fio person_list [i-1].fio[j]
Массив структурных переменных можно описать и следующим образом:
struct {char name[20];
char title[44];
int year;
float price;
} books[25];
Тогда к полю year в i-ом элементе массива структур books можно обратиться следующим образом:
books[i].year=2007;
(*(books+i)).year=2007;
(books+i)->year=2007;