Партнеры сайта:

Никита Французов на сервере Стихи.ру

Игра "2tris" уже в Google play
Игра "2tris" уже в Google play

Урок №9. Создание собственных процедур и функций Delphi

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

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

   И процедуры, и функции позволяют добиться одинаковых результатов. Но разница всё же есть.

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

   Функция Delphi также позволяет выполнить всё перечисленное, но дополнительно возвращает результат в присвоенном ей самой значении. То есть вызов функции может присутствовать в выражении справа от оператора присваивания. Таким образом, функция - более универсальный объект!

   Описание подпрограммы состоит из ключевого слова procedure или function, за которым следует имя подпрограммы со списком параметров, заключённых в скобки. В случае функции далее ставится двоеточие и указывается тип возвращаемого значения. Обычная точка с запятой далее - обязательна! Сам код подпрограммы заключается в "логические скобки" begin/end. Для функции необходимо в коде присвоить переменной с именем функции или специальной зарезервированной переменной Result (предпочтительно) возвращаемое функцией значение. Примеры:

procedure Имя_процедуры((*параметры*));

begin
 //Код процедуры;
end;

 

function Имя_функции((*параметры*)): тип_результата;
begin
  //Код функции;

  Result := результат;
end;

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

 

    Параметры - это список идентификаторов, разделённых запятой, за которым через двоеточие указывается тип. Если списков идентификаторов разных типов несколько, то они разделяются точкой с запятой. Всё, как и в случае обычного описания данных. Это так называемые формальные параметры. При вызове подпрограммы они заменяются на фактические - следующие через запятую данные того же типа, что и формальные.
   Параметры в описании подпрограммы могут и отсутствовать, тогда она оперирует данными прямо из основной программы.

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

   Теперь пример. Напишем программу суммирования двух чисел. Она будет состоять из Формы, на которой будет кнопка (компонент Button), по нажатию на которую будет выполняться наша подпрограмма, и двух строк ввода (компоненты Edit), куда будем вводить операнды. Начнём с процедуры.

var
  Form1: TForm1;
  A, B, Summa: Integer;
  procedure Sum(A, B: Integer);

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 A:=StrToInt(Edit1.Text);
 B:=StrToInt(Edit2.Text);
 Sum(A, B);
 Caption:=IntToStr(Summa);
end;

procedure Sum(A, B: Integer);
begin
 Summa:=A+B;
end;

   Есть особенности в использовании в качестве параметров больших по объёму структур данных, например, массивов, состоящих из нескольких тысяч (и больше) элементов. При передаче в подпрограмму данных большого объёма могут быть большие расходы ресурсов и времени системы. Поэтому используется передача не самих значений элементов (передача "по значению", как в предыдущих примерах), а ссылки на имя переменной или константы (передача "по имени"). Достигается это вставкой перед теми параметрами, которые мы хотим передать по имени, ключевого слова var.


Function Sum(A, B: Integer; var Arr: array[1..1000000] of Integer): Integer;


   Eсли взглянуть на описание нашей подпрограммы и описание обработчика нажатия кнопки (это тоже подпрограмма!), который был создан Delphi, то видим, что перед именем обработчика (Button1Click) стоит TForm1. Как мы знаем, в Delphi точкой разделяется объект и его атрибуты (свойства и методы). Таким образом, Delphi создаёт Button1Click как метод объекта Form1. Причём, буква T перед объектом говорит о том, что Button1Click не просто метод объекта, а метод класса объекта. Не будем этим пока заморачиваться, а просто будем поступать также. Описав свою процедуру или функцию как метод класса TForm1, мы получаем возможность использовать в ней объекты класса без указания его имени, что гораздо удобнее. То есть, если мы используем в нашей подпрограмме какие-либо компоненты, размещённые на Форме (например, Button1), то мы пишем

Button1.Width:=100;   //Ширина кнопки
   а не
Form1.Button1.Width:=100;

   Также появляется возможность использовать встроенные переменные, такие как параметр Sender. В каждом обработчике этот объект указывает на источник, то есть тот объект, который вызывает данную подпрограмму. Например, в нашей процедуре суммирования Sender = Button1. Проанализировав эту переменную, можно принять решение о тех или иных действиях.

   Описав подпрограмму как метод класса, её описание мы должны поместить туда же, куда их помещаетDelphi - в описание класса TForm1. Смотрите сами, где находится описание процедуры Button1Click. Для этого, поставив курсор внутрь подпрограммы Button1Click, нажмите CTRL+Shift и кнопку управления курсором "Вверх" или "Вниз" одновременно. Произойдёт переход к описанию подпрограммы (чтобы вернуться обратно, повторите это действие ещё раз). Ставьте описание своей подпрограммы рядом, с новой строки. Обратите внимание, что TForm1 уже не пишется.

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


Пример вычисления факториала

Вычисление факториала - классическая в программировании задача на использование рекурсии.Факториал числа N - результат перемножения всех чисел от 1 до N (обозначается N!):

N! = 1*2* ... *(N-1)*N = N*(N-1)!

   Создавая программу вычисления факториала числа, мы можем применить и функции, и рекурсиюМожно скачать проект данной программы.

Факториал.rar
compressed file archive 1.6 MB

   Рассмотрим программу вычисления факториала. Используем компоненты Edit и UpDown. КомпонентUpDown имеет полезное свойство Associate. Стоит в Инспекторе объектов присвоить ему (из выпадающего списка) один из находящихся на Форме компонентов Edit, как компонент UpDown пристроится к нему, примет его размеры, и изменение его свойства Position будет отображаться компонентом Edit без всякого программирования!


implementation


{$R *.dfm}


function fak(N: Integer): Int64; //Функция, вычисляющая факториал, принимает число N как параметр
begin
 if((N=0)or(N=1)) //Условие прекращения рекурсивных вызовов
  then Result:=1 //Факториал чисел 0 и 1 равен 1
  else Result:=N*fak(N-1); //Если число больше 1, то осуществляется рекурсивный вызов функции самой себя с параметром N-1
end;

{используем процедуру onMouseUp, так как при использовании простого щелчка (onClick) будет вычислен факториал текущего числа, а нужное число появится с опозданием:}
procedure TForm1.UpDown1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 Label1.Caption:=IntToStr(fak(UpDown1.Position));
end;

end.

   Нужно отметить, что даже тип Int64 не может вместить значение факториала числа, большего 18.

Write a comment

Comments: 6
  • #1

    школомон (Monday, 02 December 2013 06:35)

    не работает

  • #2

    Школомон2 (Monday, 02 December 2013 08:15)

    Иди учи, там все норм написано:)

  • #3

    ПЬЕР (Wednesday, 19 March 2014 12:39)

    С первого раза никогда не заработает. Надо очень хорошо врубиться в код, потом помаслу пойдет.

  • #4

    Noizu (Wednesday, 03 December 2014 21:11)

    Всё работает если разобраться.

  • #5

    грша (Saturday, 19 September 2015 09:17)

    Это точно я разобрался и всё нормально сработало. (программу делаю)

  • #6

    "XSS (Sunday, 05 March 2017 07:51)

    "><s>XSS


About | Privacy Policy | Cookie Policy | Sitemap
Производство Никиты Французова