Поделиться через


Спецификатор класса хранения 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. Внутренние статические переменные сохраняют свои значения при выходе из программы, а затем повторно выполняют вход в блок, в котором они определены.

См. также

Основные понятия

Спецификаторы классов хранения для объявлений внутреннего уровня