Спецификатор класса хранения extern
Переменная, объявленная с описателем класса хранения extern, представляет собой ссылку на переменную с тем же именем, определенным на внешнем уровне в любом из файлов исходного кода программы. Внутреннее объявление extern используется, чтобы сделать определение переменной внешнего уровня видимым в блоке. Если иное не объявлено на внешнем уровне, переменная, объявленная с использованием ключевого слова extern, видна только в блоке, в котором она объявлена.
Пример
Этот пример иллюстрирует объявления на внутреннем и внешнем уровнях.
// extern_StorageClassSpecified.c
#include <stdio.h>
void other( void );
int main()
{
// Reference to i, defined below:
extern int i;
// Initial value is zero; a is visible only within main:
static int a;
// b is stored in a register, if possible:
register int b = 0;
// Default storage class is auto:
int c = 0;
// Values printed are 1, 0, 0, 0:
printf_s( "%d\n%d\n%d\n%d\n", i, a, b, c );
other();
return;
}
int i = 1;
void other( void )
{
// Address of global i assigned to pointer variable:
static int *external_i = &i;
// i is redefined; global i no longer visible:
int i = 16;
// This a is visible only within the other function:
static int a = 2;
a += 2;
// Values printed are 16, 4, and 1:
printf_s( "%d\n%d\n%d\n", i, a, *external_i );
}
В этом примере переменная i определяется на внешнем уровне с исходным значением 1. Объявление extern в функции main используется для объявления ссылки на i внешнего уровня. Статическая переменная a по умолчанию инициализируется со значением 0, поскольку инициализатор опущен. Вызов метода printf печатает значения 1, 0, 0 и 0.
В функции other адрес глобальной переменной i используется для инициализации статической переменной указателя external_i. Это работает, поскольку глобальная переменная имеет статическое время существования, то есть ее адрес не меняется во время исполнения программы. Кроме того, переменная i переопределяется как локальная переменная с исходным значением 16. Это переопределение не влияет на значение i внешнего уровня, который скрыт путем использования его имени для локальной переменной. Значение глобального i теперь доступно только косвенно в пределах блока, через указатель external_i. Попытка присвоить адрес автоматической переменной i указателю не работает, поскольку он может различаться всякий раз при входе в блок. Переменная a объявляется в виде статической переменной и инициализируется к 2. Данная a не конфликтует с a в main, поскольку статические переменные на внутреннем уровне видны только внутри блока, в котором они определены.
Переменная a увеличивается на 2, давая результат 4. Если функция other снова вызывается в той же программе, исходное значение a будет равно 4. Внутренние статические переменные сохраняют свои значения при выходе из программы, а затем повторно выполняют вход в блок, в котором они определены.
См. также
Основные понятия
Спецификаторы классов хранения для объявлений внутреннего уровня