Выводы по проделанной работе. 4 страница

Функция должна обязательно возвращать какое-нибудь значение. В данном примере сначала используется временная переменная TmpValue, но перед окончанием работы функции значение данной переменной присваивается имени функции:

Power := TmpValue;

Тем самым, был определен результат работы функции. Если этого не сделать, то функция все равно вернет некоторый результат, но это будет непредсказуемое (случайное) числовое значение.

После вызова функции Power(5, 2), в переменную Res будет записан результат «25».

Поскольку функция возвращает значение, ее вызов может находиться справа от оператора присваивания «:=» (но не слева).

При выполнении оператора

Writeln(Power(X, A) + Power(Y, B) + Power(Z, C));

программа 3 раза вызовет функцию Power с указанными аргументами, просуммирует результаты и выведет полученную сумму на экран.

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

 

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

Подпрограмма, возвращающая значение-результат, называется функцией. Функция, состоит из заголовка и тела. Заголовок содержит зарезервированное слово «function», идентификатор (имя) функции, необязательный список формальных параметров, заключенный в круглые скобки и тип возвращаемого функцией значения. Тело функции представляет собой блок операторов, заключенный в BEGIN..END:

 

function <имя>(<список формальных параметров>): <тип результата>;

const ... {объявление констант, используемых в функции}

var ... {локальные переменные функции}

Begin

<операторы>

end;

 

где <имя> – любой допустимый идентификатор, например, Func1;

<список формальных параметров> – список имен переменных и их типов, разделенных точкой с запятой «;», например (Value: Real; Stepen: Integer);

Важно! Имена переменных, перечисленные в списке формальных параметров, не обязаны совпадать с именами переменных, указанных при вызове подпрограммы. Подпрограмма может вызываться из нескольких различных мест программы, причем в каждом случае переменные могут называться по-разному. В рассмотренном примере для функции «Power» были объявлены параметры «Value» и «Stepen», однако при ее вызове использовались разные переменные: X, Y, Z, A, B, C. Более того, при вызове функции можно указывать непосредственные значения, например, Power(5, 2). В любом случае передаваемые в функцию значения будут скопированы в соответствующие формальные параметры, с которыми будет осуществляться дальнейшая работа (исключением является использование формальных параметров-переменных).

<тип результата> – тип возвращаемого функцией результата, например, Integer, Real и т.д.

Среди входящих в функцию операторов должен обязательно присутствовать как минимум один оператор присваивания «:=», в левой части которого указано имя данной функции, а в правой – значение-результат. В точку вызова возвращается результат последнего присваивания.

5.5.2 Объявление процедуры

Подпрограмма, которая не возвращает значение-результат, называется процедурой (в терминологии языка Pascal). Процедура, состоит из заголовка и тела. Заголовок содержит зарезервированное слово «procedure», идентификатор (имя) процедуры и необязательный список формальных параметров, заключенный в круглые скобки. Тело процедуры представляет собой блок операторов, заключенный в BEGIN..END:

 

procedure <имя>(<список формальных параметров>);

const ... {объявление констант, используемых в процедуры}

var ... {локальные переменные процедуры}

Begin

<операторы>

end;

 

Следующий пример демонстрирует использование процедуры для ввода двух значений A и B, где A > 0 (Real), B <> 0 (Integer). В процедуре «InputAB» организован контроль правильности вводимых данных. Для выхода из программы требуется, чтобы произведение двух чисел было равно 100.

 

program ProcDemo;

{ InputAB – процедура для ввода двух чисел. ValueA и ValueB – параметры-

переменные, поэтому в момент вызова процедуры InputAB в нее будут

переданы непосредственно сами переменные A и B, а не их копия }

procedure InputAB(var ValueA: Real; var ValueB: Integer);

Begin

Repeat

Write('Введите значение A (любое положительное число): ');

Readln(ValueA);

if ValueA <= 0 then

Writeln('Ошибка! Число должно быть > 0. Повторите ввод!');

until ValueA > 0;

 

Repeat

Write('Введите значение B (целое ненулевое число): ');

Readln(ValueB);

if ValueB = 0 then

Writeln('Ошибка! Число не может быть = 0. Повторите ввод!');

until ValueB <> 0;

end;

 

Var

A: Real;

B: Integer;

Begin

repeat {Начало цикла REPEAT}

InputAB(A, B); {Вызов процедуры InputAB}

Writeln('Произведение A * B = ', A * B:8:2);

until A * B = 100; {Условие завершения цикла REPEAT}

end.

 

Особенностью данного примера является то, что в процедуре «InputAB» формальные параметры «ValueA» и «ValueB» являются параметрами-переменными (используется ключевое слово «var»), поэтому в момент вызова процедуры «InputAB» в нее будут переданы непосредственно сами переменные «A» и «B», а не их копия. Любое изменение формальных параметров «ValueA» и «ValueB» внутри процедуры приведет к тому, что будут изменены переменные «A» и «B».

Следующий простой пример демонстрирует вывод на экран информации о разработчике программы с помощью процедуры About:

 

program ProcDemo2;

 

procedure About; {Процедура объявлена без параметров}

Begin

Writeln('Программа для демонстрации процедуры без параметров');

Writeln('Автор программы: Иванов И.И.');

Writeln('Версия программы: 1.0');

end;

 

Begin

About;

{Прочие операторы программы}

end.

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

5.5.3 Передача аргументов в подпрограмму с использованием параметров-значений и параметров-переменных

Переменные, перечисленные в заголовке подпрограммы, называются «формальными параметрами», в языке Pascal они отделяются друг от друга точкой с запятой «;». Формальные параметры получают фактические значения аргументов в момент вызова подпрограммы. Существуют 2 основных способа передачи аргумента в подпрограмму: «по значению» (с использованием параметров-значений) и «по ссылке» (с использованием параметров-переменных).

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

 

procedure MyProc(MyParam: Integer); {MyParam - параметр-значение}

Begin

...

end.

 

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

Ниже представлен пример вызова процедуры, в которой «MyParam» является параметром-переменной (используется ключевое слово «var»):

 

procedure MyProc(var MyParam: Integer); {MyParam -параметр-переменная}

Begin

MyParam := MyParam * 2; {изменяем значение параметра MyParam}

end;

 

Var

A: Integer;

Begin

A := 5;

Writeln(A); {Будет напечатано значение "5"}

MyProc(A); {Вызов процедуры MyProc}

Writeln(A); {Будет напечатано значение "10"}

end.

 

Следует отметить, что в подпрограмме могут одновременно быть объявлены и параметры-значения и параметры-переменные, например:

 

procedure MyProc(A, B: Integer; var X: Real; C: Real; var Y: Integer);

 

В данном примере A, B, C являются параметрами-значениями, а X, Y являются параметрами-переменными.

 

5.5.4 Локальные и глобальные переменные и их область действия

Переменные, описанные внутри процедур и функций, называются локальными. Они создаются при каждом вызове подпрограммы и уничтожаются при выходе из нее, т.е. локальные переменные существуют только при выполнении подпрограммы и недоступны в основной программе. К локальной переменной в языке Pascal возможен доступ из любого участка подпрограммы, в которой объявлена эта переменная. Если в подпрограмме имеются вложенные подпрограммы (допускается любой уровень вложенности), то все они могут иметь доступ к данной переменной, кроме случаев, когда объявление переменной находится ниже, чем код подпрограммы.

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

Количество обращений к глобальным переменным из подпрограмм должно быть минимальным, поскольку это ухудшает читабельность кода, а также усложняет отладку и исправление ошибок.

5.5.5 Предварительное описание подпрограммы

