Структуры. С / С++. Тема 9

Содержание

Слайд 2

НРТК, 2022 г. Структуры Созонов А.А. Структуры в C++

НРТК, 2022 г. Структуры Созонов А.А.

Структуры в C++

Слайд 3

НРТК, 2022 г. Структуры Созонов А.А. Структуры Структура — это набор

НРТК, 2022 г. Структуры Созонов А.А.

Структуры

Структура — это набор элементов

различных типов (ср. массив)
Синтаксис объявления структуры:
struct [<имя_типа>] { <описание_членов> }
[<список_переменных>];
Пример:
struct Friend
{
char name[20];
int age;
} Sam, July;
Слайд 4

НРТК, 2022 г. Структуры Созонов А.А. Операции со структурами Инициализация при

НРТК, 2022 г. Структуры Созонов А.А.

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

Инициализация при объявлении

переменной:
Friend John = { "Иван", 23 };
Присваивание:
Friend Mike = John;
Другие операторы (например: ==, !=, …) не определены
Friend dude1, dude2;
...
if(strcmp(dude1.name, dude2.name) == 0 &&
dude1.age == dude2.age)
...
Слайд 5

НРТК, 2022 г. Структуры Созонов А.А. Члены структур Элемент структуры называется

НРТК, 2022 г. Структуры Созонов А.А.

Члены структур

Элемент структуры называется членом

структуры
Обращение к членам структуры через переменную:
<имя_переменной>.<член_структуры>
Пример:
Friend Mike, Helen, Bob;
strcpy(Mike.name, "Миша");
Mike.age = 17;
Helen.age = 18;
Bob.age = Mike.age + Lena.age;
Слайд 6

НРТК, 2022 г. Структуры Созонов А.А. Указатели/массивы и структуры Обращение к

НРТК, 2022 г. Структуры Созонов А.А.

Указатели/массивы и структуры

Обращение к членам

структуры через указатель:
<имя_указателя>-><член_структуры>
Пример:
Friend* Mike = new Friend;
(*Mike).age = 18;
strcpy(Mike->name, "Миша");
Массив структур:
Friend friends[100];
// или:
Friend* friends = new Friend[100];
friends[3].age = 17;
// или:
(friends + 3)->age = 17;
Слайд 7

НРТК, 2022 г. Структуры Созонов А.А. Члены структур Элементы «простых» типов

НРТК, 2022 г. Структуры Созонов А.А.

Члены структур

Элементы «простых» типов
Массивы
«простых» элементов
массивов
структур
Другие

(вложенные) структуры
...
phonebook.records.pages[i].item[0].name
Слайд 8

