Подпрограммы
Цель работы
Целью работы является освоение метода декомпозиции задачи, средств и приёмов процедурного программирования, механизма обмена данными между программными блоками.
Задание
1) Разработайте функцию для вычисления арифметического выражения Вашего варианта предыдущей работы.
2) Используя полученную функцию, вычислите три значения, начиная с X0 и приращением dX.
3) Обеспечьте контроль ввода данных и исключите возможность аварийного завершения программы.
4) Протестируйте Вашу программу.
Теоретические сведения
Структура подпрограмм
Подпрограмма (процедура или функция) - именованная, логически завершённая последовательность операторов, к которой можно многократно обращаться с различными фактическими параметрами в вызывающем подпрограмму исполняемом блоке. В модуле могут использоваться три вида подпрограмм: стандартные, созданные разработчиками языка; процедуры обработки событий, шаблоны которых автоматически создаются средой программирования и дополняются пользователем; подпрограммы, созданные пользователем.
Отличие функции от процедуры состоит в том, что результатом исполнения операторов функции, всегда является значение. Процедура значения не имеет.
Структуры процедур и функций аналогичны структуре программы и также имеют раздел описаний и исполняемый блок. Отличий в описании процедур и функций всего три: зарезервированные слова заголовка (procedure и function); поскольку функция возвращает значение, то в заголовке указывают тип; в исполняемом блоке идентификатору функции присваивают значение (Имя_Ф:=Выражение). Отличия выделены в тексте подчёркиванием.
procedure Имя_Прц (Список формальных параметров: Тип);
cons t Список локальных констант, типов, переменных
Type
Var
begin {Исполняемый блок процедуры}
Операторы
end; {Конец описания процедуры}
function Имя_Ф(Список формальных параметров: Тип): Тип;
const Список локальных констант, типов, переменных
Type
Var
begin {Исполняемый блок функции}
Операторы
Имя_Ф:=Выражение; {Присваивание значения функции}
end; {Конец описания функции}
Место процедур в модуле
Если подпрограмма используется только в модуле, то её описывают в разделе implementation после описания констант и переменных.
unit Unit1;
Interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, Dialogs;
Type
TForm1 = class(TForm)
End;
var Form1: TForm1;
Implementation
{Описание констант и переменных модуля}
{Описание подпрограмм пользователя }
End.
Вызов процедур и функций производят внутри какой-либо процедуры обработки события. Вызываемая процедура должна быть описана раньше, чем процедура обработки события, вызывающая эту процедуру.
Если по какой-либо причине процедура пользователя не может быть описана ранее вызывающей её процедуры обработки события, то используют опережающее описание процедур.
Implementation
{$R *.dfm}
procedure Имя_Проц(Параметры); Forward;
Заголовок процедуры с зарезервированным словом Forward указывают перед описанием процедур. Полный текст процедуры может располагаться после вызывающих процедур.
Вложенные описания процедур
implementation | |||||||
Function Имя_Ф1; Описание функции | |||||||
Procedure Имя_Прц {Раздел описаний} | |||||||
Function Имя_Ф2 Описание функции | |||||||
begin //Исполняемый блок процедуры ............... A := Имя_Ф2; //Вызов функции Имя_Ф2 B:= Имя_Ф1; //Вызов функции Имя_Ф1 | |||||||
………………………………………………… | |||||||
Рис. 1. Схема вложенности процедур
Описание подпрограммы может содержать описание и вызов другой подпрограммы - вложенное описание, см. рисунок 1. Для вложенных подпрограмм понятиеглобальныеи локальные -относительное, зависит от взаимного расположения подпрограмм. Структура с вложенными подпрограммами имеет вид:
Параметры процедур
Все константы и переменные, используемые в программе, должны быть описаны. Константы и переменные, в зависимости от места описания в структуре, подразделяют на локальные и глобальные. Понятие локальный – глобальный относительное. Константы и переменные, объявленные в подпрограммах являются локальными, вне подпрограмм они недоступны. Константы и переменные, объявленные в разделах interface или implementation являются для подпрограмм раздела implementation глобальными и внутри процедур их можно использовать без дополнительного описания. В подпрограмме локальные имена могут совпадать с ранее объявленными глобальными именами. В этом случае локальное имя “закрывает” глобальное и делает его недоступным.
Способ передачи данных через глобальные переменные позволяет создавать процедуры без параметров
Пример 1. Процедуры без параметров
Дано: текстовые поля для ввода вещественных чисел Edit1.. Edit9.
Требуется: разработать процедуру без параметров, позволяющую контролирующую ввод символов (событие OnKeyPress) соответствующих алфавиту вещественных чисел применимую для всех полей.
В разделе implementation определим глобальную переменную Key символьного типа и процедуру без параметров Inp_Real1.
Implementation
{$R *.dfm}
Var Key: Char; {глобальная переменная Key будет использована в
процедуре Inp_Real1 без дополнительного описания}
procedure Inp_Real1; //контроль ввода символов вещественных чисел
Begin
If Not (Key in ['0'..'9', ',', '-', '+', ’.’, #8]) //все остальные символы недопустимы
then Key:= #0; //недопустимый символ подменяем пустым значением
end; //конец описания процедуры
True |
False |
Начало |
Конец |
Key – вводимый символ – глобальная переменная not (Key in['0'..'9', '+', '-', ‘,’, #8]) |
Недопустимые символы Подмена недопустимого символа пустым key:= #0 |
Схема алгоритма. Ввод вещественных чисел procedure Inp_Real1 |
Если при вводе данных использовать событие OnKeyPress, то разработанную процедуру можно применить для любого количества полей предназначенных для ввода вещественных чисел.
Implementation
Var Key: Char; {глобальную переменную Key доступна в процедуре
Inp_Real1 без дополнительного описания}
procedure Inp_Real1; //контроль ввода символов вещественных чисел
Begin
If Not (Key in ['0'..'9', ',', '-', '+', ’.’, #8]) // Key – глобальная переменная
{все остальные символы недопустимы}
then Key:= #0; //недопустимый символ подменяем пустым значением
end; //конец описания процедуры
procedure TForm1.LabeledEdit1KeyPress(Sender: TObject; var Key: Char);
Begin
Inp_Rea1; //вызов процедуры
End;
………………………………
procedure TForm1.LabeledEdit9KeyPress(Sender: TObject; var Key: Char);
Begin
Inp_Rea1; //вызов процедуры
End;
В данном примере процедура Inp_Rea1 вызывается девять раз – это одно из достоинств использования процедур. Другое достоинство – если процедура отлажена, то возникновение ошибки выполнения исключено.
Имя глобальной переменной Key, используемой в процедуре Inp_Rea1, выбрано не случайно, в процедуре обработки события TForm1.LabeledEdit1KeyPress(Sender: TObject; var Key: Char) через параметр-переменную Key формируется строка ввода.
Если задать другое имя глобальной переменной, то строка ввода не будет сформирована, это безусловный недостаток.
Способ передачи данных в процедурах без параметров, через глобальные переменные хорош в простейших случаях, Однако, использование только глобальных связей исключает возможность вызова процедуры с другими параметрами, делает программу запутанной и сложной в отладке. Реализация обмена данными через объявление параметров процедур более эффективный способ.
Параметры, указываемые в заголовках подпрограмм при их описании, - формальные параметры. Параметры, указываемые при вызове подпрограмм, - фактические параметры.
В списке формальных параметров должны быть перечислены имена формальных параметров и их типы, например,
Procedure ABC(a: Real; b: Integer; с: Char);
Однотипные параметры объединяют в подсписки, например,
Function Fab(a,b: Real): Real;
Объявленные формальные параметры процедур могут быть следующих типов:
· параметры-значения;
· параметры-переменные, перед которыми должно стоять зарезервированное слово Var и после которых указывается их тип;
· параметры-процедуры, перед которыми должно стоять зарезервированное слово procedure;
· параметры-функции, перед которыми должно стоять зарезервированное слово function и после которых указывается тип возвращаемого значения;
· нетипизированные параметры, перед которыми должно стоять зарезервированное слово Var, а указание типа отсутствует.
В этой работе будем использовать только параметры-значения и параметры-переменные, остальные типы параметров рассмотрим позднее.
Параметр-значение - значение переменной, соответствующей этому параметру, можно изменять внутри процедуры, однако в исполняемый блок программы эти изменения не будут переданы. Фактическим параметром-значением при вызове может быть переменная, выражение, обращение к функции.
Параметр-переменная - переменную, соответствующей этому параметру, можно изменять внутри процедуры, в вызывающий исполняемый блок будет передано изменённое значение. В заголовке процедуры параметру-переменной предшествует зарезервированное слово Var. Фактическим параметром-переменной при вызове может быть только переменная.