Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции ЯП (Кузьмин) ч.2_new (Паскаль).docx
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
4 Мб
Скачать
☆
  1. 4) При описании подпрограммы после заголовка надо ставить точку с запятой.

  2. 5) Соответствие между формальными и фактическими параметрами устанавливается по порядку их записи слева направо.

  3. 6) Количество и тип формальных и фактических параметров должны совпадать.

  4. 7) Для формальных параметров – переменных соответствующим фактическим параметром может быть только переменные (не значение).

  5. 8) Для формальных параметров – значений соответствующим фактическими параметрами могут быть константы, переменные, вызовы функций, выражения.

  6. 9) Имена формальных и фактических параметров обычно не совпадают.

  7. копирование при вызове стек

  8. Фактические параметры

  9. (в вызывающей п/п) копия a область памяти под форм. пар-р x (x:=a)

  10. Var копия b область памяти под форм. пар-р y (y:=b)

  11. a:...; адрес с область памяти под адрес факт. пар-ра z (z:=адрес_с^)

  12. область памяти в стеке под копии значений и адреса фактических параметров вызова

    b: ...;

  13. c: ...;

  14. вызов: p(a, b, c);

  15. наложение при вызове

  16. вызываемая п/п:

  17. Procedure P (x, y : read:

  18. Var z: char);

  19. begin

  20. ..x:=1;

  21. y:=2;

  22. z:=3;

  23. ..............

  24. end;

ПРИМЕР. Вычислить с помощью процедуры сумму 3-х чисел:

Program P;

Var описание глобальных переменных

a, b, c, s: char;

procedure summa(x, y, z: real;

var g: real);

begin описание процедуры

g:=x+y+z;

end

begin

c:=1;

b:=2; ввод значений фактических параметров

a:=3;

s:=0;

writeln(‘s=’,s); до вызова

summa(a,b,c,s); вызов процедуры

writeln(‘s=’,s); после вызова

end.

В результате выполнения данной программы на экран будет выведено две строки:

s = 0

s = 6

В этом примере x, y, z и g - в заголовке процедуры - формальные параметры. При вызове процедуры в формальные параметры примут значения соответствующих фактических:

x=a, y=b, z=c, g=s

причем g и s станут синонимами.

Что произойдет, если из заголовка удалить слово Var Переменная g становится параметром - значением.

Что будет выведено на экран В этом случае при вызове процедуры внутри процедуры g - примет значение 6. Это значение будет размещено в стеке и при выходе из процедуры там же и останется. Ввиду того, что не была установлена связь между фактическим и формальным параметром, значение S останется после вызова = 0. На экран будет выведено ,то значение s , которое она имела до вызова процедуры, т.е. s=0.

18.7 Подпрограммы, возвращающие значение (функции)

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

Заголовок и тело такой подпрограммы отличаются от заголовка и тела процедуры.

На Паскале отличия проявляются в том, что 1) вместо слова procedure пишется function и справа от круглых скобок через двоеточие указывается тип возвращаемого значения; 2) в теле функции должен быть оператор присваивания типа

имя_функции:= возвращаемое значение.

Заголовок функции имеет вид:

function имя(список_формальных_параметров) : тип_возвращаемого_значения ;

ПРИМЕР. Рассмотренная задача нахождения суммы трех чисел может быть оформлена с помощью функции; 1)

var 3)

a, b, c, s : real;

function summa (x, y, z : real) : real;

begin

summa : = x+ y+ z; // в Delphi result:= x+ y+ z; --- возврат знвчения

end;

begin 2)

a := 1;

b := 2; ввод начальных значений

c := 3;

s := 0;

4) writeln(‘s=’,s:8:4); --- до

s := summa(a,b,c,); --- вызов функции

writeln(‘s=’,s:8:4); --- после

end.

Из примера важно выделить два момента:

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

В общем случае при вычислении выражения, содержащего вызов функции, выполняются следующие действия:

а) вычисляются значения выражений для фактических параметров функции;

б) значения фактических параметров присваиваются соответствующим формальным параметрам ;

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

г) возвращаемое значение подставляется в выражение, из которого (в котором) осуществляется обращения к функции;

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

2-ой момент В теле функции обязательно должна быть хотя бы одна строчка в которой имени функции присваивается возвращаемое значение. (в Delphi вместо этого д.б. строка вида: result:= возвращающие значение;)

Обычно делают две следующих ошибки при записи функции:

Должно быть имя := значение

1). function f(x : real): real;

begin

f(x) := x*3.14*2;

end;

Нет параметра при вызове функции

2). function g(a: byte): real;

Begin

g:=25;

g := g * a;

end;

В первом случае сделано две ошибки:

1-я синтаксическая: Нарушен синтаксис, т.к. для возврата из функции значения должен быть записан оператор присваивания в форме имя := значение.

2-я семантическая: для f(x) -компилятор посчитает, что вызов функции стоит слева от знака присваивания.

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

Примечания.

  1. Возвращаемым значением может быть значение простого типа или строкового типа или ссылочного типа. Если в теле функции отсутствует оператор присваивания имени функции какого - либо значения, то возвращаемое значение функции считается неопределенным.

  2. Часто бывает так, что необходимо возвращать разные значения функции в зависимости от наступления или не наступления различных ситуаций. В этом случае в теле цикла появляется несколько операторов присваивания имени функции возвращаемого значения. В таких функциях трудно понять, какой из них на самом деле возвращает в данный момент значение, и поэтому такие функции труднее отлаживать. Целесообразно придерживаться следующего правила: если необходимо вычислить возвращаемое значение в нескольких местах тела функции, то нужно ввести специальную вспомогательную переменную для такого присваивания, а затем непосредственно перед завершением тела функции, записать оператор присваивания, где слева - имя функции, а справа - имя вспомогательной переменной:

function fact(n:byte):longint;

var

i:word; //параметр (счетчик) цикла for

f:longint; //вспомогательная переменная

begin

f:=1;

for i:=1 to n do

f := f * i;

fact := f;

end;