Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Pesni_o_Paskale_2012-11-23.pdf
Скачиваний:
35
Добавлен:
19.03.2016
Размер:
5.16 Mб
Скачать

Глава 22 О передаче параметров

Современные программы — даже не самые сложные — содержат тысячи строк. Как же распределена эта сложность? Почти вся она «размазана» по процедурам и функциям, — главную программу составляют обычно лишь несколько строчек! Процедуры и функции, вызывая друг друга, передают данные по цепочке, как спортсмены эстафетную палочку. Будущий профессионал должен владеть тонкостями этого механизма.

Процедура обмена

Рассмотрим процедуру с несколькими параметрами. Пусть требуется обменять значения переменных A и B, это можно сделать так.

T:= A;

{ временно запомнить A }

A:= B;

 

B:= T;

{ поместить в B то, что раньше было в A }

 

 

Здесь T — переменная для временного хранения данных. Поручим эту простенькую работу некой процедуре, назовем её Swap (обмен). Создавать процедуру Swap начнем, как водится, с заголовка. Поскольку в обмене участвуют два числа, оба следует передать через параметры. Для разделения формальных параметров используют точку с запятой. Если заголовок процедуры будет таким:

procedure Swap (x: integer; y: integer);

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

procedure Swap (var x: integer; var y: integer);

Если формальные параметры имеют одинаковый тип и способ передачи, то заголовок можно сократить так.

procedure Swap (var x, y: integer);

Принцип объединения в заголовке тот же, что при объявлении однотипных переменных в секции VAR.

Теперь напишем процедуру Swap и программу P_22_1 для её проверки.

144

Глава 22

Опередаче параметров

{P_22_1 – процедура обмена и программа её проверки }

{процедура обмена }

procedure SWAP(var x,y : integer); var t: integer;

begin

t:= x;

x:= y;

y:= t;

end;

var A, B : integer;

begin {--- главная программа ---} A:= 10; B:= 20;

Writeln(’A= ’, A, ’ B= ’, B);

SWAP(A, B);

Writeln(’A= ’, A, ’ B= ’, B);

Readln;

end.

Работает ли эта программа? Обязательно проверьте!

Замена символов в строке

Вернемся к программе P_20_1, где возможности процедуры Scan небогаты: допускается менять только символы «A» на символы «B». А если надо менять символы по своему усмотрению? Пожалуйста! Добавим в заголовок процедуры пару формальных параметров, например, так.

procedure Scan(var arg: string; Ch1, Ch2: char); var k: integer;

begin

for k:=1 to Length(arg) do

if arg[k]= Ch1 then arg[k]:= Ch2;

end;

Здесь параметры Ch1 и Ch2 определяют, что и на что надо поменять.

Поскольку параметры однотипны, они разделяются запятой. Порядок объявления формальных параметров в заголовке не важен. Но важно, чтобы при вызове процедуры порядок фактических параметров был таким же. Вот пример правильного вызова (символ «1» меняется на символ «2»).

Scan(S, ’1’, ’2’);

А вот ошибочные:

145

 

 

Глава 22

 

 

 

О передаче параметров

 

 

 

 

 

 

Scan(S, ’1’);

{ указаны не все параметры }

 

 

Scan(’1’, S, ’2’);

{ нарушен порядок следования параметров }

 

 

Scan(S, ’1’, ’2’, ’3’);

{ указан лишний параметр }

 

 

Scan(S, 1, 2);

{ неверный тип параметров }

 

 

 

 

 

За соответствием фактических параметров формальным жестко следит компилятор. Исключение составляют встроенные в язык процедуры ввода-вывода, такие как Readln и Writeln, где допускается гибкая передача параметров разных типов.

Переработайте программу P_20_1 с тем, чтобы испытать новую версию процедуры замены символов, а затем исследуйте её в пошаговом режиме.

О передаче строк

Передача строковых данных таит свои тонкости. Рассмотрим процедуру Calc для подсчета заданного символа в некоторой строке.

procedure Calc(arg: string; Ch: char; var Res: integer); var k: integer;

begin

Res:=0;

for k:=1 to Length(arg) do

if arg[k]= Ch then Res:= Res+1;

end;

Процедура принимает три разнотипных параметра: строку arg, символ Ch и ссылку на переменную Res — в ней возвращается результат. Здесь все правильно. Но недаром говорят: «меньше знаешь, — крепче спишь», — мой сон тревожит параметр arg строкового типа.

Поскольку строка может содержать до 255 символов, параметру arg отводится немалая память — 256 байтов! При передаче по значению все эти байты копируются в параметр arg, и на это тратится время. Если же параметр arg будет ссылкой на строку, то копирования не потребуется, и программа заработает быстрее. Вдобавок мы и память сэкономим, ведь ссылка на строку занимает в памяти всего 4 байта! Раз так, объявим процедуру иначе.

procedure Calc(var arg: string; Ch: char; var Res: integer);

Этот вариант лучше, но не сработает, если в вызове процедуры указать строковую константу, например:

146

Глава 22

О передаче параметров

Calc(’PASCAL’, ’L’, Result);

Здесь компилятор воспротивится не на шутку, требуя в первом параметре переменную. И будет прав, поскольку ключевое слово VAR в заголовке процедуры объявляет ссылку на переменную, а не на константу. Что делать? Вернуться к первому способу? Нет, есть лучшее средство: вместо ключевого слова VAR укажите в заголовке слово CONST, вот так.

procedure Calc(const arg: string; Ch: char; var Res: integer);

Такая ссылка будет годна как для переменной, так и для константы.

Calc(’PASCAL’, ’L’, Result);

{

вызов

с

константой

}

Calc(S, ’L’, Result);

{

вызов

с

переменной

}

 

 

 

 

 

 

Слово CONST перед формальным параметром, так же, как и VAR, определяет ссылку на данные, но без возможности их изменения. Обратите внимание на двойное назначение слов CONST и VAR: их применяют и для открытия соответствующих секций, и для объявления ссылочных параметров.

Итоги

Количество фактических параметров, их тип и порядок следования в вызове должны совпадать со списком формальных параметров процедуры.

Для экономии памяти и повышения быстродействия строковые данные (и другие сложные типы данных) передают по ссылке с применением ключевых слов CONST и VAR.

Если строку передают по ссылке только внутрь процедуры, используют ключевое слово CONST, а если обратно или в оба направления – слово VAR.

Если строка передается только внутрь процедуры и далее применяется там как локальная переменная, то ключевые слова CONST и VAR в объявлении параметра не ставят (так происходит передача параметра по значению).

Аслабо?

А) Введите в компьютер программу P_22_1 и проверьте её работу.

Б) Измените программу P_20_1 так, чтобы заменяемый и замещаемый символы передавались в процедуру Scan через параметры.

В) Напишите программу для проверки рассмотренной выше процедуры Calc, подсчитывающей символ в строке.

147