Лекция Паскаль 8 – Понятие подпрограммы, Объявления подпрограммы, ее тело и оператор ее вызова


Тема: Подпрограммы.

Цель: Научиться работать с подпрограммами, широко используя языковые средства; рассмотреть ситуации, требующие при написании программного кода использования процедур и функций, ознакомиться с устроенными подпрограммами для работы с строчными типами данных. Уделить внимание работе с графическими возможностями Delphi.

1. Понятие подпрограммы. Объявления подпрограммы, ее тело и оператор ее вызова.

Представим себе следующую ситуацию: в нашей программе одна и та же последовательность действий повторяется и прописана в различных ее частях. В чем недостатки такого дублирования? Прежде всего, более объемным становится собственно код. Но не это главное. Дело в том, что прямое копирование фрагментов кода вызывает осложнения при дальнейшей модификации кода программы — необходимо вносить изменения в различные части программы. Чтобы предотвратить такое нерациональном способа работы, целесообразно использовать подпрограммы.

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

В языке Delphi подпрограммы оформляются в виде процедур и функций. Имя процедуры и функции задается в соответствии с правилами создания имен идентификаторов (переменных). Оно может состоять только из латинских букв, цифр и знака подчеркивания, при этом не может начинаться с цифры. Имена должны быть уникальными — в одной программе не может существовать несколько подпрограмм с одинаковыми именами.

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

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

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

Если ничего не нужно возвращать или же необходимо вернуть более одного результата, то используют процедуры.

2. Понятие функции. Создание и использование собственных функций.

Изучение подпрограмм рассмотрим на примере функции. В общем виде описание функции имеет следующий вид:

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

Type …;

Var …;

Begin

<Операторы> End;

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

Приведем два способа возврата рассчитанных значений — обе функции идентичны по своему содержанию.

1 вариант:

Function sum (a, b: real): real; Begin

Sum = a + b;

End;

2 вариант:

Function sum (a, b: real): real; Begin

Result: = a + b;

End;

Правила описания и использования функций:

1. Заголовок функции начинается со служебного слова function, за которым указывается имя функции.В приведенных примерах — sum.

2. По имени функции в круглых скобках перечисляются входные параметры и их типы (в данных примерах два параметра a, b типа real).

3. Если функция не имеет формальных параметров, то круглые скобки в заголовке не ставятся.

4. После скобок, в которых помещены входные параметры, через двоеточие указывают тип значения, которое возвращает функция. Функция предназначена для расчета только одного значения, которое передается в программу через имя функции. Причем тип значения, которое возвращается, — это произвольный скалярный тип данных (числовой, символьный, булево, строчный или указатель).

Читать  Алгоритмы и программы с циклами – Средства реализации базовой алгоритмической структуры повторения с предусловием

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

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

6. Все переменные, описанные в программе до объявления функции, также доступны внутри функции. Эти переменные называются глобальными. Для предотвращения возникновения ошибок доступны сменные внутри функции использовать рекомендуется!

7. Тело функции размещается между begin … end; и представляет собой набор команд.

8. Для возврата в программу результата функции имя функции в выполняемой части должно получить свое значение. С этой целью можно применять внутреннюю переменную Result. Преимущество использования такой переменной заключается в том, что она может участвовать в выражениях как операнд. Например, для функции нахождения суммы можно использовать присвоении result = result + a, однако недопустимо использовать присвоении sum = sum + a.

Вызов функции используется внутри основной программы (или другой функции). Например, для записанной функции sum возможен следующий вызов:

Var x, y, s: real; Begin

// ввод переменных х и у S = sum (x, y)

// вывод переменной S End;

Пример. Найти наибольший общий делитель (НОД) трех целых чисел. Решение. Учтем, что НОД (a, b, c) = НОД (НОД (a, b), c)

Как алгоритм определения наибольшего общего делителя для двух чисел воспользуемся алгоритмом Евклида. Используются переменные типа cardinal (переменные этого типа представляют собой цели 4-байтовые числа без знака).

Вид формы для решения этой задачи:

Программный код:

 

3. Понятие процедуры. Создание и вызов процедур.

По своей структуре процедуры напоминают программу: они, как и программа, состоят из заголовка и тела процедуры. Заголовок процедуры содержит зарезервированное слово procedure, имя процедуры и список формальных параметров, которые в случае их использования размещены в круглых скобках. Имя процедуры — это идентификатор, уникальный в рамках программы. Формальные параметры — это данные, которые передаете в процедуру для обработки, и данные, процедура возвращает. Если процедура не получает данных извне и ничего не возвращает, формальные пар матери (в том числе и круглые скобки) не записываются. Тело процедуры представляет собой локальный блок, по структуре аналогичный программе:

Procedure <имя процедуры> (<список формальных параметров>); Const …;

Type …;

Var …;

Begin

<Операторы> End;

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

С подпрограммами, которые реализованы в виде процедур, мы уже встречались много раз — произвольный обработчик любого события есть подпрограммой. Когда мы создаем обработчик нажатия кнопки, появляется заготовка кода, где есть заголовок с именем, например, Button1Click, далее следует блок begin … end; — блок реализации, а выше него мы вписываем свои переменные, константы и другие необходимые элементы.

Вызов процедуры для выполнения осуществляется по ее именем, за которым следует помещен в круглые скобки список фактических параметров, то есть, данных, которые передаются в процедуру:

<Имя процедуры> (<список фактических параметров>);

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

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

Возникает вопрос: в каком месте нужно размещать подпрограмму? Во-первых, ее необходимо писать в таком месте, где программа сможет найти ее. Подпрограммы можно описывать в разделе описаний, в котором описываются переменные, но только выше их. Например, если наша подпрограмма используется только в обработчике нажатия кнопки и больше нигде, то ее можно разместить в разделе описания этого обработчика. Тогда из других обработчиков подпрограмму не будет видно. Второе правило: произвольная подпрограмма может быть описана выше того места, откуда она вызывается. Вызвать подпрограмму, которая размещена ниже, нельзя, так как компилятор в данный момент времени знать о подпрограмму не будет. И третье правило: чтобы подпрограмма была видна с произвольного места текущего модуля (текущей формы), ее нужно описать в разделе implementation выше всех обработчиков событий.

Читать  Лекция Паскаль 7 – Виды операторов цикла, Поиск суммы и произведение последовательности чисел

4. Подпрограммы с параметрами. Параметры процедур и функций.

Параметры предназначены для передачи входных данных в подпрограмм и приема результатов работы этих подпрограмм.

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

Входные параметры объявляются с помощью ключевого слова const; их значения не могут быть изменены внутри подпрограммы.

Рассмотрим в качестве примера функцию отыскания наименьшего значения из двух целых чисел:

Function min (const a, b: integer): integer;

Begin

If a <b then Result: = a else Result: = b; End;

Для объявления выходных параметров служит ключевое слово out: Procedure SizeForm (out width, height: integer);

Begin Width = Form1.ClientWidth; Height = Form1.ClientHeight; End;

Присвоение значений выходных параметров внутри подпрограммы приводит к присвоению значений переменных, которые переданы в роли аргументов:

Procedure TForm1.Button1Click (Sender: TObject); Var w, h: integer;

Begin

SizeForm (w, h) Caption = inttostr (w) + » + inttostr (h) End;

После вызова процедуры SizeForm переменные w и h будут содержать значения, присвоенные формальным параметрам width и height соответственно.

Если параметр является одновременно и входным и выходным, то он описывается с ключевым словом var:

Procedure exchange (var a, b: integer); Var c: integer;

Begin c = a;

a = b;

b = c; End;

Изменение значений var -параметров внутри подпрограммы приводит к изменению значений переменных, переданных в качестве аргументов:

Var x, y: integer; Begin

X = 7;

Y = 11;

Exchange (x, y)

// теперь х = 11, у = 7

… End;

При вызове процедуры на место out — и var -параметров можно подставлять только переменные, но не константы или выражения.

Если при описании параметра не указано ни одно из ключевых слов — const, out, var — то параметр считается входным, его можно менять, при этом все изменения не влияют на фактический аргумент, поскольку они выполняются с копией

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

Различные способы передачи параметров: с использованием const, out, var и без них можно совмещать в одной подпрограмме.

Способы передачи параметров и их значения

ключевое слово назначение способ передачи
<Отсутствует> входной Передается копия значения
Const входной Передается копия значения или ссылки на значение в зависимости от типа данных
Out выходной Передается ссылка на значение
Var Входной и выходной Передается ссылка на значение

Пример. Создадим процедуру Average, которая принимает четыре параметра. Первые два параметра (x, y) являются входными и предназначены для передачи исходных данных. Другие два аргумента являются исходными и предназначены для приема в основной программе результатов вычислений среднего арифметического (sa) и среднего геометрического (sg) значений х и у.

Внешний вид формы:

Если передается значение, то подпрограмма использует копию аргумента.

Такой способ называется передачей по значению (by value).

Если передается ссылка на значение, то подпрограмма использует непосредственно аргумент, обращаясь к нему через переданную адрес. Данный способ называется передачей по ссылке (by reference).

5. Привязка подпрограмм к формы.

Если пользователя нами подпрограммы занимаются действиями, не связанными с визуальными компонентами формы (это, например, какие-то арифметические расчеты), то они могут просто размещаться в коде. Однако попытки обратиться с подпрограммы в форму или к ее компонента ни к чему не приведет — подпрограмма «не знает» о нашей форму. Для того, чтобы в процедуре или функции можно было работать с компонентами формы, необходимо выполнить определенные действия — оформить их в виде метода формы.

Читать  Таблица и ее элементы, табличные величины

Рассмотрим конкретный пример. Допустим, у нас на форме есть три кнопки — Button1, Button2, Button3. Нам нужно в разных частях программы поочередно включать и выключать эти кнопки (используя свойство Enabled). Чтобы не копировать один и тот же код, лучше написать подпрограмму, которая будет делать все необходимое.

Запишем нашу процедуру:

Procedure EnableButtons (Enabl: Boolean); Begin

Button1.Enabled = Enabl; Button2.Enabled = Enabl; Button3.Enabled = Enabl; End;

Однако данный код программы выдаст ошибку компиляции. Это связано с тем, что разработана процедура «не видит» кнопки Button.

Для того, чтобы «привязать» процедуру в форму, нам нужно выполнить следующие действия:

1. Необходимо добавить заголовок метода в описании самой формы. Для этого нужно скопировать заголовок нашей процедуры в секцию private или

public, в раздел type, где описана наша форма. Выбор секции — private или public, в каждом случае нужно определять отдеьно. Все, что написано в private, доступно только в рамках данной формы. А все, что написано в public, может быть доступным и при других формах и модулей.

2. В разделе implementation в заголовок процедуры перед названием нужно добавить имя класса формы. Имя класса формы в Delphi автоматически формируется из буквы «Т» и имени самой формы.Например, для формы Form1 имя класса будет TForm1. Между именем класса формы и именем подпрограммы должна стоять точка. В результате заголовок процедуры будет иметь следующий вид:

Procedure TForm1.EnableButtons (Enabl: Boolean);

Если вызов созданной нами процедуры осуществляется с самой Form1, то можно обращаться к процедуре просто по имени. Например, поместим на форму флажок типа TCheckBox и в обработчике его события OnClick напишем:

Procedure TForm1.CheckBox1Click (Sender: TObject); Begin

EnableButtons (CheckBox1.Checked) End;

6. Устроены процедуры и функции: строчные, преобразования типов данных, генератор псевдослучайных чисел.

Все процедуры и функции в Delphi делятся на две группы: устроены и определены программистом. Устроены процедуры и функции являются частью языка и могут вызываться по имени без предварительного описания.

Арифметические функции:

Название назначение Тип результата
Abs (x) Возвращает абсолютное значение аргумента х Integer, Real
Exp (x) Возвращает экспоненты в степени х Real
Ln (x) Возвращает натуральный логарифм аргумента х Real
Pi Возвращает значение числа π Extended
Sqr (x) Возвращает квадрат аргумента х Integer, Extended
Sqrt (x) Возвращает корень квадратный аргумента х Extended

примеры:

выражение результат
Abs (-7) 7
Exp (1) 2.17828182845905
Ln (Exp (1)) 1
Pi 3.14159265358979
Sqr (7) 49
Sqrt (64) 8

Тригонометрические функции:

Название назначение Тип результата
ArcTan (x) Возвращает угол, тангенс которого равен х (в радианах) Extended
Cos (x) Возвращает косинус аргумента х (х задается в радианах) Extended

 

Sin (x) Возвращает синус аргумента х (х задается в радианах) Extended

примеры:

выражение результат
ArcTan (Sqrt (3)) 1.04719755119660
Cos (Pi / 3) 0.5
Sin (Pi / 6) 0.5

Нужно отметить, что в состав среды Delphi входит стандартный модуль Math, который содержит множество дополнительных подпрограмм для тригонометрических, логарифмических, статистических и финансовых функций.

Функции выделения целой и дробной части:

Название назначение Тип результата
Frac (x) Возвращает дробную часть аргумента х Extended
Int (x) Возвращает целую часть действительного числа х Extended
Round (x) Округляет действительное число х до целого Int64
Trunc (x) Возвращает целую часть действительного числа х.Результат принадлежит целом типа Int64

примеры:

выражение результат
Frac (2.5) 0.5
Int (2.5) 2.0
Round (2.7) 3
Trunc (2.5) 2

Порядковыми переменными называются величины типов integer, char, boolean, а также производные от этих типов. Для всех них предусмотрены операции> и <которые определяют, какое значение является предварительным, а какое — следующим.

Подпрограммы для работы с порядковыми величинами:

Название назначение Тип результата
Chr (x) Возвращает символ, порядковый номер которого равен х Char
Dec (x [, n]) Уменьшает целую переменную х на 1 (или указанное число n) Ordinal type, Pointer
Inc (x [, n]) Увеличивает целую переменную х на 1 (или указанное число n) Ordinal type, Pointer
Odd (x) Возвращает True, если аргумент х является нечетным числом Boolean
Ord (x) Возвращает порядковый номер аргумента х в своем диапазоне значений Ordinal type
Pred (x) Возвращает значение, которое идет впереди аргумента х в диапазоне указанного типа Ordinal type
Succ (x) Возвращает значение, которое идет после аргумента х в диапазоне указанного типа Ordinal type
Читать  Введение и вывод значений величин | Составляющие алгоритма обработки величин

примеры:

выражение результат
Chr (65) ‘A’

 

Odd (3) True
Ord ( ‘A’) 65
Pred ( ‘B’) ‘A’
Succ ( ‘A’) ‘B’

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

Процедуры передачи управления:

Название назначение
Break Прерывает выполнение цикла
Continue Начинает новое повторение цикла
Exit Прерывает выполнение текущего блока
Halt Останавливает выполнение программы и возвращает управление операционной системе

Стандартные процедуры и функции для работы со строками.

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

Процедуры и функции для работы со строками:

Название назначение
Concat (s1, s2, …, sn): string Возвращает строку, полученный в результате склеивания строк s1, s2, …, sn.По принципу работы функция Concat аналогична операции склеивания строк (+).
Copy (s: string, index, Count: integer): string Копирует из строки s подстроку длиной count символов начиная с позиции index.
Delete (var s: string, index, count: integer) Удаляет из строки s count символов начиная с позиции index.
Insert (source: string, var s: string, index: integer) Вставляет строку Source в строку s начиная с позиции index.
Length (s: string): integer Определяет реальную длину строки S в символах.
SetLength (var s: string, NewLength: integer) Устанавливает для строки S новую длину NewLength.
Pos (Substr, s: string): integer Ищет первое вхождение подстроки Substr в строку s. Возвращает номер той позиции, где находится первый символ подстроки Substr. Если в строке s НЕ изысканы подстроки Substr, то результат равен 0.
AnsiLowerCase (const s: string): string Превращает заглавные буквы строки s в строчные буквы с учета языка, установленной в среде Windows.
AnsiUpperCase (const s: string): string Превращает строчные буквы строки s в заглавные буквы с учета языка, установленной в среде Windows.

примеры:

S = concat ( ‘Object’, ‘Pascal’); «Object Pascal»
S = copy ( ‘программирования’, 3,3); Приложения
S: = ‘программирования’; Delete (s, 2, 3); «Прамування»
S: = ‘программирования в’; Insert ( ‘Delphi’, s, 15); «Программирования Delphi в»
Pos ( ‘ра’, ‘программирования’); 5
Length ( ‘программирования в’); 18

Преобразование типов данных.

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

Процедуры и функции преобразования типов:

