Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР14-С++-24-мая-2012.doc
Скачиваний:
34
Добавлен:
23.09.2019
Размер:
2.26 Mб
Скачать

1.9. Массивы структурного типа

Структуры могут быть объединены в массивы структур. Наглядно массив структур можно представить в виде таблицы, где столбцы таблицы представляют собой поля структуры, а строки – элементы массива структур. Объявление массива структур делается аналогично объявлению массива переменных.

Общий вид объявления массива структур:

Имя_структурного_типа имя_переменной [количество_элементов_массива];

Например, описана структура

Struct Man

{

char fio[31]; // ФИО

int year; // Год рождения

float pay; // Оклад

};

то объявление массива структур может иметь вид:

Man d[3]; // массив d структур из четырех элементов

Например, информация о студенте объявлена в структурной переменной student (см. пример 14.???), то для хранения информации о студенческой группе stud101, состоящей из 30 студентов, объявление массива может быть следующим

struct student stud101[30];

Здесь stud101 - имя массива структур типа student, а stud101[0] - это первая структура, stud101[1] - вторая... stud101[9] - десятая структура.

Обратите внимание, что нумерация элементов массива структур начинается с нулевой компоненты и заканчивается индексом, равным количеству элементов массива минус 1.

Доступ к элементам массива структурного типа также осуществляется с использованием операции точка, например:

stud101[4].age // доступ к полю age пятой структуры stud101

stud101[0].kurs // доступ к полю kurs первой структуры stud101

personal[5].weight // доступ к полю weight шестой структуры personal

personal[3].birthday.day // доступ к полю day подструктуры birthday четвертой структуры personal

и т. п.

При обращении к полю структуры сначала происходит обращение к элементу массива (stud101[i]), а затем только обращение к полю структуры (stud101[i]. age).

Доступ к полю элемента массива структур может быть получен через константу-указатель на массив и смещение внутри массива, например, доступ к полю элемента массива с номером i следует записать следующим образом:

(*(stud101+i)).age или (stud101+i) ->age.

Инициализация массива структур обычно выполняется в цикле с помощью оператора for.

Пример 14.120

Date mas[15]; //массив mas структур Date

// из трех полей day, month и year

//ввод значений массива

for(int i=0;i<15;i++)

{

cout<<”\nEnter day:”;cin>>mas[i].day;

cout<<”\nEnter month:”;cin>>mas[i].month;

cout<<”\nEnter year:”;cin>>mas[i].year;

}

Массив структур также может быть передан в функцию в качестве аргумента, передача массива происходит через указатель на массив.

1.10. Структурные переменные и указатели

Синтаксис описания указателя:

<тип>*<имя_переменной>;

Таким образом, для описания указателя на структуру должен быть создан новый тип.

-> – операция доступа к полям структурной переменной через указатель (минус больше).

Пример 14.45

typedef struct Student

{ char fio[30];

char Adress[40];

int Age;

int oc[4];

float sr;

} MY_Student; //имя нового типа

MY_Student *S3 // Указатель на структуру

Примеры обращения к полям:

S3->Age, S3->oc[0], S3->oc[i], S3->fio, S3-> sr

Мы уже упомянули, что нельзя передавать функции структурную переменную целиком в качестве аргумента (хотя можно передавать отдельные элементы). Но существует возможность обойти это ограничение, используя в качестве аргумента указатель на структуру. Описание

                struct anketa *uk;

говорит, что uk - указатель на структуру типа anketa. Обозначение относится к конкретному элементу структуры и означает выборку этого элемента, например: uk-> tab_nom. Поскольку uk есть указатель на структуру anketa, то к элементу tab_nom можно обращаться и так:

   (*uk).tab_nom,

если учесть, чтоуказатель установлен на начало массива структур. Имя массива, как обычно, эквивалентно адресу его начального элемента и при добавлении к указателю на структуру или вычитании из него целого числа размер структуры учитывается автоматически  Так, оператор uk=a; устанавливает указатель на первый экземпляр массива структур, а запись ++a; обеспечивает автоматический переход к следующему экземпляру. В выражении (*uk).fio скобки обязательны, так как приоритет операции выделения элемента " . " выше чем у "*".

Если функции передается большая структура, то эффективнее передать указатель на эту структуру, нежели копировать ее в стек целиком. Указатель на структуру по виду ничем не отличается от указателей на обычные переменные.

Формат: struct point *pp;

где pp – указатель на структуру типа struct point, *pp – сама структура, (*pp).x и (*pp).y – члены структуры.

Скобки (*pp).x необходимы, так как приоритет операции (.) выше приоритета операции (*). В случае отсутствия скобок *pp.x понимается как *(pp.x).

Инициализация указателя на структуру выполняется так же, как и инициализация указателей других типов: struct point var1, *S1; здесь var1 – структурная переменная, *S1 – указатель на структуру.

Для определения значения указателя ему нужно присвоить адрес уже сформированной структуры:

S1 = &var1;

Теперь возможно еще одно обращение к элементам структуры:

(*S1).name.

Указатели на структуры используются весьма часто, поэтому для доступа к ее полям была введена короткая форма записи. Если р – указатель на структуру, то p -> <поле структуры> позволяет обратиться к указанному полю структурной переменной.

Знак -> вводится с клавиатуры с помощью двух символов: '–' (минус) и '>' (больше). Например, pp -> x; pp -> y.

Операторы доступа к полям структуры (.) и (->) вместе с операторами вызова функции () и индексами массива [] занимают самое высокое положение в иерархии приоритетов операций в языке C.

Указатели на структуру используются в следующих случаях:

     доступ к структурам, размещенным в динамической памяти;

     создание сложных структур данных – списков, деревьев;

     передача структур в качестве параметров в функции.

Если обращение к структуре происходит через указатель, то операцию «точка» используют после разыменования указателя (*p).kurs. Для этой конструкции предусмотрен более наглядный аналог p->kurs — операция «стрелка» — обращение к полю kurs структуры, на которую указывает указатель p.

Переменные структурного типа можно создавать динамически. Для этого нужно описать указатель на структуру

student *p;

а затем создать экземпляр структуры с помощью операции new:

p = new student; //.

Структура не может содержать в качестве элемента структуру такого же типа, но может включать указатель на структуру этого типа, при условии, что в объявлении структуры указано имя типа. Это позволяет создавать связанные списки структур.

Пример 14.77

Описание бинарного дерева,

struct tree

{

int number;

struct tree *left;

struct tree *right;

};