Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Бичков - Основи сучасного програмування.doc
Скачиваний:
69
Добавлен:
07.03.2016
Размер:
2.67 Mб
Скачать

Void f(void)

{

i++;

}

int i=5;

main()

{

i++;

}

У функції f змінна і недоступна. Щоб вона була доступною, необхідно розширити область дії змінної шляхом її оголошення перед функцією f: int i;

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

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

6.8. Класи пам'яті

Існує чотири специфікації класів пам'яті:

 register;

 auto;

 static;

 extern.

Специфікатори класу пам'яті можуть впливати на час життя та область дії програмних об'єктів. Специфікатор класу пам'яті register дозволяє розміщувати відповідну змінну (типу int) у регістрах мікропроцесора. Якщо місця там немає, то відповідна специфікація ігнорується і змінна вважається автоматичною, тобто має клас пам'яті auto. Клас пам'яті auto може бути випущеним. Будь-яка змінна вважається автоматичною за умовчанням, локальна змінна записується в стек. Специфікатор класу пам'яті static, що застосовується до зовнішнього об'єкта – змінної чи функції, – обмежує область дії лише вихідним файлом. Відповідний специфікатор може застосовуватись і до внутрішніх об’єктів. Це дає можливість вплинути на час життя відповідної змінної – він стає глобальним. Наприклад:

{

static int i;

}

Статистичні змінні записуються у сегмент даних.

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

файл1 файл2

extern int i; int i=5;

Зауважимо, що при визначенні змінної допускається її ініціалізація:

TYPE x=вираз;

або

TYPE x; /*опис*/

x=вираз; /*обрахування початкового значення*/

Розглянемо фрагмент програми:

#include <stdio.h>

extern double sqrt(); /*квадратний корінь*/

double x=1.17;

double s12=sqrt(12.0); /*#1*/

double y=x*2.0; /*#2*/

FILE *fp=fopen("out.out","w"); /*#3*/

main(){

double ss=sqrt(25.0)+x; /*#4*/

...

}

Рядки з мітками #1, #2 і #3 помилкові, адже при ініціалізації статичних даних (а s12, y і fp такими і є, оскільки описані поза тілом деякої функції) вираз має складатися тільки з констант, оскільки він обраховується компілятором. Тому ні використання значень змінних, ні виклики функцій у даному випадку не допустимі (але можна брати адресу змінних).

У рядку #4 ми ініціалізуємо автоматичну змінну ss. Тому вираз для ініціалізації обраховується вже не компілятором, а під час виконання програми, що дає нам право використовувати змінні, виклики функцій і т. п., тобто вирази мови С, без обмежень.

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

Таблиця 6.1

Рівень

Об'єкт

СПКП

Час життя

Область дії

Зовнішній

визначення

змінної

Static

глобальний

від точки визначення до кінця файла

оголошення

змінної

Extern

глобальний

від точки визначення до кінця файла

оголошення

чи визначення

функції

Extern чи

Static

глобальний

від точки визначення до кінця файла

Внутрішній

оголошення

змінної

Extern

глобальний

блок

визначення

змінної

Static

глобальний

блок

визначення

змінної

Auto чи

Register

локальний

блок

оголошення

функції

Extern чи

Static

глобальний

залишок

вихідного файла