Олег Деревенец - Песни о Паскале
- Название:Песни о Паскале
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Олег Деревенец - Песни о Паскале краткое содержание
Песни о Паскале - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
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; { обнуляем счетчик }
for i:=1 to Length(str) do
if str[i]=ch then N:= N+1;
Count:= N; { передаем результат через имя функции }
end;
var S: string;
begin {--- главная программа ---}
S:='PASCAL';
Writeln( Count(S, 'A'));
Writeln( Count('BANAN', 'N') + Count('BANAN', 'B'));
Readln;
end.
Вернемся к программе «P_20_1», заменяющей символы «A» на символы «B». Помните сколько крови она попортила прежде чем заработать? Заменив процедуру Scan на функцию с тем же именем, мы решим проблему возврата результата. Результат, разумеется, должен иметь строковый тип. Обратите внимание на то, что ключевые слова VAR или CONST в заголовке не указаны, а потому параметр arg можно употребить в теле функции в качестве локальной переменной.
{ P_23_2 – замена символов в строке с применением функции }
function Scan(arg : string): string;
var k: integer;
begin
for k:=1 to Length(arg) do
if arg[k]=’A’ then arg[k]:=’B’; { замена в параметре arg }
Scan:= arg;
end;
var S: string; k: integer;
begin {--- главная программа –--}
for k:=1 to 3 do begin
Write(’Введите строку: ’); Readln(S);
Writeln(Scan(S));
end;
Readln;
end.
Хорошая функция возвращает правильный результат, а отличная делает ещё что-нибудь полезное. Программисты нередко поручают одной функции несколько дел, вот пример: напишем функцию Swap (обмен) булевого типа, принимающую ссылки на две переменные. Функция должна сравнить эти переменные и вернуть TRUE, если первая из них окажется больше второй. Мало того, в этом случае она должна обменять значения этих переменных (как в процедуре Swap, рассмотренной ранее). Короче, функция будет такой.
function Swap( var a1, a2 : integer) : Boolean;
var t: integer;
begin
if a1 > a2
then begin
{ обмен значений переменных }
t:=a1; a1:=a2; a2:=t;
Swap:= true
end
else Swap:= false
end;
Где применить такую функцию? Пусть переменные N1, N2, N3 содержат три разных числа. Переложим эти числа так, чтобы в N1 оказалось наименьшее, а в N3 – наибольшее число, то есть, чтобы соблюдалось условие: N1 < N2 < N3. Такая сортировка выполняется тремя вызовами функции Swap (в комментариях показаны результаты обмена).
Swap (N1, N2); { N1 < N2 }
if Swap (N2, N3) { N2 < N3 }
then Swap (N1, N2); { N1 < N2 < N3 }
Здесь в первой и третьей строках функция вызывается как процедура, поскольку возвращаемый ею булев результат не используется. Во второй строке она вызывается как функция, поскольку результат использован оператором IF.
Возможность вызывать функцию как процедуру называют расширенным синтаксисом (Extended syntax), – он должен быть разрешен в настройках компилятора, иначе вызов функции как процедуры компилятор сочтет ошибкой.
Современные версии компиляторов дают новую возможность в части построения функций. Так, компилятор Delphi позволяет, наряду с именем функции, для возврата результата использовать автоматически объявляемую переменную Result. Тип переменной Result совпадает с типом функции. Тогда функцию подсчета символов можно упростить так:
function Count(const str : string; ch: char): integer;
Интервал:
Закладка: