Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Тurbo Pascal 7+.doc
Скачиваний:
12
Добавлен:
24.12.2018
Размер:
10.09 Mб
Скачать

13.3. Подпрограммы. Локальные и глобальные переменные

Назовем процедуры и функции подпрограммами, так как они входят внутрь программы.

Деление переменных на локальные и глобальные является способом повысить надежность больших программ и понизить вероятность запутаться при их написании. Программы, создаваемые профессиональными программистами, очень велики - десятки и сотни тысяч строк. Один человек не может достаточно быстро создать такую программу, поэтому пишется она обычно большой группой программистов. Для этого программа делится на десятки и сотни подпрограмм, и каждый программист пишет одну или несколько подпрограмм.

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

        1. присвоить значение 5 переменной х;

        2. затем вызвать процедуру В, возводящую 10 в квадрат и печатающую текст Результат равен;

        3. и наконец, напечатать значение х:

VAR x,y: Integer;

PROCEDURE B; BEGIN у;=10*10; Write('Результат равен') END,

BEGIN

х:=5;

В;

WriteLn(x);

END.

Очевидно, программа напечатает Результат равен 5.

Допустим программу А пишет программист А, он же руководитель, а процедуру В - программист В. Когда дело касается большой программы, каждый программист досконально знает только задачу, решаемую его подпрограммой, а об остальных подпрограммах и обо всей программе он может иметь лишь минимальное представление. Задача руководителя - умело разделить программу на подпрограммы и четко определить задачу для каждой подпрограммы.

Сами подпрограммы тоже достаточно велики, и каждая из них может использовать десятки переменных. При этом возникает опасность, что автор какой-нибудь подпрограммы случайно использует внутри подпрограммы имя переменной, применяемой в другой подпрограмме или в общей программе, и таким образом исправит ее значение. Пусть, например, в нашей процедуре В ее автор нечаянно присвоил бы значение 10 * 10 переменной с именем х. Тогда программа выглядела бы так::

VAR х,у: Integer;

PROCEDURE B, BEGIN x:=10*10; Write('Результат равен') END;

BEGIN

х:=5;

В;

WriteLn(x)

END.

Очевидно, данная программа напечатала бы Результат равен 100.

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

VAR х: Integer;

PROCEDURE B;

VAR х: Integer;

BEGIN х:=10*10, Write('Результат равен') END; BEGIN

х:=5;

В;

WriteLn(x);

END.

Данная программа напечатает

Результат равен 5.

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

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

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

Рассмотрим еще один пример:

VAR x,z: Integer;

PROCEDURE B;

VAR x,y: Integer;

BEGIN

x:=20;y:=30;z:=40

END;

BEGIN

x:=1;z:=2;

B;

WriteLn(x,' ',z)

END.

Программа напечатает 140.

Пояснение. Оператор WriteLn(x,z) находится снаружи процедуры В, и поэтому локальная переменная х=20, описанная внутри В, из него не видна. Зато прекрасно видна глобальная переменная х=1, которую он и выводит. Переменная же z не описана внутри В, поэтому она глобальна, и оператор z:=40 с полным правом меняет ее значение с 2 на 40.

Для полной ясности приведем порядок работы компьютера с этой программой:

  1. В ячейках данных оперативной памяти компилятор отводит место под X глобальную и Z глобальную.

  2. Работа начинается с присвоения значений X глобальная = 1 и Z глобальная = 2.

  3. Вызывается процедура в. При этом в стеке оперативной памяти отводится место под X локальную и Y локальную.

  4. Присваиваются значения X локальная = 20, Y локальная = 30 и Z глобальная = 40.

  5. Программа выходит из процедуры в. При этом исчезают переменные X локальная = 20 и Y локальная = 30.

  6. Компьютер печатает X глобальная = 1 и Z глобальная = 40.

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