Область видимости переменных в C++ для начинающих. Поверхностное знакомство

В С++ есть понятия областей видимости переменных. Эта статья должна помочь немного разобраться начинающему программисту, что это такое.
Поскольку многие мои читатели скорее всего ещё далеко не ушли, в этой статье будет только поверхностное знакомство с областями видимости переменных.
На заметку:

  • Областью видимости или областью действия переменных называют участок кода, внутри которого с переменной можно работать.
Участки кода делятся не некоторые блоки кода: тело цикла, тело функции, просто тело и другие. В С++ эти тела обозначаются фигурными скобками. Так вот, можно использовать одну переменную, доступную всем телам сразу или переменные, доступные только внутри блоков кода. Простейший пример на самых простых блоках кода выглядит так:

Будет ли доступна переменная в блоке кода или не будет — зависит от места объявления переменной. Всё, что объявляется внутри блока кода — доступно внутри блока и только внутри собственного блока. Конечно можно связать такую переменную с внешним миром, но изначально она принадлежит только внутреннему миру блока, внутри которого объявлена.
В показанном коде задействуется три переменные: many_visible, value1 и value2. Переменная many_visible объявлена внутри функции main и отдельные блоки кодов используются внутри функции main. Два созданных блока не связаны междц собой и скрывают своё нутро от постороннего мира, поэтому всё, что внутри них — внешнему миру закрыто. Поэтому последние две попытки вывода на экран значений переменных, созданных внутри некоторых блоков кода, приводит к ошибкам компиляции. Те переменные скрываются блоками от функции main. Это называется локализацией переменных.
  • Локальные переменные — это переменные некоторого блока кода, доступные только внутри собственного блока.
Таким образом у нас получается, что в коде две локальные переменные для самых простых блоков кода и одна локальная переменная для функции main. Для функции main локальна и переменная many_visible, и каждый блок, описанный внутри неё. Поэтому переменная many_visible легко внедряется в любой из блоков, описанных внутри main.
Это основа природы видимости переменных: в каких-то блоках кода переменные доступны, в каких-то нет. По правилам хорошего тона, нужно максимально локализовать переменные.

На этой картинке заливкой показано приблизительное представление областей видимости. Самая внутренняя область считается самой актуальной для блока. И актуальность происходит изнутри наружу. Если снаружи есть какая-то переменная, не закрытая каким-нибудь блоком, то такая переменная доступна.

Я надеюсь, что у меня получилось, объяснить, что это такое вообще. Теперь немного углубимся.
Если взять обычные функции, то внутри них могут быть внутренние, сокрытые функцией от внешнего мира переменные. Такие переменные называются локальными для функций переменными. А есть переменные, которые могут легко внедриться в любую функцию — такие переменные называют глобальными. Правда, использование глобальных переменных почти никем не приветствуется, но такие переменные иногда используют.
  • Глобальные переменные — это такие переменные, которые доступны по всей программе, в любом блоке кода.
Пример с глобальной переменной:

Глобальная переменная объявляется вне тела функций и доступна она до конца программы. В приведенном примере вне функций было объявлено две переменные. К каждой из них можно обратиться в любом блоке программы. При этом, последнее запомненное значение таких переменных остается в памяти и доступно для последующей обработки. Просто немного поизучайте показанный пример. Персонально для функции sum переменных создано не было, но несмотря на это, я смог с помощью функции sum вывести верные значения переменных на экран. Смог, потому что объявил их вне тел функций, а значит сделал глобальными, т. е. доступными для любой функции (любого блока программы).
Кроме глобальных переменных существуют локальные переменные. Локальные для функций переменные объявляются внутри функций и доступны они только внутри своих функций. От внешнего мира функциями они скрываются.

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

  • Внутренняя переменная затеняет внешнюю переменную, если внешняя переменная имеет такое же имя как внутренняя и пытается внедриться в блок кода, внутри которого живёт внутренняя переменная.
Проще говоря, если в один блок кода происходит попытка закинуть переменную с таким именем, которое уже занято внутриблоковой переменной, то тогда мог бы быть конфликт имён. Но в С++ внутренние переменные первичны над внешними, поэтому для внутренней для блока переменной ничего не изменится, а вот работать со внешней нам придётся немного иначе, чем обычно.
Пример кода. Локальная переменная затеняет глобальную:

