Delphi-Help

Главная Азы Урок 20. Подпрограммы (часть 2)

Урок 20. Подпрограммы (часть 2)

Оцените материал
(14 голосов)


Подпрограммы (часть 2)

Введение

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

Структура подпрограммы

Заголовок представляет собой строку, в которой содержится вся необходимая информация о подпрограмме: её тип, имя, список аргументов, выходное значение. Заголовок является обязательной частью подпрограммы. Тело подпрограммы, т.е. блок, содержащий все команды, выполняемые подпрограммой, записывается после заголовка. Если быть более точным, под заголовком размещается раздел описаний (переменные, константы и т.д.), а уже затем блок реализации. Таким образом, общая структура подпрограммы напоминает любую самостоятельную программу.
С подпрограммами вы уже сталкивались много раз - любой обработчик любого события - это подпрограмма. Помните, когда мы создаём обработчик нажатия кнопки, появляется заготовка кода, где есть заголовок с именем вроде Button1Click, ниже идёт блок begin .. end - блок реализации, а выше него мы вписываем свои собственные переменные, константы и другие необходимые элементы. (Подробнее - см. урок №11 "События")

Описание заголовка

Итак, мы решили создать свою подпрограмму. Чтобы программа могла её вызывать, подпрограмму нужно описать. Описание обычно начинается с заголовка. Как мы отметили ранее, в заголовке содержится основная информация о подпрограмме. Разберёмся отдельно с каждой из составляющей заголовка.

Тип подпрограммы

Ранее мы установили, что существуют два типа подпрограмм - процедуры и функции. Их различие в том, что функция возвращает какой-то результат после завершения работы, а процедура этого не делает. Значит, мы должны явным образом указать, чем является наша подпрограмма - процедурой или функцией. Указывается это в самом начале заголовка соответствующим зарезервированным словом - procedure или function.

Название подпрограммы

Чтобы иметь возможность вызывать подпрограмму, нужно присвоить ей имя. Имя подпрограммы составляется по тем же правилам, что и имя любого идентификатора (переменной). Кто забыл - смотрите урок №8 "Pascal - первое знакомство", там эти правила подробно рассмотрены. Итак, вы придумали имя своей подпрограмме. Куда его написать? А всё просто - сразу же за словом procedure или function через пробел:

procedure MyProcedure;

или

function MyFunction;

Иногда подпрограмме не присваивают осмысленного имени и используют именно такие названия, как указано выше. Ещё применяются сокращения вроде MyFunc или MyProc. Если подпрограмма пишется в тестовых целях, то такие названия вполне подойдут, но если разрабатывается "серьёзное" приложение, следует избегать таких названий. Представьте, легко ли будет вам ориентироваться в коде, если подпрограммы будут имена имена MyFunc1, MyFunc2, ..., MyProc1, MyProc2, ... ? Именно поэтому давайте подпрограммам (а также и переменным, константам) какие-то осмысленные имена. Впоследствии разобраться в коде будет гораздо проще.

Окончание заголовка

Тип подпрограммы указан, название тоже... Что дальше? А дальше следует подумать над тем, требует ли ваша подпрограмма какие-то входные параметры (аргументы) или она работает без них. Окончание заголовка как и окончание любой команды указывается символом точки с запятой (";"). Допустим, ваша процедура скрывает на форме какие-то элементы и при этом не требует входных параметров. Тогда её заголовок будет выглядеть так:

procedure HideElements;

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

Описание входных параметров

Теперь разберёмся, как описать входные параметры. Делается это ни чуть не сложнее, чем описание обычных переменных. Всё, что вам нужно сделать - это открыть круглую скобку после имени подпрограммы, перечислить параметры как обычные переменные, т.е. в формате "имя: тип_данных" и закрыть скобку. При этом переменные одного типа можно перечислять как через запятую, так и отдельно. Сами параметры отделяются друг от друга точкой с запятой, что вполне логично.

function Sum(A,B: Integer);

или

function Sum(A: Integer; B: Integer);

Возвращаемое значение (только у функций).

