Урок 48. Локальные переменные, область видимости и время жизни

   ⁄ 

 Обновлено 23 Мар 2017

  ⁄   

Этот материал является продолжением урока о локальной области видимости в C++.

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

Переменные, определенные внутри блока, называются локальными переменными. Локальные переменные имеют автоматическую продолжительность: они создаются (и инициализируются, если необходимо) в точке определения и уничтожаются при выходе из блока. Локальные переменные имеют локальную область видимости (или блочную), то есть они входят в область видимости с точки объявления и выходят в самом конце блока, в котором определены.

Рассмотрим простую функцию:

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

Переменные, определенные внутри вложенных блоков, уничтожаются, как только заканчивается вложенный блок:

Такие переменные можно использовать только внутри блоков, в которых они определены. Поскольку каждая функция имеет свой собственный блок, то переменные одной функции никак не соприкасаются и не влияют на переменные другой функции:

То есть в разных функциях могут находиться переменные или параметры с одинаковыми именами. Это хорошо, потому что не нужно беспокоиться о возможности возникновения конфликтов имен между двумя независимыми функциями. В примере ниже в обеих функциях есть переменные x и y. Они не даже не подозревают о существовании друг друга.

Вложенные блоки считаются частью внешнего блока, в котором они определены. Следовательно, переменные, определенные во внешнем блоке, могут быть видны внутри вложенного блока:

Сокрытие имен в C++

Переменная внутри вложенного блока может иметь то же имя, что и переменная внутри внешнего блока. Когда подобное случается, то переменная во вложенном блоке «скрывает» внешнюю переменную. Это называется сокрытием имен.

Если вы запустите эту программу, то результатом будет:

10
5

В программе выше мы сначала объявляем переменную oranges во внешнем блоке. Затем объявляем другую переменную (тоже oranges), но уже во вложенном блоке. Когда мы присваиваем oranges значение 10, то оно относится только к переменной во вложенном блоке. После вывода этого значения, вложенная переменная oranges уничтожается, оставляя внешнюю oranges с исходным значением (5), которое затем выводится. Программа выполнялась бы также, даже если бы мы назвали вложенную переменную по-другому (например, nbOranges).

Обратите внимание, если бы мы не определили вложенную переменную oranges, то сам идентификатор oranges относился бы к внешней переменной и значение 10 было бы присвоено внешней переменной:

Результат программы выше:

10
10

В обоих примерах, на внешнюю переменную oranges никак не влияет то, что происходит с вложенной переменной. Единственное различие между двумя программами — это то, к чему применяется выражение oranges = 10.

Сокрытие имен — это то, чего, как правило, следует избегать, поскольку оно может быть довольно запутанным!

Правило: Избегайте использования вложенных переменных с теми же именами, что имеют внешние переменные.

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

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

Ограничивая область видимости, вы уменьшаете сложность программы, поскольку число активных переменных уменьшается. В будущем будет легче увидеть, где какие переменные используются. Переменная, определенная внутри блока, может использоваться только внутри этого же блока (или вложенных в нее подблоков). Этим мы упрощаем понимание программы.

Если во внешнем блоке нужна переменная, то её и необходимо объявлять во внешнем блоке:

Это один из редких случаев, когда вам может понадобиться объявить переменную до её первого использования.

Правило: Определяйте переменные в наиболее ограниченной области видимости.

Параметры функции

Хоть параметры функций не определяются внутри основного блока (тела) функции, в большинстве случаев они имеют локальную область видимости.

Итого

Переменные, определенные внутри блоков, называются локальными переменными. Они доступны только внутри блока, в котором определены (включая вложенные блоки) и уничтожаются, как только блок заканчивается.

Определяйте переменные в наименьшей возможной области видимости. Если переменная используется только внутри вложенного блока, то определять её следует в том же вложенном блоке.

Тест

1. Напишите программу, которая просит пользователя ввести два целых числа: второе должно быть больше первого. Если пользователь введет второе число меньше, то используйте блок и временную переменную для рокировки чисел. Затем выведите значение этих переменных. Добавьте в свой код комментарии, указывающие, где какая переменная уничтожается.

Результат работы программы должен быть примерно следующим:

Введите число: 4
Введите большее число: 2
Меняем значения
Меньшее число: 2
Большее число: 4

Подсказка: Чтобы писать русскими буквами в консоль — добавьте следующую строчку кода в самое начало блока main():

2. В чем разница между областью видимости и продолжительностью переменной? Какую область видимости и продолжительность, по умолчанию, имеют локальные переменные (и что это значит)?

Ответы

Ответ 1

Ответ 2

Область видимости определяет, где переменная доступна. Продолжительность определяет, когда переменная создается и уничтожается.

Локальные переменные имеют локальную (блочную) область видимости, доступ к ним осуществляется только внутри блока, в котором они определены.

Локальные переменные имеют автоматическую продолжительность, что означает, что они создаются в точке определения и уничтожаются в конце блока, в котором определены.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (14 оценок, среднее: 5,00 из 5)
Загрузка...
Поделиться в:
Подписаться на обновления:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *