В Си существует четыре основных класса хранения: auto, extern, static, register.
Класс хранения auto является классом по умолчанию для всех локальных1) переменных.
void myFunction() { int a; // То же самое, что и "auto int a;"" a = 10; // a доступна только внутри myFunction }
Используется для объявления глобальной переменной или функции, которая определена в другом файле.
// main.c #include <stdio.h> char message[] = "Hello"; void print() { printf("Hello from extern function\n"); } int sum(int x, int y) { return x + y; }
//app.c #include <stdio.h> 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 применяется к глобальной переменной или функции, он ограничивает их область видимости текущим файлом. Это означает, что к такой переменной или функции нельзя будет обратиться из другого файла с помощью extern. В этом случае действуют следующие характеристики:
Класс хранения register является рекомендацией для компилятора поместить переменную не в оперативную память, а в регистр процессора. Компилятор может проигнорировать это указание, если нет свободных регистров или если тип данных не подходит для хранения в регистре.