- •Лабораторная работа №7. Работа в delphi.
- •Процедуры и функции
- •Задание 1.1 Опишем процедуру вычисления корней квадратного уравнения.
- •Заметьте что, прототип процедуры указывается в разделе interface, а заготовка процедуры в разделе реализации который предваряет ключевое слово implementation.
- •Ключевое слово Result в функции, содержит возвращаемый ею результат определенного типа. Вместо этого слова можно писать имя самой функции.
- •Задание 1.3. Создадим функцию, подсчитывающую количество букв «f» в введённой пользователем строке.
- •Задание 1.5. Создадим простую, отдельную от какого либо класса функцию с именем Bush(X,y:integer):integer возвращающую значение произведения X*y.
- •Перегрузка функций.
- •Задание 1.6. Напишем ещё две перегруженные функции с тем же именем Bush.
- •Задание 1.7. Изучим Основной блок Begin и End модуля.
Лабораторная работа №7. Работа в delphi.
Процедуры и функции
Современную серьезную программу трудно представить без множества функций и процедур, которые преследуют принцип модульности, введённый с целью упрощения кода программы.
В Delphi и Pascal существуют процедуры и функции, которые являются подпрограммами позволяющими разбить на более простые блоки сложную программу.
Процедуры или функции могут иметь или не иметь входных параметров, могут изменять или не изменять их.
Особенность функции в том, что она всегда “что-то” делает, но обязательно возвращает конкретное значение определенного типа, а процедуры в том, что она также всегда “что-то” делает, но не обязана, возвращать конкретное значение определенного типа.
При этом процедуры и функции, принадлежащие определенному классу, называются методами класса. От обычных процедур и функций методы отличаются тем, что им при вызове передается указатель на тот объект, который их вызвал. Поэтому обрабатываться будут данные именно того объекта, который вызвал метод.
Процедура объявляется следующим образом:
procedure <имя процедуры> (список параметров)
<объявления локальных переменных, типов, констант>
Begin
<операторы тела функции>
End;
Функция объявляется следующим образом:
function <имя процедуры>(список параметров): <тип возвращаемого значения> ;
<объявления локальных переменных, типов, констант>
Begin
<операторы тела функции>
End;
Задание 1.1 Опишем процедуру вычисления корней квадратного уравнения.
Создайте новый проект. Перенесите на форму Button1.
В окне редактора кода в секции Public класса TForm1 объявите прототип вашей процедуры KvadrKoren(a,b,c:real; var x1,x2:real), должно быть так:
type
TForm1 = class(TForm)
Button1: TButton;
private
{ Private declarations }
public
procedure KvadrKoren(a,b,c:real; var x1,x2:real); // это прототип
{ Public declarations }
end;
Теперь обязательно поставьте курсор на данную строчку описания процедуры в любое место записи прототипа:
procedure KvadrKoren(a,b,c:real; var x1,x2:real);
И нажмите Ctrl+Shift+C. Перед вами появится сформированная, пока ещё пустая заготовка описания вашей процедуры:
procedure TForm1.KvadrKoren(a, b, c: real; var x1, x2: real);
begin
end;
Заметьте что, прототип процедуры указывается в разделе interface, а заготовка процедуры в разделе реализации который предваряет ключевое слово implementation.
Опишем конкретно нашу процедуру. Измените заготовку процедуры следующим образом:
procedure TForm1.KvadrKoren(a, b, c: real; var x1, x2: real);
var D:real;
begin
D:=sqr(b)-4*a*c;
if D<0 then begin ShowMessage('Корней нет');exit; end;
x1:=(-b+sqrt(D))/(2*a); x2:=(-b-sqrt(D))/(2*a);
a:=10000; b:=10000; c:=10000; {попытка изменить значения переданных
трех первых параметров, Эта строка нужна в учебных целях}
end;
Всё, процедура готова. Теперь просто будем вызывать её из другой процедуры, в частности из обработчика щелчка Button1 (метода класса TForm1).
Поэтому сбросьте на форму одну кнопку Button1.
Обработчик щелчка на Button1 должен выглядеть следующим образом:
procedure TForm1.Button1Click(Sender: TObject);
var a1,b1,c1, x1,x2:real;
begin
a1:=1; b1:=2; c1:=-3; //начальные значения a1, b1 и c1
KvadrKoren(a1, b1, c1, x1,x2); //Вызываем процедуру и передаём ей аргументы
InputBox('Процедура квадр', 'корни', 'x1= '+FloatToStr(x1)+' x2= '+FloatToStr(x2));
// Выводим значения x1 и x2
Showmessage('a1= '+FloatToStr(a1)+' b1= '+FloatToStr(b1)+' c1= '+FloatToStr(c1));
{Проверяем, изменились ли значения a1, b1 и c1 на 10000 как записано в процедуре}
end;
Обратите внимание на вызов процедуры KvadrKoren(a1, b1, c1, x1,x2);
из обработчика щелчка на Button1
Здесь будет следующее соответствие:
в качестве a будет получено значение a1
в качестве b будет получено значение b1
в качестве c будет получено значение c1
При этом допускается чтобы имена параметров описанных в прототипе процедуры и переданных в неё - совпадали, поэтому можно не вводить переменные a1, b1 и c1, а просто в обработчике щелчка определить переменные a, b, c и передать их процедуре, что и было сделано только для x1 и x2.
Разберем описание прототипа процедуры KvadrKoren(a, b, c: real; var x1, x2: real). Здесь первые 3 параметра a, b, c: real; а вторые 2 параметра x1, x2: real предваряются ключевым словом Var.
Дело здесь состоит в следующем: Если нет ключевого слова Var, то при вызове процедуры с параметрами, ей передаются не сами параметры, а их копии, и она работает лишь с копиями этих параметров не изменяя значений самих переданных параметров. Этот способ называется передачей по значению.
Мы намеренно написали в коде процедуры KvadrKoren инструкции
a:=10000; b:=10000; c:=10000; то есть мы хотим, чтобы она изменила переданные ей значения a1, b1 и c1 на 10000, так как считаем, что есть соответствие между a и a1, b и b1, c и c1.
А затем уже из обработчика щелчка на Button1, после вызова процедуры, проверяем, поменяла ли она значения a1, b1 и c1 на 10000 как в ней записано.
Результат таков, первые 3 параметра a1, b1, c1 не изменятся процедурой, как бы она “не старалась”, для проверки мы выводим их значения на экран, после передачи их в процедуру.
Запустите программу и щелкните по кнопке. Сначала вы получите значения корней x1 и x2 (рис.1)
Рис.1 Расчет корней квадратного уравнения
А затем, после щелчка на OK увидите, что значения a1, b1 и c1 остались прежними (рис.2) несмотря на то, что в процедуре KvadrKoren мы присваиваем a:=10000; b:=10000; c:=10000.
.
Рис.2 Неизмененные процедурой значения a1, b1 и c1
Таким образом, значения a1, b1, c1 не изменяются процедурой. Вернитесь в режим программирования.
При этом можно просто передавать значения, в процедуру не вводя лишних переменных, слегка изменим код для обработчика щелчка на Button1:
Вместо KvadrKoren(a1, b1, c1, x1,x2); напишите там KvadrKoren(1, 2, -3, x1,x2);
Программа будет работать точно так же. Проверьте это. Вернитесь в режим программирования.
Совершенно противоположное действие, когда в процедуре перед параметрами пишется ключевое слово Var. В этом случае процедура может изменять значение переданного ей параметра. Этот способ передачи параметров называется передачей по ссылке. Поэтому значения x1 и x2 предваренные словом var, могут, и в данном случае будут изменяться процедурой KvadrKoren. Проверим это.
Исходные аргументы a1,
b1, c1
процедуре не доступны и меняться не
могут (НЕТ VAR)
передача по значению
Исходные аргументы x1,
x2 процедуре
доступны и меняться могут (ЕСТЬ VAR)
передача по ссылке
Рис. 3 Схема
передачи параметров по значению и по
ссылке
Для большей убедительности измените обработчик щелчка Button1 следующим образом:
var a1,b1,c1, x1,x2:real;
begin
a1:=1; b1:=2; c1:=-3;
x1:=10000; x2:=10000; // Устанавливаем начальные значения X1 и X2
// Эта строка нужна в учебных целях
InputBox('', 'начальные значения', 'x1= '+FloatToStr(x1)+' x2= '+FloatToStr(x2));
// KvadrKoren(a1, b1, c1, x1,x2); //не может менять a1, b1, c1, может менять x1 и x2
KvadrKoren(1, 2, -3, x1,x2); //может менять x1 и x2
InputBox('Процедура Квадр', 'корни', 'x1= '+FloatToStr(x1)+' x2= '+FloatToStr(x2));
end;
Запустите программу, и щелкните по кнопке. Сначала вы получите начальные значения переменных x1 и x2 равные 10000 (рис.4), так как в начале мы специально устанавливаем их в это значение.
Рис. 4 Начальные значения переменных x1 и x2 равные 10000
Затем, после щелчка на OK вы обнаружите, что x1 и x2 поменялись процедурой
(рис. 5). В данном случае процедура KvadrKoren рассчитала корни и присвоила их значения к переменным x1 и x2 объявленные в обработчике щелчка Button1.
Рис. 5 Измененные значения переменных x1 и x2 равные 10000
Вернитесь в режим программирования.
В Delphi функция отличается от процедуры тем, что всегда в результате своей работы возвращает некоторое значение определенного типа.
Все рассуждения относительно параметров переданных процедуре, присутствия или отсутствия ключевого слова Var также распространяются и на функцию.
Задание 1.2. Создадим функцию, возвращающую значения факториала 10! Будем вызывать её из обработчика щелчка на Button2 и выведем десять её значений в Memo1.
В этом же проекте сбросьте Button2 и Memo1 на форму (рис. 6).
Рис. 6 Приложение вычисляющее факториал
Факториал n обозначается n! и равен n!=n·(n-1) (n-2) …·3·2·1.
В окне редактора кода в секции Public класса TForm1 объявите прототип вашей функции, всё должно выглядеть примерно так:
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
procedure KvadrKoren(a,b,c:real;var x1,x2:real);
function Faktorial(n:word):word; // Прототип функции
{ Public declarations }
end;
Точно так же как и для процедуры обязательно поставьте курсор на данную строчку описания процедуры в любое место записи function Faktorial(n:word):word;
И нажмите Ctrl+Shift+C. И снова перед вами появится сформированная, заготовка описания вашей функции, измените её следующим образом:
function TForm1.Faktorial(n: word): word;
var i,j:word;
begin
j:=1;
for i:=1 to n do j:=j*i;//вычисляем факториал в переменную j
Result:=j; { ключевое слово Result для функции, означающее конечный результат её действия}
//хотя можно было бы написать вместо Result:=j; инструкцию Faktorial:=j
end;
Так как в передаваемых параметрах нет слова Var, то функция “безопасная” и менять значение переданного параметра не будет.