Область видимости переменных
Lazarus IDE: Основы программирования в Windows
Несмотря на то, что всё потихоньку уходит в сеть, программирование для настольных компьютеров остаётся востребованным. И будет таковым ещё долго. Ну а самая распространённая операционная система для настольных компьютеров – это по-прежнему Windows. Поэтому любой программист, даже если он собирается стать веб-разработчиком, должен знать хотя бы основы создания программ для Windows. Подробнее... |
В этом разделе мы рассмотрим очень важную тему - область видимости переменных. В предыдущих разделах об этом уже упоминалось. Однако пришло время разобраться с видимостью переменных подробнее.
Итак, что это такое?
Допустим, что у нас есть программа myprog, в которой есть процедура myProc:
program myprog; var globalVar : byte; procedure myProc; var localVar : byte; begin localVar := 200; end; begin globalVar := 100; localVar := 200; //!!!Ошибка end.
Эта программа вызовет ошибку во время компиляции, так как переменная localVar объявлена в процедуре myProc и является локальной, то есть НЕ ВИДНА из программы.
Отсюда следует вывод, что
Для каждой переменной или константы (а также для каждой подпрограммы, типа данных и т.п.) существует область видимости, то есть область, в пределах которой эта переменная видна (область кода, в пределах которой можно использовать эту переменную).
При этом следует помнить, что в мире программирования (как и в мире людей) всё относительно. То есть переменная может являться глобальной относительно модуля, но локальной относительно программы в целом.
Настоящими глобальными переменными (то есть переменными, которые видны из любого участка программы) можно считать лишь переменные, объявленные в системных модулях, которые подключаются к программе автоматически.
Все остальные переменные, строго говоря, являются локальными. Например, в описанной выше программе myprog есть глобальная переменная globalVar. Эту переменную можно использовать в любом участке кода этой программы. То есть во всех подпрограммах и в самой программе.
Однако, если мы создадим модуль и подключим его к нашей программе, то глобальные переменные этого модуля будут видны в нашей программе. Но переменная globalVar не будет видна в этом модуле, если не принять специальных мер. То есть для модуля переменная globalVar будет локальной переменной программы myprog.
Запутались? Ну ничего, по началу всё кажется сложным и запутанным)))
А теперь ещё немного путаницы)))
program myprog; var myVar : byte; procedure myProc; var myVar : byte; begin WriteLn('myVar in myProc = ', myVar + 50); end; begin myVar := 100; myProc; WriteLn('myVar in myprog = ', myVar); ReadLn; end.
Как вы думаете, что выведет на экран эта программа? Или по другому - как будет вести себя программа при совпадении имён локальной и глобальной переменной?
Вообще это может зависеть от настроек компилятора, но в общем случае в области видимости локальной переменной приоритет имеет локальная переменная. То есть в пределах процедуры myProc будет использоваться локальная переменная myVar. Мы можем как угодно изменять её значение в процедуре - на значение глобальной переменной myVar это не повлияет. Поэтому вторая строка выведет на экран:
myVar in myprog = 100
А вот первая строка может вывести любое значение, так как мы не инициализировали локальную переменную, то есть при запуске программы в ней может содержаться “мусор”, который остался в области памяти, с которой связана локальная переменная myVar.
А если убрать локальную переменную:
program myprog; var myVar : byte; procedure myProc; begin myVar := myVar + 50; WriteLn('myVar in myProc = ', myVar); end; begin myVar := 100; myProc; WriteLn('myVar in myprog = ', myVar); ReadLn; end.
то обе строки выведут число 150:
myVar in myProc = 150 myVar in myprog = 150
потому что значение глобальной переменной мы изменили в нашей процедуре.
Выводы:
- Переменная, объявленная в разделе переменных программы или модуля, является глобальной относительно этой программы или модуля. Эту переменную можно использовать во всех участках исходного кода этой программы или модуля.
- Переменная, объявленная в подпрограмме является локальной, то есть использовать эту переменную можно только в пределах данной подпрограммы.
- При совпадении имён локальной и глобальной переменной приоритет имеет локальная переменная.
Увы, но это далеко не вся информация о видимости переменных. Есть ещё немало нюансов. Но об этих нюансах как-нибудь в другой раз.