Масиви структур

Розширимо програму “книжка”, щоб вона могла обробляти 10 книг.

#include <iostream.h>

#define maxnazva 41 /*максимальна довжина заголовка*/

#define maxavtor 31 /*максимальна довжина імені автора*/

#define maxbk 10 /*максималька кількість книг*/

struct book {

char nazva[maxnazva];

char avtor[maxavtor];

float cina;

};

main()

{

struct book libry[maxbk];

int c=0;

int i;

сout<<“введіть назву книги\n”;

cin.get(odna.nazva,maxnazva); cin.get();

while (c< maxbk && gets(libry[c].nazva)!=null

&& libry[c].nazva[0]!=’\0’)

{

cout<<“введіть автора\n”;

cin.get(odna.avtor,maxavtor); cin.get();

cout<<“введіть ціну\n”;

cin>>odna.cina;

while (getch()!=‘\n’)

continue;/*знищення стрічки вводу*/

if (c< maxbk)

cout<<“введіть наступну книгу\n”;

}

cout<<“тепер виведемо список книг.\n”;

for (I=0;I<c;I++)

cout<<libry[i].avtor<< libry[i].nazva<< libry[i].cina;

return 0;

}

Спочатку розглянемо опис масиву структур і доступ до окремих елементів.

Опис масиву структур подібний до опису будь-якого іншого масиву.

 

struct book libry[maxbk];

Тут описується масив libry з елементами maxbk. Кожний елемент цього масиву є структурою book. Таким чином, libry[0] -одна структура типу book, libry[1]- друга структура і т.д. Це показано на рисунку

nazva avtor cina

Libry[0] libry[0].nazva libry[0].avtor libry[0].cina
         
Libry[1] libry[1].nazva libry[1].avtor libry[1].cina
         
Libry[2] libry[2].nazva libry[2].avtor libry[2].cina
. .   .  
. .   .  
. .   .  
Libry[9] libry[9].nazva libry[9].avtor libry[9].cina

 

Рис.Масиви структур.

 

Для ідентифікації елементів масиву структур застосовується теж правило, що і для ідентифікації окремих структур: після імені структури йде крапка, а потім ім’я єлемента.

libry[0].nazva /*елемент структури cina зв’язаний з першим елементом масиву*/

libry[9].cina /*елемент структури cina зв’язаний з десятим елементом масиву*/

Треба звернути увагу на те, що індекс масиву приєднаний до імені libry, а не до закінчення повного імені.

libry[0].nazva /*правильно*/

libry.cina[9] /*неправильно*/

Пояснемо, що означає запис libry[2].cina[4]. Це п’ятий символ елемента cina (частина cina[4])елемента типу book ,описаного третьою структурою (libry[2]).

В програмі рядок while (c< maxbk && gets(libry[c].nazva)!=null

&& libry[c].nazva[0]!=’\0’) трактується так:

gets(libry[c].nazva)-задає зчитування стрічки назви книги. Коли ця функція захоче читати після символа кінця файла, вираз приймає значення null.Вираз libry[c].nazva[0]!=’\0’ перевіряє чи не перший символ стрічки нульовим. Це би означало, що стрічка пуста. Рядок while (getch()!=‘\n’) continue;/*знищення стрічки вводу*/ компенсує недоліки функції scanf() і переводить введений результат на нову стрічку.

 

2. Вкладені структури.

Інколи необхідно створити структури, яка містить іншу (вкладену) структуру. Складемо програму-“облік друзів”.

#include <iostream.h>

#define l 20

struct names{ /*перший шаблон*/

char im[l];

char prizv[l];

};

struct harakter { /*другий шаблон*/

struct names druzi; /*вкладена структура*/

char bludo[l];

char robota[l];

float zarob;

};

main()

{

struct harakter x1{ /*ініціалізація змінної*/

{“Іван” ,“Петренко”}, “вареники”, “інженер”,30250.00

};

сout<<x1.druzi.im;

сout<< x1.druzi.prizv;

сout<< x1.robota;

сout<< x1.bludo;

сout<< x1.zarob;

return 0;

}

 

Доступ до елементів вкладених структур здійснюється так: спочатку записується назва зовнішньої структури, потім внутрішньої, а тоді вказуємо поле.

