Курс ПЯВУ 2 сем / Лекции 2 сем / Л№24.Классы памяти / Область видимости
.odtОбласть видимости переменных
При работе с переменными, имеющими разную область видимости, часто возникают непредвиденные ошибки, называемые побочными эффектами. Например, в программе могут быть объявлены две переменные с одинаковым именем, но одна локально, внутри функции, а другая на уровне всего файла. Правила определения области видимости говорят о том, что в пределах функции локальная переменная имеет преимущество перед глобальной, делая последнюю недоступной. Все это звучит достаточно просто, но давайте рассмотрим ряд проблем, часто возникающих в программах и, на первый взгляд, не совсем очевидных.
Попытка получить доступ к переменной вне ее области видимости
В следующем примере в функции 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".