Как было показано в параграфе 1.7.4, процедурные типы можно использовать в разделе объявления типов, переменных, а также типированных констант. Значения процедурного типа также могут передаваться в качестве параметров процедурам и функциям.
Задача 48. Вывести на экран таблицы сложения, вычитания, умножения, деления и возведения в степень.
Решение задачи не представляет особой сложности. Однако без использования процедур и процедурных типов оно будет громоздким и лишенным универсальности:
uses crt;
type MathFunc= Function (a,b:real):real; {определяем процедурный тип}
MathRecord=record {определяем запись для хранения информации о соответствующей математической функции}
Name:string[20];{имя функции}
Func:MathFunc;{сама функция}
end;
{$F+}{устанавливаем дальнюю модель вызова}
Function Add(a,b:real):real; {функция сложения}
begin Add:=a+b; end;
function Sub(a,b:real):real; {функция вычитания}
begin Sub:=a-b; end;
Function Mul(a,b:real):real; {функция умножения}
begin Mul:=a*b; end;
function Division(a,b:real):real; {функция деления}
begin Division:=a/b; end;
function Power(a,b:real):real; {функция возведения в степень}
begin Power:=exp(b*ln(a)); end;
const Funcs:array[1..5] of MathRecord={константный массив для хранения информации о математических функциях}
((Name:'сложение';func:Add),
(Name:'вычитание';func:Sub),
(Name:'умножение';func:Mul),
(Name:'деление';func:Division),
(Name:'возведение в степень';func:Power));
procedure PrintTable(dx,dy:integer; Func:MathFunc);
{--------------процедура для вывода на экран таблицы--------------}
{ dx, dy - размеры таблицы (не советуем выводить таблицы с количеством столбцов более семи, не хватает ширины экрана для универсального форматирования)
func - соответствующая математическая функция}
var i,j:integer;
begin
for i:=1 to dy do begin
for j:=1 to dx do write(' ',func(i,j):9:2);
writeln;
end;
end;
{------основная программа--------}
var a,b:integer;
i:byte;
begin
clrscr;
write('Введите размеры таблицы (2 числа): '); readln(a,b);
for i:=1 to 5 do begin
with funcs[i] do begin {ведем обработку очередной записи информации о математической функции}
writeln('Вывод таблицы, операция - ',Name);
PrintTable(b,a,func);
readkey; {после вывода каждой таблицы ожидаем нажатия клавиши}
end;
end;
end.
Например, при выводе таблицы размером в 3 строки и 7 столбцов мы получим следующий результат:
Введите размеры таблицы (2 числа): 3 7
Вывод таблицы, операция - сложение
2.00 3.00 4.00 5.00 6.00 7.00 8.00
3.00 4.00 5.00 6.00 7.00 8.00 9.00
4.00 5.00 6.00 7.00 8.00 9.00 10.00
Вывод таблицы, операция - вычитание
0.00 –1.00 –2.00 –3.00 –4.00 –5.00 –6.00
1.00 0.00 –1.00 –2.00 –3.00 –4.00 –5.00
2.00 1.00 0.00 –1.00 –2.00 –3.00 –4.00
Вывод таблицы, операция - умножение
1.00 2.00 3.00 4.00 5.00 6.00 7.00
2.00 4.00 6.00 8.00 10.00 12.00 14.00
3.00 6.00 9.00 12.00 15.00 18.00 21.00
Вывод таблицы, операция - деление
1.00 0.50 0.33 0.25 0.20 0.17 0.14
2.00 1.00 0.67 0.50 0.40 0.33 0.29
3.00 1.50 1.00 0.75 0.60 0.50 0.43
Вывод таблицы, операция - возведение в степень
1.00 1.00 1.00 1.00 1.00 1.00 1.00
2.00 4.00 8.00 16.00 32.00 64.00 128.00
3.00 9.00 27.00 81.00 243.00 729.00 2187.00
К сожалению, ТП не поддерживает присваивание процедурным переменным локальных процедур и функций, а также методов объектов, что тормозит применение процедурных типов в объектно-ориентированном программировании. К счастью в Delphi данная проблема решена.