- •Структуры методические указания
- •Содержание
- •1.2 Описание и инициализация структур
- •1.3 Доступ к компонентам структуры через указатель
- •1.4 Массивы и структуры
- •2 Задание
- •2.1 Организация массива структур
- •2.2 Индивидуальное задание на структуры
- •3. Требования к содержанию и оформлению отчета
- •4.Контрольные вопросы
1.3 Доступ к компонентам структуры через указатель
Во всех предыдущих примерах компоненты структур использовались в выражениях подобно обычным переменным. Аналогично обычным переменным, можно создавать указатели на переменные-структуры. Для доступа к компонентам структуры через указатель применяется операция "->". Например:
void print_person( Person* p ) {
cout << p->name << '\n';
cout << p->birthdate.day << '\n';
cout << p->birthdate.month << '\n';
cout << p->birthdate.year << '\n';
cout << p->salary << '\n\n'; }
Функцию "print_person()" можно переписать в эквивалентном виде с помощью операции разыменования указателя "*" и операции доступа к компонентам структуры ".". Обратите внимание на скобки в записи "(*p).", которые необходимы, поскольку приоритет операции "." выше, чем у "*":
void print_person( Person* p ) {
cout << (*p).name << '\n';
cout << (*p).birthdate.day << '\n';
cout << (*p).birthdate.month << '\n';
cout << (*p).birthdate.year << '\n';
cout << (*p).salary << '\n\n'; }
Использование указателей на структуры показано в примере 2. В функции "main()" этой программы указателю "sp" cначала присваивается адрес "s1", и затем с помощью операции "->" компонентам "s1" присваиваются начальные значения. Затем указателю "sp" присваивается адрес "s2", и компоненты этой структуры также инициализируются. Возможность динамического перенаправления на различные объекты является одним из важнейших свойств указателей, которые, в частности, полезны для реализации динамических структур данных (например, связного списка или стека).
Пример 2
struct ExStruct {
char c; int i; float f; double d; };
void main() {
ExStruct s1, s2;
ExStruct* sp = &s1;
sp->c = 'a';
sp->i = 1;
sp->f = 3.14f;
sp->d = 0.00093;
sp = &s2;
sp->c = 'b';
sp->i = 2;
sp->f = 6.28f;
sp->d = 2.5; }
При рассмотрении функций уже говорилось про понятие рекурсивных структур данных. Для создания в структуре ссылки на структуру такого же типа необходимо пользоваться указателем. В программе примера 3 создаются две структуры, содержащие ссылки друг на друга.
Пример 3
struct SelfReferential {
int i;
SelfReferential* sr; };
void main() {
SelfReferential sr1, sr2;
sr1.sr = &sr2;
sr2.sr = &sr1;
sr1.i = 47;
sr2.i = 1024; }
Описание без указателя является недопустимым, т.к. в нем при описании компоненты структуры тип структуры используется в тот момент, когда этот тип еще не определен полностью:
struct SelfReferential {
int i;
SelfReferential sr; // Недопустимое описание компоненты };
1.4 Массивы и структуры
У массива и структуры есть общее свойство: оба этих типа данных являются типами с произвольным доступом. Но структура более универсальна, поскольку не требуется, чтобы типы всех ее компонент были одинаковы. С другой стороны, в некоторых случаях массив предоставляет бóльшие возможности, т.к. индексы его элементов могут вычисляться, а имена компонент структуры – это фиксированные идентификаторы, задаваемые в описании типа.
Массивы и структуры могут комбинироваться различными способами. Например, i-я компонента массива "a", который является компонентой структуры "r", обозначается как r.a[i].
Определение массива структур и указателя на структуру:
struct {
char fio[30];
int date, code;
double salary; }
staff[100]. *ps;
Напротив, компонента с именем "s", входящая в i-ю компоненту-структуру массива структур "a" обозначается как a[i].s
В качестве примера далее приведено описание переменной "screen", которая является двумерным массивом структур типа "Cell". Этот массив предназначен для хранения содержимого текстового экрана размером 80х25 знакомест:
struct Cell {
unsigned char character; // Символ
int foreground; // Цвет символа
int background; // Цвет фона
bool blink; // Мигание включено/выключено
};
void main() {
Cell screen[25][80];
... }