top of page

Локальные и глобальные переменные

Напомним, что каждый модуль (процедура, функция, программа) состоит из заголовка (procedure…, function…, program…) и блока.

Если блок какой-либо процедуры p1содержит внутри процедуру p2, то говорят, чтоp2 вложена в p1.

 

Пример.

 

  1. procedure p1(x: real; var y: real);

  2.     var c: integer;

  3.     procedure p2(var z: real);

  4.         …………………….

  5.     end;

  6.     begin

  7.         …………………….

  8.     end;

 

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

 

Пример.

 

  1. procedure t1;

  2.     var y1, y2: real;

  3.     procedure sq1;

  4.         var a, b, c, d: real;

  5.         begin

  6.             { Переменные a, b, c, d являются локальными для sq1,

  7.                область их действия – процедура sq1 }

  8.             ……………………………………

  9.         end;

  10.  

  11.     begin

  12.         { Переменные y1, y2 - нелокальные для sq1,

  13.            область их действия – t1 и sq1 }

  14.     end;

 

Константы, переменные, типы, описанные в блоке program, называютсяглобальными. Казалось бы, проще иметь дело вообще только с глобальными переменными, описав их все в program. Но использование локальных переменных позволяет системе лучше оптимизировать программы, делать их более наглядными и уменьшает вероятность появления ошибок.

 

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

1.    Описывать идентификаторы в том блоке, где они используются, если это возможно.

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

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

 

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

 

Пример.

 

  1. var k: integer;

  2. procedure a;

  3.     var x, z: real;

  4.     begin

  5.         { через x, z обозначены две величины –

  6.         локальные переменные для a;

  7.         k – глобальная переменная для a }

  8.         …………………………………

  9.     end;

  10.  

  11. procedure b;

  12.     var x, y: integer;

  13.     begin

  14.         { через x, y обозначены две другие величины –

  15.         локальные переменные для b;

  16.         k – глобальная переменная для b }

  17.         …………………………………

  18.     end;

  19.  

  20. begin

  21. { k – единственная переменная, которую

  22. можно использовать в основной ветке программы }

  23. …………………………………

  24. end.

 

Если один и тот же идентификатор описан в блоке b и второй раз описан во вложенном в b блоке c, то надо помнить, что эти два одинаковых идентификатора соответствуют разным ячейкам памяти.

 

  1. var

  2.     i: integer;

  3.     a: real;

  4.  

  5. procedure p(var d: real);

  6.     var i: integer;

  7.     begin

  8.         i :=3;

  9.         d :=i + 10 * d;

  10.     end;

  11.  

  12. begin

  13.     a :=2.0;

  14.     i :=15;

  15.     p(a);

  16.     writeln(' i=', i, ' a=', a);

  17.  

  18. readln

  19. end.

 

Глобальным переменным i и a отводятся две ячейки памяти. Первыми выполняются операторы a :=2.0 и i :=15. Затем вызывается процедура p(a). В процессе работы p отводится ячейка для локальной переменной i и туда засылается число 3. После окончания работы процедуры p эта ячейка i программой «забывается». После возврата на оператор writeln программа знает только одну ячейку i – глобальную, т.е. ту, которая содержит число 15. Поэтому программа выдаст на печать i=15, a=23.0, т.к. a=3 + 10 * 2.

 

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

 

Пример.

 

  1. type ab=array[1..3] of real;

  2. var a: ab;

  3. procedure q;

  4.     var b: ab;

  5.     …………………………..

  6. end;

 

В этом примере переменные a и b описаны через общий тип ab. Если же локальная и глобальная переменные описаны одинаково, но не через общий тип, то программа может «не понять», что эти переменные принадлежат одному типу.

 

Пример.

 

  1. var a: array[1..3] of real;

  2. procedure q;

  3.     var b: array[1..3] of real;

  4.     ……………………….

  5. end;

 

В этом примере переменные a и b – одинаковые массивы, т.е. типы этих переменных одинаковы, но программа, тем не менее, «не считает», что a и b принадлежат одному типу. Это происходит из-за того, что описание массивов дано в разных блоках.

bottom of page