В случае, когда программист объявляет глобальную переменную и одноименную с ней локальную, локальная затеняет глобальную. При вызове функции с локальными переменными, локальные переменные по приоритету выше глобальных. Так как локальные переменные по приоритету выше, значит значения для вычислений берутся из них. По завершении функции глобальная переменная вновь приобретает силу. Это можно понять по приведенному примеру. Вне функций была объявлена некоторая переменная i (вне = глобальная), вместе с ней внутри функции sum была объявлена еще одна переменная i (внутри = локальная). Очень надеюсь, что этот пример нагляден вам и хорошо даёт понять выражение затенение переменной.
Когда мы вытаскивали затенённую переменную, мы использовали двоеточие перед названием переменной. Это двоеточие — это обозначение сущности из глобально пространства имён, т. е. мы явно указываем, что хотим глобальную переменную.

Конечно в этой статье написано не всё, но статья ориентирована на совсем начинающих программистов, которым очень нужно растолковывать подробно некоторые простые вещи.
Писал ранее, но напомню. Глобальные переменные может быть удобнее использовать, чем локальные, но глобальных переменных нужно по максимуму избегать, предпочитая им локальные переменные.
Все комментарии на сайте проверяются, поэтому ваш комментарий может появиться не сразу. Для вставки кода в комментарий используйте теги: [php]ВАШ_КОД[/php]

Один комментарий: Область видимости переменных в C++ для начинающих. Поверхностное знакомство

  • Sergio говорит:

    Добрый день! Возможно ли передать из одной функции локальную переменную (да и локальный массив) в другую функцию? Понятно, что проще объявить глобальную переменную, но всё же интересно… 🙄

    Автор сайта отвечает:
    Глобальных переменных нужно избегать.
    или я не понял вопроса или вы не так его задали.
    передать с помощью параметров. Без указания параметров передать нельзя, указать в параметрах можно.

    А как поступить в данном случае?

    Правильно ли я всё делаю?

    Автор сайта отвечает:
    Прототипы неправильно.
    myfunc2(); должно быть myfunc2(int);
    myfunc2(); должно быть myfunc2(int, char[]); //вроде так

    Вы правильно поняли вопрос, спасибо.
    Массив, как понимаю, передаётся таким же образом?

    Автор сайта отвечает:
    Смотря какой массив, они разными бывают.
    Мне кажется, что основные ответы на подобные вопросы можно найти если на странице содержания тем
    (http://ci-plus-plus-snachala.ru) нажать ctrl+F и ввести Перед подсветятся разные темы по работе с параметрами у функций
    Все -таки это отдельные темы и описывались они отдельно.

    Спасибо. Я почему-то до этого момента был уверен, что на странице содержания темы выстроены по порядку изучения С++, а не просто сгруппированы по разделам…

    Автор сайта отвечает:
    Я могу быть неправ, но не забегая вперед будет очень трудно изучить какой бы то ни было язык программирования.
    Язык С++ изучается как по спирали и изучив что-то новое часто приходится возвращаться к тому что уже однажды вроде бы было изучено и постоянно получается узнавать что-то новое.
    Многие авторитетные авторы используют забегание наперед, чтобы лучше объяснять своим читателям то что они хотят объяснить.
    Я не авторитетный автор и авторитетным стать не смогу. К сожалению, у меня очень много ошибок и я плохо разбираюсь в матчасти. Лучше чем многие создатели похожих сайтов, но недостаточно, чтобы считать себя хорошим учителем.

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

    Автор сайта отвечает:
    И еще такой момент есть.
    На каждой странице с описанием темы вверху всегда расположены 2 ссылки.
    http://ci-plus-plus-snachala.ru/?p=121 ===> С++ первая программа Очистка экрана clrscr(); (хорошо видно, тут одна)
     
    Если жать на эти ссылки, то порядок будет больше напоминать книгу чем смотреть порядок в содержании. И немного удобнее, не нужно каждый раз возвращаться к содержанию, чтобы перейти к следующей теме.




    0



    0

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

Ваш e-mail не будет опубликован.

Поиск

 
     

Случайная книга в электронном формате

Яндекс.Метрика
НАГРАДИ АВТОРА САЙТА
WEBMONEY
R375024497470
U251140483387
Z301246203264
E149319127674

Демотиватор вероисповедание программист

Выражаю свою признательность

  • Максиму очень признателен за указание на мои ошибки и неточности.
  • Sergio ===> за оказание помощи в исправлении моих ошибок
  • Gen ===> за правильное стремление помочь другим новичкам и выявления моих ошибок