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

  Юрий  | 

  Обновл. 15 Апр 2019  | 

 14057

 ǀ   13 

Этот материал является продолжением урока №15.

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

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

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

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

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

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

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

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

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

Сокрытие имён


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

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

10
5

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

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

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

10
10

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

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

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

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

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

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

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

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

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

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


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

Заключение

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

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

Тест


Задание №1

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

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

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

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

Ответ №1

Задание №2

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

Ответ №2

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

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

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

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

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (164 оценок, среднее: 4,93 из 5)
Загрузка...

Комментариев: 13

  1. Аватар armus1:

  2. Аватар Елена:

    Еще вариант:

  3. Аватар Дмитрий:

  4. Аватар Игорь:

  5. Аватар Максим:

  6. Аватар Георгий:

    хм, сделал немного наоборот, но вроде смысл тот же

  7. Аватар master114:

    У меня получился такой вариант — ibb.co/jJLATc. Сделал пару функций. Перед выполнением думал, что получится поменять без временной переменной (в моем случае Z).

    1. Юрий Юрий:

      Вы правильно сделали, разбив программу на функции. А насчет временной переменной, то без неё здесь не обойтись 🙂

      1. Аватар master114:

        Нашел вариант без временной переменной — onlinegdb.com/B1E-4RKpM.

        1. Юрий Юрий:

          Хоть и работает, но у вас здесь вместо одной временной переменной используются две временные переменные: xFunc и yFunc. + еще глобальные переменные, которые нежелательно лишний раз использовать.

          Но в общем, реализация интересная однозначно.

      2. Аватар Mirovengil:

        В каком смысле "без дополнительной переменной не обойтись"? А как же классика?

        PS: имена переменным поставил простейшие, чтобы было понятно, что происходит.

  8. Аватар Sergey Groysman:

    Юрий, доброго дня.
    При решении теста №1, как сюда ввести вариант, если ввели равные числа?
    Спасибо.

    1. Юрий Юрий:

      Если ввести правильные числа сразу, то они и выведутся после, без выполнения условия if. Дополнительно ничего прописывать не нужно. В условии if ведь и указывается, что менять значение нужно только при условии что значение smaller, которое ввел пользователь — больше значения large. Если же это не так, то ничего менять и не нужно.

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

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

telegram канал
НОВОСТИ RAVESLI