Область действия идентификатора информационного объекта программы
Область действия идентификатора информационного объекта программы – часть программы, в которой этот идентификатор можно использовать для доступа к связанной с ним области памяти (т.е. часть программы, в которой на идентификатор можно ссылаться):
• блок: область действия идентификатора начинается в точке определения и заканчивается в конце блока, содержащего это определение; внутри блока определена локальная переменная, размещаемая в сегменте стека в момент выполнения оператора определения;
• функция: единственными идентификаторами, имеющими в качестве области действия функцию, являются метки операторов (вне функции они недоступны);
• прототип функции: идентификаторы, указанные в списке формальных параметров в прототипе функции (и не являющиеся частью определения функции), имеют областью действия прототип функции;
• файл: идентификаторы области действия типа файл объявляются вне всех функций, блоков и классов; их действие лежит между точкой объявления и концом исходного файла; файл считается областью действия глобальной переменной, размещаемой в сегменте данных; глобальная переменная изначально обнуляется; время ее жизни: с начала выполнения программы и до ее окончания; память под нее выделяется компилятором.
Идентификатор, объявленный вне любой функции, имеет областью действия файл (он «известен» всем функциям от точки его объявления до конца файла). Глобальные переменные, описания и прототипы функций, находящиеся вне функции - имеют областью действия файл.
Необходимо запомнить и уметь диагностировать ряд моментов:
l Переменные доступны (т.е. имеют область действия и видимы) в том блоке программы, в котором они описаны.
l Если переменная описана вне функций, она является глобальной и доступна (имеет область действия и видима) из любой части программы.
l Внутри функции может быть введено сколько угодно блоков, и внутри каждого из них можно описывать локальные переменные, доступные (т.е. видимые и имеющие область действия) только внутри этого блока.
l Если во вложенном блоке описана переменная с тем же именем, что и в охватывающем, внутри блока будет доступна (т.е. видима и имеет область действия) описанная в нем локальная переменная. В охватывающем блоке (до и после завершения вложенного блока), будет доступна (т.е. видима и имеет область действия) описанная в нем переменная (и ее значение). Во вложенном блоке эта переменная имеет область действия видима, но невидима (недоступна). Т.е. доступ к глобальной переменной может быть утрачен при объявлении одноименной локальной переменной.
l Для доступа (изменения области видимости) к одноименной глобальной переменной из блока, где описана одноименная локальная переменная, следует использовать операцию разрешения области видимости :: .
Примеры использования переменных разных классов памяти
1.
Файл my_main.cpp
#include <iostream.h>
int a; //определение глобальной переменной a
static long li; //определение статической глобальной переменной li
int main ()
{
int b; // определение локальной переменной b
extern int x; //объявление переменной х, определение ее где-то в другом месте
static int c; // определение статической локальной переменной с
a = 1; //присваивание глобальной переменной а
int a; //определение локальной переменной а
a = 2; //присваивание локальной переменной а
::a = 3; //присваивание глобальной переменной а
//(:: – это операция изменения области видимости
cout << a << endl; //вывод локальной переменной
cout << ::a << "\n"; //вывод глобальной переменной
return 0;
}
2.
Файл my_main_1.cpp
#include <stdio.h>
int i=0; // глобальная переменная i определена в файле со значением 1
void main()
{ auto int i=1; //локальная переменная i определена в функции main со значением 1
printf (”%d”, i); // 1
{ int i=2; // локальная переменная iопределена в блоке { } со значением 2
printf (%d”, i); // 2
{ i +=1; // в блоке { }действует определение i из объемлющего блока { }
printf (”%d”, i); // 3
}
printf (”%d”, i); // 3, продолжает действовать определение блока { }
}
printf (”%d”, i); // 1, в блоке функции main i =1
}
3.
Область действия может превышать область видимости:
{
int i; //автоматическое распределение памяти по умолчанию
char ch; // int i и char ch в области действия блока { }и видимы
i=3;
……
{
double i; // double i в области действия блока { } и видима
i=3.0; // int i хотя и в области действия блока { }, но скрыта
ch=’A’; // char ch в области действия блока { } и видима
}
i+=1; // int i в области действия блока { }, видима и равна 4
……. // double i вне области действия блока { }
……. // char ch в области действия блока { }, видима и равна ’A’
}
…… // int i и char ch вне области действия блока { }
4.
Пример соотношения областей видимости и действия в проекте на основе двух файлов:
Файл f1.cpp
#include <iostream.h>
int m = 10; //определение глобальной переменной
double x = 100.56; //определение глобальной переменной
extern int func1 (); //объявление функции, определенной в другом файле
extern double func2 (); //объявление функции, определенной в другом файле
int main () {
сout << m << " " << func1() << endl; // 10 100
cout << x << " " << func2() << endl; // 100.56 110.56
return 0; }
Файл f2.cpp
extern int m; //объявление переменной, определенной в другом файле
extern double x; //объявление переменной, определенной в другом файле
int func1 () { return m * m; }//определение функции
double func2 () { return x + m; }//определение функции
5.
Пример изменения 1 в проекте на основе двух файлов:
Файл f12.cpp
#include <iostream.h>
static int m = 10; //определение только в этом файле глобальной статической переменной
double x = 100.56;//определение в файле глобальной переменной