Язык программирования Си для персонального компьютера | страница 54
Возможно наличие в одном исходном файле на внешнем уровне нескольких объявлений переменной с одним и тем же именем. Следующая таблица позволяет определить реакцию компилятора языка Си в различных ситуациях изменения спецификации класса памяти в объявлении. Слово "пусто" в таблице означает ситуацию отсутствия спецификации класса памяти. Очевидно, что компилятор СП MSC строже ограничивает возможность переопределения класса памяти переменной.
Класс 1 | Класс 2 | СП TC | СП MSC |
extern | static | static | static |
static | пусто | static | ошибка |
static | extern | static | static |
пусто | static | static | ошибка |
Пример: /* ИСХОДНЫЙ ФАЙЛ 1 */
/* объявление i, ссылающееся на данное ниже определение i */
extern int i;
main()
{
i = i + 1;
printf("%d\n", i); /* значение i равно 4 */
next();
}
int i = 3; /* определение i */
next()
{
printf("%d\n", i); /* значение i равно 5 */
other());
}
/* ИСХОДНЫЙ ФАЙЛ 2 */
/* объявление i, ссылающееся на определение i в первом исходном файле */
extern int i;
other()
{
i = i + 1;
printf("%d\n", i); /* значение i равно 6 */
}
Два исходных файла в совокупности содержат три внешних объявления i. Только в одном объявлении содержится инициализация:
int i = 3; — глобальная переменная i определена с начальным значением 3.
Самое первое объявление extern в первом исходном файле делает глобальную переменную i доступной прежде ее определения в файле. Без этого объявления функция main не могла бы использовать глобальную переменную i. Объявление переменной i во втором исходном файле делает глобальную переменную i доступной во втором исходном файле.
Все три функции выполняют одно и то же действие: увеличивают i на 1 и печатают полученное значение. Значения распечатываются с помощью стандартной библиотечной функции printf. Печатаются значения 4, 5 и 6.
Если бы переменная i не была инициализирована ни в одном из объявлений, она была оы неявно инициализирована нулевым значением при компоновке. В этом случае программа напечатала бы значения 1, 2 и 3.
Объявление переменной на внутреннем уровне
Любая из четырех спецификаций класса памяти может быть использована для объявления переменной на внутреннем уровне. Если спецификация класса памяти опущена в объявлении переменной на внутреннем уровне, то подразумевается класс памяти auto. Как правило, ключевое слово auto опускается. Понятия объявления и определения для переменных внутреннего уровня совпадают, если только в объявлении не задана спецификация класса памяти extern.
Спецификация класса памяти