Урок №15. Локальная область видимости

  Юрий  | 

  Обновл. 1 Июл 2020  | 

 39607

 ǀ   13 

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

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

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

Параметры 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.

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

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

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

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

Тест


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

Ответ

main: a = 6 and b = 7
doMath: a = 6 and b = 5
doMath: a = 4 and b = 5
main: a = 6 and b = 7

Вот ход выполнения этой программы:

   выполнение начинается с функции main();

   создается переменная a в функции main(), ей присваивается значение 6;

   создается переменная b в функции main(), ей присваивается значение 7;

   cout выводит main: a = 6 and b = 7;

   вызывается doMath() с аргументом 6;

   создается переменная a в функции doMath(), ей присваивается значение 6;

   выполняется инициализация переменной b функции doMath() значением 5;

   cout выводит doMath: a = 6 and b = 5;

   переменной a функции doMath() присваивается значение 4;

   cout выводит doMath: a = 4 and b = 5;

   a и b функции doMath() уничтожаются;

   cout выводит main: a = 6 and b = 7;

   main() возвращает 0 в операционную систему;

   a и b функции main() уничтожаются.

Обратите внимание, даже когда мы присвоили значения переменным a и b внутри функции doMath(), на переменные внутри функции main() это никак не повлияло.

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

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

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

  1. Аватар Андрей:

    Здравствуйте.
    Материал отличны, легко и интересно читать.
    Спасибо

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

    Исходя из правила немного не понятно как и откуда переменная "а" получает значение "6". По моему пониманию значение все таки взято из  main так называемого caller и передано в функцию doMath и присвоено опять же переменной "a". ведь в функции doMath до исполнения строки кода std::cout << "doMath: a = " << a << " and b = " << b << std::endl; значение переменной "а" определено не было.

    Но вот что меня совсем запутало так это то что все происходит и самое главное компилируется без ошибок — так это то что функция doMath с типом возврата void.

    Поясните пожалуйста для тех кто в танке.
    Заранее благодарен.

  2. Аватар Михаил:

    не понял как формируются две срединных строки. Почему сначала аргументу "a" сначала присваивается значение из main-на, а потом из doMath ? А "b" всегда остается из doMath ?

    1. Аватар Сергей:

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

  3. Аватар Андрей:

    Можете объяснить, что означает выход из области видимости(какой нибудь жизненный пример привести), и как переменные после этого уничтожаются.
    Я хоть и внимательно прочитал и законспектировал, но эти 2 момента не понял

    1. Аватар Константин:

      Андрей, ну вот представь подсобные хозяйства на селе: фигурные скобки в функции это ограничители вольера (область видимости), животные это переменные, килограммы массы — их значения. Какие имена хрюшек? Правильно! Внутри одной области видимости уникальные, а вне — одинаковые. Пусть дело происходит в мультфильме. Тогда мы можем взять килограммы одной хрюшки и не отобрать их у неё, а именно скопировать в другую хрюшку при этом вытеснив уже имевшиеся кг в последней! Андэсденд ми?

      1. Аватар Андрей:

        Спасибо за ответ.
        Про область видимости я давно понял, а про уничтожение переменных не до конца понимал.
        Я тут у прогеров поспрашивал и они сказали, что уничтожение — вынос мусора из памяти. И тогда да меня дошло

  4. Аватар данила:

    судя из теста понятно так же что уничтожаются аргументы ,сами то параметры остаются. Но аргумент так же уничтожается после объявления нового аргумента к этому же параметру . Как пример ,в функции майн() переопределил значение переменной B ( В=8),получается что предыдущее значение В (7) уничтожено. Так ли я понял урок?

  5. Аватар Александра:

    Отличный урок! Да и все остальные тоже =) Понятным и доступным языком все объясняется.
    Но вот проблема с этим уроком: не посмотреть ответ на тест =(

  6. Аватар Степан:

    Привет! Будешь дальше переводить оригинальный сайт?
    Интересно почитать про жесть из STL.

    Отличный сайтец, спасибо!

    1. Юрий Юрий:

      Привет. Да, малость уроков осталась. Самому тоже интересно дойти до STL.

      Пожалуйста 🙂

  7. Аватар painkiller:

    Очень полезный урок. Спасибо!

    1. Юрий Юрий:

      Пожалуйста 🙂

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

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