Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЯП - ПОИТ (Бахтизин) часть 1 редакт.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
1.76 Mб
Скачать

7.5. Внешний класс хранения (extern)

Не все переменные должны быть скрытыми для функций, находящихся в других файлах, в противном случае вообще программы как единого целого не существовало бы. Поэтому в Си введен внешний класс хранения, позволяющий объявлять в функциях глобальные переменные, определенные после тел функций или в других файлах.

Приведем пример объявления переменной после ее первого использования:

#include <stdio.h>

void main(void)

{

printf("\ni=%5.2f", i);

}

float i = 10.25;

При компиляции будет выдана ошибка: неопределенный символ i. И правда, область видимости глобальной переменной – от момента объявления до окончания выполнения программы. В примере – ошибка, которую можно исправить путем добавления в функцию main перед строкой

printf("\ni=%5.2f", i);

строки

extern float i;

Это объявление переменной происходит без выделения памяти на нее, а лишь сообщает компилятору, что переменная объявлена и описана (с выделением памяти) после функции main в нашем случае. При объявлении переменной со спецификатором класса хранения extern подразумевается, что она уже существует, инициализировать переменную каким-либо значением нельзя.

Однако чаще всего ключевое слово extern используется, если область видимости глобальной переменной, описанной в одном файле, нужно расширить на функцию, находящуюся в другом файле:

/* исходный файл file1.cpp */

main()

{

...

}

funс1()

{

extern double i;

...

}

/* исходный файл file2.cpp */

double i = 9.36;

funс2()

{

...

}

Переменная i описана в файле file2.cpp, по умолчанию она – static, т.е. в других файлах не видна. Чтобы сделать ее видимой для функции func1 объявляется i в этой функции как extern. Необходимо отметить, что для функции main эта переменная по-прежнему будет недоступна. То есть, описан с выделением памяти один объект (в нашем случае переменная) может быть только единожды, объявлять же ее как внешнюю можно сколь угодно большое число раз. При разработке больших программных проектов обычно включают объявления extern в заголовочные файлы, которые затем подключаются к каждому файлу исходного текста программы. Это – очевидное упрощение по отношению к ручному объявлению переменных, которое может привести к ошибкам.

7.6. Заключение

Подведем итоги.

Глобальные переменные могут объявляться со спецификаторами классов хранения static и extern. Локальные переменные – с любым из четырех спецификаторов.

Любая локальная переменная по умолчанию – auto, любая глобальная – static. Локальные переменные auto и register автоматически не инициализируются никакими осмысленными значениями; и локальные, и глобальные static инициализируются нулем.

Переменная, объявленная глобально, видима в пределах остатка исходного файла, в котором она определена. Выше своего описания и в других исходных файлах эта переменная невидима, пока не объявлена как extern. В другом исходном файле может быть объявлена другая глобальная переменная с таким же именем и с классом хранения static, области видимости этих переменных не пересекаются, поэтому ошибок не будет.

Подводя итог, можно составить таблицу 7.1, суммирующую информацию о классах хранения.

Таблица 7.1. Информация о классах хранения

Класс хранения

Место хранения

Время жизни

Область видимости

автоматический

(auto)

сегмент стека

равно времени выполнения программного блока

внутри блока программы, в котором объявлена

регистровый

(register)

регистры процессора (если доступны)

--//--

--//--

локальный статический

(static)

сегмент данных

равно времени выполнения

всей программы

--//--

глобальный статический (static)

--//--

--//--

файл, в котором глобально объявлена

внешний

(extern)

--//--

--//--

внутри всего проекта (даже, если программа состоит из нескольких файлов)