Область действия на все исходные формы программы.
Auto, Registr – имеют локальное время жизни.
Static, Extern – определяют объекты с глобальным временем жизни. В совокупности с местоположением объекта спецификации класса памяти определяет область действия переменной или функции. Область действия объявляет часть программы, куда возможен доступ.
Время жизни. Область действия.
Ø Глобальное
Ø Локальное
уровень
| объект
| спецификация
класса памяти
| время жизни
| область действия
|
1.
Внешний
| Определение переменной
| Static
| Глобальное
| Остаток исходного файла
|
Объявление переменной
| Extern
| Глобальное
| Остаток исходного файла
|
Объявление или определение функции
| Static или Extern
| Глобальное
| Остаток исходного файла
|
2.
Внутренний
| Объявление переменной
| Extern
| Глобальное
| Блок
|
Определение переменной
| Static
|
| Блок
|
Определение переменной
| Auto
Registr
| Глобальное
Локальное
| Блок
|
Объявление функции
| Extern
Static
|
Локальное
| Блок
|
Блок представляет собой составной оператор. Переменная объявленная внутри блока, имеющая тоже имя, что и объявленная на внешнем уровне переменная, заменяет в пределах блока объявление (локальное переобъявление переменной). Область действия переменной внешнего уровня восстанавливается по завершению блока. Блок внутри другого блока может содержать локальные переобъявления переменных, объявленных в охватывающем блоке.
Пространство имен.
Имена (идентификаторы)используются для ссылок на различного рода объекты (функции, переменные и т.п.)
При соблюдении определенных правил допускается использование 1 идентификатора для >1 программного объекта.
Пространства имен в С устанавливаются для идентификации объектов различного рода. Внутри одного пространства имена должны быть уникальны, в разных могут быть идентичны.
Для определения принадлежности имени к объекту используется контекст объекта. В С 4 пространства:
o Объекты (переменные, функции, формальные параметры, элементы списка перечисления и что определяется с помощью typedef). Уникальность имен в представляемом пространстве связана с исходной областью действия. Имена могут совпадать, если не пересекаются области действия именуемых объектов.
o Объекты – теги всех переменных перечислимого типа: struct,union. В пределах области действия каждый тег должен отличаться от другого. Ни с какими другими именами теги не конфликтуют.
o Элементы struct,union. Образуют свое пространство имен. Имя уникально в struct,union, но не обязано отличаться от других имен.
o Метки операторов. Метка должна отличаться от других в пределах одной функции.
Область действия Extern распространяется на все исходные файлы. Объявления, расположенные вне тел функций относятся к внешнему уровню, внутри тел — к внутреннему. Функции могут быть объявлены как Static или Extern либо без спецификации класса памяти.
Функции всегда имеют глобальное время жизни. Объявление функции без спецификации аналогично объявлению с Extern. Если в объявлении функции указан класс Static, то в определении тоже должен указываться Static.
Объявление функции на внутреннем уровне по смыслу эквивалентно, т.е. оно действует не до конца блока объявления, а до конца файла.
Объявление переменной на внешнем уровне.
Используется класс памяти Static и Extern; класс памяти Auto и Registr на внешнем уровне недопустим; класс памяти может отсутствовать.
Объявление на внешнем уровне.
v Либо определение
v Либо объявление (ссылки на определение, сделанные в другом месте).
Определение внешней переменной - объявление, вызывающее выделение памяти для этой переменной и ее инициализацию (явную или неявную).
Определение на внешнем уровне задается одной из следующих форм:
1. переменная определяется путем ее объявления с класса памяти Static, такая переменная может быть явно инициализирована константным выражением static int.
Если инициализатор отсутствует, то переменная автоматически инициализируется нулевым значением во время компиляции.
k=16, n=0
2. Переменная может быть определена без класса памяти и при этом явно проинициализирована (int j=3).
Область действия переменной, определенной на внешнем уровне распространяется от точки, где она определена, до конца исходного файла, определенная переменная недоступна.
На другие исходные файлы область действия распространяется в том случае, если переменная объявлена без указания класса памяти Static и в других исходных файлах имеется ее определение. Если в объявлении присутствует класс памяти Static, то в других исходных файлах могут определяться другие переменные с исходным именем и любым классом памяти. Эти переменные не связаны между собой, так как каждое определение Static – переменной доступно только в пределах своего исходного файла.
Спецификация класса памяти Extern.
Для объявления переменной, определенной где-то в другом месте программы. Такие объявления используют в случае, когда надо распространить на данный исходный файл область действия переменной, определенной в другом исходном файле, либо сделать переменную доступную в том же исходном файле, выше её определения.
Область действия переменной распространяется от места объявления до конца исходного файла. Инициализация Extern – переменных не допускается, так как они ссылаются на переменные, значения которых определены в другом месте.
Каждая переменная внешнего уровня должна быть определена только 1 раз в каком-либо из составных файлов программы.
Замечание. Существует исключение из вышеописанных правил, позволяющее опускать в объявлении переменной на внешнем уровне и спецификацию класса памяти, и инициализатор.
int х; имеет различный смысл от контекста
1. если в каком-то другом исходном файле есть определение на внешнем уровне, переменная с таким же именем, то данное объявление является ссылкой на это определение, то есть подразумевается наличие ключевого слова Extern.
2. если такого определения переменной в программе нет, то данное определение считается определением переменной. На этапе компоновки программы переменной выделяется память, которая инициализируется нулевым значением.
Если в программе больше 1 объявления переменной с одним и тем же именем, размер выделяемой памяти будет равен размеру наибольшего типа среди всех объявлений. Таким образом, глобальную переменную можно рассматривать как единую область памяти, разделенную несколькими исходными файлами, причем в каждом из них переменная может иметь различный тип. Этим пользоваться не рекомендуется (рекомендуется всегда инициализировать переменные на внешнем уровне). В результате при случае совпадении имен обнаружит ошибку повторной инициализации глобальной переменной и сообщит об ошибке.
В одном исходном файле возможно наличие на внешнем уровне нескольких объявлений с одним и тем же именем. Реакция компилятора зависит от реализации. Возможны следующие варианты:
ü присутствие объявления класса Extern и Static.тор проинтерпретирует как Static;
ü Static и отсутствие класса памяти приведет к объявлению Static, либо сигнал об ошибке;
ü Static и Extern. Будет использован класс Static;
ü Отсутствует Static. Либо Static, либо ошибка.
Присутствует 2 исходных файла программы.
1. исходный файл
extern int i
объявляем i, которая ссылается на другое определение i
main()
{
i+=1; //увеличим i на 1
printf (“%d”,i); //напечатаем i
next ();// вызовем функцию next
}//конец главного модуля
Определим значение i
int i=3;
в соответствие с определением будет напечатано 4.
next (){
определим функцию next:
i+=1;
увеличивает i на 1
printf (“%d”,i);
напечатаем значение i
будет напечатано 5
вызовем другую функцию other()
2. исходный файл
extern int i
other()
{
i+=1;
printf (“%d”,i); //напечатаем i: будет выведено 6
}
Без инициализации переменная инициализируется 0; получаем 1,2,3 соответственно.
Использовать не рекомендуется (трудно обнаружить ошибки). Глобальные переменные и переходы в структурное программирование не используются.
Объявление переменной на внутреннем уровне.
На внутреннем уровне можно использовать любой из классов памяти. При отсутствии auto. Понятия определения и объявления совпадают, если не задана в объявлении Extern.
Спецификация класса памяти auto объявляет переменную с локальным временем жизни. Область действия блок и вложенные блоки. Переменная класса памяти auto не инициализируется по умолчанию. Без инициализатора ее значение не определено. Память под auto- переменную отводится в стеке.
Регистровые переменные. При наличие свободных регистров процессора размещается в них (иначе класс памяти auto). При вызове функции из блока, где регистровые переменное содержимое регистров сохраняется в памяти, а при возврате восстанавливается. Для каждого рекурсивного входа в блок порождается новый набор регистровых переменных, при этом каждый раз проводится инициализация переменных, в объявлении которых заданы инициалы.
Static – переменная внутреннего уровня с глобальным временем жизни. Область действия блок и вложенные блоки. При выходе из блока значение Static – переменной сохраняется в отличие от auto-переменной. Static – переменные могут инициализироваться константным выражением. Если инициализатор отсутствует, то 0. Инициализируется во время компиляции и не повторяется при входе в блок. Все рекурсивные вызовы разделяют единственный экземпляр Static – переменной.