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

Int year;

char mon_name[4];

};

struct DATE * input_date(int day, int year, char *month)

{

struct DATE tmp;

tmp.day = day;

tmp.year = year;

strcpy(tmp.mon_name, month); // копіювання стрічки

return &tmp; // взяття адреси змінної

}

void print_date(struct DATE *d)

{

printf(“\nDate - %d %s %d\n”, d->day, d->mon_name, d->year);

}

int main(void)

{

struct DATE d;

d = *(input_date(1, 2000,”січ”));

print_date(&d);

return 0;

}

// або елегантніше

int main(void)

{

print_date(input_date(1, 2000,”січ”));

return 0;

}

Розглянемо детальніше функцію void print_date(struct DATE * d). Як видно з оголошення функції, як формальний параметр використано вказівник на структуру. В такому випадку для звертання до полів структури використовується оператор “->. Для наочної різниці між звертанням змінної типу DATE та вказівником на змінну типу DATE наведено таблицю 1.

Таблиця 1.

struct DATE d;

struct DATE d,*d1;

d1 = &d;

d.date = 1;

d.year = 2000;

strcpy(d.mon_name, “січ”);

d1->date = 1;

d1->year = 2000;

strcpy(d1->mon_name, “січ”);

Структури можна об'єднувати в масив.

Тоді запис struct DATE d[5]; відображає масив з п’яти елементів типу DATE. Доступ до полів структури відбувається наступним чином:

d[0].year;

d[0].date;

Розмір структури можна взнати використавши стандартну операцію. Справа в тому що в мові "C" передбачена унарна операція sizeof, яка виконується під час компіляції, дозволяючи обчислити розмір будь-якого об’єкта. Вираз

sizeof (object)

видає ціле число, що дорівнює розміру вказаного об’єкта. (Розмір визначається в неспецифіцикованних одиницях "байти", які мають той же розмір, що і змінні типу char). Об’єкт може бути фактичною змінною, масивом і структурою, або іменем основного типу, як int або double, або іменем похідного типу, як структура. В нашому випадку

int size;

struct DATE d;

size = sizeof(d);

Структури широко використовуються при побудові різноманітних дерев та списків.

Доступ до компонентів структури

Доступ до полів структури здійснюється за допомогою оператора "." при безпосередній роботі зі структурою або "->" - при використанні вказівників на структуру. Ці оператори (. і ->) називаються селекторами членів класу. Загальний синтаксис для доступу до компонентів структури наступний:

ім'я_змінної_структури . член_даних ;

ім'я_вказівника -> ім'я_поля;

(*ім'я_вказівника) . ім'я_поля;

Наприклад:

1. Прямий доступ до елемента (оператор " . "):

datel[5].day=10;

datel[5].year=1983;

strcpy (bguіr[10].fam, "Ільків");

strcpy (bguіr[10].іm, "Сергій");

bguir[10].weіght=70.0;

bguіrtl] .heіght=180;

bguіr[і].bіrthday.day=15;

bguіr[10].bіrthday.month=l;

bguіr[10].bіrthday.year=1980;

/* Використовуючи пряме звертання до елемента, присвоюємо значення вибраній змінній. Текст поміщається в змінну, використовуючи функцію копіювання - strcpy(); */

2. Доступ по вказівнику (оператор "->"). Попередні оператори можна реалізувати в такий спосіб:

strcpy((per_ptr+10)->fam, "Ільків");

strcpy((per_ptr+l0)->іm,"Сергій");

(per_ptr+10)->weіght=70.0;

(per_ptr+10)->heіght=180;

(per_ptr+10)->bіrthday.day=15;

(per_ptr+10)->bіrthday.month=l;

(per_ptr+10)->bіrthday.year=1980;

/* Використовуючи доступ по вказівнику на структуру, присвоюємо значення відповідній змінній. Вказівник можна використовувати й так:

strcpy(*(per_ptr+10)).fam,"Ільків");

strcpy((*(per_ptr+10)).іm,"Сергій");

(*(per_ptr+10>).weіght=70.0;

(*(per_ptr+10)).heіght=180;

(*(per_ptr+10)).bіrthday.day=15;

(*(per_ptr+10)).bіrthday.month=l;

(*(per_ptr+10)).bіrthday.year=1980; */

Слід зазначити, що якщо змінна i задає номер елемента в масиві структур, то наступні оператори рівноцінні:

bguіr[і].weіght=70;

(bguіr+і)->weіght=70;

(*(bguіr+і)).weіght=70;

(per_ptr+і)->weіght=70;

(*(per_ptr+і)).weіght=70;

per_ptr[і].weіght=70;

тому що було виконане присвоювання per_ptr=bguіr; // per_ptr=&bguіr[0];

Вказівник на елемент структури має всі властивості звичайної змінної. Наприклад, якщо елемент структури є масивом символів, то per_ptr->fam - вказівником- константою на перший байт цього масиву, а per_ptr->fam[0]=’Я' запише в нього букву "Я". Сам же вказівник per_ptr визначає адресу першого байта структурної змінної й одночасно є адресою першого елемента, що входить у структуру. У нашому випадку - адресою fam[0]. Можна визначити адресу будь-якого елемента, що міститься в структурній змінній.

Наприклад:

struct person P1, P2, *р_Р1, *р_Р2;

р_Р1=&Р1; р_Р2=&Р2; // Установили вказівники на змінні

іnt *pі; // Оголошення

float *pf; // вказівників

char *pc; // на відповідний тип

//Їхня ініціалізація

pі=&p_Pl->heіght;

pf=&p_Pl->weіght;

pc=&p_P2->fam[0]; // або pc=p_P2->fam;

Можна визначити адресу змінної-структури, що є елементом іншої структури:

struct date *p_d=&p_P2->bіrthday;

p_d->day=15;

p_d->month=l ;

p_d->year=1980;

Ці оператори рівносильні наступним:

Р2.bіrthday.day=15;

Р2.bіrthday.month=l;

P2.bіrthday.year=1980;

Інший приклад оголошення шаблонів і присвоювання значень елементам змінних типу структура:

struct Poіnt /* Оголошуємо шаблони структур */

{ double х, y;

};

struct Rect

{ struct Poіnt Up_corn;

struct Poіnt Down_corn;

double length;:

double wіdth;

};

voіd maіn()

{ /* Оголошуємо змінні типу структура */

struct Poіnt p1, p2, p_arrl5];

struct Rect r1, r2;

struct Poіnt *p_ptr; // Оголошуємо вказівники

struct Rect *r_ptr; //на тип структури

// Виконання операцій над компонентами структури

pl.x=20;

p_arr[5].x=pl.x-10;

rl.Up_corn.x=p_arr[5].x;

rl.Down_corn.x-30;

rl.Up_corn.y=pl.x;

p_ptr=&pl;

p_ptr->y=35; // Використання вказівника або (*p_ptr).y=35;

p_ptr=p_arr;

(p_ptr+5)-> y-40; // (*( p_ptr+5M .y-40;

r_ ptr=&rl;

r_ptr->Down_corn.y=60; // (*(r_ptr)).Down_corn.y=60;

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

struct man { char *fam;

char *name;

struct man any; };

Однак структура може включати елементи, що є вказівниками на оголошений тип цієї ж структури:

struct man { char *fam;

char *name;

struct man *p_man; };

Можна визначити вказівник на оголошений тип структури й проініціалізувати його. Наприклад:

struct man group[20], studl, *pl, *p2;

pl=&studl;

p2=group; // або p2=Sgroup [0];

Установимо вказівник p_man структури group[0] на studl;

group[0].p_man " PІ; // або p2->p_man=Pl; або p2->p_man=&studl;

Нехай є визначення:

char famі[] = "Давидiв", namel[]="Андрій";

Тоді реалізація операторів:

p2->p_man->fam=faml;

p2->p_man->name=namel;

запише в структурну змінну studl у змінні fam і name відповідно адреси розміщення в пам'яті текстів "Давидiв" і "Андрій". Просування вказівника операцією ++ або -- відповідно збільшує або зменшує значення вказівника на розмір шаблона, тобто встановлює вказівник на початок іншого елемента масиву - наступного або попереднього.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]