В языке C буквальное значение static легко может ввести нас в заблуждение; на самом деле у него три роли.
(1) Сначала представим его первую и самую важную роль: сокрытие.
Когда мы одновременно компилируем несколько файлов, все глобальные переменные и функции без префикса static имеют глобальную видимость. Чтобы понять это утверждение, приведу пример. Нам нужно одновременно скомпилировать два исходных файла: один — a.c, другой — main.c.
Ниже приведено содержимое a.c:
Код файла a.c
void msg()
{
printf("Hello\n");
}
Ниже приведено содержимое main.c:
Код файла main.c
{
extern char a; // переменная extern должна быть объявлена перед использованием
printf("%c ", a);
(void)msg();
return 0;
}
Вывод программы:
A Hello
Вы можете спросить: почему глобальная переменная a и функция msg, определённые в a.c, могут использоваться в main.c? Как упоминалось ранее, все глобальные переменные и функции без префикса static имеют глобальную видимость, и другие исходные файлы также могут получать к ним доступ. В этом примере a — глобальная переменная, а msg — функция, и ни у одной нет префикса static, поэтому они видимы другому исходному файлу main.c.
Если добавить static, они будут скрыты от других исходных файлов. Например, если static добавить перед определениями a и msg, main.c их не увидит. Используя эту возможность, мы можем определять функции и переменные с одинаковыми именами в разных файлах, не беспокоясь о конфликтах имён. static можно использовать как префикс для функций и переменных. Для функций эффект static ограничивается скрытием, тогда как для переменных static имеет следующие две дополнительные роли.
(2) Вторая роль static — обеспечивать сохранение содержимого переменной.
Переменные, хранящиеся в области статических данных, инициализируются при первом запуске программы, и это единственная инициализация. В статической области хранения есть два вида переменных: глобальные переменные и static-переменные. Однако по сравнению с глобальными переменными static может управлять видимой областью действия переменных. В конечном счёте static всё ещё используется для скрытия. Хотя это использование не распространено, я всё же приведу пример.
Пример
int fun(void){
static int count = 10; // На самом деле этот оператор присваивания никогда не выполнялся.
return count--;
}
int count = 1;
int main(void)
{
printf("global\t\tlocal static\n");
for(; count <= 10; ++count)
printf("%d\t\t%d\n", count, fun());
return 0;
}
Вывод программы:
global local static 1 10 2 9 3 8 4 7 5 6 6 5 7 4 8 3 9 2 10 1
(3) Третья роль static — инициализировать по умолчанию значением 0.
На самом деле, глобальные переменные также обладают этим свойством, потому что глобальные переменные тоже хранятся в области статических данных. В области статических данных значение по умолчанию каждого байта в памяти равно 0,0x00и иногда эта особенность может уменьшить нагрузку на программиста. Например, при инициализации разреженной матрицы мы можем задать все элементы по одному равными 0,0а затем присвоить немногочисленные элементы, которые не равны 0.0Если определить как static, начальная операция установки в 0 опускается. Другой пример: если мы хотим использовать массив символов как строку, но считаем утомительным добавлять00 в конец массива символов каждый раз.\0Если строку определить как static, этой проблемы удаётся избежать, потому что там уже есть 0.\0 。
Давайте проведём небольшой эксперимент, чтобы проверить это.
Пример
int a;
int main(void)
{
int i;
static char str[10];
printf("integer: %d; string: (begin)%s(end)", a, str);
return 0;
}
Вывод программы следующий:
integer: 0; string: (begin)(end)
В заключение давайте суммируем три роли static одним предложением. Во-первых, самая важная роль static — сокрытие; во-вторых, поскольку static-переменные хранятся в статической области хранения, они обладают сохраняемостью и значением по умолчанию 0.
Источник: https://www.cnblogs.com/dc10101/archive/2007/08/22/865556.html