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

Структури в якості аргументів функції

У мові Cі існує ряд обмежень на використання структур. Обов'язкові правила полягають у тім, що єдині операції, що ви можете проводити зі структурами, складаються у визначенні її адреси за допомогою операції & і доступі до одного з її членів. Це спричиняє те, що структури не можна привласнювати чи копіювати як ціле, і вони не можуть бути передані функціям чи повернуті ними. На вказівники структур ці обмеження однак не накладаються, так що структури і функції все-таки можуть зі зручністю працювати спільно. І нарешті, автоматичні структури, як і автоматичні масиви, не можуть бути ініціалізовані. Ініціалізація можлива тільки у випадку зовнішніх чи статичних структур.

Давайте розберемо деякі з цих питань, переписавши з цією метою функції перетворення, щоб вони використовували структури. Тому, що правила забороняють безпосередню передачу структури функції, то ми повинні або передавати окремо компоненти, або передати вказівник усієї структури. Перша можливість демонструється на прикладі функції DAY_OF_YEAR:

D.YEARDAY = DAY_OF_YEAR(D.YEAR, D.MONTH, D.DAY);

інший спосіб складається в передачі вказівника. Якщо ми опишемо

HIREDATE як

STRUCT DATE HIREDATE;

і перепишемо DAY_OF_YEAR потрібним образом, ми зможемо тоді написати

HIREDATE YEARDAY = DAY_OF_YEAR(&HIREDATE);

передаючи вказівник на HIREDATE функції DAY_OF_YEAR . Вона повинна бути модифікована, тому що її аргумент тепер є вказівником, а не списком змінних.

DAY_OF_YEAR(PD) /* SET DAY OF YEAR FROM MONTH, DAY */ STRUCT DATE *PD;

{

INT I, DAY, LEAP;

DAY = PD->DAY;

LEAP = PD->YEAR % 4 == 0 && PD->YEAR % 100 != 0

|| PD->YEAR % 400 == 0;

FOR (I =1; I < PD->MONTH; I++)

DAY += DAY_TAB[LEAP][I];

RETURN(DAY);

}

Опис

STRUCT DATE *PD;

говорить, що PD є вказівником структури типу DATE. Запис, показаний на прикладі

PD->YEAR

є новий. Якщо P - вказівник на структуру, то

P-> член структури

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

(*PD).YEAR

але вказівники структур використовуються настільки часто, що запис -> виявляється зручним скороченням. Круглі дужки в (*PD).YEAR необхідні, тому що операція вказівки члена структури старша, ніж * . Обидві операції, "->" і ".", асоціюються ліворуч праворуч, так що конструкції ліворуч і праворуч еквівалентні.

P->Q->MEMB (P->Q)->MEMB

EMP.BIRTHDATE.MONTH (EMP.BIRTHDATE).MONTH

Для повноти нижче приводиться інша функція, MONTH_DAY, переписана з використанням структур.

MONTH_DAY(PD) /* SET MONTH AND DAY FROM DAY OF YEAR */ STRUCT DATE *PD;

{

INT I, LEAP;

LEAP = PD->YEAR % 4 == 0 && PD->YEAR % 100 != 0

|| PD->YEAR % 400 == 0;

PD->DAY = PD->YEARDAY;

FOR (I = 1; PD->DAY > DAY_TAB[LEAP][I]; I++)

PD->DAY -= DAY_TAB[LEAP][I];

PD->MONTH = I;

}

Операції роботи зі структурами "->" і "." поряд з () для списку аргументів і [] для індексів знаходяться на самому верху ієрархії операцій і, отже, зв'язуються дуже міцно. Якщо, наприклад, мається опис

STRUCT {

INT X;

INT *Y;

} *P;

те вираз

++P->X

збільшує х, а не р, тому що він еквівалентний вираженню ++(P->х). Для зміни порядку виконання операцій можна використовувати круглі дужки: (++P)->х збільшує P до доступу до х, а (P++)->X збільшує P після.

Лекція 14

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