Песни о Паскале - [38]

Шрифт
Интервал


>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» для её проверки.


>{ 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’);


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


>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);


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


>      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» и проверьте её работу.


Рекомендуем почитать
«Ад» для поступающих

Если бы не этот контракт, где прописывается, что я, Ринара Моисара-Делин-ту-Рейн, должна отпахать учителем в магической академии двадцать лет из-за своих экспериментов, то вообще бы снесла эту шаражкину контору к чертям собачьим!  Пока ректор скрипел пером по пергаменту и злобно поглядывал на меня, сидела и курила сигарету в форточку.  -Забыл сказать, свои успехи вам придется демонстрировать в конце каждой недели в течении полугода! – радостно засиял ректор. Я бы покривила лицо, да надо держать марку.


Маленькая история большой любви

Академия Прикладной Магии и Магичеких Ремёсел - обычное учебное заведение. Даже не самое престижное. Обычные студенты. Обычный учебный год. Всё здесь было обычным, только преподаватель иллюзий мастерина Альэдера нарушала эту традицию. Что могло привести дочь Светлого Леса, чистокровную эльфийку, скрывающую ото всех своё истинное имя, настоящее лицо, богатое событиями прошлое, в эти стены. Почему вечерами она бродит часами по огромному парку и вспоминает, вспоминает... вспоминает. О чём? Всё в её жизни когда-то было по-другому.


В погоне за неприятностями

Я — Елена. Второй мастер гильдии боевиков. Вроде бы все шло вполне обычно, но в один день в моей жизни появился ОН! И вот надо же было так случиться, что я влюбилась именно в этого вредного и ехидного ангела, а он в меня, но этого же, как обычно, мало судьбе! На меня охотится первая половина империи, а на него вторая и еще прибавились проблемы с переворотом в нашей вполне процветающей стране, но когда это останавливало влюбленных мужчин? Да как вообще такое злобное бедствие остановишь? Он одним лишь появлением способен довести до обморочного состояния всех присутствующих… Ну впрочем, как и я, если нахожусь в состоянии бешенства.


Хранители: Город Сновидений

Шестнадцатилетняя девочка Энни, через книгу, попадает в город Сновидений, в котором происходит невероятная магия Луны. Там она узнает, что относится к необыкновенному роду людей – хранителям, которые защищают и помогают людям. Чтобы вернуться домой ей нужно найти лунный цветок расцветающий раз в сто лет, и который может исполнить любое, но одно желание.


Другая Земля Наследие Дружан

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


Зазеркалье. Фея для демона

Добрая и наивная сказка о любви.