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

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

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

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

Глава 23

Функции



Процедуры и функции – сестры-близнецы, потому и носят общее имя – подпрограммы. Все, что сказано о передаче параметров, относится и к тем, и к другим. И все же функции чем-то отличаются от процедур, иначе, зачем их придумали? А затем, чтобы упростить возвращение результата.

Нередко таким результатом бывает число, строка, символ или булево значение. Конечно, вернуть результат можно и через ссылку на переменную, но функция сделает это удобней – через своё имя. Результат, возвращаемый функцией, можно вставлять внутрь выражений наряду с переменными и константами. Взять хотя бы знакомые нам функции Random и Length, вызовы которых можно применить, например, так:


>      x:= 1+ Random(10);       { арифметическое выражение }

>      Writeln(Length(S)); { печатается длина строки S };


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

Объявление функции

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


>function Имя_Функции : Тип;       { функция без параметров }

>function Имя_Функции (Параметры) : Тип;       { функция с параметрами }


Отличий от процедуры всего два. Во-первых, вместо ключевого слова PROCEDURE указано слово FUNCTION. А во-вторых, завершает заголовок тип функции (тип возвращаемого ею результата), – его указывают после двоеточия.

Пример функции

Разберем все это на примере. Создадим функцию, выбирающую большее из двух чисел. Разумеется, что функция будет принимать два параметра – сравниваемые числа, и возвращать будет тоже число. Стало быть, её заголовок может быть таким:


>function Max(arg1, arg2 : integer) : integer;


Имя функции выбираем на свой вкус, здесь имя Max вполне подходит, оно означает MAXIMUM (наибольший). К этому заголовку прилепим тело функции, состоящее из одного условного оператора.


>function Max(arg1, arg2 : integer) : integer;

>begin

>      if arg1 > arg2

>      then Max:= arg1

>      else Max:= arg2

>end;


Но откуда взялась переменная Max, которой присваиваем значение? Ведь мы её не объявляли! А её и не надо объявлять, – это имя нашей функции, оно и принимает в себя результат. Мало того, если результату не присвоить значение, он останется неопределенным, и это будет ошибкой!

Созданная нами функция может вызываться так:


>      A:= Max( 20, 10 );       { A = 20 }

>      Writeln( Max( A, B ) );       { печатается большее из A и B }


Вызов функции можно использовать даже как фактический параметр в её собственном вызове, то есть организовать вложенные вызовы, например:


>      A:= Max ( Max( 20, 10 ), 40 );       { A = 40 }

>      A:= Max ( Max( 20, 10 ), Max( 200, 100 ) ); { A = 200 }


В первом случае сначала вызывается функция Max(20,10), вставленная как первый фактический параметр, а затем Max(20,40), – то есть результат первого вызова подставляется параметром во второй. Похоже работает и другой пример, только функция вызывается трижды. Полезно понаблюдать за такими вызовами через отладчик. Напишите главную программу для исследования функции Max и прогоните её в отладчике.

Подсчет символов в строке

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

Начнем, разумеется, с заголовка функции, дадим ей имя Count (подсчет).


>function Count(const Str : string; Ch : char): integer;


Функция принимает два параметра: ссылку на строку и символ, который надо подсчитать. Напомню, что ключевое слово CONST в объявлении параметра позволяет ссылаться и на константу, и на переменную. Тело функции строим на базе цикла со счетчиком.


>function Count(const str : string; ch: char): integer;

>var N, i: integer;

>begin

>N:=0; { обнуляем счетчик }

>for i:=1 to Length(str) do

>      if str[i]=ch then N:= N+1;

>Count:= N; { определяем результат функции }

>end;


Подсчет символов в массиве ведется в локальной переменной N, и лишь по завершении цикла результат копируется в имя функции. Грубой ошибкой было бы накапливать счетчик прямо в имени функции:


>      if str[i]=ch then Count:= Count+1; { – это ошибка! }


Запомните: в теле функции её имя применяется только слева от оператора присваивания! Есть исключения из этого правила, но мы пока не будем их касаться.

И, наконец, напишем программу «P_22_1» для проверки функции Count. В главной программе функция вызывается сначала для переменной S, а затем для константы «BANAN». Причем во втором случае она вызывается дважды, а результат суммируется. Испытайте эту программу.


>{ P_23_1 – подсчет заданных символов в строке }


>function Count(const str : string; ch: char): integer;

>var N, i: integer;

>begin

>N:=0; { обнуляем счетчик }


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

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


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

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


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

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


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

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


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

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


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

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