Подпрограмму (допустим, A) можно вызвать не только из основной программы, но и из любой другой подпрограммы (допустим, B) при условии, что объявление подпрограммы A расположено выше, чем объявление подпрограммы B. В действительности данное условие не всегда является выполнимым. Обычно ограничения связаны с обеспечением более наглядной логической структуры программы, например, требуется, чтобы вначале располагались все подпрограммы, ответственные за ввод данных, за ними следовали подпрограммы, обеспечивающие все необходимые вычисления, а подпрограммы вывода результатов на экран располагались после всех предыдущих. Как в таком случае из подпрограммы ввода данных вызвать подпрограмму для проведения вычислений (ведь она расположена ниже)? Для разрешения подобных ситуаций применяется предварительное описание подпрограммы. В языке Pascal для предварительного описания подпрограммы вместо тела подпрограммы указывается ключевое слово «forward». Пример:

 

procedure ProcA(S: string); forward; {Предварительное описание }

 

procedure ProcB(S: string);

Begin

ProcA(S); {Процедура ProcA объявлена выше, поэтому ошибки не будет}

end;

 

procedure ProcA; {Параметры не обязательно указывать еще раз }

Begin

Writeln(S); {Будет напечатана строка «Hello!»}

end;

 

begin {Начало основной программы}

ProcB('Hello!'); {Вызываем процедуру ProcB с аргументом 'Hello!' }

end.

5.5.6 Рекурсивный вызов подпрограммы

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

 

 

5.6. Варианты заданий

№ варианта Функция Начальное значение Шаг Конечное значение
0,1
0,2
0,5
0,1
0,2
0,5
0,1
0,2
0,5
0,1
0,2
0,5
0,1
0,2
0,5
0,1
0,2
0,5
0,1
0,5

5.7. Содержание отчета (см. п. 1.10)

5.8. Контрольные вопросы

1) Что называется подпрограммой?

2) Какова структура программы с подпрограммами?

3) Какова структура подпрограммы-процедуры?

4) Какова структура подпрограммы-функции?

5) В чем состоит различие и сходство процедур и функций?

6) Как осуществляется вызов процедур и функций?

7) Что называется параметром и каково его назначение?

8) Каково назначение формальных и фактических параметров и какова их взаимосвязь?

9) Опишите последовательность событий при вызове процедур или функций.

10) Для чего при отладке используется пошаговый режим с заходом в подпрограммы и как его осуществить?

11) В чем разница между способами передачи аргументов в подпрограмму «по значению» и «по ссылке»?

12) Чем отличаются локальные и глобальные переменные? Какова их область действия?

 


Лабораторная работа № 6. Обработка символов и строк на языке Pascal

6.1. Цель работы

Приобретение навыков обработки символьных данных на языке Pascal.

6.2. Задание на лабораторную работу

Составить программу обработки символьных данных в соответствии с вариантом задания (п. 6.7).

6.3. Требования к программе

Программа должна выводить:

– номер варианта, назначение программы и ФИО автора;

– информационные сообщения о необходимости ввода данных;

– результаты работы в соответствии с вариантом задания. Обработка символьных данных должна выполняться в подпрограмме пользователя (п. 6.6).

6.4. Порядок выполнения работы

1) Получить вариант задания (п. 6.7).

2) Изучить операторы объявления и обработки символов и строк (п. 6.5).

3) Разработать и отладить программу обработки символьных данных.

4) Ответить на контрольные вопросы (п. 6.9).

5) Оформить отчет (см. п. 1.10).

6.5. Операторы объявления и обработки символов и строк на языке Pascal

6.5.1. Операторы определения и обработки данных символьного типа

Символьный тип обеспечивает программисту возможность работы с символами, к которым относятся: цифры (от 0 до 9), буквы латинского алфавита (как строчные, так и прописные), буквы национального алфавита (как строчные, так и прописные), знаки препинания и др. В связи с тем, что элемент, объявленный как Char, занимает в памяти 8 бит (1 байт), то всего доступно 256 символов. Каждый символ имеет собственный числовой код (от 0 до 255), причем коды от 0 до 127 являются стандартными (соответствуют американскому стандарту ANSI). Коды этих символов одинаковы практически в любых устройствах, компьютерах, операционных системах, языках программирования, Unicode-кодировках и т.д.

