Классы хранения в C: auto, extern, static, register — подробное объяснение
Что такое класс хранения в C?
Класс хранения определяет область видимости переменной, ее расположение, инициализацию, время жизни и доступность. В C каждая переменная не только типизирована, но также назначается ей класс хранения, определяющий, где и как к ней можно получить доступ.
Существует четыре стандартных класса хранения:
- auto — по умолчанию для локальных переменных.
- extern — объявляет глобальную переменную или функцию, существующую в другом файле.
- static — сохраняет значение переменной между вызовами и ограничивает видимость файлом или функцией.
- register — подсказывает компилятору хранить переменную в регистре процессора для быстрего доступа.
Класс хранения auto
Переменные, объявленные с auto (по умолчанию для локальных переменных), существуют только внутри блока, где они определены. Они уничтожаются при выходе из блока и инициализируются неопределенным значением, если не заданы явно.
int add(void) { int a = 13; auto int b = 48; // auto опционален return a + b; }
Демонстрация области видимости:
#include <stdio.h> int main(void) { auto int j = 1; { auto int j = 2; { auto int j = 3; printf("%d ", j); // печатает 3 } printf("\t%d ", j); // печатает 2 } printf("%d\n", j); // печатает 1 }
Вывод: 3 2 1
Класс хранения extern
Ключевое слово extern объявляет переменную или функцию, определенную в другой единице трансляции. Оно обеспечивает обмен данными между исходными файлами.
/* main.c */ #include <stdio.h> extern int i; // объявление int main(void) { printf("value of the external integer is = %d\n", i); return 0; } /* original.c */ #include <stdio.h> int i = 48; // определение
Скомпилируйте оба файла вместе: gcc main.c original.c -o program. Запуск ./program выводит:
value of the external integer is = 48
Класс хранения static
Статические переменные сохраняют свое значение на протяжении всей программы. Они могут использоваться как локальные статические или файловые статические.
- Локальный static — виден только внутри функции, но сохраняется между вызовами.
- Файловый static — виден только в файле, где объявлен.
/* глобальный static */ static int counter = 7; void next(void) { /* локальный static */ static int iteration = 13; iteration++; printf("iteration=%d and counter=%d\n", iteration, counter); } int main(void) { while (counter < 10) { next(); counter++; } return 0; }
Вывод:
iteration=14 and counter=7 iteration=15 and counter=8 iteration=16 and counter=9
Класс хранения register
Используйте register, когда переменной нужен частый доступ и она помещается в регистр процессора. Компилятор может игнорировать подсказку, если регистры заняты.
#include <stdio.h> int main(void) { register int weight; /* попытка взять адрес вызывает ошибку */ // int *ptr = &weight; // ошибка компиляции return 0; }
Компиляция кода дает:
error: address of register variable 'weight' requested
Сводная таблица
| Класс хранения | Контекст объявления | Место хранения | Значение по умолчанию | Область видимости | Время жизни |
|---|---|---|---|---|---|
| auto | внутри функции/блока | Память | Непредсказуемое | Функция/блок | Функция/блок |
| register | внутри функции/блока | Регистр CPU | Непредсказуемое | Функция/блок | Функция/блок |
| extern | вне всех функций | Память | Ноль | Вся программа | Время выполнения программы |
| static (local) | внутри функции/блока | Память | Ноль | Функция/блок | Время выполнения программы |
| static (global) | вне всех функций | Память | Ноль | Файл | Время выполнения программы |
Ключевые выводы
- Классы хранения управляют видимостью и временем жизни переменных.
- Используйте
autoдля стандартных локальных переменных. - Используйте
registerдля счетчиков, критичных к производительности (с учетом поддержки компилятора). - Используйте
staticдля сохранения состояния между вызовами функции или ограничения файловой области. - Используйте
externдля обмена переменными или функциями между исходными файлами.
Язык C
- Классы и объекты в C#: Фундаменты надёжного ООП
- Ключевое слово static в C#: статические переменные, методы и классы
- Вложенные классы в C#: определение, использование и наследование
- Классы и объекты в C++: практическое руководство по объектно-ориентированному программированию
- Дружественные функции и классы в C++: мастерство контроля доступа
- Шаблоны классов в C++: практическое руководство
- Классы хранения в C: область видимости, время жизни и производительность
- Классы хранения в C: auto, register, static, extern — область видимости и время жизни
- Классы хранения в C++: область видимости, время жизни и использование
- Интерфейсы в C++: абстрактные классы и чисто виртуальные функции