Остался последний штрих: если мы описываем функцию, то должны указать, каково будет её выходное значение. А точнее, какой тип данных это значение имеет. Само значение, конечно, мы установим в процессе выполнения функции. Если функция возвращает всё время одно и то же значение, то у неё нет смысла и её можно заменить на процедуру, а само значение сделать константой.
Итак, нам нужно задать тип данных выходного значения функции. Как это сделать? А вполне логичным, как всегда, способом - как при описании переменной. Только представьте теперь, что имя переменной - это имя вашей подпрограммы. На входные параметры внимания не обращайте - считайте, что это всё является именем переменной. Итак, ставим в конце двоеточие и далее указываем тип данных. Вот и всё.

Для нашего примера:

function Sum(A,B: Integer): Integer;

Сумма двух целых чисел, очевидно, тоже целое число. На этом описание нашей функции закончено.

Тело подпрограммы

Заголовок написан, дальше дело за малым - написать тело подпрограммы. Здесь ничего особенного - всё пишется также, как и раньше. Входные параметры становятся самостоятельными переменными и к ним можно обращаться обычным образом. Итак:

procedure|function имя_подпрограммы [входные_параметры] [: тип_данных_выходного_значения];
  {раздел описаний}
begin
  {раздел реализации}
end;

Таким образом, сначала написали заголовок подпрограммы, затем её тело и далее подпрограмму можно вызывать. Какие правила при этом нужно соблюдать, сейчас рассмотрим.

Возвращаемое значение

Указать выходное значение функции очень легко. Существует 2 способа сделать это, и оба заключаются в присвоении значения "воображаемой" переменной. Первый способ - можно присвоить значение самой функции, т.е. использовать её название как имя переменной и выполнить присвоение. Второй способ - присвоить значение переменной Result. Эта переменная существует только в рамках данной функции, но описывать её нигде не нужно. Вернёмся к нашему примеру функции, выполняющей сложение двух чисел. Ниже представлены оба способа задания возвращаемого значения:

function Sum(A,B: Integer): Integer;
begin
  Sum:=A+B
end;
function Sum(A,B: Integer): Integer;
begin
  Result:=A+B
end;

Эти записи эквивалентны и означают абсолютно одно и то же.

Где располагать подпрограмму?

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

Чтобы подпрограмма была видна из любого места текущего модуля (т.е. текущей формы), её следует описать в разделе implementation выше всех обработчиков событий:

{...}
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure MyProc1;
procedure MyProc2;
{...}
function MyFunc1: Integer;
function MyFunc2: Real;
{...}
 
{обработчики}
 
end.

Пример.

Пусть требуется найти максимальное из трёх введённых чисел с использованием подпрограммы. Числа будут вводиться в 3 текстовых поля TEdit, результат будет появляться при нажатии на кнопку в текстовой метке TLabel.
Подпрограмма будет принимать на вход 3 параметра - 3 числа и возвращать максимальное из этих чисел. Её заголовок будет приблизительно таким:

function Max3(A,B,C: Integer): Integer;

Реализация тоже довольно проста: например, принимаем первое число за максимальное, а далее смотрим - если второе/третье больше него, то максимальным будет это второе/третье. Итак, полное описание функции:

function Max3(A,B,C: Integer): Integer;
begin
  Result:=A;
  if B > Result then
    Result:=B;
  if C > Result then
    Result:=C
end;

Ну а далее то, что вы уже прекрасно знаете и умеете:

procedure TForm1.Button1Click(Sender: TObject);
 
function Max3(A,B,C: Integer): Integer;
begin
  Result:=A;
  if B > Result then
    Result:=B;
  if C > Result then
    Result:=C
end;
 
var N1,N2,N3: Integer;
 
begin
  N1:=StrToInt(Edit1.Text);
  N2:=StrToInt(Edit2.Text);
  N3:=StrToInt(Edit3.Text);
  Label1.Caption:='MAX = '+IntToStr(Max3(N1,N2,N3));
end;

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

Важно: обратите внимание, что имена переменных, передаваемых в качестве параметров, не обязаны быть одинаковыми. В данном случае передаются только значения (числа). В объявлении функции указаны имена A, B, C, а значения подставляются из переменных N1, N2, N3. При этом, вместо переменных можно указать вполне конкретные значения, например Max3(N1,10,N3).

Заключение

На этом изучение подпрограмм не закончено. Есть ещё важные моменты и приёмы, о которых нужно знать. Их мы рассмотрим в следующем уроке.

Авторизация



Счетчики