Глава 7. Процедуры и Функции (Подпрограммы)
Итак, теперь перейдем к частям языка таким как процедуры и функции. Что это такое? Это подпрограммы. Функция отличается от процедуры лишь тем, что она возвращает какое либо значение, процедура ничего не возвращает.
Если вы решили написать какую-нибудь игрушку, например какую-нибудь экономическую стратегию, то без процедур и функций вам не обойтись. Пускай одна функция будет отвечать за количество собранного урожая, другая будет отвечать за количество работников. Но до игр нам пока далековато.
Начнем изучать процедуры. Простая процедура имеет такой синтаксис:
Procedure имя процедуры [ (параметры) ];
Var переменные процедуры;
Begin
Операторы;
End;
То, что находится внутри квадратных скобок – это необязательные параметры. Переменные объявленные в процедуре или функции называются локальными переменными. Такие переменные доступны только процедуре или функции в которой эта переменная объявлена. Переменные, которые были объявлены в разделе описаний переменных самой программы называются глобальными переменными и доступны полностью всей программе. Процедура или функция вызывается через их заданные имена. Например, процедура:
Procedure Example;
Begin
Операторы;
End;
Через ее имя, процедуру можно вызывать главной программой или другой программой. Например:
Program Ex_pr;
Procedure Example;
Begin
Операторы;
End;
Begin
Example;
End.
Процедура или функция всегда должна стоять выше главной программы. Если одна процедура или функция вызывает вторую процедуру или функцию, то вторая процедура или функция должна стоять выше первой. Например:
Procedure b;
Begin
Операторы;
End;
Procedure a;
Begin
Операторы;
End;
Begin
a;
End.
Если например процедура a вызывает процедуру b, а та в свою очередь вызывает процедуру a, то необходимо создать опережающую процедуру. Т.е поверх всех этих процедур и функций вставить строчку procedure a; forward;
Например:
Program ex_pr;
Procedure a; forward;
Procedure b;
Begin
Операторы;
End;
Procedure a;
Begin
Операторы;
End;
Begin
a;
End.
Таким образом, получается, что процедура стоит поверх всех остальных. Теперь перейдем к параметрам процедур.
Бывают случаи, когда нужно выполнить процедуру или функцию получив от главной программы или другой подпрограммы какие-нибудь данные. Рассмотрим процедуру, выполняющую функцию калькулятора:
Procedure Calculator(num1, num2: integer; op: string);
Begin
if op = ‘+’ then rez:=num1+num2; // сложить
if op = ‘-’ then rez:=num1-num2; // вычесть
if op = ‘/’ then rez:=num1/num2; // делить
if op = ‘*’ then rez:=num1*num2; // умножить
End;
Здесь процедура принимает три параметра: num1 (первое число), num2 (второе число), op (операция с числами). Если представить, что у нас будет три поля ввода, то первые два нам будут нужны для чисел, третье для ввода операции. Параметр op будет получать операцию вводимую пользователем в третье поле, и если строка, записанная в переменную совпадет с одной из строки (+, -, / или *), то выполнится соответствующая операция над числами записанные в переменные num1 и num2. Переменная rez должна быть объявлена в самом начале программы. Эта переменная получает результат вычисления.
Такую процедуру можно записать и с помощью функции. Давайте немножко ознакомимся с функциями. Функция отличается от процедуры лишь тем, что она может возвращать какое-нибудь значение. Синтаксис функции следующий:
Function имя_функции [необязательные_параметры]:возвращаемый_тип;
Begin
Тело функции (код);
End;
Тело функции – это код, который находится внутри функции. Возвращаемый тип – это тип данных которая возвращает функция (текст, число и пр.).
Для понимания запишем процедуру Calculator в виде функции:
function Calculator(num1, num1: integer; op: string): integer;
Begin
if op = ‘+’ then Calculator:=num1+num2; // сложить
if op = ‘-’ then Calculator:=num1-num2; // вычесть
if op = ‘/’ then Calculator:=num1/num2; // делить
if op = ‘*’ then Calculator:=num1*num2; // умножить
end;
Заметьте, такая строка Calculator:=num1+num2 и идущие за ней дальше, в них слово Calculator – это уже не переменная, а та же самая функция. Получается что функция вызывает саму себя (с процедурами это тоже допустимо). Такие случаи называются рекурсией. В данном случае так функция получает значение при операциях над теми же переменными num1, num2. Возвращаемый тип должен строго соответствовать типу данных которая получает функция иначе вы получите ошибку о том что операнды должны иметь одинаковые типы данных. Операнды это переменные или числа над которыми введется какая либо математическая или логическая операция.
Получив знания о процедурах и функциях, мы теперь разработаем проект «калькулятор. Это будет наш первый полезный проект J.
Листинг программы «калькулятор»:
Program Calc;
Var
n1,n2:integer; // переменные чисел
rez:string; // переменная для операции над операндами
function calculator(num1, num2:integer; op: string): integer;
Begin
if op = '+' then calculator := num1 + num2; // сложить
if op = '-' then calculator := num1 - num2; // вычесть
if op = '/' then calculator := num1 / num2; // поделить
if op = '*' then calculator := num1 * num2; // умножить
end;
procedure start; // интерфейс программы
var num1f, num2f, opf : integer; //переменные для полей ввода чисел и операций
ok: command; // переменная для команды «решить»
Begin
ShowForm; // показать форму на экран
ok:=createCommand('Решить',CM_OK,1); // создать команду
num1f:=formAddTextField('Введите первое число','',20,TF_NUMERIC); // текстовое поле для ввода чисел
num2f:=formAddTextField('Введите второе число','',20,TF_NUMERIC);
opf:=formAddTextField('Операция','',1,TF_ANY); // текстовое поле для ввода операций
addCommand(ok); // помещаем команду «решить» на экран
delay(500); // чтобы не зависало
repeat until getClickedCommand = ok; // ждем нажатия команды «решить»
n1:=StringToInteger(formGetText(num1f)); // извлекаем текст из текстовых полей и переводим в число
n2:=StringToInteger(formGetText(num2f));
rez:=formGetText(opf); // извлекаем операцию из поля ввода текста для операций
if rez = '#' then halt; // если операция будет соответствовать символу «#» то закрываем программу
ShowAlert('Решение','Ответ '+calculator(n1,n2,rez),LoadImage('/icon.png'),ALERT_INFO); // показываем сообщение с результатом решения.
playAlertSound; // проигрываем звук
delay(3000); // показываем сообщение 3 секунды
clearForm; // и очищаем форму
start; // вызываем процедуру start заново, для дальнейших действий с программой
end;
Begin
start; //вызываем интерфейс программы (процедура start)
end.
Итак, вот наш проект Calculator. На рис. 13 показан его вид на эмуляторе MidpX.
Рис. 13. Проект «калькулятор» |
Наша программка имеет интерфейс, состоящий из трех текстовых полей и одной команды. Все это помещается на форму. Форма это контейнер, в который может помещаться такие элементы, как текстовые поля, шкалы, картинки и пр. подробнее об этом в следующей главе.
Теперь попробуем разобрать такую строку:
n1:=StringToInteger(formGetText(num1f));
Это строка состоит из двух функций: StringToInteger и formGetText.
Первая конвертирует строку в целое число, вторая функция извлекает строку из текстового поля с заданным идентификатором текстового поля. Таким образом, переменная получает число из текстового поля.
Строка
ShowAlert('Решение','Ответ '+calculator(n1,n2,rez),LoadImage('/icon.png'),ALERT_INFO);
Выводит ответ на экран в виде сообщения. Эта строка так же обращается к нашей функции calculator с параметрами извлеченных из текстовых полей чисел и строки операции и получает результат вычисления в виде числа. Но чтобы ее отобразить мы поставили слово «Ответ» и прибавили функцию calculator. Таким образом, число перекодировалось в строку (вспомните операции со строками, что если к строке прибавить число, то это число так же станет строкой).