Объявления переменных
Объявление переменных допустимо без указания класса памяти или использовать спецификатор класса памяти static или extern.
Объявление статических переменных на глобальном уровне может задаваться в следующих формах:
Переменная объявлена с классом памяти static. Такая переменная может быть инициализирована явно константным выражением или по умолчанию нулевым значением. Таким образом, объявления static int i=0 и static int i эквивалентны, и в обоих случаях переменной i будет присвоено значение нуль;
Переменная объявлена без указания класса памяти, но с явной инициализацией. Такой переменной по умолчанию присваивается класс памяти static. Таким образом, объявления int i=1 и static int i=1 будут эквивалентны.
Объявление внутри блока переменной класса static позволяет создать переменную с глобальным временем жизни, но с локальной видимостью.
Рассмотрим пример.
Функция print выводит на экран значения статической переменной stat, автоматической переменной av, параметра функции p:
#include <stdio.h>
void print(int); //Прототип функции print()
int main(void)
{
int count;
for(count=9; count>=5; count-=2)
print(count); //Вызов функции print()
return 0;
}
//Определение функции print()
void print(int p)
{
int av=1;
static int stat=1;
printf("p=%d stat=%d av=%d\n",p,stat,av);
stat++;av++;
return 0;
}
Переменная p получает свое значение из функции main(), меняющееся от 9 до 5 с шагом 2. Статическая переменная stat создается в сегменте данных при первом вызове функции print() и получает начальное значение, равное единице. Функция увеличивает это значение на единицу. Переменная stat находится в сегменте данных, при повторном вызове функции print() переменная stat «вспоминает» свое прошлое значение. Локальная (автоматическая) переменная av при каждом вызове функции создается заново, каждый раз инициализируется и при выходе из функции перестает существовать.
В результате выполнения этого примера на экран будет выведена следующая информация:
p=9 stat=1 av=1
p=7 stat=2 av=1
p=5 stat=3 av=1
Глобальная переменная может быть определена только один раз в пределах своей области видимости. В другом исходном файле может быть объявлена другая глобальная переменная с таким же именем и с классом памяти static, конфликта при этом не возникает, так как каждая из этих переменных будет видимой только в своем исходном файле.
Внешняя переменная представляет собой ссылку на глобальную переменную с таким же именем. Внешние переменные могут объявляться как на внешнем уровне, так и внутри блока. Внешние переменные могут объявляться как в файлах, не содержащих глобальную переменную, так и в файлах, где эта переменная объявлена. Глобальная переменная видима в пределах файла, в котором она объявлена, начиная с места объявления. Выше своего описания и в других файлах эта переменная невидима. Создание внешней переменной класса extern в качестве ссылки на глобальную переменную, объявленную в другом месте программы, расширяет область видимости этой переменной. При этом область видимости глобальной переменной расширяется от места объявления внешней переменной до конца файла или блока, в котором сделано объявление.
В объявлениях с классом памяти extern не допускается инициализация, так как эти объявления ссылаются на уже существующие и определенные ранее переменные. Переменная, на которую делается ссылка с помощью спецификатора extern, может быть определена только один раз в одном из исходных файлов программы.
Рассмотрим следующий пример. Глобальная переменная a объявлена в середине текста программы таким образом, что функция summa() находится вне области видимости переменной. Чтобы функция summa() могла использовать переменную a, внутри функции объявляется внешняя переменная:
#include <stdio.h>
void summa()
{
extern float a;
float b=8;
float y=a+b;
printf("Summa=%f\n",y);
}
float a=10;
int main()
{
summa();
return 0;
}
После завершения работы программы на экран будет выведено значение 18.