====== классы хранения ======
В Си существует четыре основных класса хранения: auto, extern, static, register.
===== auto =====
Класс хранения auto является классом по умолчанию для всех **локальных**((Это означает, что если вы объявляете переменную внутри функции или блока без указания класса хранения, она автоматически принимает тип хранения auto. )) переменных.
* Область видимости: действие переменной ограничена блоком, в котором она объявлена (локальная видимость).
* Жизненный цикл: переменная создается при входе в блок и уничтожается при выходе из него.
* Начальное значение: если переменная не инициализирована явно, то она содержит "мусорное" неопределенное значение.
void myFunction() {
int a; // То же самое, что и "auto int a;""
a = 10;
// a доступна только внутри myFunction
}
===== extern =====
Используется для объявления глобальной переменной или функции, которая определена в другом файле.
* Область видимости: глобальная (доступна во всем проекте).
* Жизненный цикл: существует в течение всего времени выполнения программы.
* Начальное значение: определяется в месте ее инициализации. Если глобальная переменная не инициализирована явно, она получает значение 0.
// main.c
#include
char message[] = "Hello";
void print() {
printf("Hello from extern function\n");
}
int sum(int x, int y) {
return x + y;
}
//app.c
#include
extern char message[]; // переменная message из файла main.c
void print(void); // функция print из main.c
int sum(int, int); // функция sum из main.c
int main(void){
// выводим на консоль внешнюю переменную message
printf("%s \n", message);
// вызываем внешнюю функцию print
print();
// вызываем другую внешнюю функцию - sum
printf("4 + 5 = %d \n", sum(5, 4));
return 0;
}
===== static =====
Ключевое слово static имеет два основных применения в зависимости от контекста: для локальных переменных и для глобальных переменных/функций.
Когда static применяется к **локальной** переменной, он изменяет ее жизненный цикл, сохраняя ее значение между вызовами функции. Основные характеристики:
* Область видимости: Локальная, как у auto переменных.
* Жизненный цикл: Существует в течение всего времени выполнения программы, а не только внутри функции.
* Начальное значение: Инициализируется только один раз при первом вызове функции. Если не инициализирована явно, получает значение 0.
Когда static применяется к **глобальной** переменной или функции, он ограничивает их область видимости текущим файлом. Это означает, что к такой переменной или функции нельзя будет обратиться из другого файла с помощью extern. В этом случае действуют следующие характеристики:
* Область видимости: действие переменной/функции ограничено файлом, в котором они объявлены.
* Жизненный цикл: переменная/функция существует в течение всего времени выполнения программы.
===== register =====
Класс хранения register является рекомендацией для компилятора поместить переменную не в оперативную память, а в регистр процессора. Компилятор может проигнорировать это указание, если нет свободных регистров или если тип данных не подходит для хранения в регистре.
Однако в современных компиляторах register почти не используется, так как они самостоятельно выполняют очень сложную оптимизацию и часто лучше программиста решают, какие переменные стоит помещать в регистры.
* Область видимости: Локальная.
* Жизненный цикл: Локальный.
К register-переменной нельзя применить оператор взятия адреса &, так как у нее нет адреса в памяти.