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

9.2.3. Статичні змінні

Статичні змінні типу static – це змінні "довготривалого" зберігання, тобто вони зберігають свої значення у межах своєї функції або файлу. Від глобальних вони відрізняються тим, що за рамками своєї функції або файлу вони невідомі. Оскільки специфікатор класу пам'яті static по-різному визначає "долю" локальних і глобальних змінних, то ми розглянемо їх окремо.

Локальні static-змінні

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

Локальна static-змінна підтримує своє значення між викликами функції.

Щоб оголосити статичну змінну, достатньо, щоб її типу передувало ключове слово static. Наприклад, у процесі виконання цієї настанови змінна count оголошується статичною:

static int count;

Статичній змінній можна присвоїти початкове значення. Наприклад, у цій настанові змінній count присвоюється початкове значення 200:

static int count = 200;

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

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

Розглянемо приклад використання модифікатора static-змінної. Вона слугує для зберігання поточного середнього значення від чисел, що вводяться користувачем.

Код програми 9.4. Демонстрація механізму використання локальних static-змінних

#include <vcl>

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

#include <conio> // Для консольного режиму роботи

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

int srZnach(int izm); // Обчислення поточного середнього значення.

int main()

{

int num;

do {

cout << "Введіть число (-1 означає вихід): ";

cin >> num;

if(num != -1)

cout << "Поточне середнє дорівнює: " << srZnach(num);

cout << "\n";

} while(num > -1);

getch(); return 0;

}

int srZnach(int izm) // Обчислення поточного середнього значення.

{

static int sum = 0, count = 0;

sum = sum + izm;

count++;

return sum / count;

}

У цій програмі обидві локальні змінні sum і count оголошено статичними, тобто вони були ініціалізовані значенням 0.

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

У цій програмі функцію srZnach() використовують для обчислення поточного середнього значення від чисел, що вводяться користувачем. Оскільки обидві змінні sum і count є статичними, вони підтримують свої значення між викликами функції srZnach(), що дає змогу нам отримати правильний результат обчислень. Щоб переконатися в потребі модифікатора static, спробуйте видалити його з програми. Після цього програма не працюватиме коректно, оскільки проміжна сума втрачатиметься під час кожного виході з функції srZnach().

Глобальні static-змінні

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

Глобальна static-змінна відома тільки для файлу, у якому вона оголошена.

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

Код програми 9.5. Демонстрація механізму використання глобальних static-змінних

// --------------------Перший файл-------------------

#include <vcl>

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

#include <conio> // Для консольного режиму роботи

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

int srZnach(int izm); // Обчислення поточного середнього значення.

void reset();// Очищення глобальних змінних.

int main()

{

int num;

do {

cout << "Введіть число (-1 для виходу, -2 для скидання): ";

cin >> num;

if(num==-2) {

reset();

continue;

}

if fun(num != -1)

cout << "Середнє значення дорівнює: " << srZnach(num);

cout << "\n";

} while(num != -1);

getch(); return 0;

}

// -------------------Другий файл--------------------

static int sum=0, count = 0;

int srZnach(int izm) // Обчислення поточного середнього значення.

{

sum = sum + izm;

count++;

return sum / count;

}

void reset() // Очищення глобальних змінних.

{

sum = 0;

count = 0;

}

У цій версії програми змінні sum і count є глобально статичними, тобто їх глобальність обмежена другим файлом. Отже, вони використовуються функціями srZnach() і reset(), причому обидві вони розташовані в другому файлі. Цей варіант програми дає змогу скидати нагромаджену суму (шляхом встановлення в початкове положення змінних sum і count), щоб можна було усереднити інший набір чисел. Але жодна з функцій, розташованих поза другим файлом, не може отримати доступ до цих змінних. Працюючи з цією програмою, можна очистити попередні нагромадження, ввівши число -2. У цьому випадку буде викликано функцію reset(). Перевірте це. Окрім того, спробуйте отримати з першого файлу доступ до будь-якої із змінних sum або count1.

Отже, ім'я локальної static-змінної відоме тільки функції або блоку коду програми, у якому вона оголошена, а ім'я глобальної static-змінної – тільки файлової, у якому вона "мешкає". По суті, модифікатор static дає змогу змінним існувати так, що про них знають тільки функції, які використовують їх, тим самим "тримаючи у шорах" і обмежуючи можливості негативних побічних ефектів. Змінні типу static дають змогу програмісту "приховувати" одні частини своєї програми від інших. Це може виявитися просто суперперевагою, коли Вам доведеться розробляти дуже велику і складну програму.

Варто знати! Попри те, що глобальні static-змінні, як і раніше, допускаються і широко використовуються в С++-програмі, стандарт мови C++ заперечує проти їх застосування. Для керування доступом до глобальних змінних рекомендуємо інший метод, який полягає у використанні просторів імен. Цей метод буде описано далі (див. розд. 21.1).