НРТК, 2022 г. Структуры Созонов А.А. Пример: Outlook struct Date {

НРТК, 2022 г. Структуры Созонов А.А.

Пример: Outlook

struct Date { int

year, month, day; };
struct Address { char* town, *street, *comment;
int house, apart; };
struct Phone { char* code, *num, *comment; };
struct Business { char* organization, *position;
Address address;
Phone phones[4]; };
struct Person
{
char* name;
Date birthday;
Address address[3];
Phone phone[4];
Business business;
};
Слайд 9

НРТК, 2022 г. Структуры Созонов А.А. Члены структур Структура не может

НРТК, 2022 г. Структуры Созонов А.А.

Члены структур

Структура не может быть

членом самой себя:
struct BadStruct
{
BadStruct bad_member; // Ошибка компиляции
};
Но указатель на структуру — может:
struct Friend
{
char name[20];
int age;
Friend* best_friend;
};
Слайд 10

НРТК, 2022 г. Структуры Созонов А.А. Члены структур Что если две

НРТК, 2022 г. Структуры Созонов А.А.

Члены структур

Что если две структуры

должны указывать друг на друга?
Опережающее описание:
struct S2; // Без этой строчки нельзя
// создавать указатели на S2
struct S1
{
S2* link;
};
struct S2
{
S1* link;
};
Слайд 11

НРТК, 2022 г. Структуры Созонов А.А. Размеры структур Размер структуры —

НРТК, 2022 г. Структуры Созонов А.А.

Размеры структур

Размер структуры — сумма

размеров ее членов плюс выбираемое компилятором выравнивание
struct Struct1
{
int i1; char s1[6];
int i2; char s2[6];
};
struct Struct2
{
char s1[6]; char s2[6];
int i1; int i2;
};
int len1 = sizeof(Struct1); // len1 = 24;
int len2 = sizeof(Struct2); // len2 = 20;
Слайд 12

НРТК, 2022 г. Структуры Созонов А.А. Размеры структур Выравнивание нужно для

НРТК, 2022 г. Структуры Созонов А.А.

Размеры структур

Выравнивание нужно для более

быстрого доступа к членам структуры
Часто выравнивание — по границе машинного слова
Сортировка членов структур по размеру минимизирует неиспользуемое пространство
Слайд 13

НРТК, 2022 г. Структуры Созонов А.А. Объединения

НРТК, 2022 г. Структуры Созонов А.А.

Объединения

Слайд 14

НРТК, 2022 г. Структуры Созонов А.А. Объединения Объединение — это структура

НРТК, 2022 г. Структуры Созонов А.А.

Объединения

Объединение — это структура в

которой все члены расположены по одному и тому же адресу
Синтаксис объявления объединения:
union [<имя_типа>] { <описание_членов> }
[<список_переменных>];
Пример:
union PhoneNumber
{
long number;
char coded[8];
} phone1, phone2;
Слайд 15

НРТК, 2022 г. Структуры Созонов А.А. Пример left top union Rectangle

НРТК, 2022 г. Структуры Созонов А.А.

Пример

left

top

union Rectangle
{
struct { int

left, top, right, bottom; };
struct { int x_centr, y_centr, width, height; };
} r;
r.Left = 4; // r.x_centr == 4
struct Rectangle
{
int left, top;
union { int right, width; };
union { int bottom, height; };
};
Слайд 16

НРТК, 2022 г. Структуры Созонов А.А. Структуры и объединения в C

НРТК, 2022 г. Структуры Созонов А.А.

Структуры и объединения в C

В

C имена структур и объединений не являются типами, если не указывать struct (union)
struct S { int dummy; };
S s; // Ошибка, идентификатор не найден
struct S s; // Верно
Обычно:
typedef struct S { int dummy; } S;
S s; // Верно
Есть и другие различия
Слайд 17

НРТК, 2022 г. Структуры Созонов А.А. Битовые поля

НРТК, 2022 г. Структуры Созонов А.А.

Битовые поля

Слайд 18

НРТК, 2022 г. Структуры Созонов А.А. Битовые поля Битовые поля —

НРТК, 2022 г. Структуры Созонов А.А.

Битовые поля

Битовые поля — способ

указать количество бит, необходимых для хранения члена структуры или объединения
Объявление битовых полей
{struct|union} [<имя_типа>] {
<тип> [<имя_поля>] : <количество_бит>; ... }
[<список_переменных>];
Тип может быть интегральным типом (bool, signed/unsigned int, short, long) или перечислением (enum)
Слайд 19

НРТК, 2022 г. Структуры Созонов А.А. Пример struct Date { unsigned

НРТК, 2022 г. Структуры Созонов А.А.

Пример

struct Date
{
unsigned int year

: 11;
unsigned int month : 4;
unsigned int : 1;
unsigned int day : 5;
unsigned int week : 3;
};
Слайд 20

НРТК, 2022 г. Структуры Созонов А.А. Структуры и функции

НРТК, 2022 г. Структуры Созонов А.А.

Структуры и функции

Слайд 21

НРТК, 2022 г. Структуры Созонов А.А. Структуры как возвращаемые значения: Friend

НРТК, 2022 г. Структуры Созонов А.А.

Структуры как возвращаемые значения:
Friend CreateFriend(char*

name, int age);
Структуры как параметры функций:
int WhoIsOlder(Friend friend1, Friend friend2)
{
if(friend1.age == friend2.age)
return 0;
else if(friend1.age < friend2.age)
return -1;
else
return 1;
}

Структуры и функции

Слайд 22

НРТК, 2022 г. Структуры Созонов А.А. Вариант 1 — по значению

НРТК, 2022 г. Структуры Созонов А.А.

Вариант 1 — по значению

int

WhoIsOlder(Friend friend1, Friend friend2);
int main()
{
Friend Bob, Mike;
...
int who = WhoIsOlder(Bob, Mike);
}
int WhoIsOlder(Friend friend1, Friend friend2)
{
if(friend1.Age == friend2.Age)
...
}
Слайд 23

НРТК, 2022 г. Структуры Созонов А.А. Вариант 1 — по значению

НРТК, 2022 г. Структуры Созонов А.А.

Вариант 1 — по значению

int

WhoIsOlder(Friend friend1, Friend friend2);
int main()
{
Friend Bob, Mike;
...
int who = WhoIsOlder(Bob, Mike);
}
int WhoIsOlder(Friend friend1, Friend friend2)
{
if(friend1.Age == friend2.Age)
...
}

Копирование всей структуры — плохо!

Слайд 24

НРТК, 2022 г. Структуры Созонов А.А. Вариант 2 — по указателю

НРТК, 2022 г. Структуры Созонов А.А.

Вариант 2 — по указателю

(C)

int WhoIsOlder(Friend* friend1, Friend* friend2);
int main()
{
Friend Bob, Mike;
...
int who = WhoIsOlder(&Bob, &Mike);
}
int WhoIsOlder(Friend* friend1, Friend* friend2)
{
if(friend1->age == friend2->age)
...
}

Слайд 25

НРТК, 2022 г. Структуры Созонов А.А. Вариант 3 — по ссылке

НРТК, 2022 г. Структуры Созонов А.А.

Вариант 3 — по ссылке

(C++)

int WhoIsOlder(Friend& friend1, Friend& friend2);
int main()
{
Friend Bob, Mike;
...
int who = WhoIsOlder(Bob, Mike);
}
int WhoIsOlder(Friend& friend1, Friend& friend2)
{
if(friend1.Age == friend2.Age)
...
}

Слайд 26

НРТК, 2022 г. Структуры Созонов А.А. Плюсы и минусы При передаче

НРТК, 2022 г. Структуры Созонов А.А.

Плюсы и минусы

При передаче по

ссылке (по указателю) не копируются большие объемы памяти
При вызове функции нельзя использовать константы
Изменение локальных переменных меняет глобальные
int WhoIsOlder(Friend& friend1,
Friend& friend2)
{
// Ошибочное присваивание:
if(friend1.age = friend2.age)
...
}
Слайд 27

НРТК, 2022 г. Структуры Созонов А.А. Вариант 4 — окончательный int

НРТК, 2022 г. Структуры Созонов А.А.

Вариант 4 — окончательный

int WhoIsOlder(const

Friend* friend1,
const Friend& friend2);
int main()
{
Friend Bob, Mike;
...
int who = WhoIsOlder(&Bob, Mike);
}
int WhoIsOlder(const Friend* friend1,
const Friend& friend2)
{
if(friend1->age = friend2.age) // Ошибка компиляции
}