Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Програм. и основы алгорит.з.о..doc
Скачиваний:
5
Добавлен:
17.11.2019
Размер:
293.89 Кб
Скачать

Контрольные вопросы

1. Какие формы доступа к элементам массива предусмотрены синтаксисом языка С++?

2. Какие предусмотрены способы инициализации векторов?

3. Какой размерности могут быть вектора?

4. Могут ли быть объявлены массивы без указания количества элементов?

5. Может ли массив содержать элементы различных типов?

6. Предусмотрен ли контроль количества элементов массива?

7. Какая связь между массивами и указателями?

8. В чем отличие ссылки от указателя?

9. Чем отличается указатель-константа от указателя-переменной?

2.4 Типы данных, определяемые пользователем

2.4.1 Структуры

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

1) Описание (объявление структуры)

Формат описания структуры:

struct [ имя_типа ] {

тип_1 элемент_1 ;

тип_2 элемент_2 ;

. . .

тип_n элемент_n ;

} [ список_описателей ];

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

struct Sobyt{

int hour, min;

char theme[100], name[100];

int num;

};

Имя этого типа данных – Sobyt.

Описание структуры представляет собой задание нового типа struct имя_типа и не приводит к выделению памяти, а лишь даёт информацию компилятору о типах и количестве полей. Эта информация используется компилятором при описании структурных переменных (или массивов) для резерви­рования необходимого места в памяти и организации доступа к необходимым полям структурной переменной или масива структур.

2) Выделение памяти под структуру (описание структурной переменной или массива структур)

Если нам предстоит работать только с одной строкой структуры, то создаем структурную переменную, а если с таблицей (больше одной строки), то создаем массив (вектор) структур.

Описание структурной переменной состоит из задания типа и имени структурной переменной (массива), и имеет вид

[ struct ] имя_типа имя_структурной_переменной | имя_массива;

То есть можно описать переменные или массивы типа (например, Sobyt), так же, как переменные и массивы встроенных (cтандартных) типов, например:

Sobyt e1, e2[10]; //структура (переменная)е1 и массив структур е2

Если структура используется только в одном месте программы, можно совместить описание типа с описанием переменных, при этом имя типа можно не указывать:

struct {

int hour, min;

char theme[100], name[100];

int num;

} e1, e2[10];

Переменные структурного типа можно размещать и в динамической области памяти, для этого надо описать указатель на структуру и выделить под нее место:

Sobyt *pe = new Sobyt; // структура

Sobyt *pm = new Sobyt[m]; // массив m структур

  1. Доступ к полям структурной переменной.

Элементы структуры называют полями. Поля могут быть любого основного типа, массивом, указателем, объединением или структурой. Поля разных структур могут иметь одинаковые имена, поскольку у них разная область видимости.

Доступ к полям структурных переменных производится с помощью:

- оператора выбора - «.» (точка);

  • указателя.

Оператор выбора формирует ссылку на нужное поле_i структурной переменной (массива), используется с именем переменной (массива) и имеет вид -

имя_структурной_переменной | имя_массива [номер_строки] . имя_поля_i

Такая ссылка может располагаться в любом месте, где допустимы ссылки на простые перемен­ные. Ссылка на поле структурной переменной обладает всеми свойствами обычных переменных. Например, если поле это массив символов (char name[10];), то tov1.name - указатель- константа на первый элемент этого массива, а выражение &tov1.price - есть взятие адреса первого байта поля price. Нет также отличий в правилах видимости и времени существования от обычных переменных.

Если определён указатель на структуру, то доступ к элементам структуры можно обеспечить двумя способами:

- классическим;

используя оператор разыменования

(*указатель_на_структуру).имя_члена ;

- используя оператор указателя на структуру

указатель_на_структуру-> имя_члена ;

Оператор указателя на структуру печатается на клавиатуре как сочетание знаков «минус» и «больше».

И в том и в другом случаях может быть использован как указатель-константа, так и указатель-переменная. Разницу в применении этих указателей мы рассматривали в лабораторной работе №2.

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

e1.hour = 12; e1.min = 30;

strcnpy(e2[0].theme, “Новые пути развития ИТ”, 99);

pe+=3; // сдвинули указатель на 3 строки таблицы вниз

pe->num = 30; // или (*pe).num = 30; pe- указатель-

// переменная

pm[2].hour = 14; // или (*(pm+2)).hour = 14; pm-указатель-

// const

tov1.name=’’Volga’’,

tov2.price=12000;

mass_tov[1][1].name = “HONDA”;

Если элементом структуры является другая структура, то доступ к ее элементам выполняется через две операции выбора. Например:

struct A {int a; double x};

struct B {A a; double x} g[2];

g[0].a.a = 1;

g[1].x = 0.1;

4) Операции со структурами.

Структуры одного типа можно присваивать друг другу:

*pe = e1; pm[1] = e1; pm[4] =e2[0];

Но присвоение – это и все, что можно делать со структурами целиком. Другие операции, например сравнение на равенство или вывод, не определены. Хотя пользователь может задать их самостоятельно.

Структуру можно передавать в функцию и возвращать в качестве значения функции.

5) Ввод/вывод структур, как и массивов, выполняется поэлементно. Например:

// с использованием классов ввода-вывода <iostream.h>

cin>>e1.hour>>e1.min;

cin.getline(e1.tneme,100);

cout<<e1.hour<<’ ‘<<e1.min<<’ ‘<<e1.theme<<endl;

// с использованием ввода-вывода в стиле С (<stdio.h>)

scanf(“%d%d”, &e1.hour, &e1.min; gets(e1.theme);

printf(“%d %d %s”, e1.hour, e1.min, e1.theme);

Структуры (только не динамические) можно инициализировать перечислением значений их элементов, т.е. явно:

Sobyt e3 = {12, 30, “ Новые пути развития ИТ ”, 25};

При инициализации массивов структур следует заключать в фигурные скобки каждый элемент массива (учитывая, что многомерный массив – это массив массивов):

struct tovar1 { char name[10];

longint price;}mass_tov[2][3]= {

{{“AUDI”,50000},{“BMW”, 39100},{“CITROEN”,20000}},

{{“DAEWOO”,16000},{“HONDA”,31000},{“FORD”,38000}}

};

В качестве примера рассмотрим программу вывода на экран студентов группы, родившихся в определенном месяце (месяц вводим интерактивно)

# include <iostream.h>

# include <stdio.h>

# include <string.h>

# define n 25 // const int n=25; - количество студентов в

// группе

void main()

{struct stud {

char fam[20]; // фамилия студента

char mr[8]; // месяц рождения студента

}std[n],*p=&std[0]; // описание массива 25 структур и

//указателя на структуру

int i;

char mes[8];

for(i=0;i<n;i++,p++) // указатель сдвигается построчно

{cout<<"\n"<<"введите фамилию \n";

cin>>((*p).fam); // используем операцию

// разыменования

cout<<'\n'<<"введите месяц\n";

cin>>(*p).mr;

}

p-=n; // указатель возвращаем на начало списка

cout<<"\n"<<"введите искомый месяц\n";

cin>>mes;

for(i=0;i<n;i++,p++)

if(strcmp(std[i].mr,mes)==0 ) // сравнение месяца

// рождения каждого

// студента с введенным

cout<<(*p).fam<<"\n";

}