- •Процедуры и функции
- •Процедуры
- •Пример Вызов процедуры InpInt для ввода k целых чисел в массив m.
- •Функции
- •Формальные и фактические параметры
- •Параметры-значения Параметры-значения передаются основной программой в подпрограмму через стек в виде их копий. Сам параметр программы подпрограммой измениться не может.
- •Параметры-переменные
- •Этот вариант лучше предыдущего, так как в стеке не создается копия исходного массива, что улучшает быстродействие и экономит память.
- •Локализация имен
- •Пример Структура вложенной программы.
- •Основное правило Паскаля
- •Допустимые вызовы процедуры
- •Совместимость и преобразование типов данных
- •Параметры-массивы и строки открытого типа
- •Процедурные типы
- •Проблема совместимости
- •Рекурсия
- •Побочный эффект
- •Рекурсивная функция
- •Стеки для локальных переменных и параметров
- •Реализация стеков параметров в Паскале
Параметры-массивы и строки открытого типа
7.0-версия использует открытые параметры-переменные подпрограммы: массивы и строки. Открытые массивы - это параметры-массивы подпрограммы, размер которых не указывается в списке формальных параметров заголовка подпрограммы.
Пример Объявление открытого одномерного массива
function Sum(var a: array of byte): byte;
var в объявлении параметра открытого типа обязательно.
Фактическим параметром открытого массива может быть массив любого размера. Тип элементов фактического массива должен совпадать с типом массива-формального параметра.
В качестве открытых массивов могут использоваться только одномерные массивы. Внутри подпрограмм границы переданного массива могут определяться с помощью функций Low и High.
function Low(x:<тип>):word;
Возвращает минимальное значение величины;
x – параметр или идентификатор порядкового типа, типа-массива, типа-строки или открытого массива.
function High (x:<тип>):word;
Возвращает максимальное значение величины;
x – параметр или идентификатор порядкового типа, типа-массива, типа-строки или открытого массива.
Обращение к Low всегда будет давать 0, а результат функции High – верхнее возможное значение индекса при обращении к массиву относительно нуля, независимо от значений границ массива, передаваемого в подпрограмму.
Напомним, как передавались в подпрограмму массивы.
type
arr=array[1...10] of byte;
…..
procedure P(var a: arr);
begin
…..
end;
Определён в программе тип arr и затем в заголовке подпрограммы объявлена переменная А указанного типа. После такого объявления процедуры Р в качестве в качестве фактического параметра при ее вызове мог фигурировать только массив, описанный при помощи того же самого( из-за именной эквивалентности типа) типа arr, т.е.
var
A1, A2: Arr;
…..
P(A1);
…..
P(A2)
Таким образом, процедура Р может работать только с массивами из десяти элементов типа byte, «пронумерованных» от 1 до 10. Это сильно ограничивает универсальность процедуры.
Параметры-массивы открытого типа существенно расширяют возможности, т.к. в массиве – формальном параметре подпрограммы возможно не задавать его границы.
Пример Программа подсчета суммы элементов разных массивов с использованием в процедуре формального параметра-открытого массива.
Возможные пути решения задачи подсчета суммы элементов разных массивов:
-
написание отдельных суммирующих функций;
-
использование нетипизированных (бестиповых) параметров;
-
использование открытых массивов.
program OtkrPar;
type
ta1=array[1..5] of byte;
ta2=array[0..2] of byte;
ta3=array[-2..2] of byte;
const
a1:ta1=( 1, 2, 3, 4, 5);
a2:ta2=( 7, 8, 9);
a3:ta3=( 1, 2, 3, 4, 5);
procedure p(var a: array of byte);
var
i,s:word;
begin
s:=0;
for i:=low(a) to high(a) do begin
s:=s+a[i];
write(‘ ‘, i ,’ ‘,a[i]); end;
writeln(‘s= ‘,s);
end;
begin
p(a1); p(a2); p(a3);
end.
Результат выполнения программы program OtkrPar.
Вывод на экран:
0 1 1 2 2 3 3 4 4 5 s=15
0 7 2 8 3 9 s=24
0 1 1 2 2 3 3 4 4 5 s=15
Программа иллюстрирует интерпретацию граничных значений и индексов открытых массивов.
Остановимся на механизме открытых строк. Во многом они аналогичны открытым массивам и позволяют передавать в подпрограммы строки произвольной длины.
Директива {$V+/-}-проверка строковых параметров.
Если использовать ключ{$V+}, то при обращении к подпрограммам и передаче ей параметров типа string фактические и формальные параметры должны быть идентичными.
Если использовать ключ{$V-}, то формальные и фактические параметры могут быть строками разного типа, в том числе разной длины. Ключ являются локальным.
По умолчанию используется ключ {$V+}. Эквивалентное меню Options/Compiler/Strict var-strings.
В 7.0 версии есть директива {$P+/-} –использование в качестве параметров массивов открытого типа. Она ориентирована специально на поддержку открытых строк. По умолчанию используется ключ{$P-}. Эквивалентное меню Options/Compiler/Open parameters.
Если в программе установили {$P-}, то var-параметры подпрограммы, имеющие тип string, считаются обычными параметрами, передаваемыми по ссылке; для них действительны обычные правила эквивалентности типов.
Если в программе задана директива {$P+}, то var-параметры подпрограмм, имеющие тип string, считаются открытыми параметрами. Это означает, что независимо от установки директивы {$V+/-} в качестве фактического параметра подпрограмме можно передать переменную любого строкового типа.
При этом внутри подпрограммы размер (максимальная длина) строки – формального параметра всегда будет совпадать с размером фактического параметра.
Пример
{$P+}
program TestOpen;
uses crt;
var
s1:string;
s2:string[10];
procedure p(var s: string);
begin
writeln(‘s= ‘,sizeof(s),’ ‘,’l=’, length(s))
end;
begin
s1:=’abs’; p(s1);
s2:=’xxxxxxxxxx’; p(s2);
end.
function size of(x):word;
Возвращает размер аргумента в байтах;
х-переменная любого типаили любой тип.
function length (s:string):integer;
Возвращает текущий размер строки;
S-строка, у которой определяется размер.
Результат выполнения программы program TestOpen.
Вывод на экран:
S=256 L=3
S=11 L=10
Внутри процедуры Р размер открытой строки всегда будет соответствовать реально переданной в ней фактической строки.
Установим {$V-}.
Тогда
S=256 L=3
S=256 L=10
В этом случае внутри процедуры Р строка-параметр всегда трактуется по «максимуму», независимо от того, какой фактический параметр реально ей передан.
По существу, директива {$V-} просто снимает контроль за соответствием типов и за корректностью присваивания строковым var-параметрам, что может привести к тяжелым ошибкам во время исполнения.
Механизм открытых строк, предоставляет большую гибкость при передаче параметров, сохраняет полный контроль за их использованием.
Дополнение Версия 7.0 содержит специальный стандартный строковый тип с именем openstring, который указывать вместо любого строкового типа при спецификации параметров подпрограмм.
Использование типа openstring включает механизм открытых строк для данного параметра независимо от текущей установки директивы {$P+/-}.
Пример
procedure p(var s: openstring);
begin
writeln(‘s=’, sizeof(s),’L=’,length(s));
end;