08. Локальная область видимости
2019-04-08, 1:27 PM

Как мы уже знаем из предыдущих уроков, при выполнении процессором стейтмента int х; создаётся переменная. Возникает вопрос: «Когда эта переменная уничтожается?».

Область видимости переменной определяет, кто может видеть и использовать переменную во время её существования. И параметры функции, и переменные, которые объявлены внутри функции, имеют локальную область видимости. Другими словами, эти переменные используются только внутри функции, в которой они объявлены. Локальные переменные создаются в точке объявления и уничтожаются, когда выходят из области видимости.

Рассмотрим следующую программу:

1  #include <iostream>

2

3  int add(int a, int b) // здесь создаются переменные a и b
4  {
5   // a и b можно видеть/использовать только внутри этой функции
6   return a + b;
7  } // здесь a и b выходят из области видимости и уничтожаются

8

9  int main()
10  {
11   int x = 7; // здесь создаётся и инициализируется переменная x
12   int y = 8; // здесь создаётся и инициализируется переменная y
13   // x и y можно использовать только внутри функции main()
14   std::cout << add(x, y) << std::endl; // вызов функции add() с a = x и b = y
15   return 0;
16  } // здесь x и y выходят из области видимости и уничтожаются

Параметры a и b функции add() создаются при вызове этой функции, используются только внутри неё и уничтожаются при завершении выполнения этой функции.

Переменные x и y функции main() можно использовать только внутри main() и они также уничтожаются при завершении выполнения функции main().

Для лучшего понимания разберём детальнее ход выполнения этой программы:

  •    выполнение начинается с функции main();
  •    создаётся переменная x функции main() и ей присваивается значение 7;
  •    создаётся переменная y функции main() и ей присваивается значение 8;
  •    вызывается функция аdd() с параметрами 7 и 8;
  •    создаётся переменная a функции add() и ей присваивается значение 7;
  •    создаётся переменная b функции add() и ей присваивается значение 8;
  •    выполняется операция сложения чисел 7 и 8, результатом чего является значение 15;
  •    функция add() возвращает значение 15 обратно в caller (в функцию main());
  •    переменные функции add() a и b уничтожаются;
  •    main() выводит значение 15 на экран;
  •    main() возвращает 0 в операционную систему;
  •    переменные функции main() x и y уничтожаются.

Всё!

Обратите внимание, если бы функция add() вызывалась дважды, параметры a и b создавались и уничтожались бы также дважды. В программе с большим количеством функций, переменные создаются и уничтожаются часто.

Локальная область видимости предотвращает возникновение конфликтов имён
Из примера выше понятно, что переменные x и y отличаются от переменных a и b.

Теперь давайте рассмотрим следующую программу:

1  #include <iostream>

2

3  int add(int a, int b) // здесь создаются переменные a и b функции add()
4  {
5   return a + b;
6  } // здесь a и b функции add() выходят из области видимости и уничтожаются

7

8  int main()
9  {
10   int a = 7; // здесь создаётся переменная a функции main()
11   int b = 8; // здесь создаётся переменная b функции main()
12   std::cout << add(a, b) << std::endl; // значения переменных a и b функции main() копируются в переменные a и b функции add()
13   return 0;
14  } // здесь a и b функции main() выходят из области видимости и уничтожаются

Здесь мы изменили имена переменных x и y функции main() на a и b. Программа по-прежнему работает корректно, несмотря на то, что функция add() также имеет переменные a и b. Почему это не вызывает конфликт имён? Дело в том, что a и b функции main() являются локальными переменными, функция add() не может их видеть (и наоборот). Ни add(), ни main() не знают, что они имеют переменные с одинаковыми именами!

Это значительно снижает возможность возникновения конфликта имён. Любая функция не должна знать или заботиться о том, какие переменные находятся в другой функции. Это также предотвращает возникновение ситуаций, когда одни функции могут непреднамеренно (или намеренно) изменять значения переменных других функций.

Правило: Имена, которые используются внутри функции (включая параметры), доступны/видны только внутри этой же функции.

Тест

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

1  #include <iostream>

3  void doMath(int a)
4  {
5    int b = 5;
6    std::cout << "doMath: a = " << a << " and b = " << b << std::endl;
7    a = 4;
8    std::cout << "doMath: a = " << a << " and b = " << b << std::endl;
9  }
10 
11  int main()
12  {
13    int a = 6;
14    int b = 7;
15    std::cout << "main: a = " << a << " and b = " << b << std::endl;
16    doMath(a);
17    std::cout << "main: a = " << a << " and b = " << b << std::endl;
18    return 0;
19  }

Категория: C++ теория | Добавил: shadrinuro
Просмотров: 267 | Загрузок: 0 | Рейтинг: 0.0/0
Всего комментариев: 0
avatar