Подпрограммы (часть 2)
Автор: |
© Ерёмин А.А., 2008 |
Готовой работающей программой называют код, содержащий пока еще не обнаруженные ошибки. |
Номер урока: |
20 |
Решение домашнего задания из урока №19
Для начала разберём домашнее задание, которое было предложено в прошлом уроке. Задание было следующим:
Определить, какие входные параметры было бы логично задать для следующих подпрограмм:
- Функция, считающая, сколько раз буква встречается в тексте.
- Функция, вычисляющая объём цилиндра.
- Функция, проверяющая, является ли параллелепипед кубом.
- Процедура, делающая 3 кнопки, расположенные на форме, недоступными для нажатия.
- Процедура, изменяющая разрешение экрана.
1. Необходимо указать текст, в котором будет выполняться поиск буквы и сама буква для поиска.
2. Как известно, объём цилиндра равен произведению площади основания на высоту, а площадь основания - произведение числа ПИ на квадрат радиуса. Итак, параметрами будут радиус основания цилиндра и его высота.
3. Параллелепипед будет кубом тогда, когда все его три измерения (т.е. длина, ширина, высота) равны. И параметров будет соответственно 3.
4. Если процедура работает с какими-то конкретными кнопками, то входные параметры не потребуются. Другой вариант - процедуре передаются 3 параметра - какие именно кнопки следует сделать недоступными.
5. Чтобы изменить разрешение экрана, нужно задать новые параметры - ширину и высоту - всего 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).
Заключение
На этом изучение подпрограмм не закончено. Есть ещё важные моменты и приёмы, о которых нужно знать. Их мы рассмотрим в следующем уроке.
Домашнее задание
Составить подпрограммы:
- Для вычисления факториала указанного числа.
- Для преобразования текста, содержащего русские буквы, в верхний регистр.
- Для вычисления результата импликации двух логических выражений (A -> B).
Примечание к заданию 1: Факториалом числа n называется произведение 1*2*3*...*n и обозначается факториал "n!". Факториал числа 0 равен 1.
Примечание к заданию 3: Импликация (лат. implico - тесно связываю) - логическая операция, образующая сложное высказывание из двух высказываний посредством логической связки, соответствующей союзу "если ..., то ...". Импликация ложна лишь в случае истинности первого выражения и ложности второго и истинна во всех остальных случаях. Обозначается импликация стрелкой вправо (A -> B).
Автор: Ерёмин А.А.
Статья добавлена: 9 апреля 2008
Следующая статья: Обучающий курс. 21. Подпрограммы (часть 3) »
Зарегистрируйтесь/авторизируйтесь,
чтобы оценивать статьи.
Статьи, похожие по тематике
- Обучающий курс. 10. Логические выражения
- Обучающий курс. 12. Функции и процедуры. Математические вычисления. Случайные числа
- Обучающий курс. 14. Выбор (ветвления)
- Обучающий курс. 16. Циклы - общее понятие; цикл с параметром
- Обучающий курс. 17. Циклы - цикл с предусловием и цикл с постусловием
- Обучающий курс. 18. Работа со строками и символами
- Обучающий курс. 19. Подпрограммы (часть 1)
- Обучающий курс. 21. Подпрограммы (часть 3)
- Обучающий курс. 22. Простые типы данных
- Обучающий курс. 23. Множества
- Обучающий курс. 24. Записи (часть 1)
Для вставки ссылки на данную статью на другом сайте используйте следующий HTML-код:
Ссылка для форумов (BBCode):
Быстрая вставка ссылки на статью в сообщениях на сайте:
{{a:120}} (буква a — латинская) — только адрес статьи (URL);
{{статья:120}} — полноценная HTML-ссылка на статью (текст ссылки — название статьи).
Поделитесь ссылкой в социальных сетях:
Комментарии читателей к данной статье
Репутация: нет |
zvygin1964 (1 декабря 2013, 21:48): Заработало только когда написал так:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Label1: TLabel; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} 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; end. Надеюсь, что хозяин сайта именно это и имел в виду. |
Репутация: +40 |
Ерёмин А.А. (9 августа 2010, 18:34): У кого-то в школе вообще ещё компьютеров не было :-)
|
Репутация: +1 |
antoca (9 августа 2010, 18:26): Да это всё в школе еще изучалось.
|
Репутация: нет |
alexkrv (6 марта 2010, 11:58): Используйте функцию AnsiUpperCase
|
Репутация: +40 |
Ерёмин А.А. (1 мая 2009, 21:44): Вероятно, функция UpperCase не может корректно обработать русские буквы. Попробуйте на английских - должно работать.
Да, и одно замечание: вокруг max(s) скобки не нужны. |
Репутация: нет |
nightly (1 мая 2009, 21:24): Д/3- 2 задание я сделал по-своему,но у меня не работает почему-то программа:
procedure TForm1.Button1Click(Sender: TObject); function max(n:string):string; begin result:=uppercase(n); end; var s:string; begin s:=edit1.Text; label1.caption:=(max(s)); end; Почему? |
Оставлять комментарии к статьям могут только зарегистрированные пользователи.