Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Бичков - Основи сучасного програмування.doc
Скачиваний:
69
Добавлен:
07.03.2016
Размер:
2.67 Mб
Скачать

4.3. Еквівалентність типів

При обробці операції присвоювання вигляду

х=вираз

компілятор мови програмування або дозволить, або не дозволить її виконання, якщо типи лівої та правої частин не збігаються (це залежить від компілятора конкретної мови програмування). У випадку різнотипних лівої та правої частин можливі неадекватний результат, втрата значимості тощо. Тому перевірка еквівалентності типів логічна в багатьох випадках. Існує два типи еквівалентності: структурна та іменна.

При використанні структурної еквівалентності два об'єкти належать еквівалентним типам, якщо їх структури однакові. Тому компілятор дозволяє присвоювання в операторі square=kut/2, оскільки структурно ці дві змінні належать типу float. Фактично при структурній еквівалентності похідні типи – не більше ніж синоніми для імені породжувального.

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

4.4. Успадкування атрибутів

Множина значень і визначені для типу операції складають множину атрибутів типу. Якщо використовується структурна еквівалентність типів, то питання про те, які атрибути похідний тип має успадкувати від породжувального, досить просте: він успадковує їх усі. Однак підвищена надійність під час компіляції, що досягається при іменній еквівалентності, ускладнює успадкування атрибутів для похідних типів. Немає причин, з яких похідний тип не міг би успадковувати повну множину значень і літеральні позначення від породжувального, але є вагомі підстави вважати, що він не має успадковувати всі його операції.

Розглянемо просту програму для обчислення площі прямокутника:

#include <stdio.h>

main()

{

typedef float length, square;

length x,y;

square a;

scanf("%d%d',&x,&y);

a=x*y;

printf("a=%d',a);

}

Якщо операція * успадковується від типу float, то розумно припустити, що тип результату операції х*у такий самий, як і тип операндів (у нашому випадку – тип length). Отже, операція присвоювання а=х*у; незаконна, тому що змінна a типу square. Операція присвоювання х=х*у; є законною, але нісенітницею з погляду предметної галузі.

Однак мова С++ має механізми перевизначення існуючих операцій і визначення нових. Операція *, визначена для двох операндів типу type1, відрізняється від операції *, визначеної для двох операндів типу type2. У таких випадках говорять, що операція перевантажена. Яка операція мається на увазі в конкретному контексті, визначається компілятором при дослідженні типів передбачуваного результату. Тому використання а=х*у; цілком коректне.

4.5. Перераховні типи

Визначають множини значень та операцій для відповідної змінної. Визначений користувачем перераховний тип можна описати за допомогою простого перерахування значень, що ним задаються. Наприклад, потрібен тип для позначення днів тижня. Його можна описати як

enum day_of_week {mon, tue, wed, the, fri, sat, son};

Кожне значення типу позначається ім'ям ідентифікатора, за допомогою якого на це значення потім посилаються. Значення відповідних ідентифікаторів за умовчанням у мові С визначаються як послідовні цілі числа, починаючи з 0. Такий порядок можна змінити, присвоївши відповідному ідентифікатору необхідне число. Наприклад, можемо досить елегантно визначити новий тип для зображення шістнад­цяткового числа:

enum hexx

{A=10,B,C,D,E,F};

Десяткові цифри 0–9 будуть одночасно й шістнадцятковими, тому немає необхідності в їх перевизначенні. Тут усі символи від 'А' до 'F' перевантажені. Оскільки порядкові значення нового типу безпосередньо зображують фактичні шістнадцяткові, то програмування істотно спрощується.