Лекции по C++

Информация - Компьютеры, программирование

Другие материалы по предмету Компьютеры, программирование

quot;явления extern функция main не смогла бы сослаться на глобальную переменную i. Об"явление extern переменной i во втором исходном файле делает глобальную переменную видимой в этом исходном файле.

Все три функции выполняют одну и ту же задачу: они увеличивают i на 1 и печатают получившееся значение. (Предполагается, что функция printf определена где-то еще в программе.). Печатаются величины равные 4, 5 и 6.

Если бы переменная i не была бы инициализирована,она бы была автоматически установлена в 0 при линковании. В этом случае напечатанные значения были бы равны 1, 2 и 3.

Об"явление переменной на внутреннем уровне

Любой из четырех спецификаторов класса памяти может быть использован для об"явления переменной на внутреннем уровне. Если спецификатор класса памяти опускается в об"явлении переменной на внутреннем уровне, то подразумевается класс памяти auto.

Спецификатор класса памяти auto об"являет переменную с ло-

кальным временем жизни. Переменная видима только в том блоке, где она об"явлена. Об"явления переменных auto могут включать инициализаторы. Переменные класса памяти auto автоматически не инициализируются, а инициализируются явно при об"явлении или присваивании начальных значений, посредством операторов внутри блока. Если нет инициализации, то величина переменной auto считается неопределенной.

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

ют ту же самую видимость, что и переменные auto.

Число регистров, которое может быть использовано под память переменных, зависит от машины. Когда компилятор встречает спецификатор класса памяти register в об"явлении, а свободного регистра не имеется, то для переменной распределяется память класса auto. Компилятор назначает переменным регистровую память в том порядке, в котором появляются об"явления в исходном файле. Регистровая память, если она имеется, гарантирована только для целого и адресного типов.

Переменная, об"явленная на внутреннем уровне со спецификатором класса памяти static,имеет глобальное время жизни и имеет видимость только внутри блока, в котором она об"явлена. В отличие от переменных auto, переменные, об"явленные как static, сохраняют свое значение при завершении блока.

Переменные класса памяти static могут быть инициализированы константным выражением. Если явной инициализации нет, то переменная класса памяти static автоматически устанавливается в 0. Инициализация выполняется один раз во время компиляции. Инициализация переменной класса памяти static не повторяется при новом входе в блок.

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

Цель внутреннего об"явления extern состоит в том, чтобы

сделать определение переменной внешнего уровня видимой внутри блока. Внутреннее обявление extern не изменяет видимость глобальной переменной в любой другой части программы.

Пример:

int i = 1;

main()

{/* reference to i, defined above */

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("%d\n%d\n%d\n%d\n", i, a, b, c);

other();

}

other()

{

/* i is redefined */

int i = 16;

/* this a is visible only within other */

static int a = 2;

a += 2;

/* values printed are 16, 4 */

printf("%d\n%d\n", i, a);

}

Переменная i определяется на внешнем уровне с инициализацией 1. В функции main об"явлена ссылка extern на переменную i внешнего уровня. Переменная класса памяти static автоматически

устанавливается в 0, так как инициализатор опущен. Вызов функции print (предполагается, что функция print определена в каком-то месте исходной программы.) печатает величины 1, 0, 0, 0.

В функции other, переменная i переопределяется как локальная переменная с начальным значением 16. Это не влияет на значение внешней переменной i. Переменная a об"является как переменная класса памяти static с начальным значением 2. Она не противоречит переменной a, об"явленной в функции main, так как видимость переменных класса памяти static на внутреннем уровне ограничена блоком, в котором она об"явлена.

Значение переменной увеличивается на 2 и становится равным 4. Если бы функция other была вызвана снова в той же самой программе, то начальное значение a стало бы равным 4. Внутренние переменные класса памяти static сохраняют свои значения, когда заканчивается выполнение блока, в котором они об"явлены.

Об"явление функции на внешнем и внутреннем уровнях

Функции могут быть об"явлены со спецификаторами класса памяти static или extern. Функции всегда имеют глобальное время жизни.

Правила видимости для функций отличаются от правил видимости для переменных. Об"явления функций на внутреннем уровне имеют тот же самый смысл, что и об"явления на внешнем уровне. Это значит, что функции не могут иметь блочной видимости и видимость функций не может быть вложенной. Функция об"явленная как static,

видима только в пределах исходного файла, в котором она определяется. Любая функция в том же самом исходном файле может вызвать функцию static, но функции static из других файлов нет. Функция static с тем же самым именем мож