Помощничек
Главная | Обратная связь


Археология
Архитектура
Астрономия
Аудит
Биология
Ботаника
Бухгалтерский учёт
Войное дело
Генетика
География
Геология
Дизайн
Искусство
История
Кино
Кулинария
Культура
Литература
Математика
Медицина
Металлургия
Мифология
Музыка
Психология
Религия
Спорт
Строительство
Техника
Транспорт
Туризм
Усадьба
Физика
Фотография
Химия
Экология
Электричество
Электроника
Энергетика

Інші властивості структур



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

Приклад виведення програми:

Як бачите, почленне присвоювання працює, і всі члени структури choice отримали відповідні значення членів структури bouquet.

Можна комбінувати визначення форми структури зі створенням структурних змінних. Щоб зробити це, відразу після закриваючої фігурної дужки потрібно вказати ім'я змінної або декількох змінних:

Можна навіть ініціалізувати створену змінну, як показано нижче:

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

Ще один трюк, який можна зробити зі структурою - створити структуру без імені типу. При визначенні ім'я дескриптора опускається і відразу слідує ім'я змінної:

Це створює одну структурну змінну з ім’ям position. До її членів можна звертатися через операцію точки, як в position.х, але ніякого загального імені для типу не оголошується. Ви не зможете згодом створювати інші змінні того ж типу.

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

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

Структура inflatable містить масив (з ім’ям name). Також можна створювати масиви, елементами яких є структури. Підхід тут в точності збігається з таким для масивів фундаментальних типів. Наприклад, щоб створити масив з 100 структур inflatable, можна вчинити так:

Це оголошення робить gifts масивом структур inflatable. В результаті кожен елемент масиву, такий як gifts[0] або gifts[99], є об'єктом типу inflatable і може бути використаний з операцією членства:

Майте на увазі, що сам по собі gifts є масивом, а не структурою, тому конструкція на зразок gifts.price - некоректна.

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

Оскільки кожен елемент масиву є структурою, його значення представляється ініціалізацією структури. Таким чином, ми отримуємо наступну конструкцію:

Як звичайно, можете форматувати все це на свій розсуд. Наприклад, обидві ініціалізації можуть бути розташовані в одному рядку або ж ініціалізація кожного окремого члена структури може займати окремий рядок.

У лістингу 11 показано приклад використання масиву структур. Зверніть увагу, що оскільки guests - масив inflatable, типом елемента guests[0] є inflatable, тому ви можете використовувати його з операцією точки для доступу до членів структури inflatable.

Лістинг 11. arrstruct.cpp

Приклад виконання програми:

Лекція 4

Об’єднання

Об'єднання - це формат даних, який може зберігати в межах однієї області пам'яті різні типи даних, але в кожен момент часу тільки один з них. Тобто, в той час як структура може містити, скажімо, int, long і double, об'єднання може зберігати або int, або long, або double. Синтаксис схожий на синтаксис структур, але зміст відрізняється. Наприклад, розглянемо таке оголошення:

Змінну one4all можна використовувати для зберігання int, long або double, якщо тільки робити це не одночасно:

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

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

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

Оскільки об'єднання є анонімним, id_num і id_char трактуються як два члени prize, що розділяють одну і ту ж саму адресу пам'яті. Необхідність в проміжному ідентифікаторі idval відпадає. Яке поле активно в кожен момент часу, залишається на розсуд програміста.

Об'єднання часто (але не тільки) використовуються для економії простору пам'яті. У наші часи, коли доступні гігабайти ОЗУ і терабайти на жорстких дисках, це може здатися не особливо важливим, але не всі програми на C++ орієнтовані на подібні системи. Мова C++ також застосовується для вбудованих систем, таких як процесори, керуючі, МРЗ-програвачем або марсоходом. У таких додатках простір може бути дефіцитним ресурсом. Крім того, об'єднання часто використовуються при роботі з операційними системами або апаратними структурами даних.

Перерахування

­Засіб C++ enum є альтернативний по відношенню до const спосіб створення символічних констант. Він також дозволяє визначати нові типи, але в дуже обмеженій манері. Синтаксис enum подібний синтаксису структур. Наприклад, розглянемо наступний оператор:

Цей оператор робить дві речі.

· Оголошує ім'я нового типу - spectrum; при цьому spectrum називається перерахуванням, майже так само, як змінна struct називається структурою.

· Встановлює red, orange, yellow і т.д. як символічні константи для цілочисельних значень 0-7. Ці константи називаються нумераторами.

За замовчуванням нумераторам присвоюються цілочисельні значення, починаючи з 0 для першого з них, 1 - для другого і т.д. Це правило за замовчуванням можна перевизначити, явно привласнюючи цілочисельні значення.

Ім'я перерахування можна використовувати для оголошення змінної з цим типом перерахування:

Змінні типу перерахувань мають ряд спеціальних властивостей.

Єдиними допустимими значеннями, які можна привласнити змінної типу перерахування без необхідності приведення типів, є значення, вказані у визначенні цього перерахування. Розглянемо приклад:

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

Для перерахувань визначена тільки операція присвоювання. Зокрема, арифметичні операції не передбачені:

Однак деякі реалізації не накладають таких обмежень. Це дозволяє порушити обмеження типу. Наприклад, якщо band рівне ultraviolet, або 7, а потім виконується ++band, і якщо таке дозволено компілятором, то band отримає значення, неприпустиме для типу spectrum. Знову-таки, для досягнення максимальної переносимості ви повинні дотримуватися обмежень.

Перерахування - цілочисельні типи, і вони можуть бути представлені у вигляді int, проте тип int НЕ перетворюється автоматично в тип перерахування:

Зверніть увагу, що хоча значення 3 в цьому прикладі відповідає нумератору green, все ж присвоювання 3 змінній band викликає помилку невідповідності типу. Але присвоювання green змінній band коректне, тому що обидва вони мають тип spectrum. І знову, деякі реалізації не накладають такого обмеження. У виразі 3+red додавання не визначене для перерахувань. Однак red перетворюється в тип int, в результаті чого виходить значення типу int. Завдяки перетворенню перерахування до int в даній ситуації, ви можете використовувати нумератори в арифметичних виразах, комбінуючи їх із звичайними цілими, навіть незважаючи на те, що така арифметика не визначена для самих нумераторів.

Попередній приклад

не працює з іншої причини. Так, дійсно, операція + не визначена для нумератора. Але також вірно і те, що нумератори перетворюються в цілі числа, коли застосовуються в арифметичних виразах, тому вираз orange+red перетворюється на 1+0, що цілком коректно. Але це вираз має тип int, тому воно не може бути присвоєно змінної band типу spectrum.

Ви можете присвоїти значення int змінної enum, якщо отримане значення допустимо і застосовується явне зведення типу:

Але що буде, якщо ви спробуєте виконати приведення типу для неприпустимого значення? Результат не визначений, в тому сенсі, що спроба не буде сприйнята як помилкова, але ви не можете покладатися на отримане в результаті значення:

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





©2015 studopedya.ru Все права принадлежат авторам размещенных материалов.