Спецификация класса памяти переменной определяет, какое время жизни она имеет (глобальное или локальное), и влияет на область действия переменной. Объект с глобальным временем жизни существует и имеет значение на протяжении всего времени выполнения программы. В языке Си имеется четыре спецификации класса памяти: auto, register, static, extern. Область действия функций, объявленных со спецификацией класса памяти extern, распространяется на все исходные файлы, которые составляют программу, такие функции могут быть вызваны из любой функции в любом исходном файле программы. Переменные классов памяти auto и register имеют локальное время жизни. Спецификации static и extern определяют объекты с глобальным временем жизни.
|
уровень
|
объект
|
спецификация
класса памяти
|
время жизни
|
область действия
|
|
1.
Внешний
|
Определение переменной
|
Static
|
Глобальное
|
Остаток исходного файла
|
|
Объявление переменной
|
Extern
|
Глобальное
|
Остаток исходного файла
|
|
Объявление или определение
функции
|
Static или Extern
|
Глобальное
|
Остаток исходного файла
|
|
2.
Внутренний
|
Объявление переменной
|
Extern
|
Глобальное
|
Блок
|
|
Определение переменной
|
Static
|
Глобальное
|
Блок
|
|
Определение переменной
|
Auto
Registr
|
Локальное
|
Блок
|
|
Объявление функции
|
Extern
Static
|
Локальное
|
Блок
|
Объявление переменной на внешнем уровне Объявления переменной на внешнем уровне используют спецификации класса памяти static и extern или вообще опускают их. Спецификации класса памяти auto и register не допускаются на внешнем уровне. Объявления переменных на внешнем уровне—это либо определения переменных, либо объявления, т.е. ссылки на определения, сделанные в другом месте. Определение внешней переменной—это объявление, которое вызывает выделение памяти для этой переменной и инициализирует ее. Объявление переменной на внутреннем уровне Любая из четырех спецификаций класса памяти может быть использована для объявления переменной на внутреннем уровне. Если спецификация класса памяти опущена в объявлении переменной на внутреннем уровне, то подразумевается класс памяти auto. Область действия переменной распространяется на блок, в котором она объявлена, (и на все вложенные в него блоки). Переменные класса памяти auto автоматически не инициализируются, поэтому в случае отсутствия инициализации в объявлении значение переменной класса памяти auto считается неопределенным. Память под переменные класса памяти auto отводится в стеке. Спецификация класса памяти register требует, чтобы компилятор языка Си выделил переменной память в регистре микропроцессора, если это возможно. Использование регистровой памяти обычно ускоряет доступ к переменной и уменьшает размер выполняемого кода программы. Переменные, объявленные с классом памяти register, имеют ту же самую область действия, что и переменные auto. Переменная, объявленная на внутреннем уровне со спецификацией класса памяти static, имеет глобальное время жизни, но ее область действия распространяется только на блок, в котором она объявлена (и на все вложенные блоки), но отличие от переменных класса памяти auto, переменные, объявленные со спецификацией класса памяти static, сохраняют свое значение при выходе из блока. Переменные класса памяти static могут быть инициализированы константным выражением. Если явной инициализации нет, то переменная класса памяти static автоматически инициализируется нулевым значением. Инициализация выполняется один раз во время компиляции и не повторяется при каждом входе в блок. Переменная, объявленная со спецификацией класса памяти extern, является ссылкой на переменную с тем же самым именем, определенную на внешнем уровне в любом исходном файле программы. Цель внутреннего объявления extern состоит в том, чтобы сделать определение переменной внешнего уровня (как правило, данное в другом исходном файле) доступным именно внутри данного блока. |