Название назначение
IntToStr (value: integer): string Превращает целое число value в строку
StrToInt (const s: string): integer Превращает строку в целое число
FloatToStr (value: extended): string Превращает действительное число value в строку
StrToFloat (const s: string): extended Превращает строку в действительное число
Str (x [: width [: decimals]], var s: string) Превращает числовое значение величины х в строку s. Необязательные параметры width (ширина поля результирующей строки) и decimals (количество символов в дробной части записи действительного числа) являются целочисленными выражениями.
Val (s: string, var v; var code: integer) Превращает строку s в величину целого или вещественного типа и помещает результат в переменную v. Если во время операции ошибки не возникло, значение переменной code равен 0; если же ошибку изысканы (строка содержит недопустимые символы), code содержит номер позиции первого ошибочного символа, а значение v не определено.
StrToBool (const s: string): boolean Превращает строку в булево значение.
BoolToStr (b: boolean; UseBoolStrs: boolean = False): string Превращает булево значение в строку.
DateTimeToStr (const datetime: TDateTime): string Превращает значения даты и времени в строку.
StrToDateTime (const s: string): TDateTime Превращает строку в значение даты и времени.
Читать  Теоретические основы программирования на языке PASCAL, составление алгоритмов

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

Задание 1. На форме ввести вес в виде «числовое значение», пробел, «кг», например: «89 кг». Нажатием на кнопку «Удвоить вес» вывести значение удвоенной веса, например: «178 кг».

Программный код для решения этой задачи:

Задача 2. Ввести на форму произвольный строку символов (слова можно отделять

произвольным количеством пробелов). Вывести все слова строки, которые являются палиндромами.

Палиндромами могут быть не только числа (типа 313, 10101 и т.д.). Слова или фразы, которые имеют одинаковый смысл при чтении их как слева направо, так и в обратном направлении, также палиндромы. Пример — «пробка».

Интерфейс задачи:

Программный код:

 

Предложенный алгоритм выделения слова в строке является довольно распространенным.  Поэтому

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

Рассмотрим еще один подход к работе с текстовой информацией.

Задача 3. Создать программу, которая последовательно «осыпает» вниз строку, который находится в верхней части формы.

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

На рисунке приведен пример падения букв.              Чтобы строка визуально не сокращался, целесообразно установить шрифт Courier New.

 

Программный код:

 

 

 

Генератор псевдослучайных чисел.

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

Генератор псевдослучайных чисел — это алгоритм, генерирующий последовательность случайных чисел, элементы которой почти не зависящие друг от друга и подчиняются заданному распределению (как правило, равномерному).

Процедуры и функции для работы с псевдослучайными числами:

Название назначение
Random Возвращает случайное действительное число из промежутка от 0 до 1
Random (n) Возвращает случайное действительное число из промежутка от 0 до n
Randomize Заново инициализирует устроен генератор случайных чисел новым значением, полученным от таймера

Рассмотрим работу генератора псевдослучайных чисел на примере следующей программы: на форме размещена кнопка и таймер. Эта кнопка каждую секунду (timer1.interval = 1000) меняет свое положение (но не выходит за пределы формы).

Программный код:

Кнопка действительно «скачет» с места на место. Для того, чтобы каждый раз, когда запускается данная программа, кнопка перемещалась на другие точки, нужно в обработчике события OnCreate формы вписать процедуру Randomize.

7. Теоретические вопросы для самоконтроля.

1. Чем обусловлена необходимость использования подпрограмм?

2. В чем разница между применением процедур и функций?

3. Какие типы данных может возвращать функция?

4. Опишите, как выглядит заголовок функции.

5. Каким образом можно записать результат внутри тела функции?

6. Назовите причины использования процедур.

7. В каких случаях при передаче параметров используется ключевое слово var?

8. В каких случаях при передаче параметров используется ключевое слово const?

9. В каких случаях при передаче параметров используется ключевое слово out?

10. Что представляет собой передача параметров по ссылке и передача параметров по значению?

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

12. Перечислите тригонометрические функции. наведите примеры.

13. Перечислите функции выделения целой и дробной частей. наведите примеры.

14. Какие функции Delphi предназначены для обработки строчных данных?

15. Перечислите процедуры, используемые при работе с строками.

16. Перечислите функции преобразования типов данных.

17. Для чего используются псевдослучайные числа?

[Всего голосов: 3    Средний: 5/5]