Значения от 128 до 255 предназначены для кодирования символов из других национальных алфавитов (в том числе кириллицы). Поскольку этого числового пространства хватает на кодирование алфавита лишь одного языка, то оперировать одновременно несколькими национальными алфавитами не представляется возможным. Более того, существуют языки, содержащие в алфавите свыше 127 символов (например, китайский, в котором более 50 тыс. иероглифов), поэтому использовать стандартные средства языка Pascal для работы с такими алфавитами весьма затруднительно.

Представляемые типом Char символы (в том числе кириллица) и их коды приведены на рисунке 6.1.

 

Рисунок 6.1 – Символы и их коды

Особое значение имеют символы с кодами:

– 9 – код символа табуляции. Используется для выравнивания текста. Осуществляет смещение курсора вправо на одну или несколько (но не более 8) позиций в зависимости от текущего расположения курсора. Новое положение курсора будет кратно 8 плюс 1.

– 10 – код перевода строки. В результате следующие символы будут напечатаны на новой строке.

– 13 – код возврата каретки. Возвращает курсор ввода на начало строки. Новые символы будут затирать предыдущие.

– 32 – код пробела.

Ниже представлен текст программы, с помощью которой был подготовлен рисунок 6.1:

Var

I: Integer; {Объявление счетчика цикла FOR }

C: Char; {Объявление переменной «символ»}

Begin

WriteLn('Перечень символов и их кодов:');

for I := 0 to 255 do{Цикл перебора всех кодов символов}

Begin

C := Chr(I); {Получаем символ из его кода}

Write(I:3, ':', C, ' '); {Печать на экране символа и его кода}

if I mod 12 = 0 then{Если код символа кратный 12,}

WriteLn; {то переходим на следующую строку}

end;

end.

Значение переменной Char можно задать также с помощью оператора Readln, либо путем непосредственного присвоения отдельного символа (символьной константы), заключенного в одинарные кавычки (апострофы), например:

C := 'F';

Поскольку тип Char является порядковым, допускается использование по отношению к нему операций сравнения, например:

if (C >= 'A') and (C <= 'Z') then

Writeln('Это символ из латинского алфавита!');

 

 

Стандартные функции языка Pascal, применимые к типу Char, представлены к таблице 6.1.

Таблица 6.1 – Стандартные функции Pascal для работы с символами

Функция Назначение Тип аргумента Тип функции Пример
Chr Получение символа по его коду Byte Char x := 68; y := Chr(x); {y = 'D'} y := Chr(2*x-5); {y='Г'}
Ord Определение кода символа Char Byte x := 'G'; y := Ord(x); {y=71}
Pred Возвращение предыдущего символа Char Char x := 'Б'; y := Pred(x); {y='A'}
Succ Возвращение следующего символа Char Char x := 'Г'; y := Succ(x); {y='Д'}
Upcase Преобразование строчной буквы в прописную Char Char Ch := 'd'; Y := Upcase(Ch); {Y='D'}

6.5.2. Определение переменных строкового типа STRING. Операторы обработки строк

Последовательность нескольких символов, расположенных друг за другом, образует строку. В общем случае, в строке может присутствовать произвольное количество символов, в том числе, ни одного. В случае языка Pascal, максимальная длина одной строки ограничена 255 символами. В современных языках программирования подобные ограничения, как правило, отсутствуют. Для объявления строки в языке Pascal служит ключевое слово STRING. Примеры объявления строки и присвоения строковых значений:

Const

sConstStr = 'Строка 1'; {Объявление именованной константы}

Var

S1: string; {объявление строки максимальной длины 255 символов}

