Тема 6. Программирование с использованием подпрограмм и модулей

Вызов функции: y:=<имя функции > ([список имен формальных параметров без указания их типов]);

Процедуры и функции могут быть использованы в качестве формальных параметров подпрограмм. Для этого определяется тип:

Вызов функции: y:=<имя функции > ([список имен формальных параметров без указания их типов]);

Процедуры и функции могут быть использованы в качестве формальных параметров подпрограмм. Для этого определяется тип:

Type <имя> = function ([список формальных параметров]):<тип рез-тата>;

или  

Type <имя> = procedure ([список формальных параметров]);.

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

6.2. Использование модулей

Модуль – автономно компилируемая программная единица, включающая в себя процедуры, функции, а также различные разделы описаний. Структура модуля представлена в п.1.2 и содержит следующие основные части: заголовок, интерфейсная часть, исполняемая, инициирующая и завершающая (последние две части могут отсутствовать).

Заголовок состоит из зарезервированного слова Unit и следующего за ним имени модуля, которое должно совпадать с именем дискового файла. Использование имени модуля в разделе Uses основной программы приводит к установлению связи модуля с основной программой.

Интерфейсная часть расположена между ключевымисловами interface иimplementation и содержит объявление тех конструкций и разделов описаний модуля, которые должны быть доступны другим программам.

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

Инициирующая часть начинается ключевым словом initialization и содержит операторы, которые исполняются перед началом выполнения основной программы (может отсутствовать).

Завершающая часть начинается ключевым словом finalization и выполняется в момент окончания работы программы (может отсутствовать).

6.3. Пример написания программы

Задание: написать программу вывода на экран таблицы функции, которую оформить в виде процедуры. В качестве функции использовать по выбору или .

Рис. 6.1

6.3.1. Создание модуля

В среде Delphi модули могут создаваться как со своей формой, так и без нее. Для создания нового модуля без своей формы необходимо в меню File выбрать New – Unit. В результате будет создан файл с заголовком Unit Unit2. Имя модуля можно изменить на другое, отвечающее внутреннему содержанию модуля, например Unit Matfu. Для этого необходимо сохранить содуль с новым именем (например Matfu.pas). Следует обратить внимание на то, что имя файла должно совпадать с именем модуля.

6.3.2. Подключение модуля

Для того чтобы подключить модуль к проекту, необходимо в меню Project выбрать опцию Add to Project… и выбрать файл, содержащий модуль. После этого в разделе Uses добавить имя подключаемого модуля – MatFu. Теперь в проекте можно использовать функции, содержащиеся в модуле.

Панель диалога будет иметь следующий вид (рис. 6.1).

Тексты модуля (Листинг 6.1) и вызывающей программы (Листинг 6.2) приведены ниже (получение рекуррентной формулы см. п. 3.3).

Листинг 6.1

unit matfu;

interface

uses StdCtrls, SysUtils;

  Type

  fun = function(x : extended):extended; // Объявление типа функция

  {Расчет таблицы функции f (табуляция функции)}

  procedure Tabl(f:fun;xn,xk:extended; m: word; Mem1 : TMemo);

implementation

  procedure Tabl;

  var x,y,h: extended;

  i : integer;

  begin

  x:=xn;  h:=(xn-xk)/m;

for i:=1 to m+1 do begin

  y:=f(x);

  Mem1.Lines.Add(' x='+FloatToStrf(x,fffixed,8,3)+

  ' y='+FloatToStrf(y,fffixed,8,3));

  x:=x+h;

  end;

  end;

end.  // Конец модуля matfu

Листинг 6.2

unit Unit6;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls, Buttons, ExtCtrls, Matfu;

type

  TForm1 = class(TForm)

  Label1: TLabel;

  Label2: TLabel;

  Label3: TLabel;

  Label4: TLabel;

  Edit1: TEdit;

  Edit2: TEdit;

  Edit3: TEdit;

  Edit4: TEdit;

  RadioGroup1: TRadioGroup;

  Memo1: TMemo;

  BitBtn1: TBitBtn;

  BitBtn2: TBitBtn;

  procedure FormCreate(Sender: TObject);

  procedure BitBtn1Click(Sender: TObject);

  private

  { Private declarations }

  public

  { Public declarations }

  end;

var

  Form1: TForm1;

  xn,xk,e : extended;

  m : word;

implementation

{$R *.dfm}

function sx(x:extended):extended;

var a,n,s : extended;

  k : integer;

begin

  k:=-1;  a:=1;  n:=0; s:=1;

  try

  while (abs(a) > e) do begin

  n:=n+1;

  a:=-a*x/n; 

  s:=s+a;

  end;

  Result:=s;

  except

on EInvalidOp do 

  k:=MessageDlg('Неправильная операция с плавающей точкой. ’+ 

  ’ Продолжить вычисления?',mtError,[mbYes,mbNo],0);

on EOverFlow do 

  k:=MessageDlg('Переполнение при выполне-нии операции с’+

  ’ плавающей точкой! Продолжить вычисления?',mtError,[mbYes,mbNo],0);

  else 

  k:=MessageDlg('Возникла неизвестная исключительная ситуация!’+

  ‘ Продолжить вычисления?',mtError,[mbYes,mbNo],0);

  end;

  case k of

  mrYes : Result:=0;

  mrNo  : Halt(1);

  end; 

end;

function yx(x:extended):extended;

begin

  Result:=exp(-x);

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

  Memo1.Clear;

  RadioGroup1.ItemIndex:=0;

  Edit1.Text:='0';

  Edit2.Text:='2';

  Edit3.Text:='6';

  Edit4.Text:='0,001';

end;

procedure TForm1.BitBtn1Click(Sender: TObject);

begin

  Memo1.Clear;

  Memo1.Lines.Add('Лаб. раб. №6 ст. гр. 552003 Иванова А.А.');

  xn:=StrToFloat(Edit1.Text);

  Memo1.Lines.Add(' xn='+FloatToStrF(xn,ffFixed,6,2));

  xk:=StrToFloat(Edit2.Text);

  Memo1.Lines.Add(' xk='+FloatToStrF(xk,ffFixed,6,2));

  m:=StrToInt(Edit3.Text);

  Memo1.Lines.Add(' h='+IntToStr(m));

  e:=StrToFloat(Edit4.Text);

  Memo1.Lines.Add(' e='+FloatToStrF(e,ffFixed,8,5));

  case RadioGroup1.ItemIndex of

  0 : begin

  Memo1.Lines.Add('Расчет S(x)');

  Tabl(sx,xn,xk,m,Memo1);

  end;

  1 : begin

  Memo1.Lines.Add('Расчет Y(x)');

  Tabl(yx,xn,xk,m,Memo1);

  end;

  end;

end;

end.

6.4. Выполнение индивидуального задания

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

Вы здесь: