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


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

Діапазони значень нумераторів



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

Наприклад, припустимо, що bits і myflag визначені наступним чином:

У такому випадку показаний нижче оператор є допустимим:

Тут 6 не є значенням жодного з нумераторів, проте знаходиться в діапазоні цього певного перерахування.

Діапазон визначається наступним чином. Для знаходження верхньої межі вибирається нумератор з максимальним значенням. Потім шукається найменше число, що є степенем двійки, яке більше цього максимального значення, і з нього віднімається одиниця. (Наприклад, максимальне значення bigstep, як визначено вище, рівне 101. Мінімальне число, що представляє ступінь двійки, яке більше 101, дорівнює 128, тому верхньою межею діапазону буде 127.) Для знаходження мінімальної межі вибирається мінімальне значення нумератора. Якщо воно дорівнює 0 або більше, то нижньою межею діапазону буде 0. Якщо ж мінімальне значення нумератора негативне, використовується такий же підхід, як при обчисленні верхньої межі, але зі знаком мінус. (Наприклад, якщо мінімальний нумератор дорівнює -6, то наступним степенем двійки буде -8, і нижня межа виходить рівною -7.)

Ідея полягає в тому, щоб компілятор міг з'ясувати, скільки місця необхідно для зберігання перерахування. Він може використовувати від 1 байт чи менше для перерахувань з невеликим діапазоном, і до 4 байт - для перерахувань зі значеннями типу long.

Стандарт C++ 11 розширює перерахування додаванням форми, яка називається обмеженим перерахуванням.

 

Лекція 5

Вказівники та вільне сховище

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

Давайте розглянемо іншу стратегію, важливість якої проявляється при розробці класів C++. Ця стратегія заснована на вказівниках, які представляють змінні, що зберігають адреси значень замість самих значень. Але перш ніж звернутися до вказівників, давайте поговоримо про те, як явно отримати адресу звичайної змінної. Для цього застосовується операція отримання адреси, що позначається символом &, до змінної, адреса якої цікавить. Наприклад, якщо home - змінна, то &home - її адреса. У лістингу 12 демонструється використання цієї операції:

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

У показаній тут конкретній реалізації cout використовується шістнадцяткова нотація при відображенні значень адрес, тому це звичайна нотація, застосовувана для вказання адрес пам'яті. (Деякі реалізації застосовують десяткову нотацію.) Наша реалізація зберігає donuts в пам'яті з меншими адресами, ніж cups. Різниця між цими двома адресами становить 0x0065fd44-0x0065fd40, або 4 байти. Звичайно, в різних системах ви отримаєте різні значення цих адрес. До того ж деякі системи можуть зберігати cups перед donuts, і різниця між адресами складе 8, тому що cups має тип double. Інші системи можуть навіть розмістити ці змінні в пам'яті далеко один від одного, а не поруч.

Таким чином, використання звичайних змінних трактує значення як іменовану величину, а її місце розташування - як похідну величину.

Нова стратегія зберігання даних змінює трактування місця розташування як іменованої величини, а значення - як похідної величини. Для цього передбачений спеціальний тип змінної - вказівник, який може зберігати адресу значення. Таким чином, ім'я вказівника представляє розташування. Застосовуючи операцію *, яка називається непрямим значенням або операцією розіменування, можна отримати значення, що зберігається в зазначеному місці. (Так, це той же символ *, який застосовується для позначення арифметичної операції множення; C++ використовує контекст для визначення того, що мається на увазі в кожному конкретному випадку - множення або розіменування.) Припустимо, наприклад, що manly - це вказівник. У такому випадку manly представляє адресу, a *manly - значення, що знаходиться за цією адресою. Комбінація *manly стає еквівалентом простої змінної типу int. Ці ідеї демонструються в лістингу 13. Також там показано, як оголошується вказівник.

Лістинг 13. pointer.cpp

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

Як бачите, змінна updates типу int і змінна-вказівник p_updates - це дві сторони однієї монети. Змінна updates в першу чергу представляє значення, а для отримання його адреси використовується операція &, в той час як p_updates представляє адресу, а для отримання значення застосовується операція * (мал. 7) Оскільки p_updates вказує на updates, конструкції *p_updates і updates повністю еквівалентні. Ви можете використовувати *p_updates точно так само, як використовуєте змінну типу int. Як показано в прикладі з лістингу 13, можна навіть присвоювати значення *p_updates. Це змінює значення вказаної змінної - updates.

Мал. 7. Дві сторони однієї монети

 




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

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