Структуры

Содержание

Слайд 2

Структуры

struct имя_структуры {
описание полей структуры
};
Здесь имя_структуры – идентификатор, соответствующий синтаксису языка

Структуры struct имя_структуры { описание полей структуры }; Здесь имя_структуры – идентификатор,
Си,
описания полей структуры – любая после-довательность описаний переменных, имена и типы этих переменных могут быть произвольными.

; обязательна

Слайд 3

Структуры

Опишем вектор в трехмерном пространстве, который задается тремя вещественными координатами x, y,

Структуры Опишем вектор в трехмерном пространстве, который задается тремя вещественными координатами x,
z:
struct R3Vector {
double x;
double y;
double z;
};
При описании структуры память не выделяется, только лишь описывается новый тип.

Слайд 4

Структуры

Таким образом, вводится новый тип "struct R3Vector"; объект этого типа содержит внутри

Структуры Таким образом, вводится новый тип "struct R3Vector"; объект этого типа содержит
себя три вещественных поля с именами x, y, z. После того как структура определена, можно описывать переменные такого типа, при этом в качестве имени типа следует использовать выражение struct R3Vector. Например, ниже описываются вещественные вектора в трехмерном пространстве с именами u, v и a, b, а также выделяется память.
struct R3Vector u, v;
Правила С++ разрешают опускать спецификатор struct
R3Vector a, b;

Объявлены переменные структурного типа R3Vector

Объявлены переменные структурного типа R3Vector

Слайд 5