3. Вказівники на структури.

Існує, принаймні, три причини використання вказівників на структури:

- вказівниками легче керувати;

- структура не може передаватись функції в якості аргумента, але це можливо для вказівника;

- в деяких оголошеннях даних використовуються структури, які містять вказівники на інші структури.

Оголошення вказівника на структуру:

struct book *dn;

Спочатку йде службове слово struct ,потім назва структури book , зірочка і ім’я вказівника. Це оголошення не створює нову структуру, але дозволяє використовувати вказівник dn для позначення будь-якої існуючої структури типу book.

Вказівник ініціалізується таким чином, що вказує на структуру.

dn=&x1;

 

Розглянемо приклад:

#include <iostream.h>

#define l 20

 

struct names{ /*перший шаблон*/

char im[l];

char prizv[l];

};

struct harakter { /*другий шаблон*/

struct names druzi; /*вкладена структура*/

char bludo[l];

char robota[l];

float zarob;

};

main()

{

struct harakter x1[2]{{ /*ініціалізація змінної*/

{“Іван” ,“Петренко”}, “вареники”, “інженер”,30250.00},

{“Петро”,”Іващенко”},”борщ”,”лікар”,40325.00}};

struct harakter *x2;

x2=&x1[0]; /*вказує на структуру*/

cout<<“заробіток:\n”<<x2->zarob);

x2++; /*вказує на наступну структуру*/

cout<<“заробіток:\n”<<(*x2).zarob);

cout<<“улюблена страва n”<<x2->druzi.prizv<<x2->bludo);

return 0;}

 

Вказівник х2 вказує на елемент х1[0].Можна використати цей вказівник для отримання значення елемента х1[0].

1.за допомогою нової операції ->.Ця операція ск ладається з дефіса(-) і символа “більше”(>). Іншими словами, вказівник структури з операцією -> має такий самий зміст, які ім’я структури, після якого застосовується операція “крапка”.

2.якщо х2= =&x1[0],то і *x2= =x1[0], оскільки & і * є еквівалентними операціями. Тому можлива заміна

х1[0].zarob= =(*x2).zarob

Дужки необхідні, оскільки приоритет операції “крапка” вище, ніж приоритет операції “зірочка”.

Приклад. Створити та вивести на екран базу даних з 5 студентів. Полями кожного студента є: прізвище; ім’я; день, місяць та рік народження, адреса (дані вводяться з клавіатури)

#include<iostream.h>

#include<conio.h>

struct person

{

char fam[15],name[15];

int day,month,year;

char address[50];

};

//-----------------------------------------

void input(person *stud, int n)

{

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

{

cout<<"\tЗапис "<<i+1<<":\n";

cout<<"Прiзвище - ";cin>>stud[i].fam;

cout<<"Iм'я - "; cin>>stud[i].name;

cout<<"День народж. - "; cin>>stud[i].day;

cout<<"Мiсяць - "; cin>>stud[i].month;

cout<<"Рiк - "; cin>>stud[i].year;

cout<<"Адреса - "; cin>>stud[i].address;

}

}

//-----------------------------------------

void output(person *stud, int n)

{

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

{

cout<<"\tЗапис "<<i+1<<":\n";

cout<<stud[i].fam<<" "

<<stud[i].name<<"\t"

<<stud[i].day<<"."

<<stud[i].month<<"."

<<stud[i].year<<"\t"

<<stud[i].address<<endl;

}

}

//-----------------------------------------

void main()

{

clrscr();

person *student = new person[5];

input(student,5);

output(student,5);

delete [ ]student;

getch();

}

 

Тема. Об’єднання. Робота з елементами об’єднань.

План.

1. Об’єднання.

2. Робота з елементами об’єднань.

 

Опис об'єднань у мові C++ нагадує опис структур, але їхнє призначення інше. Об'єднання слугу­ють для зберігання (послідовного, не одночасного) в деякій ділянці оперативної пам'яті комп'ютера даних різних типів. Потреба в цьому виникає, наприклад, під час створення таб­лиці з даними різних типів. Об'єднання можна описати так:

union <назва типу об'єднання>

