Класи пам’яті у C++ Builder

Кожна змінна характеризується деяким класом пам’яті, який визначає її час життя, протягом якого ця змінна існує у пам’яті. Одні змінні існують недовго, інші неодноразово створюються і знищуються, треті існують протягом виконання програми. У C++ Builder є чотири специфікації класу пам’яті: auto, register, extern і static. Специфікація класу пам’яті ідентифікатора визначає клас пам’яті, область дії та простір імен. Області дії (областю видимості) ідентифікатора називається область програми, в якій на дану змінну (як, втім, і на будь-який ідентифікатор – константу, функцію і т.п.) можна послатися. На деякі змінні можна послатися у будь-якому місці програми, тоді як на інші лише у певних її частинах.

Клас пам’яті визначається, зокрема, місцем оголошення змінної. Локальні змінні оголошуються усередині деякого блоку чи функції. Ці змінні видно тільки в межах блоку, в якому вони оголошені. Блоком називається фрагмент коду, обмежений фігурними дужками “{ }”. Глобальні змінні оголошуються поза будь-яким блоком або функцією.

Специфікації класу пам’яті можуть бути розбиті на два класи: автоматичний клас пам’яті із локальним часом життя та статичний клас пам’яті із глобальним часом життя. Ключові слова auto та register використовуються для оголошення змінних з локальним часом життя. Ці специфікації можна застосовувати лише до локальних змінних. Локальні змінні створюються при вході до блоку, в якому вони оголошені, існують лише під час активності блоку і зникають при виході з блоку.

Специфікація auto, як і інші специфікації, може вказуватися перед типом оголошення змінних. Наприклад:

auto float x, у;

Локальні змінні є змінними з локальним часом життя за промовчанням, тому ключове слово auto використовується рідко. Далі ми посилатимемося на змінні автоматичного класу пам’яті просто як на автоматичні змінні. Нехай, наприклад, є наступний фрагмент коду:

{
int i = 1;
...
i++;
...
}

до якого під час роботи програми відбувається неодноразове звернення. При кожному такому зверненні змінна i створюватиметься заново (під неї виділятиметься пам’ять) і ініціалізуватиметься одиницею. Потім під час роботи програми її значення збільшуватиметься на 1 операцією інкременту. Наприкінці виконання цього блоку змінна зникне і виділена під неї пам’ять звільниться. Отже, у такій локальній змінній неможливо зберігати якусь інформацію між двома зверненнями до блоку.

Специфікація класу пам’яті register може бути поміщена перед оголошенням автоматичної змінної, щоб компілятор зберігав змінну над пам’яті, а одному з високошвидкісних апаратних регістрів комп’ютера. Наприклад:

register int i = 1;

Якщо змінні, що інтенсивно використовуються, такі як лічильники або суми можуть зберігатися в апаратних регістрах, накладні витрати на повторне завантаження змінних з пам’яті в регістр і зворотне завантаження результату в пам’ять можуть бути виключені. Це скорочує час обчислень.

Компілятор може проігнорувати оголошення register. Наприклад, може виявитися недостатньою кількість регістрів, доступних компілятор для використання. До того ж компілятор, що оптимізує, здатний розпізнавати часто використовувані змінні і вирішувати, поміщати їх в регістри чи ні. Отже, явне оголошення специфікації register використовується рідко.

Ключові слова extern і static використовуються, щоб оголосити ідентифікатори змінних як ідентифікатори статичного пам’яті з глобальним часом життя. Такі змінні існують з початку виконання програми. Для таких змінних пам’ять виділяється та ініціалізується одразу після початку виконання програми.

Існує два типи змінних статичного класу пам’яті: глобальні змінні та локальні змінні, оголошені специфікацією класу пам’яті static. Глобальні змінні за умовчанням належать до класу пам’яті extern. Глобальні змінні створюються шляхом розміщення їх оголошень поза описом будь-якої функції та зберігають свої значення протягом усього часу виконання програми. На глобальні змінні може посилатися будь-яка функція, яка розташована після їхнього оголошення або опису у файлі.

Змінні, які використовуються лише в окремій функції, краще оголошувати як локальні змінні цієї функції, а не як глобальні змінні. Це полегшує читання програми і дозволяє уникнути випадкового доступу до таких змінних інших функцій.

Локальні змінні, оголошені з ключовим словом static, відомі лише тому блоці, у якому визначено. Але на відміну від автоматичних змінних локальні змінні static зберігають свої значення протягом усього часу виконання програми. При кожному наступному зверненні до цього блоку локальні змінні містять значення, які вони мали при попередньому зверненні.

Повернемося до вже розглянутого вище прикладу, але вкажемо для змінної i статичний клас:

{
static int i = 1;
...
i++;
...
}

Ініціалізація змінної i відбудеться лише один раз за час виконання програми. При першому зверненні до цього блоку значення змінної i дорівнюватиме 1. До кінця виконання блоку її значення дорівнюватиме 2. При наступному зверненні до блоку це значення збережеться і при закінченні повторного виконання блоку i дорівнюватиме 3. Таким чином, статична змінна здатна зберігати інформацію між зверненнями до блоку і, отже, може використовуватися, наприклад, як лічильник числа звернень.

Усі числові змінні статичного класу пам’яті приймають нульові початкові значення, якщо програміст явно не вказав на інші початкові значення. Статичні змінні – покажчики, які теж мають нульові початкові значення.

Специфікації класу пам’яті extern використовуються у програмах із кількома файлами. Нехай, наприклад, у модулі Unit1 у файлі Unit1.cpp або Unit1.h (немає значення) оголошено глобальну змінну:

int а = 5;

Тоді, якщо в іншому модулі Unit2 у файлі Unit2.cpp або Unit2.h оголошено глобальну змінну:

extern int а;

то компілятор розуміє, що йдеться про одну і ту ж змінну. І обидва модулі можуть із нею працювати. Для цього навіть немає необхідності зв’язувати ці модулі директивою #include, що включає модуль Unit1 заголовковий файл другого модуля.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *