====== Использование процедурных типов ====== Суть этой возможности в **Компонентном Паскале** состоит в том, что можно создать //переменную//, которой позже можно присвоить //адрес// какой-либо //процедуры//, после чего, можно использовать эту переменную как саму процедуру. При этом, нужно помнить, что **список аргументов** у //переменной процедурного типа// и самой //процедуры// **должны** совпадать. ==== Пример ==== MODULE FunctionalCalculator; IMPORT Out := StdLog; TYPE CalculatorLong = PROCEDURE (VAR acc: LONGINT; cur: INTEGER); CalculatorBool = PROCEDURE (VAR acc: BOOLEAN; a, b: INTEGER); PROCEDURE Add(VAR acc: LONGINT; cur: INTEGER); BEGIN acc := acc + cur END Add; PROCEDURE Sub(VAR acc: LONGINT; cur: INTEGER); BEGIN acc := acc - cur END Sub; PROCEDURE Mul(VAR acc: LONGINT; cur: INTEGER); BEGIN acc := acc * cur END Mul; PROCEDURE Div(VAR acc: LONGINT; cur: INTEGER); BEGIN acc := acc DIV cur END Div; PROCEDURE Greater(VAR acc: BOOLEAN; a, b: INTEGER); BEGIN acc := acc & (a > b) END Greater; PROCEDURE Less(VAR acc: BOOLEAN; a, b: INTEGER); BEGIN acc := acc & (a < b) END Less; PROCEDURE ReduceLong(IN nums: ARRAY OF INTEGER; c: CalculatorLong): LONGINT; VAR i: INTEGER; acc: LONGINT; BEGIN acc := nums[0]; FOR i := 1 TO LEN(nums) - 1 DO c(acc, nums[i]) END; RETURN acc; END ReduceLong; PROCEDURE ReduceBool(IN nums: ARRAY OF INTEGER; c: CalculatorBool): BOOLEAN; VAR i: INTEGER; acc: BOOLEAN; BEGIN acc := TRUE; i := 1; REPEAT c(acc, nums[i-1], nums[i]); INC(i); UNTIL (i = LEN(nums)) OR ~acc; RETURN acc; END ReduceBool; PROCEDURE Start*; VAR sn: ARRAY 5 OF INTEGER; (* sn - some nums *) orderedNums: ARRAY 3 OF INTEGER; sum, mul: LONGINT; greater, less: BOOLEAN; BEGIN sn[0] := 1; sn[1] := 3; sn[2] := 5; sn[3] := 7; sn[4] := 9; sum := ReduceLong(sn, Add); Out.String('sum = '); Out.Int(sum); Out.Ln; mul := ReduceLong(sn, Mul); Out.String('mul = '); Out.Int(mul); Out.Ln; orderedNums[0] := 7; orderedNums[1] := 5; orderedNums[2] := 1; greater := ReduceBool(orderedNums, Greater); Out.String('greater = '); Out.Bool(greater); Out.Ln; less := ReduceBool(orderedNums, Less); Out.String('less = '); Out.Bool(less); Out.Ln; END Start; END FunctionalCalculator. ==== Важные замечания ==== Если переменной процедурного типа не присвоить значение, она будет иметь значение **NIL**.