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

Оголошення містять специфікатор класу пам’яті extern не можуть містити ініціаторів.

  1. Глобальні змінні завжди ініціалізуються, і якщо це не зроблено явно, то вони ініціалізуються нульовим значенням.
  2. Змінна з класом пам’яті static може ініціалізувати константним виразом. Ініціалізація для них виконується один раз перед початком програми. Якщо явна ініціалізація відсутня, то змінна ініціалізується нульовим значенням.
  3. Ініціалізація змінних з класом пам’яті auto або register виконується всякий раз при вході в блок, в якому вони оголошені. Якщо ініціалізація змінних в оголошенні відсутня, то їх початкове значення не визначено.

Початковими значеннями для глобальних змінних і для змінних з класом пам’яті static повинні бути константні вирази. Адреси таких змінних є константами і ці константи можна використовувати для ініціалізації оголошених глобально покажчиків. Адреси змінних з класом пам’яті auto або register не є константами і їх не можна використовувати в ініціаторах.

Приклад:

1int global_var;
2int func(void)
3{
4   int local_var;                      /* за умовчанням auto */
5   static int *local_ptr=&local_var;   /* так неправильно  */
6   static int *global_ptr=&global_var; /* а так правильно  */
7   register int *reg_ptr=&local_var;   /* і так правильно  */
8}

У приведеному прикладі глобальна змінна global_var має глобальний час життя і постійна адреса в пам’яті, і цю адресу можна використовувати для ініціалізації статичного покажчика global_ptr. Локальна змінна local_var, що має клас пам’яті auto розміщується в пам’яті тільки на час роботи функції func, адреса цієї змінної не є константою і не може бути використаний для ініціалізації статичної змінної local_ptr. Для ініціалізації локальної регістрової змінної reg_ptr можна використовувати неконстантні вирази, і, зокрема, адресу змінної local_ptr.