Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

9.2. Специфікатори класів пам'яті

Мова програмування C++ підтримує п'ять специфікаторів класів пам'яті:

auto, extern, register, static, mutable

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

Специфікатори класів пам'яті визначають, як повинна зберігатися змінна.

Специфікатор mutable застосовується тільки до об'єктів класів, про які йтиметься попереду. Решту специфікаторів ми розглянемо у цьому розділі.

9.2.1. Застосування специфікатора класу пам'яті auto

Специфікатор класу пам'яті auto оголошує локальну змінну. Але він використовується досить рідко (можливо, Вам ніколи і не доведеться застосувати його), оскільки локальні змінні є "автоматичними" за замовчуванням. Навряд чи Вам трапиться це ключове слово і в чужих програмах.

Рідко використовуваний специфікатор класу пам'яті auto оголошує локальну змінну.

9.2.2. Застосування специфікатора класу пам'яті extern

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

Специфікатор класу пам'яті extern оголошує змінну, але не виділяє для неї області пам'яті.

У програмах, які складаються з двох або більше файлів, кожен файл повинен "знати" імена і типи глобальних змінних, що використовуються програмою в цілому. Проте не можна просто оголосити копії глобальних змінних у кожному файлі. Йдеться про те, що у мові програмування C++ програма може містити тільки одну копію кожної глобальної змінної. Отже, якщо Ви спробуєте оголосити необхідні глобальні змінні у кожному файлі, то виникнуть проблеми. Коли компонувальник спробує скомпонувати ці файли, то він виявить дубльовані глобальні змінні, і компонування програми не відбудеться. Щоб вийти з цього скрутного становища, достатньо| оголосити всі глобальні змінні в одному файлі, а в інших використовувати extern-оголошення, як це показано в табл. 9.1.

Табл. 9.1. Використання глобальних змінних в окремо компільованих модулях

Файл F1

Файл F2

int x, y;

char ch;

int main()

{

//...

}

void func1()

{

x = 123;

}

extern int x, y;

extern char ch;

void func22()

{

x = y/10;

}

void func23()

{

y = 10;

}

У файлі F1 оголошуються та визначаються змінні х, y і ch. У файлі F2 використовується скопійований з файлу F1 перелік глобальних змінних, до оголошення яких додано ключове слово extern. Специфікатор класу пам'яті extern робить змінну відомою для модуля, але насправді не створює її. Іншими словами, ключове слово extern надає компіляторові інформацію про тип і ім'я глобальних змінних, повторно не виділяючи для них пам'яті. Під час компонування цих двох модулів усі посилання на ці зовнішні змінні будуть визначені.

Необхідно пам'ятати! Дотепер ми не уточнювали, у чому полягає відмінність між оголошенням і визначенням змінної, але тут це надзвичайно важливо. Під час оголошення змінної їй присвоюється ім'я і тип, а за допомогою визначення для змінної виділяється тільки пам'ять. Здебільшого оголошення змінних одночасно є їх визначеннями. Якщо імені змінної передує специфікатор класу пам'яті extern, то можна оголосити змінну, не визначаючи її.

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

Для розуміння сказаного розглянемо такий приклад. Звернемо Вашу увагу на те, що глобальні змінні first і last оголошуються не перед, а після функції main().

Код програми 9.3.

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

int main()

{

extern int first, last; // Використання глобальних змінних.

cout << first << " " << last << "\n";

getch(); return 0;

}

// Глобальне визначення змінних first і last.

int first = 10, last = 20;

У процесі виконання цієї програми на екран буде виведено числа 10 20, оскільки глобальні змінні first і last, що використовуються в настанові cout, ініціалізувалися цими значеннями. Оскільки extern-оголошення у функції main() повідомляє компіляторові про те, що змінні first і last оголошуються десь у іншому місці (у цьому випадку нижче, але у тому ж файлі), програму можна скомпілювати без помилок, незважаючи на те, що змінні first і last використовуються до їх визначення.

Важливо розуміти, що extern-оголошення змінних, показані в попередній програмі, необхідні тут тільки з тієї причини, що змінні first і last не були визначені до їх використання у функції main(). Якби їх визначення компілятор виявив раніше визначення функції main(), то потреби в extern-настанові не було б.

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

Варто знати! Незважаючи на те, що специфікатор класу пам'яті extern оголошує, але не визначає змінну, то існує один виняток з цього правила. Якщо в extern-визначенні змінна ініціалізувалася, то таке extern-оголошення стає визначенням. Це дуже важливий момент, оскільки будь-який об'єкт може мати декілька оголошень, але тільки одне визначення.