Специфікатори класу пам'яті
Нижче перераховуються специфікатори класу пам'яті:
auto,
static,
extern,
egister,
typedef .
Специфікатор typedef не реалізовує виділення пам'яті і називається "специфікатором класу пам'яті" тільки по синтаксичних міркуваннях.
Автоматичні змінні є внутрішніми по відношенню до функцій; вони виникають при вході в функцію і зникають при виході з неї.
Описи auto, static і register служать також як визначення в тому значенні, що вони спричиняють резервування потрібної кількості пам'яті.
У випадку extern повинно бути присутнім зовнішнє визначення ідентифікаторів, що вказується десь поза функцією, в якій вони описані.
Опис register краще усього уявляти собі як опис auto разом з натяком компілятору, що описаним таким чином змінні будуть часто використовуватися.
Крім того, в регістрах можуть зберігатися тільки змінні певних типів. Існує і інше обмеження на використання регістрових змінних: до них не можна застосовувати операцію взяття адреси &.
При розумному використанні регістрових описів можна чекати отримання менших по розміру і більш швидких програм.
Опис може містити не більше за одного специфікатора класу пам'яті.
Якщо опис не містить специфікатора класу пам'яті, то вважається, що він має значення auto.
Статичні змінні (static)
Статичні змінні являють собою третій клас пам'яті, в доповненні до автоматичних змінних і extern, з якими ми вже зустрічалися.
Статичні змінні можуть бути або внутрішніми, або зовнішніми. Внутрішні статичні змінні точно так само, як і автоматичні, є локальними для деякої функції, але, на відміну від автоматичних, вони залишаються існувати, а не з'являються і зникають разом із зверненням до цієї функції. це означає, що внутрішні статичні змінні забезпечують постійне, недоступне ззовні зберігання всередині функції.
Символьні рядки, що з'являються всередині функції, як, наприклад, аргументи printf, є внутрішніми статичними.
Зовнішні статичні змінні визначені в іншій частині того початкового файла, в якому вони описані, але не в якому-небудь іншому файлі.
Статична пам'ять, як внутрішня, так і зовнішня, специфікується словом static, що стоїть перед звичайним описом. Змінна є зовнішньою, якщо вона описана поза якою б те не було функцією, і внутрішньою, якщо вона описана всередині деякої функції.
Регістрові змінні (register)
Четвертий клас пам'яті називається регістровим. Опис register вказує компілятору, що дана змінна буде часто використовуватися. Коли це можливе, змінні, описані як register, розташовуються в машинних регістрах, що може привести до менших по розміру і більш швидким програмам.
Опис register виглядає як register int x; register char с; і т.д.; частина int може бути опущена.
!!! |
Опис REGISTER можна використати тільки для автоматичних змінних і формальних параметрів функцій. |
У цьому останньому випадку описи виглядають таким чином:
f(с, n) register int с, n; { register int i; ... }
На практиці виникають деякі обмеження на регістрові змінні, відображаючи реальні можливості апаратних засобів, що є.
У регістри можна вмістити тільки декілька змінних в кожній функції, причому тільки певних типів. У разі перевищення можливого числа або використання недозволених типів слово register ігнорується.
Крім того неможливо витягнути адресу регістрової змінної.
Ініціалізація
Якщо явна ініціалізація відсутня, то зовнішнім і статичним змінним присвоюється значення нуль; автоматичні і регістрові змінні мають в цьому випадку невизначені значення (сміття).
Прості змінні (не масиви або структури) можна ініціалізувати при їх описі, додаючи вслід за ім'ям знак рівності і константний вираз:
int x = 1; char squote = '\’'; long day = 60*24; /* minutes in а day */
Для зовнішніх і статичних змінних ініціалізація виконується тільки один раз, на етапі компіляції.
Автоматичні і регістрові змінні необхідно ініціалізувати кожний раз при вході в функцію або блок.
У разі автоматичних і регістрових змінних ініціалізатор не зобов'язаний бути константою: насправді він може бути будь-яким значущим виразом, який може включати величини і навіть звернення до функцій.
Наприклад, ініціалізація в програмі бінарного пошуку могла б бути записана у вигляді
binary(x, v, n)
int x, v[], n;
{ int low = 0;
int high = n - 1;
int mid; ... }
замість
binary(x, v, n)
int x, v[], n;
{ int low, high, mid;
low = 0; high = n - 1; ...
}
За своїм результатом, ініціалізація автоматичних змінних є скорочений запис операторів присвоєння. Використовують явні присвоєння, тому що ініціалізація в описах менш помітна.
Автоматичні масиви не можуть бути ініціалізовані. Зовнішні і статичні масиви можна ініціалізувати, вміщуючи вслід за описом вкладений у фігурні дужки список початкових значень, розділених комами.
Оголошення typedef
Це оголошення визначає специфікатор типу для типу. Воно використовується для того, щоб створити більш короткі або мнемонічні імена для типів, вже визначених в мові С або оголошених користувачем, тобто для вводу нових імен для типів даних.
Формат:
