Формальные параметры


Структура функции

Структура процедуры

Описание подпрограммы начинается с ее объявления. В случае процедур объявление выглядит следующим образом.

procedure <имя-процедуры> (<параметры>);

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

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

label <метки>;

const <описания констант>;

type <определения типов данных>;

var <описания переменных>;

<процедуры и функции>

begin

<основное тело процедуры>;

end;

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

Описания двух различных подпрограмм не могут пересекаться: каждый блок должен быть логически законченным.

Пример: написать программу, которая печатает на экране слово МАМА (в столбик).

program mama;

procedure M;

begin

writeln(‘** **’);

writeln(‘* * * *’);

writeln(‘* * *’);

writeln(‘* *’);

writeln(‘* *’);

end;

procedure A;

begin

writeln(‘ ***’);

writeln(‘* *’);

writeln(‘*****’);

writeln(‘* *’);

writeln(‘* *’);

end;

begin

M;

A;

M;

A;

end.

Функции имеют такую же структуру, как и процедуры. Исключением является объявление функции.

function <имя_функции> (<параметры>) : <тип данных>;

Так же, как и в случае с процедурами, параметры используются только при необходимости.

Как упоминалось ранее, функция всегда возвращает результат. При объявлении функции всегда указывается тип данных возвращаемого результата (см. выше).

В операторной части функции (основное тело функции) задаются операторы, которые должны выполняться при вызове функции. В случае с функцией здесь должен содержаться по крайней мере один оператор присваивания, в котором имени (идентификатору) функции присваивается некоторое значение. Результатом функции является последнее присвоенное имени функции значение. Если такой оператор присваивания отсутствует или не был выполнен, то значение, возвращаемое функцией, не определено.

Пример: функция GetNumber запрашивает число у пользователя

function GetNumber: Real;

var Responce: Real;

begin

write('Введите число: ');

readln(Response);

GetNumber := Response;

end;

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

Каждый параметр, описанный в списке формальных параметров, рассматривается в процедуре или функции как некая внутренняя переменная с заданным начальным значением.

Описываются формальные параметры следующим образом:

( <тип параметра> <список параметров> : <тип параметров> )

Тип параметра определяется с помощью ключевых слов const, var или вообще не указывается. Подробнее данный пункт будет рассмотрен позже.

Список параметров представляет собой обычный список имен переменных (формальных параметров), записанных через запятую (аналогично разделу описания переменных var).

Если имеются параметры разных типов, то представленная конструкция записывается несколько раз через точку с запятой.

Пример: возможные списки формальных параметров

procedure primer1 ( x: integer );

procedure primer2 ( var x, y, z: integer );

procedure primer3 ( var a: real; const b, testconst: integer; c: char );

function primer4 ( formal: boolean ): integer;

Следует отметить, что тип параметра не может быть составным. Если же в качестве типа параметра должен быть все-таки, например, массив, то для него следует предварительно создать запись в разделе type, а затем использовать заданное имя.

Пример: типы параметров

неправильно:

procedure primer1 ( vector: array [1..10] of integer );

правильно:

type TVector: array [1..10] of integer;

procedure primer1 ( vector:TVector );

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

Пример: вызов подпрограмм с параметрами

primer1 ( 10 );

primer2 ( a, b, c );

primer3 ( x, b, test, ‘q’ );

n := primer4 ( true );

Количество и типы передаваемых в подпрограмму фактических параметров должны соответствовать количеству и типам указанных при её описании формальных параметров. Другими словами, если функция ожидает получить на входе два целых числа, то при ее вызове в нее и должны быть переданы два целых числа.

Далее рассмотрим существующие типы параметров.

1. Группа параметров без предшествующего ключевого слова является списком параметров-значений.

Пример: параметр-значение

procedure primer ( x: integer );

2. Группа параметров, перед которыми следует ключевое слово const и за которыми следует тип, является списком параметров-констант.

Пример: параметры-константы

procedure primer ( const x, y: integer );

3. Группа параметров, перед которыми стоит ключевое слово var и за которыми следует тип, является списком типизированных параметров-переменных.

Пример: типизированный параметр-переменная

procedure primer ( var x: integer );

4. Группа параметров, перед которыми стоит ключевое слово var или const, за которыми не следует тип, является списком нетипизированных параметров.

Пример: нетипизированный параметр-переменная

procedure primer ( var x );

Рассмотрим разницу между этими видами параметров.

Формальный параметр-значение обрабатывается, как локальная (внутренняя) по отношению к процедуре или функции переменная, за исключением того, что получает свое начальное значение из соответствующего фактического параметра при вызове процедуры или функции. Изменения, которые претерпевает формальный параметр-значение, не влияют на значение фактического параметра.

Пример: параметр-значение

procedure primer ( x: integer );

begin

x:=5;

end;

var k: integer;

begin

k:=10;

primer ( k );

writeln ( k ); { на экране напечатается 10 }

end.

В качестве аргумента параметра-значения могут выступать как переменные, так и константы и выражения.

Пример: параметр-значение

procedure primer ( x: integer );

primer ( 32+23 );

Формальные параметры-константы работают аналогично локальной (внутренней) константе, которая получает свое значение при вызове подпрограммы от соответствующего фактического параметра. Присваивания формальному параметру-константе не допускаются. Формальный параметр-константа также не может передаваться в качестве фактического параметра другой подпрограмме.

Пример: параметр-константа

procedure primer ( const x: integer );

begin

x:=5; – недопустимо!!!

end;

Параметр-переменная используется, когда значение должно передаваться из подпрограммы вызывающей программе. При вызове подпрограммы формальный параметр-переменная замещается фактической переменной, а следовательно, любые изменения в значении формального параметра-переменной отражаются и на фактическом параметре. Другими словами, любое обращение к формальному параметру-переменной приводит к доступу к самому фактическому параметру.

Пример: рассмотрим еще раз представленный выше пример, но уже для параметра-переменной

procedure primer ( var x: integer );

begin

x:=5;

end;

var k: integer;

begin

k:=10;

primer ( k );

writeln ( k ); { на экране напечатается 5 }

end.

Соответствующий фактический параметр в операторе вызова подпрограммы должен быть переменной (использование констант и выражений недопустимо).

В первых двух случаях (параметры-значения и параметры-константы) говорят, что фактические параметры передаются в процедуру по значению (т.е. их значение в вызывающей процедуре не изменяется), в третьем (параметр-переменная) – по адресу (т.е. при изменении значений внутри процедуры их значение изменяется и в вызывающей процедуре).

Когда формальный параметр является нетипизированным параметром, то соответствующий фактический параметр может представлять собой любую переменную или константу, независимо от ее типа. Нетипизированный параметр, описанный с ключевым словом var, может модифицироваться, а нетипизированный параметр, описанный с ключевым словом const, доступен только для чтения.

Внутри подпрограммы над нетепизированным параметром может быть осуществлено явное преобразование типа: параметр записывается в скобках, перед которым указывается имя типа данных, к которому осуществляется преобразование.

Пример: нетипизированный параметр – явное преобразование типа

procedure test ( var x );

type

TArr = array[1..10] of byte;

var

y: integer;

z: real;

m: arr;

begin

...

y:= integer(x); { преобразование к типу integer }

z:= real(x); { преобразование к типу real }

m:= arr(x); { преобразование к массиву }

...

end;

Другой способ работы с нетипизированной переменной – описать локальную переменную, которая физически будет совпадать с передаваемой в подпрограмму фактической переменной.