Механизм передачи значения
Описание
Параметр-константа
Механизм передачи значения
В отличие от параметра-значения, для параметра-переменной не создается копии при вызове подпрограммы. Вместо этого в работе подпрограммы участвует та самая переменная, которая послужила аргументом. Понятно, что если ее значение изменится в процессе работы подпрограммы, то это изменение сохранится и после того, как будет уничтожен контекст подпрограммы. Понятно опять же и ограничение на аргументы, которые должны соответствовать параметрам-переменным: ни константа, ни выражение не смогут сохранить изменения, внесенные в процессе работы подпрограммы.
Итак, параметры-переменные и служат теми посредниками, которые позволяют получать результаты работы процедур, а также увеличивать количество результатов, возвращаемых функциями.
Замечание: Для экономии памяти в параметр-переменную можно передавать и такую переменную, изменять значение которой не требуется. Скажем, если нужно передать в качестве аргумента массив, то лучше не создавать его копию, как это будет сделано при использовании параметра-значения, а использовать параметр-переменную.
В списке параметров подпрограммы перед параметром-константой ставится служебное слово const. Например, процедура proc4 имеет один параметр-переменную и один параметр-константу:
procedure proc4(var k:integer; const flag:boolean);
При вызове подпрограммы параметру-константе может соответствовать аргумент, являющийся выражением, переменной или константой. Во время выполнения подпрограммы соответствующая переменная считается обычной константой. Ограничением является то, что при вызове другой подпрограммы из тела текущего параметра-константе не может быть подставлен в качестве аргумента в параметр-переменную.
Для типов данных здесь не обязательно строгое совпадение (эквивалентность), достаточно и совместимости по присваиванию (см. лекцию 2).
В некоторых источниках можно встретить утверждение о том, что для параметра-константы, как и для параметра-переменной, не создается копии в момент вызова подпрограммы. Однако выполнение простейшей проверки
var a: byte;
procedure prob(const c:byte);
begin
writeln(longint(addr(c))); {физ.адрес параметра с}
end;
begin
a:=0;
writeln(longint(addr(a))); {физ.адрес переменной а}
prob(a);
end.
доказывает обратное: физические адреса переменной а и параметра с различаются. Следовательно, в памяти эти переменные занимают разные позиции, а не одну, как было бы в случае параметра-переменной. Вы можете убедиться в этом самостоятельно, запустив данную программу в трех разных вариантах (для параметра-значения, параметра-переменной и параметра-константы), а затем сравнив результаты.
Пример использования процедуры и функции
Программа вводит текстовую строку, преобразует все входящие в нее буквы в прописные и выводит результат.
Предполагается, что последовательность букв образуют непрерывный массив. В соответствии с таблицей кодировки символов коды символов латинских строчных букв от а до z образуют непрерывный массив монотонно нарастающих чисел от 97 до 122, а коды соответствующих им прописных букв – непрерывный массив чисел от 65 до 90. Преобразование строчных букв в прописные состоит в уменьшении кода буквы на 32.
program CharConvert;
procedure UpString(s1:string; var s2:string);
{процедура преобразует буквы входной строки s1 в
прописные буквы латинского алфавита и помещает
результат преобразования в выходную строку s2.}
var i:integer;
c:char; {рабочая переменная преобразования}
begin
s2:=’’; {вначале выходная строка пустая}
{цикл посимвольного анализа исходной строки}
for i:=1 to length(s1) do
begin
{берем из входной строки очередной символ}
c:=s1[i];
{проверяем символ на принадлежность к массиву}
if (c>=’a’) and (c<=’z’) then
c:=chr(ord(‘A’)+ord(c)-ord(‘a’));
s2:=s2+c;
end
end;
var sinp, sout:string; {исходная и преобразованная строки}
begin
write(‘Введите строку’);
readln(sinp);
UpString(sinp, sout); {преобразуем введенную строку к прописным буквам}
writeln(‘Результат’, sout)
end.
Перед параметром s2, с помощью которого в вызывающую программу возвращается результат преобразования, стоит зарезервированное слово var. Именно таким способом компилятору указываются те параметры, в которых процедура возвращает вызвавшей ее программе результат своей работы.
program CharConvert1;
function UpString(s1:string):string;
var i:integer;
c:char;
s2:string {Результат преобразования}
begin
s2:=’’;
for i:=1 to length(s1) do
begin
c:=upcase(s1[i]);
s2:=s2+c;
end;
UpString:=s2 {Присваиваем значение функции UpString}
end;
var sinp:string;
begin
write(‘Введите строку’);
readln(sinp);
writeln(‘Результат’, UpString(sinp))
end.
В теле функции необходимо осуществлять присваивание ей вычисленного значения (UpString:=s2). В левой части оператора присваивания в этом случае указывается имя функции. С помощью стандартной функции upcase преобразуется каждый очередной символ латинского алфавита.