Каким символом разделяются перечень разнотипных формальных параметров в процедуре
Pascal | Лекция №6
Подпрограммы. Процедуры и функции
СОДЕРЖАНИЕ:
Подпрограммы (см. Рапаков стр.143-157!)
Понятие подпрограмма встречается во многих языках программирования, т.к. является основным средством структурирования языка. Очень часто в программах встречаются однотипные участки, которые выполняют одни и те же вычисления с различными данными. Такие части программ целесообразно выполнять с помощью подпрограмм.
Использование подпрограмм позволяет:
Таким образом, подпрограмма – это часть операторов программы, выделенных в группу, оформленную в виде отдельной конструкции.
Вызов подпрограммы, т.е. выполнение действий, заданных в подпрограмме, может быть произведен в некоторой точке программы посредством указания имени этой подпрограммы.
Структура подпрограмм
Структура подпрограмм почти в точности повторяет структуру всей Pascal-программы.
При описании подпрограммы в общем случае необходимо задать три основные компоненты:
Интерфейс подпрограммы содержится в заголовке и говорит о том, что именно делает подпрограмма.
Две остальные компоненты называются телом подпрограммы и содержат информацию о том, как выполняется подпрограммой то, что описано в ее заголовке.
В языке Pascal выделяют два вида подпрограмм: процедуры и функции. Различия процедур и функций заключается в назначении и способе их использования.
Функции нужны для вычисления нового значения некоторого выражения, и вызов функции должен быть операндом в выражении.
Процедуры служат для задания последовательности действий и определения новых значений переменных в программе. Вызов процедуры играет роль оператора.
Описание процедур и функций. Формальные параметры
Описание процедур и функций в общем виде:
Тело подпрограммы – это блок, состоящий из двух частей: описание объектов и группа операторов. Более полный общий вид процедуры (общий вид функции отличается только заголовком):
Здесь — имя процедуры.
Раздел описаний, как и в основной программе, может включать разделы Label, Const, Type, Var и раздел процедур и функций.
Формальные параметры представляют собой список переменных с указанием их типа, которые отделяются друг от друга «;». Эти переменные не описываются в разделе описания процедур. Допускается использование процедур без параметров.
Если в качестве параметров используется массив, то предварительно нужно описать имя типа массива в разделе Type, а затем использовать это имя при описании массива в качестве формального параметра.
Параметры процедур бывают двух типов:
Описание входных параметров процедуры в списке формальных параметров имеет также вид:
Список переменных1: тип1; список переменных2: тип2;
Соответственно описание выходных параметров выглядит следующим образом:
Var Список переменных1: тип1; Var список переменных2: тип2;
Вызов процедуры в основной программе имеет следующий вид:
(список фактических параметров);
Фактические параметры перечисляются через запятую, без указания их типа. Идентификаторы формальных параметров можно считать условными обозначениями в теле подпрограммы тех реальных, фактических параметров, с которыми будет вызвана подпрограмма. При этом должны выполняться требования:
Имена соответствующих фактических и формальных параметров могут быть одинаковыми или разными.
Входными фактическими параметрами могут быть константы, переменные или выражения, выходными фактическими параметрами могут быть только переменные.
Другой вид подпрограммы в языке Турбо-Паскаль – функция – оформляется аналогично процедуре и отличается от нее по структуре только заголовком, общий вид которого выглядит следующим образом:
Function (список формальных параметров): тип;
Функции имеют несколько отличительных особенностей:
Область действия имен
Переменные, представленные в разделе описания основной программы, могут быть использованы в теле основной программы и в любой ее подпрограмме. Эти переменные называются глобальными.
Переменные, описанные в подпрограмме, действуют только в теле данной подпрограммы и в любой, объявляемой внутри нее, подпрограмме. Такие переменные называются локальными. Они недоступны для операторов основной программы и др. подпрограмм.
Наглядно схему программы, имеющей некоторые вложенные подпрограммы, можно представить следующим образом:
Самый внешний блок программы обозначен буквой A (имена этого блока «видны» во всех остальных блоках), B и D – подпрограммы, описанные во внешнем блоке, C – подпрограмма, описанная в блоке B (объекты этого блока известны только внутри самого блока).
При написании программ, имеющих вложенные подпрограммы, необходимо соблюдать следующие правила:
Использование процедур и функций на примере
Пример 1: вычислить площадь выпуклого четырехугольника
В результате выполнения данной программы на экран будет выведено:
Список формальных параметров
Параметры, описанные в заголовке подпрограммы, называются формальными.
(value: integer) (X, Y: Real) (st:string; n:integer; c,fill:char) |
Список формальных параметров – это последовательность объявлений однотипных параметров. Объявления отделяются друг от друга точкой с запятой. Каждое объявление состоит из списка имен параметров, символа ‘:’ и указания их типа. Внутри объявления имена параметров разделяются запятой. Имя параметра – это корректный идентификатор.
Существует два способа передачи параметра в подпрограмму: по значению(параметры-значения) или по ссылке. Для передачи параметра по ссылке рядом с именем параметра используется одно из зарезервированных слов: var (параметры-переменные), const (параметры-константы), out (выходные параметры). Например:
(var S: string; X: Integer)(const P; I: Integer) |
Чтобы почувствовать разницу в способах передачи параметров, обратимся к следующим примерам (из Help):
function DoubleByValue(X: Integer): Integer; // X is a value parameter begin X := X * 2; Result := X; end; function DoubleByRef(var X: Integer): Integer; // X is a variable parameter begin X := X * 2; Result := X; end; |
Эти функции возвращают одинаковый результат, но только вторая может изменять значение параметра, переданного в подпрограмму. Вызовем эти функции:
Var I, J, V, W: Integer; begin I := 4; V := 4; J := DoubleByValue(I); // J = 8, I = 4 W := DoubleByRef(V); // W = 8, V = 8 end; |
Параметры-значения можно рассматривать как локальные переменные, которые получили начальное значение при вызове подпрограммы. Если вы передали какую-нибудь переменную как параметр-значение, то подпрограмма создает копию переменной. Изменения этой копии не приводят к изменению исходной переменной и утериваются после завершения работы подпрограммы.
Параметры-переменные похожи скорее на указатели. Изменения такого параметра внутри тела процедуры или функции сохраняются после завершения работы подпрограммы и возвращаются в вызывающую программу.
Назначение зарезервированных слов:
Ключевое слово | |
Var | Можно использовать для передачи данных в подпрограмму и для получения данных из подпрограммы |
Const | Нельзя изменять значение в теле подпрограммы. Похож на локальную переменную только для чтения. |
Out | Нельзя использовать для передачи данных в подпрограмму. Используется только для получения данных из подпрограммы. |
Для параметров-значений и параметров-констант возможно указание в заголовке процедуры или функции значения по умолчанию. Для этого в объявлении параметра после типа используется ‘=’ и указывается само значение (константное выражение совместимого типа). Например:
(var S: string; X: Integer = 5)(const P, I: Integer; const M: real = 4.5) |
Для параметров, передающихся по ссылке, можно не указывать тип параметра. Такие параметры называются нетипизированными. Параметр-значение обязательно типизирован. Примеры:
(var S, X; out Z)(const P, I; var M) |
Внутри подпрограммы непизированные параметры несовместимы ни с какими типами. Необходимо выполнить приведение типов.
Локальные объявления
Тело процедуры или функции часто начинают с объявления локальных переменных, которые используются внутри подпрограммы. Эти объявления могут также включать константы, типы, другие подпрограммы. Область видимости локальных идентификаторов ограничена подпрограммой, где они объявлены.
Процедуры и функции иногда содержат в секции локальных объявлений другие функции и процедуры, так называемые вложенные. Например:
procedure DeleteRandomSymbol(var S: string); function RandomNumber(S: string):integer; var LenString: Integer; Begin LenString:=Length(s); Result:= Random(LenString) + 1; end; begin Delete(S, RandomNumber(s), 1); end; |
Область видимости вложенных подпрограмм ограничена подпрограммой, внутри которой они объявлены. В примере функцию RandomNumber можно вызывать только внутри процедуры DeleteRandomSymbol.
Тип возвращаемого значения
Понятие возвращаемого значения имеет смысл только тогда, когда мы говорим о функции, так как процедура не возвращает значения. Функции возвращают значения любых типов данных кроме Text и file of.
В теле функции должен быть, по крайней мере, один оператор, присваивающий значение имени функции или неявной локальной переменной Result. Если такого оператора нет, то значение функции будет не определено.
Var A, G: Double; procedure Average(const X, Y: Double; out M, P: Double);begin M := (X + Y) / 2; P := Sqrt(X * Y);end; procedure TForm1.Button1Click(Sender:Tobject);begin Average(10, 20, A, G); ShowMessage(‘Среднее арифметическое = ‘, FloatToStr(A)); ShowMessage(‘Среднее геометрическое = ‘, FloatToStr(G));End; end. |
При вызове подпрограмм необходимо помнить следующее:
1. Выражения, используемые для передачи в типизированные параметры-константы и в параметры-значения должны быть совместимыми по присваиванию с соответствующими формальными параметрами.
2. Выражения, используемые для передачи в параметры-переменные и в выходные параметры должны быть одинаковых с соответствующими формальными параметрами типов, исключая непизированные параметры.
3. На место параметров, передаваемых по ссылке можно подставлять только переменные, нельзя – числа и константы.
4. Если список формальных параметров отсутствует, то список фактических параметров (в том числе круглые скобки) не указывается.
5. Если вызывается подпрограмма с параметрами по умолчанию, то все фактические параметры по умолчанию, идущие перед тем параметром, который необходимо передать значение, отличное от умолчания, должны быть заполнены. Например, SomeFunction(,,X) – некорректен
Различные способы передачи параметров в подпрограмму. Передача параметров-массивов в подпрограмму. Передача параметров, значения которых заданы по умолчанию. Примеры.
Pascal: Занятие № 7. Подпрограммы: процедуры в Pascal
Процедуры в Паскале
Подпрограмма — это фрагмент кода, который имеет свое имя и создается в случае необходимости выполнять этот код несколько (много) раз. Подпрограмма описывается единожды перед началом основной программы (до begin ). Компилятор пропускает данный фрагмент кода, пока в основной программе не встретит «вызов» подпрограммы, который выглядит как обращение к ней по имени (возможно, имени с аргументами, указанными в скобках).
Во многих языках программирования подпрограммы существуют только в виде функций. Однако в Паскале подпрограмма — и функция и процедура. Разница между ними станет очевидна в данном уроке.
Итак, рассмотрим синтаксис объявления и описания процедуры в Паскале
procedure pr; var i:integer; begin for i:=1 to 60 do begin <тело подпрограммы>write(‘*’); writeln; end; end; <конец подпрограммы>begin pr; <вызов процедуры>end.
В данном примере работы с процедурой в Паскале очевидно, что компилятор пропустит блок описания процедуры и дойдет до основной программы (9 строка кода). И только после того, как встретится вызов процедуры (10 строка), компилятор перейдет к ее выполнению, вернувшись к строке 1.
Процедуры с параметрами. Фактические и формальные параметры
Рассмотрим пример необходимости использования процедуры.
Особенность: Три похожие фигуры.
Алгоритм решения:
Решение на паскале:
Процедура:
uses GraphABC; procedure Tr( x, y: integer; color:system.Drawing.Color); begin MoveTo(x, y); LineTo(x, y-60); LineTo(x+100, y); LineTo(x, y); FloodFill(x+20, y-20,color); end; begin SetPenColor(clBlack); Tr(100, 100, clBlue); Tr(200, 100, clGreen); Tr(200, 160, clRed); end.
Рассмотрим синтаксис объявления и описания процедуры с параметрами в Паскале.
Параметры процедуры (в некоторых языках они называются аргументами) указываются в скобках после ее имени (в объявлении).
В данном примере в качестве введенного символа будем использовать параметр процедуры. Формальный параметр процедуры указывается в скобках при ее описании. Обязательно необходимо указать тип формального параметра через двоеточие.
Фактический параметр — это то значение, которое указывается в скобках при вызове процедуры. Фактическим параметром может быть конкретное значение (литерал: число, символ, строка…) либо переменная, которые компилятор подставит вместо формального параметра. Поэтому тип данных у формального и фактического параметра процедуры должен быть одинаковым.
Процедуры с параметрами. Параметр-переменная
В примере формальные параметры a и b служат для помещения в них сравниваемых чисел, а параметр-переменная max — для сохранения в ней максимального из двух чисел. Параметр-переменная или выходной параметр передает свое значение в основную программу (фактическому параметру m ), т.е. возвращает значение, тогда как формальные параметры-значения (входной параметр), наоборот, принимают значения из основной программы (из фактических параметров x и y ). Для параметра-переменной ( max ) используются те ячейки памяти, которые отведены под соответствующий параметр при вызове процедуры (ячейка m ).
Таким образом, сформулируем понятия:
Если в качестве формального параметра указана обычная переменная с указанием ее типа, то такой параметр есть параметр-значение или входной параметр ( a и b в примере). Тип данных формального параметра-значения должен соответствовать типу данных его фактического параметра ( a и b должны попарно соответствовать типу данных x и y ).
Если перед именем формального параметра в объявлении процедуры стоит служебное слово var, то такой параметр называется параметром-переменной или выходным параметром ( max в примере). Для него используются те ячейки памяти, которые отведены под соответствующий параметр при вызове процедуры ( m ). Фактический параметр, соответствующий параметру-переменной, может быть только переменной (не константой, не литералом и не выражением).
Словесный алгоритм:
В задачах на Паскале часто встречается необходимость заполнить массив данными и затем вывести значения на экран. Почему бы не автоматизировать данную задачу заполнения и вывода массива — т.е. оформить при помощи процедур, а в дальнейшем использовать данные процедуры при надобности.
const n = 10; var i:integer; a, b: array[1..n] of integer; procedure arr_out (k:integer; arr: array[1..n] of integer); var i: byte; begin write (‘вывод массива: ‘); for i := 1 to k do write (arr[i]:4); writeln; end; begin for i:=1 to n do a[i]:=random(10); arr_out (n, a); end.
Пояснение:
Тело основной программы:
— формирование элементов массива (с функцией random ).
— вызов процедуры с двумя параметрами: количество элементов, массив.
Тело процедуры:
— вывод элементов массива с использованием параметров
Продолжим нашу задачу:
const n = 10; var a, b: array[1..n] of integer; procedure arr_rand (k:integer; var arr: array[1..n] of integer); var i: byte; begin write (‘Заполнение массива случайными числами ‘); randomize; for i := 1 to k do arr[i]:=random(100); end; begin arr_rand (n, a); end.
Самостоятельная работа
X и Y — входные параметры, AMean и GMean — выходные параметры вещественного типа.
В основной программе: Для заданных A, B, C, D найти среднее арифметическое и среднее геометрическое для пар (A, B), (A, C), (A, D), используя созданную процедуру.
1 вариант: для 5 одномерных массивов определять произведение элементов каждого массива, используя процедуру с двумя параметрами — число элементов массива и параметр-переменная для вывода произведения.
2 вариант: для 5 одномерных массивов определять минимальный элемент каждого массива, используя процедуру с двумя параметрами — число элементов массива и параметр-переменная для вывода минимального элемента.
Подпрограммы
В практике программирования часто складываются ситуации, когда одну и ту же группу операторов, реализующих определённую цель, требуется повторить без изменений в нескольких местах программы. Для избавления от столь нерациональной траты времени была предложена концепция подпрограммы.
4.1 Общие сведения о подпрограммах. Локальные и глобальные переменные
Для правильного определения области действия идентификаторов (переменных) необходимо придерживаться следующих правил:
4.2 Формальные и фактические параметры. Передача параметров в подпрограмму
Обмен информацией между вызываемой и вызывающей функциями осуществляется с помощью механизма передачи параметров. Переменные, указанные в списке в заголовке функции, называются формальными параметрами, или просто параметрами подпрограммы. Все переменные из этого списка могут использоваться внутри подпрограммы. Список переменных в операторе вызова подпрограммы — это фактические параметры, или аргументы.
Механизм передачи параметров обеспечивает обмен данных между формальными и фактическими параметрами, что позволяет выполнять подпрограмму с различными данными. Между фактическими параметрами в операторе вызова и формальными параметрами в заголовке подпрограммы устанавливается взаимно однозначное соответствие. Количество, типы и порядок следования формальных и фактических параметров должны совпадать.
Формальные параметры процедуры можно разделить на два класса: параметры-значения и параметры-переменные.
При передаче данных через параметры-значения в подпрограмму передаются значения фактических параметров, и доступа к самим фактическим параметрам из подпрограммы нет. При передаче данных параметры-переменные заменяют 1 Реально в подпрограмму передаются адреса фактических параметров. формальные параметры, и, следовательно, в подпрограмме есть доступ к значениям фактических параметров. Любое изменение параметров-переменных в подпрограмме приводит к изменению соответствующих им формальных параметров. Следовательно, входные данные следует передавать через параметры-значения, для передачи изменяемых в результате работы подпрограммы данных следует использовать параметры-переменные.
От общетеоретических положений перейдём к практическому использованию подпрограмм при решении задач. Изучение подпрограмм начнем с процедур.
4.3 Процедуры
Описание процедуры имеет вид:
procedure name_1( r : real; i : integer; c : char );
Однотипные параметры могут быть перечислены через запятую:
procedure name_2( a, b : real; i, j, k : integer );
Список формальных параметров необязателен и может отсутствовать:
Если в заголовке процедуры будут применяться параметры-переменные, то перед ними необходимо указывать служебное слово var :
procedure name_4( x, y : real; var z : real );
Для обращения к процедуре необходимо использовать оператор вызова:
Фактические параметры в списке оператора вызова отделяются друг от друга запятой:
a : = 5. 3; k : = 2; s := ’ a ’;
Если в описании процедуры формальные параметры отсутствовали, то и при вызове их быть не должно:
Алгоритм решения этой задачи был подробно описан в задаче 3.3 (рис. 3.14). Однако там не была рассмотрена ситуация некорректного ввода значений коэффициентов. Например, если пользователь введёт , то уравнение из квадратного превратится в линейное. Алгоритм решения линейного уравнения тривиален:
, при условии, что
. Чтобы не усложнять уже составленный алгоритм решения квадратного уравнения, запишем его в виде подпрограммы-процедуры. Далее приведён фрагмент программы с комментариями:
TURBO PASCAL
Процедуры и функции позволяют включать в основной программный блок дополнительные блоки. Каждое описание процедуры или функции содержит заголовок, за которым следует программный блок. Процедура активизируется с помощью оператора процедуры. Функция активизируется при вычислении выражения, содержащего вызов функции, и возвращаемое функцией значение подставляется в это выражение.
Примечание: Определение блока вы можете найти в Главе 8 «Блоки, локальность и область действия».
В данной главе обсуждаются различные способы описания процедуры или функции и их параметры.
Описания процедур
Описание процедуры позволяет связать идентификатор с процедурным блоком. Процедуру можно затем активизировать с помощью оператора процедуры.
Заголовки процедур именуют идентификаторы процедур и задают формальные параметры (если они имеются).
Примечание: Синтаксис списка формальных параметров показан далее в этой главе в разделе «Параметры».
Процедура активизируется с помощью оператора процедуры, в котором содержатся имя процедуры и необходимые параметры. Операторы, которые должны выполняться при запуске процедуры, содержатся в операторной части модуля процедуры. Если в содержащемся в процедуре операторе внутри модуля процедуры используется идентификатор процедуры, то процедура будет выполняться рекурсивно (будет при выполнении обращаться сама к себе).
Приведем пример описания процедуры:
procedure NumString(N: integer; var S: string);
S := Chr(N mod 10 + Ord(‘0’)) + S; N := N div 10;
Описания функций
Описание функции определяет часть программы, в которой вычисляются и возвращается значение.
Примечание: Функция не может возвращать процедурный тип или структурный тип.
В заголовке функции определяется идентификатор функции, формальные параметры (если они имеются) и тип результата функции.
Функция активизируется при вызове функции. При вызове функции указывается идентификатор функции и какие-либо параметры, необходимые для вычисления функции. Вызов функции может включаться в выражения в качестве операнда. Когда выражение вычисляется, функция выполняется и значением операнда становится значение, возвращаемое функцией.
В операторной части блока функции задаются операторы, которые должны выполняться при активизации функции. В модуле должен содержаться по крайней мере один оператор присваивания, в котором идентификатору функции присваивается значение. Результатом функции является последнее присвоенное значение. Если такой оператор присваивания отсутствует или он не был выполнен, то значение, возвращаемое функцией, не определено.
Если идентификатор функции используется при вызове функции внутри модуля-функции, то функция выполняется рекурсивно.
Приведем далее примеры описаний функции:
function Max(a: Vector; n: integer): extended;
for i := 2 to n do if x
function Power(x: extended; y: integer): extended;
if Odd(i) then z := z*x;
Аналогично процедурам функции могут описываться, как с ближним типом вызова (near), с дальним типом вызова (far), опережающие (forward), внешние (external), ассемблерные (assembler) или подставляемые (inline). Однако функции прерываний (interrupt) не допускаются.
Параметры
В описании процедуры или функции задается список формальных параметров. Каждый параметр, описанный в списке формальных параметров, является локальным по отношению к описываемой процедуре или функции и в модуле, связанным с данной процедурой или функцией на него можно ссылаться по его идентификатору.
Существует три типа параметров: значение, переменная и нетипизированная переменная. Они характеризуются следующим:
1. Группа параметров без предшествующего ключевого слова является списком параметров-значений.
2. Группа параметров, перед которыми следует ключевое слово const и за которыми следует тип, является списком параметров-констант.
3. Группа параметров, перед которыми стоит ключевое слово var и за которыми следует тип, является списком типизированных параметров-переменных.
4. Группа параметров, перед которыми стоит ключевое слово var или const за которыми не следует тип, является списком нетипизированных параметров-переменных.
Примечание: Подробнее об открытых параметрах рассказывается ниже.
Параметры-значения
Формальный параметр-значение обрабатывается, как локальная по отношению к процедуре или функции переменная, за исключением того, что он получает свое начальное значение из соответствующего фактического параметра при активизации процедуры или функции. Изменения, которые претерпевает формальный параметр-значение, не влияют на значение фактического параметра.
Соответствующее фактическое значение параметра-значения должно быть выражением и его значение не должно иметь файловый тип или какой-либо структурный тип, содержащий в себе файловый тип.
Фактический параметр должен иметь тип, совместимый по присваиванию с типом формального параметра-значения. Если параметр имеет строковый тип, то формальный параметр будет иметь атрибут размера, равный 255.
Параметры-константы
Формальные параметры-константы работают аналогично локальной переменной, доступной только по чтению, которая получает свое значение при активизации процедуры или функции от соответствующего фактического параметра. Присваивания формальному параметру-константе не допускаются. Формальный параметр-константа также не может передаваться в качестве фактического параметра другой процедуре или функции.
Параметр-константа, соответствующий фактическому параметру в операторе процедуры или функции, должен подчиняться тем же правилам, что и фактическое значение параметра.
В тех случаях, когда формальный параметр не изменяет при выполнении процедуры или функции своего значения, вместо параметра-значения следует использовать параметр-константу. Параметры-константы позволяют при реализации процедуры или функции защититься от случайных присваиваний формальному параметру. Кроме того, для параметров структурного и строкового типа компилятор при использовании вместо параметров-значений параметров-констант может генерировать более эффективный код.
Параметры-переменные
Параметр-переменная используется, когда значение должно передаваться из процедуры или функции вызывающей программе. Соответствующий фактический параметр в операторе вызова процедуры или функции должен быть ссылкой на переменную. При активизации процедуры или функции формальный параметр-переменная замещается фактической переменной, любые изменения в значении формального параметра-переменной отражаются на фактическом параметре.
Внутри процедуры или функции любая ссылка на формальный параметр-переменную приводит к доступу к самому фактическому параметру. Тип фактического параметра должен совпадать с типом формального параметра-переменной (вы можете обойти это ограничение с помощью нетипизированного параметра-переменной).
Примечание: Файловый тип может передаваться только, как параметр-переменная.
При ссылке на фактический параметр-переменную, связанную с индексированием массива или получением указателя на объект, эти действия выполняются перед активизацией процедуры или функции.
Правила совместимости по присваиванию для объектного типа применяются также к параметрам-переменным объектного типа. Для формального параметра типа T1 фактический параметр должен быть типа T2, если T2 находится в домене T1. Например, с учетом описаний Главы 4, методу TField.Copy может передаваться экземпляр TField, TStrField, TNumField, TZipField или любой другой экземпляр потомка TField.
Нетипизированные параметры
Когда формальный параметр является нетипизированным параметром-переменной, то соответствующий фактический параметр может представлять собой любую ссылку на переменную или константу, независимо от ее типа. Нетипизированный параметр, описанный с ключевым словом var, может модифицироваться, а нетипизированный параметр, описанный с ключевым словом const, доступен только по чтению.
В процедуре или функции у нетипизированного параметра-переменной тип отсутствует, то есть он несовместим с переменными всех типов, пока ему не будет присвоен определенный тип с помощью присваивания типа переменной.
Приведем пример нетипизированных параметров-переменных:
function Equal(var source,dest; size: word): boolean;
Bytes = array[0..MaxInt] of byte; var
while (N Bytes(source)[N]
Equal := N = size; end;
Эта функция может использоваться для сравнения любых двух переменных любого размера. Например, с помощью описаний:
Vector = array[1..10] of integer;
сравнивается Vес1 с Vес2, сравниваются первые N элементов Vес1 с
первыми N элементами Vес2, сравниваются первые 5 элементов Vес1 с
последними пятью элементами Vес2 и сравниваются Vес1[1] с Р.х и
Хотя нетипизированные параметры дают вам большую гибкость, их использование сопряжено с некоторым риском. Компилятор не может проверить допустимость операций с нетипизированными переменными.
Открытые параметры
Открытые параметры позволяют передавать одной и той же процедуре или функции строки и массивы различных размеров.
Открытые строковые параметры
Открытые строковые параметры могут описываться двумя способами:
· с помощью идентификатора OpenString;
Идентификатор OpenString описывается в модуле System. Он обозначает специальный строковый тип, который может использоваться только в описании строковых параметров. В целях обратной совместимости OpenString не является зарезервированным словом и может, таким образом, быть переопределен как идентификатор, заданный пользователем.
Для открытого строкового параметра фактический параметр может быть переменной любого строкового типа. В процедуре или функции атрибут размера (максимальная длина) формального параметра будет тем же, что у фактического параметра.
Открытые строковые параметры ведут себя также как параметры-переменные строкового типа, только их нельзя передавать как обычные переменные другим процедурам или функциям. Однако, их можно снова передать как открытые строковые параметры.
procedure AssignStr(var S: OpenString;
S := ‘0123456789ABCDEF’; end;
AssignStr(S1); S1 := ‘0123456789’
AssignStr(S2); S2 := ‘0123456789ABCDEF’
В AssingStr максимальная длина параметра S та же самая, что у фактического параметра. Таким образом, в первом вызове AssingStr при присваивании параметра S строка усекается, так как максимальная длина S1 равна 10.
При применении к открытому строковому параметру стандартная функция Low возвращает 0, стандартная функция High возвращает описанную максимальную длину фактического параметра, а функция SizeOf возвращает размер фактического параметра.
В следующем примере процедура FillString заполняет строку заданным символом до ее максимальной длины. Обратите внимание на использование функции High для получения максимальной длины открытого строкового параметра.
procedure FillStr(var S: OpenString; Ch: Char);
S[0] := Chr(High(S)); задает длину строки
FillChar(S[1], High(S), Ch); устанавливает число символов
Открытые параметры-массивы
Формальный параметр, описанный с помощью синтаксиса:
является открытым параметром-массивом. T должно быть идентификатором типа, а фактический параметр должен быть переменной типа T, или массивом, типом элементов которого является T. В процедуре или функции формальный параметр ведет себя так, как если бы он был описан следующим образом:
К открытому формальному параметру-массиву можно обращаться только по элементам. Присваивания всему открытому массиву не допускаются, и открытый массив может передаваться другим процедурам или функциям только как открытый параметр-массив или нетипизированный параметр-переменная.
Открытый параметр-массив может быть параметром-значением, параметром-константой и параметром-переменной и имеет тот же смысл, что и обычные параметры-значения, параметры-константы и параметры-переменные. В частности, присваивания элементам формального открытого массива-константы не допускаются, а присваивания элементам формального открытого массива, являющегося параметром-значением, не влияют на фактический параметр.
Для открытых массивов-значений компилятор создает в кадре стека процедуры или функции локальную копию фактического параметра. Таким образом, при передаче в качестве открытых параметров-значений больших массивов следует учитывать возможное переполнение стека.
При применении к открытому параметру-массиву стандартная функция Low возвращает 0, стандартная функция High возвращает индекс последнего элемента в фактическом параметре-массиве, а функция SizeOf возвращает размер фактического параметра-массива.
Процедура Clear в следующем примере присваивает каждому элементу массива вещественных значений ноль, а функция Sum вычисляет сумму всех элементов массива вещественных чисел. Поскольку в обоих случаях параметр A является открытым параметром-массивом, подпрограммы могут работать с любым массивом элементов типа Real:
procedure Clear(var A: array of Real);
for I := 0 to High(A) do A[I] := 0; end;
function Sum(const A: array of Real): Real;
for I := 0 to High(A) do S := S + A[I];
Когда типом элементов открытого параметра-массива является Char, фактический параметр может быть строковой константой. Например, с учетом предыдущего описания:
procedure PringStr(const S: array of Char);
for I := 0 to High(S) do
if S[I] <> #0 then Write(S[I]) else Break;
и допустимы следующие операторы процедур:
При передаче в качестве открытого параметра-массива пустая строка преобразуется в строку с одним элементом, содержащим символ NULL, поэтому оператор PrintStr(») идентичен оператору PrintStr(‘#0’).
(с) Все права защищены.
По всем интересующим вопросам прошу писать электронный адрес