Рассмотренная программа имеет недостаток в том, что в основной ее части идет ряд присваиваний, которые предшествуют вызову процедуры. Чтобы избавиться от этих присваиваний, вводят процедуры с параметрами. С помощью параметров осуществляется передача информации в процедуру, а также и прием информации из процедуры в основную программу.
Различают формальные и фактические параметры. Формальные параметры - это имена переменных, фигурирующих в самой процедуре. Их описание производится в заголовке процедуры - после имени процедуры в скобках. Среди них имеются параметры-аргументы и параметры-результаты. Эти параметры называют формальными, потому что они служат только для фиксации числа параметров процедуры, их имена могут быть произвольными, смена имен не отражается на ее работе.
Фактические параметры задаются в вызове процедуры, т.е. они принадлежат основной части программы. В отличие от формальных параметров, которые всегда есть переменные, фактические параметры имеют вид:
параметры-аргументы - это константы, переменные, выражения;
параметры-результаты - это всегда переменные.
Рассмотрим заново программу вычисления площади четырехугольника. В ней все переменные объявлены в основной программе. Однако среди них есть переменные, которые задействованы только в процедуре. Это переменные A, B, C, P, S. Такие переменные принято называть локальными по отношению к процедуре. Остальные переменные называются глобальными. Среди локальных переменных можно выделить параметры-аргументы A, B, C и параметр-результат S. Принято формальные параметры описывать в заголовке процедуры с указанием их типа. Локальная же переменная P является вспомогательной и описывается в процедуре так же, как в основной программе.
Порядок следования формальных параметров в заголовке процедуры и фактических параметров в вызове процедуры важен, поскольку определяет, какому параметру будет присвоено то или иное значение.
Все переменные должны быть отнесены к какому-то типу, поэтому необходимо задать тип каждого параметра. Передаваемое значение и соответствующий ему параметр (фактический) должны быть одного и того же типа.
Новые варианты программы вычисления площади четырехугольника будут даны в следующих разделах, а пока рассмотрим подробнее понятия локальных и глобальных переменных в Паскаль-программах.
В предыдущем разделе уже было дано определение локальных и глобальных переменных. Уточним еще раз, что локальные переменные объявляются внутри блока процедуры и они бывают двух видов: формальные параметры заголовка процедуры и вспомогательные переменные в разделе VAR процедуры. Эти переменные неизвестны основной программе и их использование в основном блоке вызовет сообщение об ошибке.
Глобальные переменные объявляются в разделе VAR основной программы. Глобальные переменные называют глобальными, потому что они могут фигурировать не только в основной программе, но и в теле процедуры. Заметим, что иногда одна и та же переменная может быть и локальной, и глобальной. Например, если переменная J является одновременно локальной и глобальной, то локальная переменная J отличается от переменной J из главной программы. Изменения, происходящие с J в процедуре, не влияют на значение переменной J из главной программы, и наоборот. Это происходит потому, что, несмотря на сходство имен переменных, компилятор отводит локальной переменной J одну ячейку памяти, а глобальной переменной J - другую. Обычно стараются избегать совпадения имен переменных во избежание нежелательных посторонних эффектов, которые могут возникнуть из-за использования одних и тех же имен для разных переменных.
Для ясности рассмотрим пример, связанный с использованием локальных и глобальных переменных:
program NEST;
var A,B:integer;
procedure NESTEGG;
var A,X: char;
begin
A:= "!";
X:= "?";
B:= B+1;
end;
begin { ОСНОВНАЯ ПРОГРАММА }
A:= 0; B:= 100;
NESTEGG;{ ВЫЗОВ ПРОЦЕДУРЫ }
writeln(A,' ',B);
end.
В этой программе X - локальная переменная для процедуры NESTEGG, поэтому основная программа не может ни изменить ее значение, ни обратиться к ней. С другой стороны, переменная B (глобальная) известна и в программе, и в процедуре. Если переменная B является глобальной, т.е. объявлена в главной программе, то все входящие в состав этой главной программы процедуры могут ссылаться к ней, но только в том случае, если в них нет другого объявления для B. Любое объявление имени в процедуре делает недоступным объект, имеющий то же самое имя и объявленный в основной программе. Так, у нас A для основной программы есть INTEGER, но в процедуре есть A типа CHAR. Процедуре NESTEGG недоступна переменная A из главной программы. Все изменения, происходящие с A в процедуре, становятся несущественными при выходе из этой процедуры. Но, поскольку B известна в главной программе, то все изменения с B в процедуре важны и сохраняются после выхода из нее. Итак, будет напечатано: 0 101.
Как было сказано ранее, процедуры с параметрами-значениями требуют входных данных (смотри п. 5.1). Где они записываются и как задаются? На этот вопрос может ответить синтаксическая диаграмма заголовка процедуры:
Здесь под параметром понимают имя переменной, которая является "входной" для процедуры (формальный параметр-аргумент). Этот параметр с синтаксической точки зрения является параметром-значением, при его описании в заголовке процедуры не требуется писать слов VAR. Параметры-значения принимают из основной программы при вызове процедуры свои конкретные значения.
При обращении к процедуре с параметрами-значениями в основной программе фактическими параметрами могут служить как имена переменных (которые описаны и определены выше), так и конкретные значения (константы) и выражения. При обращении необходимо следить за соответствием списка параметров при обращении и описании. Кроме этого, следует строго соблюдать "типизацию" параметров.
Рассмотрим работу процедур такого типа на примерах.
ПРИМЕР 1. Нарисовать квадрат с произвольной длиной стороны в левом верхнем углу (длина стороны задается с клавиатуры).
В этой программе также надо оформить рисование квадрата в виде процедуры, но уже с входным параметром-аргументом - длиной стороны квадрата:
program RISUNOK_2;
var I: integer;
procedure KVADRAT(N: integer);
var J,K: integer;
for J:=1 to N do write('*'); writeln;
for J:=1 to N-2 do
write('*'); for K:=1 to N-2 do write(' ');
writeln('*');
for J:=1 to N do write('*');
begin { Основная программа }
write('Введите длину стороны - ');
readln(I); clrscr; KVADRAT(I);
ПРИМЕР 2. Вычисление площади четырехугольника с применением процедуры с параметрами-значениями:
program PLOCHAD_2;
var AB,BC,CD,AD,AC,S1,S: real;
procedure GERON_2(a,b,c: real);
var P: real;
P:= (a+b+c)/2; S:= sqrt(P*(P-a)*(P-b)*(P-c));
begin {*ОСНОВНАЯ ПРОГРАММА*}
read (AB,BC,CD,AD,AC); GERON_2(AB,BC,AC); S1:= S;
GERON_2(AD,AC,CD); write ('S = ', S1+S)
В данной программе определена процедура GERON_2 с тремя параметрами-значениями и локальной переменной P. Значение же площади треугольника помещается в глобальную переменную S. При вызове этой процедуры формальные параметры a, b, c замещаются на фактические параметры AB, BC, AC при первом обращении, и на AD, AC, CD - при втором.
Заметим также, что здесь фактические параметры представлены переменными, которые получают свое значение с помощью процедуры READ. Однако, если известны длины сторон треугольника, например, 6, 7, 4, то можно вычислить площадь этого треугольника, вызвав процедуру GERON_2(6,7,4), и получить ответ в переменной S.
В отличие от процедур с параметрами-значениями, данный тип не имеет входных параметров, т.е. из основной программы не передаются значения переменных в процедуру, за исключением глобальных переменных. Отличие в описании и обращении к процедурам с параметрами-переменными заключается в специфическом написании заголовка процедуры. В остальном все процедуры схожи. Итак, синтаксическая диаграмма заголовка процедуры с параметрами-переменными:
При детальном ознакомлении с синтаксической диаграммой видно, что параметрам-переменным должно предшествовать служебное слово VAR, причем оно пишется столько раз, сколько различных типов представлено в выходных данных.
Например:
PROCEDURE PRIMER(VAR a,b,c:INTEGER; VAR m:CHAR; VAR i,j:REAL);
При обращении к процедурам с параметрами-переменными фактическими параметрами должны являться имена переменных, которые описаны в основной программе.
ПРИМЕР 1. Обмен значениями переменных A и B
program ZERKALO;
var A,B: integer;
procedure OBMEN(var X,Y: integer);
begin X:= B; Y:= A end;
A:= 1; B:= 2; writeln(A,B);
OBMEN(A,B); write(A,B);
ПРИМЕР 2. Вычисление площади четырехугольника
program PLOCHAD_3;
var AB,BC,CD,AD,AC,S1,S2,a,b,c: real;
procedure GERON_3(var S: real);
read (AB,BC,CD,AD,AC);
a:=AB; b:= BC; c:= AC; GERON_3(S1);
a:=AD; b:= AC; c:= CD; GERON_3(S2);
write ('S = ', S1+S2)
Комбинированные процедуры включает в себя входные и выходные данные. В заголовке процедуры выходные параметры предваряются, словом VAR. Порядок следования параметров может быть произвольным.
НАПРИМЕР:
PROCEDURE PRIMER(VAR a,b,c:INTEGER; m:CHAR; VAR i,j:REAL);
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39