Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lec_10-1_Klasy Pam-Skl Ogol.doc
Скачиваний:
4
Добавлен:
20.07.2019
Размер:
180.22 Кб
Скачать

Лекція № 10 34

Лекція № 10 Класи пам'яті

Складні оголошення мови

У мові С є інструмент, що дозволяє керувати ключовими механізмами використання пам'яті і створювати складні і гнучкі програми.

Цей інструмент - класи пам'яті. Кожна змінна належить до одного з чотирьох класів пам'яті. Ці 4 класи пам'яті описуються наступними ключовими словами:

auto - автоматична,

extern - зовнішня,

static - статична,

register - регістрова.

Тип пам'яті вказується модифікатором - ключовим словом, що стоїть перед специфікацією типу змінної. Наприклад: static int sum; register int plus;

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

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

Автоматичні змінні зберігаються в оперативній пам'яті машини, точніше, в стеку.

Регістрові (register) змінні зберігаються в регістрах процесора. Доступ до змінних, що зберігаються в регістровій пам'яті, набагато швидший, ніж до тих,, які зберігаються в оперативній пам'яті комп'ютера.

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

Опис регістрової змінної має вигляд: register int quick;

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

• не використати взагалі;

• використати тільки тоді, коли є ключове слово register;

• по розсуду компілятора.

Зовнішня змінна (extern) відноситься до глобальних змінних. Вона може бути оголошена як поза, так і всередині тіла функції:

void f(void) j;

{ extern int j; /*оголошення зовнішньою змінною всередині функції*/ … }

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

Коли ми в одному з файлів опишемо поза тілом функції глобальну змінну

flоаt global; то для неї виділиться місце в пам'яті в розділі глобальних змінних і констант.

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

Використання оголошення extern float global; не приводить до виділення пам'яті, а повідомляє компілятору, що така змінна буде описана в іншому файлі. І тоді при компонуванні програми, що складається з декількох файлів, компілятор буде шукати опис цієї змінної і зв'язувати її з використанням в інших файлах.

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

Якщо це ж ім'я без ключового слова extern буде оголошене всередині функції, то під цим ім'ям буде створена вже інша автоматична змінна. Можна до оголошення цією змінною додати ключове слово auto, щоб показати, що ви не помилилися, а навмисно продублювали ім'я.

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

Наступні приклади демонструють різні способи опису зовнішніх змінних:

int var; /* описана зовнішня змінна var */

main( )

{ extern int var, varl; /* оголошена та ж зовнішня змінна •/ …

func1( )

{ extern int varl; /* оголошена зовнішня змінна varl змінна var також зовнішня,

} хоча вона і не описана в цьому блоці */

func2( ) /* змінна var зовнішня* /

{ } /* змінна varl невидима для цієї функції в цьому блоці */

int varl; /* опис зовнішньої змінної */

}

func3( )

{ /*Для цієї функції varl зовнішня */

int var, /* змінна var описана як локальна і не пов'язана з глобальної змінної var.

} За замовчанням ця змінна автоматична */

func4()

{ /* тут змінна var є зовнішньою глобальною змінною */

auto int varl; /* змінна varl локальна автоматична змінна */...

}

При описі статичних змінних перед описом типу ставиться ключове слово static.

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

Локальні статичні змінні ініціалізувати нулем, якщо не вказаний інший ініціалізатор. При цьому опис з ініціалізацією

sfatfc int count =10;

локальної статичної змінної count викликає однократну ініціалізацію змінної count при виділенні під неї місця.

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

#include <stdio.h> /*Приклад із використання статичноi змiнноi */

void trystat(void); /* прототип функцiї */

main(void)

{ int i;

for (i=1; i<=3; i++)

{ printf("Виклик # %d \n", i);

trystat();

printf("Виклик # %d \n", i);

trystat();}

printf("\n======================== \n");

return 0;

}

void trystat(void)

{int auto_1=1;

static int stat_1=1;

printf("auto_1=%d stat_1=%d \n", auto_1++, stat_1++);

}

Можна описати також глобальну (зовнішню) статичну змінну, тобто описати змінну типу static поза будь-якою функцією. Відмінність зовнішньої змінної від зовнішньої статичної змінної полягає в області їх дії.

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

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

У таблиці приведені область дії і тривалість існування змінних різних класів пам'яті:

Клас пам'яті

Ключове слово

Час існування

Область дії

Автоматичний

Регістровий

Статичний

локальний

auto

register

static

тимчасово

тимчасово

постійно

блок

блок

блок

Статичний глобальний

static

постійно

файл

Зовнішній

extern

постійно

програма

У програмі може бути описано декілька змінних з одним і тим же ім'ям

Звичайно, в різних блоках.

У прикладі оголошена одна глобальна змінна і три локальних змінних з одним і тим же ім'ям var.

#include <stdio.h>

void f(void);

void f1(void);

int var = 7; /* Глобальна змінна, ініціалізувати значенням 7 */

main (void)

{int var=10; /*лок. змiнна, закриваюча видимість глоб. змінної */

printf("var=%d\n", var); /* буде надруковано vаг =10 */

var++;

// Новий блок

{int var=200; /* лок. змінна, що закриває видимість іншої

лок. і глоб. змінних*/

printf( "var=%d\n", var); /* буде надруковано var=200 */

var++;}

printf( "var=%d\n", var++); /* буде надруковано var=11*/

f(); printf( "var=%d\n", var++); /* буде надруковано var=12*/

f1(); printf( "var=%d\n", var++); /* буде надруковано var=13*/

f1(); printf( "var=%d\n", var++); /* буде надруковано var=14*/

return 0;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]