Рассмотрим пример структуры на примере набора сведений Почтовый адрес:
struct address { //

Рассмотрим пример структуры на примере набора сведений Почтовый адрес: struct address {
почтовый адрес
char* name; // имя
int number; // номер дома
char* street; // улица
char* town; // город
long zip; // индекс
} id1, id2;

Структуры

struct – ключевое слово;
address – имя структурного типа, спецификатор типа (аналогично int, char и т.д.)
name, number, street, town, zip – элементы структуры (поля).
id1, id2 – объекты структурного типа address.

Слайд 6

Для инициализации переменных структурного типа можно использовать: 
address jd = {
"Иванов", 15,

Для инициализации переменных структурного типа можно использовать: address jd = { "Иванов",

"ул. Амурская",
"Благовещенск",
675000
};
Порядок следования должен строго соответствовать порядку переменных-членов в определении структурного типа.

Структуры

Замечание: инициализация данных при объявлении структуры запрещена.

Слайд 7

Причем, если количество инициализирующих значений превышает количество членов структуры – это ошибка.
Если

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

Структуры

Слайд 8

Переменные типа address могут описываться точно также, как другие переменные, а доступ

Переменные типа address могут описываться точно также, как другие переменные, а доступ
к отдельным членам (полям) получается с помощью операции . (точка).
Например: 
address jd;
jd.name = "Иванов";
jd.number = 15;
jd.street = "ул. Амурская";
jd.town = "Благовещенск";
jd.zip = 675000;

Структуры

Слайд 9

Итак, имеется возможность работать с полями структуры.
Например, в следующем фрагменте в векторе

Итак, имеется возможность работать с полями структуры. Например, в следующем фрагменте в
w вычисляется векторное произведение векторов u и v трехмерного пространства:
w = u × v.
struct R3Vector u, v, w;
// Вычисляем векторное произведение w = u * v
w.x = u.y * v.z - u.z * v.y;
w.y = (-u.x) * v.z + u.z * v.x;
w.z = u.x * v.y - u.y * v.x;

Структуры

Слайд 10

Определение структуры обычно располагается вне определений функций (подобно опреде-лению глобальных констант).
В этом

Определение структуры обычно располагается вне определений функций (подобно опреде-лению глобальных констант). В
случае тип структуры доступен всем функциям программы. После такого опреде-ления – имя структуры может использоваться аналогично базовым типам int, char и т.д.
Параметры структурного типа могут переда-ваться в функции как по значению, так и по ссылке.
Возвращаемое функцией значение также может иметь структурный тип.

Структуры

Слайд 11

С объектами типа структура можно работать как с единым целым, например, для

С объектами типа структура можно работать как с единым целым, например, для
структур одного и того же типа допускается операция присваивания:
struct R3Vector u, v;
. . .
u = v; //Копируем вектор как единое целое
копирование структур сводится к переписыванию области памяти.

Структуры

Слайд 12

Операции сравнение (== и !=) не определены.
Однако пользователь может определить эти

Операции сравнение (== и !=) не определены. Однако пользователь может определить эти
операции, используя прием перегрузки операций.
struct R3Vector u, v;
. . .
if (u == v) {//Ошибка! Сравнивать структуры нельзя
. . .
}

Структуры

Слайд 13

В приведенных выше примерах все поля структуры R3Vector имеют один и тот

В приведенных выше примерах все поля структуры R3Vector имеют один и тот
же тип double, однако это совершенно не обязательно.
Полями структуры в свою очередь могут быть структуры.
Пример: плоскость в трехмерном пространстве задается точкой и вектором нормали, ей соответствует структура R3Plane. Точке трехмерного пространства соответствует структура R3Point, которая определяется аналогично вектору.
Никаких ограничений на уровень вложенности структур нет.

Структуры

Слайд 14

Полное описание всех трех структур:
struct R3Vector { // Вектор трехмерного пространства

Полное описание всех трех структур: struct R3Vector { // Вектор трехмерного пространства
double x;
double y;
double z;
};
struct R3Point { // Точка трехмерного пространства
double x;
double y;
double z;
};
struct R3Plane { // Плоскость в трехмерном пр-ве
struct R3Point origin; // точка в плоскости
struct R3Vector normal; // нормаль к плоскости
};

Слайд 15

Пусть plane — это объект типа плоскость.
struct R3Plane plane;
Для того, чтобы

Пусть plane — это объект типа плоскость. struct R3Plane plane; Для того,
получить координату x точки плоскости, надо два раза применить операцию доступа к полю структуры (операцию "точка")
plane.origin.x

Структуры

Слайд 16

К структурным объектам типа указатель обращаются с использованием операции -> (стрелка).
Например:

К структурным объектам типа указатель обращаются с использованием операции -> (стрелка). Например:

void print_addr (address* p)
{ cout << p->name << "\n" << p->number <<
"\n" << p->street << "\n" << p->town << "\n" <<
p->zip << "\n";
}
Вызов print_addr (&jd) ;

Структуры

Слайд 17

Имя типа становится доступным сразу после того, как оно встретилось, а не

Имя типа становится доступным сразу после того, как оно встретилось, а не
только после того, как полностью просмотрено все описание.
Например, возможно объявление:
struct link{
// информационные поля
link* previous; // указатель (превьюз - предыдущий)
link* successor; // указатель (саксесор -удачный)
};
Новые объекты структурного типа не могут быть описаны, пока все описание не просмотрено, так например, следующее объявление:
struct no_good
{ no_good member; };
является ошибочным (компилятор не может установить размер no_good).

Слайд 18

Чтобы дать возможность двум (или более) структурным типам ссылаться друг на друга,

Чтобы дать возможность двум (или более) структурным типам ссылаться друг на друга,
можно предварительно описать имя структурного типа. Например:
struct list; // должна быть определена позднее 
struct link {
link* pre;
link* suc;
link* member_of;
}; 
struct list
{ link* head; }
Без первого описания list описание link вызвало бы синтаксическую ошибку.

Структуры

Слайд 19

Рассмотрим проектирование символьной таблицы, в которой каждый элемент содержит имя и значение,

Рассмотрим проектирование символьной таблицы, в которой каждый элемент содержит имя и значение,
причем значение может быть либо строкой, либо целым числом.
Тогда придется ввести дополнительное поле type по значению которого определяется тип вводимого значения. Значение храниться либо в поле string_value, либо в поле int_value.
struct entry {
char* name;
char type;
char* string_value; // используется если type = = 's'
int int_value; // используется если type = = 'i'
}; 

Структуры

Слайд 20

Для рассмотренного типа entry приведем пример функции – печати значений:
void print_entry(entry*

Для рассмотренного типа entry приведем пример функции – печати значений: void print_entry(entry*
p)
{ cout<name;
switch p->type
{ case 's': cout << p->string_value; break;
case 'i': cout << p->int_value; break;
default: cerr << "испорчен type\n"; break;
}
}

Структуры

Слайд 21

Поскольку string_value и int_value никогда не могут использоваться одновременно, ясно, что пространство

Поскольку string_value и int_value никогда не могут использоваться одновременно, ясно, что пространство
пропадает впустую.
Ситуацию можно исправить, указав, что оба поля структуры должны быть членами union (объединения); например, так:
struct entry {
char* name;
char type;
union {
char* string_value; //используется если type== 's'
int int_value; // используется если type == 'i'
};
};

Объединения

Слайд 22

При размещении entry поля структуры string_value и int_value будут храниться по одному

При размещении entry поля структуры string_value и int_value будут храниться по одному
и тому же адресу памяти.
Все члены объединения вместе занимают лишь столько памяти, сколько занимает наибольший член объединения.

Объединения

Слайд 23

Многие компьютеры требуют, чтобы объекты определенных типов выравнивались в памяти только по

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

Структуры

Слайд 24

Когда sizeof применяется к имени типа структуры или объединения или к идентификатору

Когда sizeof применяется к имени типа структуры или объединения или к идентификатору
имеющему тип структуры или объединения, то результатом является фактический размер структуры или объединения, который может включать участки памяти, используемые для выравнивания элементов структуры или объединения.
Таким образом, результат может не соответствовать размеру, получаемому путем сложения размеров элементов структуры.
Пример:
struct {
char h;
int b;
double f;
} str;
int a1; a1=sizeof(str);

Структуры

а1 получит значение 16, в то же время если сложить длины всех используемых в структуре типов, то получим, что длина структуры str должна быть равна 13.

1 байт
4 байта
8 байт

Слайд 25

Структуры

Структуры

Слайд 27

Структуры

Пример:
#include
#include
#include
using namespace std;
struct library {
int shifr;
char author[20];
char title[20];
int year;

Структуры Пример: #include #include #include using namespace std; struct library { int

};

Слайд 28

Пример программы - библиотека

void Print ()
{
cout<<"=======================================\n";
cout<<"|| Shifr book || avtor || NAME

Пример программы - библиотека void Print () { cout cout cout }
|| year издания ||\n";
cout<<"=======================================\n";
} ;
void PrintData (library *ptr, int i)
{ cout<<"||"< cout<<"||"<} ;
void PrintEnd ()
{
cout<<"========================================\n";
} ;

Слайд 29

int main ()
{ int i, n, m, god, v=0, g=0;
char avtor[20];
struct library

int main () { int i, n, m, god, v=0, g=0; char
ptr[50];
cout<<"Vvedite kol-vo books \n"; cin>>n;
for (i=0; i {cout<<"Information of"<<(i+1)<<"book :\n";
cout<<"Shifr book \n";
cin>>ptr[i].shifr;
cout<<"FIO avtora \n";
cin>>ptr[i].author;
cout<<"Name book \n";
cin>>ptr[i].title;
cout<<"Year издания \n";
cin>>ptr[i].year;
};

Слайд 30

do { cout<<"Выберите действие :\n";
cout<<"1 – список книг в алфавитном

do { cout cout cout cout cout cin>>m; switch (m) { case
порядке\n";
cout<<"2 – список книг необходимого года \n";
cout<<"3 – список книг определенного автора \n";
cout<<"4 - выход \n";
cin>>m;
switch (m)
{ case 1:
{ Print();
for (char w='A'; w<'Z'; w++)
for (i=0; i if(ptr[i].title[0]==w) PrintData(&ptr,i);
PrintEnd();
cout<<"Для выхода в меню нажмите любую клавишу ";
getch(); break;
};

Слайд 31

case 2:
{ cout<<"Vvedite нужный year : \n";
cin>>god;
for (i=0; i

case 2: { cout cin>>god; for (i=0; i { if (ptr[i].year==god) {
i++)
{
if (ptr[i].year==god)
{ v+=1;
if (v==1) Print();
PrintData(&ptr, i);
};
};
if(v!=0) PrintEnd();
else cout <<"No books необходимого year"<< endl;
v=0;
cout<<"For exit in menu push any клавишу ";
getch(); break;
};

Слайд 32

case 3:
{ cout<<"Vvedite FIO avtora : \n";
cin>>avtor;
for (i=0; i

case 3: { cout cin>>avtor; for (i=0; i { if (strcmp(ptr[i].author, avtor)==0)
i++)
{ if (strcmp(ptr[i].author, avtor)==0)
{ g+=1;
if (g==1) Print();
PrintData(&ptr,i);
};
};
if(g!=0) PrintEnd();
else cout <<"No books данного avtora"<< endl;
g=0;
cout<<"For exit in menu push any клавишу ";
getch(); break;
};
Имя файла: Структуры.pptx
Количество просмотров: 34
Количество скачиваний: 0