{

<тип поля 1> <назва поля 1>;

<тип поля п> <назва поля п>;

}

Усі правила, які розглядалися для опису та використання структур, діють і для об'єднань.

Іншими словами, об'єднання - це змінна, яка може містити (в різні моменти часу) об'єкти різних типів і розмірів. Всі вимоги щодо розмірів і вирівнювання виконує компілятор. Об'єднання дозволяють берегти різнорідні дані в одній і тій же області пам'яті без включення в програму машинно-залежної інформації. Ці засоби аналогічні варіантним записам в Паскалі. Прикладом використовування об'єднань міг би послужити сам компілятор, завідуючий таблицею символів, якщо припустити, що константа може мати тип int, float або бути покажчиком на символ і мати тип char *. Значення кожної конкретної константи повинне зберігатися в змінній відповідного цій константі типу. Працювати з таблицею символів завжди зручніше, якщо значення займають однакову за об'ємом пам'ять і запам'ятовуються в одному і тому ж місці незалежно від свого типу. Мета введення в програму об'єднання - мати змінну, яка б на законних підставах берегла в собі значення декількох типів. Наведемо приклад об'єднання.

union u_tag {

int ival;

float fval;

char *sval;

} u;

Змінна u буде достатньо великої, щоб в ній помістилася будь-яка змінна з вказаних трьох типів: точний її розмір залежить від реалізації. Значення одного з цих трьох типів може бути присвоєно змінній u і далі використано у виразах, якщо це правомірно, тобто якщо тип узятого нею значення співпадає з типом останнього присвоєного їй значення. В тому випадку, якщо щось запам'ятало як значення одного типу, а витягується як значення іншого типу, результат залежить від реалізації.

Об'єднання можуть входити в структури і масиви, і навпаки. Запис доступу до елемента об'єднання, що знаходиться в структурі

(як і структури, що знаходиться в об'єднанні), така ж, як і для вкладених структур. Наприклад, в масиві структур

struct {

char *name;

int flags;

int utype;

union {

int ival;

float fval;

char *sval;

} u;

} symtab[NSYM];

до ival звертаються таким чином: symtab[i].u.ival

а до першого символу рядка sval можна звернутися будь-яким з наступних двох способів:

*symtab[i].u.sval

або symtab[i].u.sval[0]

Фактично об'єднання - це структура, всі елементи якої мають нульовий зсув щодо її базової адреси і розмір якої дозволяє поміститися в ній найбільшому її елементу а вирівнювання цієї структури задовольняє всім типам об'єднання. Операції, застосовні до структур, годяться і для об'єднань, тобто законні присвоєння об'єднання і копіювання його як єдиного цілого узяття адреси від об'єднання і доступ до окремих його елементів.

 

2. Робота з елементами об’єднань.

Розглянемо приклад.Для участі у конференції потрібно заповнити заявку: прізвище, ім'я, адресу, а також зазначати, чи треба бронювати номер у готелі. Якщо житло непотрібне, то записати свій контактний телефон, інакше -зазначити назву готелю. Створити програму, яка б давала змогу ввести отримані дані у базу даних конференції.

// Конференція

#include <iostream.h>

#include <conio.h>

union gotel_tel

{

char gotel[20];

char tel[7];

};

struct konfer

{

char name[15], surname[15], adres[15];

int br; // 1 - треба бронювати номер, 2 - ні

gotel_tel bron;

};

void main()

{

intn = 1;

konfer z;

while (n== 1)

{

cout<<"\n Введіть прізвище, ім'я та адресу\n";

сіn>>z.name >>>z.surname >> z.adres;

cout<<"\n Треба житло? 1 - так, 0 - ні";

сіn>>z.br;

if (z.br)

{

cout << "\n Уведіть назву готелю\п";

сіп>> z.bron.gotel;

}

else

{

cout<<"\n Уведіть номер телефону\n";

сіn>> z.bron.tel;

}

cout<<"\n Наступна заявка? 1 - так, 0 - ні";

сіn >>n;

}

}

Тема. Списки , стеки та черги в мові С++.

План.

1. Поняття про список.

2. Стек.

3. Черги.

 








Дата добавления: 2015-08-26; просмотров: 951;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.048 сек.