Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
12
Добавлен:
17.04.2015
Размер:
19.72 Кб
Скачать

Область видимости переменных

При работе с переменными, имеющими разную область видимости, часто возникают непредвиденные ошибки, называемые побочными эффектами. Например, в программе могут быть объявлены две переменные с одинаковым именем, но одна локально, внутри функции, а другая на уровне всего файла. Правила определения области видимости говорят о том, что в пределах функции локальная переменная имеет преимущество перед глобальной, делая последнюю недоступной. Все это звучит достаточно просто, но давайте рассмотрим ряд проблем, часто возникающих в программах и, на первый взгляд, не совсем очевидных.

Попытка получить доступ к переменной вне ее области видимости

В следующем примере в функции main() объявляются четыре локальные переменные. В программе как будто бы нет никаких ошибок. Тем не менее, когда функция iproduct() попытается обратиться к переменной in, она не сможет ее обнаружить. Почему? Потому что область видимости этой переменной ограничена только функцией main().

/*

* scope.с

* Эта программа на языке С иллюстрирует проблему неправильного

* определения области видимости переменной. Во время компиляции

* программы появится сообщение об ошибке.

*/

#include <stdio.h>

int iproduct(int iw, int ix);

int main () {

int il = 3;

int im = 7;

int in = 10;

int io;

io = iproductfil, im) ;

printf("Произведение чисел равно %d\n",io) ;

return(0); }

int iproduct (int iw, int ix)

{

int iy;

iy = iw * ix * in;

return (iy); }

Компилятор выдаст сообщение об ошибке, в котором говорится о том, что в функции iproduct( ) обнаружен нераспознанный идентификатор in. Чтобы решить эту проблему, нужно сделать переменную in глобальной.

В следующем примере переменная inописана как глобальная. В результате обе функции, как main(),так и iproduct(),могут использовать ее. Обратите также внимание на то, что и та, и другая функция может изменить значение переменной in.

/*

* fscope.с

* Это исправленная версия предыдущей программы. Проблема решена путем

* объявления переменной in как глобальной.

*/

#include <stdio.h>

int iproduct (int iw, int ix) ; int in = 10;

int main() (

int il = 3;

int im = 7;

int io;

io = iproduct (il,im) ;

printf("Произведение чисел равно %d\n",io) ;

return (0);

}

int iproduct(int iw, int ix)

int iy;

iy = iw * ix * in;

return(iy);

Эта программа будет корректно скомпилирована, и на экране появится результат - 210.

Как уже было сказано, локальная переменная перекрывает одноименную глобальную переменную. Ниже показан вариант предыдущей программы, иллюстрирующий данное правило.

/*

* Isсоре.с

* Эта программа на языке С иллюстрирует взаимоотношение

* между одноименными локальной и глобальной переменными.

* Функция iproduct() находит произведение трех переменных,

* из которых две передаются как аргументы функции, а еще

* одна, in,объявлена и как глобальная, и как1 локальная.

*/

#include <stdio.h>

int iproduct(int iw, int ix);

int in = 10;

int main()

int il = 3; int im = 7;

int io;

io = iproduct(il,im) ;

printf("Произведение чисел равно %d\n",io) ;

return (0);

int iproduct(int iw, int ix) {

int iy;

int in = 2;

iy = iw * ix * in;

return(iy); }

В этом примере переменная inописывается дважды: на уровне файла и на уровне функции. В функции iproduct(), где эта переменная объявлена как локальная, будет использовано "локальное" значение. Поэтому результатом умножения будет 3*7*2 = 42.

Оператор расширения области видимости

В следующей программе, написанной на языке C++, все работает нормально до момента вывода информации на экран. Объект cout правильно отобразит значения переменных 11 и im, но для переменной inбудет выбрано "глобальное" значение. Вследствие этого пользователю будет представлен неправильный результат: "3*7*10= 42". Как вы уже поняли, ошибка возникает из-за того, что в функции iproduct() используется локальная переменная in.

//

// scopel.срр

// Эта программа на языке C++ содержит логическую ошибку.

// Функция iproduct() находит произведение трех переменных,

// используя при этом значение локальной переменной in.

// В то же время в выводимых данных программа сообщает

// о том, что значение переменной inравно 10.

//

#include <iostream.h>

int iproduct (int iw, int ix);

int in = 10;

int main()

{

int 11 = 3;

int im = 7 ;

int io;

io = iproduct (il,im) ;

cout << il << " * " << im << " * " << in << " = " << io << "\n";

return (0);

}

int iproduct(int iw, int ix) {

int iy; int in = 2;

iy = iw * ix * in;

return (iy);}

Что же нужно сделать, чтобы получить правильный результат? Для этого достаточно воспользоваться оператором расширения области видимости (::), о котором мы уже упоминали:

iy = iw * ix * ::in;

Следующая программа иллюстрирует сказанное.

//

// scope2.cpp

// Это исправленная версия предыдущего примера. Проблема решена путем

// использования оператора расширения области видимости (::).

//

#include <iostream.h>

int iproduct(intiw, int ix) ; int in = 10;

int main ()

int il = 3; int im = 7; int io;

io = iproduct(il,im) ;

cout << il << " * " << im << " * " << in << " = " << io << "\n";

return (0);

}

int iproduct(intiw, int ix)

int iy;

int in = 2;

iy = iw * ix * (::in); return(iy);}

Переменная in вместе с оператором :: для наглядности взяты в скобки, хотя в этом нет необходимости, так как данный оператор имеет самый высокий приоритет среди остальных. Таким образом, на экран будет выведен правильный результат: "3*7*10 = 210".

Соседние файлы в папке Л№24.Классы памяти