S2: string[10]; {объявление строки длиной 10 символов}

S3: string[8]; {объявление строки длиной 8 символов}

Begin

S1 := 'А роза упала на лапу Азора'; {присвоение строковой константы}

Readln(S2); {Строку должен ввести пользователь}

S3 := sConstStr; {присвоение именованной строковой константы}

end;

Для определения количества символов в строке служит функция Length:

Writeln(Length(S1)); {В нашем случае напечатает значение 26}

В языке Pascal существует второй способ определения длины строки – обращение к «нулевому» символу, например:

StrLen := Ord(S1[0]); {Присвоит в переменную StrLen значение 26}

Однако, поскольку второй способ специфичен для языка Pascal и не принят в других языках программирования, рекомендуется первый способ.

С помощью нулевого символа можно также изменить длину строки:

S1[0] := Chr(Length(S1) - 1); {Уменьшает длину строки на 1 символ}

 

 

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

if S1 = 'hello' then

Writeln('Строки одинаковые')

Else

Writeln('Строки разные');

 

Кроме того, допустимы операции <> (не равно), > (больше), >= (больше или равно), < (меньше), <= (меньше или равно). В практическом программировании при сравнении строк используют только операции = или <>.

Операция сравнения ('Hello' > 'hello') вернет False, поскольку код символа 'H' (72) меньше, чем код символа 'h' (104). Если бы эти символы оказались одинаковыми, то программа бы продолжила сравнение оставшихся символов.

Для объединения двух или более строк в одну служит операция сцепления «+», например:

S2 := 'Новый';

S3 := 'Год';

S1 := S2 + ' ' + S3; {Соединяем строки S2 и S3 через пробел }

Writeln(S1); {Напечатает строку: Новый Год}

 

Обращение к отдельному символу строки осуществляется по индексу (аналогично работе с массивами), например:

 

St[1] := 'F'; {В первый символ строки будет записано «F»}

Writeln(St[2]); {Печать на экране второго символа строки}

 

Информация о процедурах и функциях языка Pascal, применяемых для обработки строк, приведена в таблице 6.2

 

Таблица 6.2 – Процедуры и функции обработки строк

Заголовок Назначение Пример
procedure Delete( var S: string; Index: Integer; Count: Integer); Удаление Count символов строки S, начиная с позиции Index S := 'абвгде'; Delete(S, 4, 2); {St='абве'}
procedure Insert( Source: string; var S: string; Index: Integer); Вставка подстроки Source в строку S, начиная с позиции Index St1 := 'абвгде'; Insert('*', St1, 4); {Str2='абв*где'}
procedure Str( X: Real; var S: string); Преобразует числовое значение величины X (Integer или Real) в строку и помещает результат в S V := 1500; Str(V:6, St); {St:=' 1500'}
procedure Val( S: string; var V: Real; var Code: Integer); Преобразует строку S в ее числовое представление и помещает результат в V (Integer или Real) величину. Параметр Code возвращает код ошибки   St := '1.455'; Val(St, V, Cod); {V=1.455, Cod=0}
function Copy( S: string; Index, Count: Integer): string; Возвращает заданный участок строки S длиной Count символов, начиная с позиции Index. Если значение Count слишком большое, то возвращает символы до конца строки. St := 'абвгде'; Y := Copy(St, 2, 3); {Y='бвг'}
function Pos( Substr, S: string): Integer; Отыскивает подстроку Substr в строке S и возвращает позицию первого символа найденной подстроки, либо ноль, если подстрока не найдена St2 := 'abcdef'; Y := Pos('de', St2); {Y=4}

 

6.6. Пример программы

Приведенный ниже пример демонстрирует программу для упорядочивания по алфавиту ФИО, заданных в строке S:

 

program SortFIO;

 

type {Объявлям пользовательские типы TFIOElem и TFIOArray}



current">56
  • Далее ⇒