2.1.1 Область видимости.

   


Назад  |  Вперёд

Описанием определяется область видимости имени. Это значит, что имя может использоваться только в определенной части текста программы. Если имя описано в функции (обычно его называют "локальным именем"), то область видимости имени простирается от точки описания до конца блока, в котором появилось это описание. Если имя не находится в описании функции или класса (его обычно называют "глобальным именем"), то область видимости простирается от точки описания до конца файла, в котором появилось это описание. Описание имени в блоке может скрывать описание в объемлющем блоке или глобальное имя; т.е. имя может быть переопределено так, что оно будет обозначать другой объект внутри блока. После выхода из блока прежнее значение имени (если оно было) восстанавливается. Приведем пример:

           int x;            // глобальное x

           void f()
           {
               int x;        // локальное x скрывает глобальное x
               x = 1;        // присвоить локальному x
               {
                   int x;    // скрывает первое локальное x
                   x = 2;    // присвоить второму локальному x
               }
               x = 3;        // присвоить первому локальному x
           }

           int* p = &x;      // взять адрес глобального x

В больших программах не избежать переопределения имен. К сожалению, человек легко может проглядеть такое переопределение. Возникающие из-за этого ошибки найти непросто, возможно потому, что они достаточно редки. Следовательно, переопределение имен следует свести к минимуму. Если вы обозначаете глобальные переменные или локальные переменные в большой функции такими именами, как i или x, то сами напрашиваетесь на неприятности. Есть возможность с помощью операции разрешения области видимости :: обратиться к скрытому глобальному имени, например:

           int x;

           void f2()
           {
             int x = 1;      // скрывает глобальное x
             ::x = 2;        // присваивание глобальному x
           }

Возможность использовать скрытое локальное имя отсутствует. Область видимости имени начинается в точке его описания (по окончании описателя, но еще до начала инициализатора - см. $$R.3.2). Это означает, что имя можно использовать даже до того, как задано его начальное значение. Например:

           int x;

           void f3()
           {
              int x = x;    // ошибочное присваивание
           }

Такое присваивание недопустимо и лишено смысла. Если вы попытаетесь транслировать эту программу, то получите предупреждение: "использование до задания значения". Вместе с тем, не применяя оператора ::, можно использовать одно и то же имя для обозначения двух различных объектов блока. Например:

           int x = 11;

           void f4()         // извращенный пример
           {
             int y = x;   //  глобальное x
             int x = 22;
             y = x;       // локальное x
           }

Переменная y инициализируется значением глобального x, т.е. 11, а затем ей присваивается значение локальной переменной x, т.е. 22. Имена формальных параметров функции считаются описанными в самом большом блоке функции, поэтому в описании ниже есть ошибка:

           void f5(int x)
           {
             int x;       // ошибка
           }

Здесь x определено дважды в одной и той же области видимости. Это хотя и не слишком редкая, но довольно тонкая ошибка.


Назад  |  Вперёд


OtDiatlovaOU
К началу книги

Оформление и дизайн книги OtDiatlovaOU.
Вся книга, архив.