Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КТіП Лекції 20110516 (1).doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1 Мб
Скачать
☆
  1. Класи пам'яті даних

    1. Клас пам'яті, час існування і видимість об’єкта

Кожен об’єкт програми (змінна, константа, функція) має свій тип і клас пам'яті. Тип визначає обсяг пам'яті, який виділяється для даного об’єкта, і операції, що можуть виконуватися над цим об’єктом. Клас пам'яті задає: 1) місце розташування об’єкта в оперативній пам'яті; 2) час існування об’єкта – це час, протягом якого об’єкт зберігається в оперативній пам'яті; 3) область видимості, яка визначає ту частину програми, де можна використовувати цей об’єкт.

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

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

Глобальні та статичні дані зберігаються в окремій області оперативної пам'яті, яку в системах з сегментною організацією пам'яті називають сегментом даних. Локальні дані зберігаються в області пам'яті, що називається стеком. динамічні дані – в області пам'яті, що підлягає динамічному розподілу.

Класи пам'яті об’єктів пов’язані з поняттям програмного блоку. Блоком в С++ вважається тіло функції, а також кожна внутрішня група описів та операторів у фігурних дужках. За правилами замовчування змінні, описані всередині блоку, та формальні параметри функцій мають локальний час існування, а змінні, описані зовні всіх блоків, тобто між функціями, мають глобальний час існування. Відповідно говорять про внутрішні (локальні) і зовнішні (глобальні) оголошення об’єктів програми.

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

За областю видимості (або областю дії) об’єкти також ділять на три групи: 1) глобальні – видимі в межах усієї програми; 2) частково глобальні – видимі в межах одного програмного файлу; 3) локальні – видимі в блоці, де оголошено даний об’єкт.

    1. Область дії глобальних і локальних змінних

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

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

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

  3. змінні, що є параметрами прототипу функції, видимі тільки в межах цього прототипу;

  4. якщо ім’я внутрішньої змінної збігається з іменем якогось зовнішнього об’єкту, то в межах цього блоку внутрішня змінна «закриває» зовнішній об’єкт, за межами блоку дія зовнішнього об’єкту відновлюється;

  5. клас пам'яті змінних можна встановити явно, використовуючи відповідні специфікатори класів пам'яті.

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

#include <iostream>

using namespace std;

int main( ) {

int a = 2, b = 3;

{

int a = 4;

cout << a << endl; // 4

cout << b << endl; // 3

a = 123;

}

cout << a << endl; // 2

cout << b << endl; // 3

}

В цьому прикладі в програмі існують дві змінні з іменем а. Вони оголошені в рідних програмних блоках, тому під час компіляції програми помилки не виникає. Але у внутрішньому блоці внутрішня змінна а буде «закривати» зовнішню – на екран виводиться її значення, всі операції, зокрема a = 123; виконуються теж над нею. При виході з даного програмного блоку внутрішня змінна а видаляється з пам'яті, знову починаємо використовувати зовнішню змінну а.

Наступний приклад:

#include <iostream>

using namespace std;

int a = 1;

void test( void ) {

int a = 3;

cout << a << endl; // 3

}

int main( ) {

int a = 2;

cout << a << endl; // 2

test( );

}

Тут є три змінні з іменем а: одна глобальна, оголошена поза межами всіх функцій, і по одній в програмних блоках функцій main i test. При виконанні програми на екран будуть виводитися значення змінних, оголошення яких розташовані найближче до точки їх використання, тобто змінна а, оголошена в функції main, буде «закривати» глобальну змінну а, змінна а, оголошена в функції test, буде закривати змінну а із main. Видалимо оголошення змінної а з функції test:

#include <iostream>

using namespace std;

int a = 1;

void test( void ) {

cout << a << endl; // 1

}

int main( ) {

int a = 2;

cout << a << endl; // 2

test( );

}

Як і в попередньому прикладі, оголошення змінної а всередині функції main закриває глобальну змінну а. Але всередині функції test виконується звертання до глобальної змінної а. Змінна а з функції main в цьому програмному блоці не визначена. Це можна побачити, якщо видалити з цієї програми оголошення глобальної змінної а:

#include <iostream>

using namespace std;

void test( void ) {

cout << a << endl; // Помилка, змінна а не визначена

}

int main( ) {

int a = 2;

cout << a << endl;

test( );

}

Всередині функції test програма звертається до змінної а. Але в цьому програмному блоці така змінна не визначена, змінна а є внутрішньою змінної іншого програмного блоку.