Все формальные параметры, которые перечислены в заголовке подпрограммы подобным образом
Procedure one(a,b,c: integer); Var n: integer; Begin n:= a * b*c; End;
называются параметрами-значениями. В данной процедуре это a,b,c. Такой способ передачи параметров в процедуру называется передачей по значению.
Фактическим параметром, соответствующим формальному, может быть константа, переменная или выражение того же типа, что и формальный параметр.
Обращение к процедуре oneможет быть таким:
const WIDTH=10; var height: integer; height:= 20; one(WIDTH, height, 2+3);
Если процедура имеет параметры-значения, то для них создаются локальные переменные с именем и типом формальных параметров, после чего в них последовательно копируются значения фактических параметров.
Первый формальный параметр aстанет локальной переменной а целого типа со значением первого фактического параметра WIDTH, то есть 10. Второй - локальной переменной bсо значением переменной height, то есть 20. И, наконец, третий - локальной переменной cсо значение 5.
После этого выполняется тело процедуры:
n:= 10 * 20 * 5; (n:= a * b * c;)
Так как nэто локальная переменная, то толку от неё не будет никакого - она умрёт сразу после вычисления значения. В данном случае можно использовать глобальную переменную n, тогда после выполнения процедуры oneей будет присвоено значение 1000.
Если имена глобальной и локальной переменных совпадают, то в процедуре будет использована локальная, поэтому мы должны закомментировать строчку
//Var n: integer;
Хотелось бы предостеречь от использования глобальных переменных в процедурах. Для отладки и использования подпрограмм го
раздо удобнее и надёжнее включать все параметры в список при её вызове. Так легче следить за соответствием типов формальных и фактических параметров, а также мы добиться определённой автономности подпрограмм. Подпрограммы, как и классы, позволяют скрывать детали реализации от пользователя, которого должен интересовать результат действия подпрограммы, а не сам код, выполняющий эти действия.
Так как в процедуру передаются только значения переменных, то соответствующие им локальные переменные не могут изменить их значения. Например, в процедуре oneмы присвоим переменной bзначение 1000:
b:= 1000;
При этом переменная height, значение которой копируется в переменную b, не изменится, то есть останется равным 20. Это главное преимущество передачи параметров по значению: подпрограмма получает в своё распоряжение не переменную, а только её значение, поэтому ни одна переменная не пострадает!
Но есть и недостатки. Для хранения локальных переменных требуется дополнительная память, а на их создание и копирование в них значений передаваемых параметров нужно время. Впрочем, для простых типов данных эти затраты очень невелики, а вот для структур, классов, массивов такие действия могут обернуться большими потерями производительности. В некоторых случаях может оказаться недостатком и неспособность процедур изменять значение внешней переменной (ещё недавно мы причислили эту особенность процедур с параметрами-значениями к достоинствам, но такова жизнь: у каждой медали две стороны). Конечно, можно воспользоваться глобальными переменными, но их лучше не упоминать все. Но выход всё-таки есть!