#14 Процедуры и функции в Паскаль. Как объявлять и использовать

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

Чем процедуры отличаются от функций

Различия между процедурами и функциями в Паскаль:

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

Сигнатура процедур и функций

Процедуры и функции принимают какие-то значения "на вход" -- это те данные, с которыми процедура или функция будут работать.

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

Вызов процедуры и её сигнатура

Сигнатура процедуры определяется:

  1. Именем процедуры
  2. Числом, типом входных переменных и порядком их следования

Например, рассмотрим реализацию процедуры $sum1()$, которая складывает два числа и выводит сумму на экран:

procedure sum1(x, y: integer;); // начало объявления процедуры
begin
  write(x + y);
end; // конец тела процедуры

Иллюстрацией к сигнатуре этой процедуры служит её заголовок:

procedure sum1(x, y: integer;); 

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

procedure sum1(x, y: integer;); // начало объявления процедуры
begin
  write(x + y);
end; // конец тела процедуры

begin // начало тела программы

  sum1(5, 7);  // вызов процедуры

end.

Вызов функции и её сигнатура

Сигнатура функции определяется:

  1. Именем функции
  2. Числом, типом входных переменных и порядком их следования
  3. Типом возвращаемого значения

Процедуры

Рассмотрим пример программы с процедурой:

 
var
  a, b, c: integer; // объявляем глобальные переменные программы
 
procedure sum(x, y: integer; var z: integer); // начало объявления процедуры
begin
  z := x + y; // тело процедуры
end;
 
begin // начало тела программы
  write('Введите два числа: ');
  readln(a, b);
  sum(a, b, c); { -- вызов процедуры с параметрами (аргументами)
  процедура вызывается своим именем,
  которое вы написали после зарезервированного слова procedure в описании}
  writeln(c);
end.

-- здесь:

  • переменная $z$ в процедуру $sum()$ передана по ссылке, это значит, что если её изменить в теле процедуре, то она изменится и в том месте, откуда её передали в процедуру (например, в теле основной программы).
  • Переменные же $x$ и $y$ переданы по значению -- это надо понимать так, что если их значения будут изменяться внутри процедуры (в данном случае), то "снаружи" эти изменения видны не будут.

Функции

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

var
  a, b, c: integer; // глобальные переменные
 
function sum(x, y: integer): integer;
begin // начало тела функции
  result := x + y; { результат для возврата наружу 
  (в глобальное пространство программы из локального пространства функции) }
end;  // конец описания функции (её тела)
 
begin // начало тела основной программы
  readln(a, b);
  writeln(sum(a, b));
end. // конец основной программы

Примеры кода -- разбор решений

Пример №1 -- функция не принимающая аргументов

Задача:

Напишите функцию, которая не принимает аргументов и возвращает число $55$

Решение:

function f1():integer; // возвращает целое число 5
begin
  result := 55;  // всё просто
end;


begin // тело программы

  writeln('f1() vernula:', f1()); // вызов функции как аргумент
  readln();
end.   

Пример №2 -- функция: входящие аргументы разного типа, локальные переменные подпрограммы

Задача:

Напишите функцию, которая принимает два аргумента: первый целого типа, а второй вещественного, и возвращает разницу между их произведением и их суммой.

Решение:

var m: integer;
  z : real;

function f2(a: integer; b: real): real;
var h: real; // объявим собственную (локальную) переменную функции
begin
  h := a*b - (a+b); // присваимаем результат выражения локальной переменной

  result := h; // возвращаем результат функции "наружу"

end; // конец тела функции

begin  // начало тела основной программы
  m := 2;
  z := 4.5;

  z := f2(m, z); // перезапишем z результатом работы функции

  writeln('z=', z);

  readln();
end.

Задачи для самостоятельного решения

  1. Напишите функцию, которая возвращает сумму трёх целых чисел.
  2. Напишите процедуру, которая выводит на экран сумму трёх целых чисел.
  3. Напишите процедуру, которая принимает переменную целого типа по ссылке, просит пользователя ввести значение в консоли и инициализирует переменную этим значением (убедитесь, что в теле программы значение изменилось).
  4. Составьте программу, которая выводит на экран прямоугольный флаг N×M вида (с чередованием плюсов и минисов в строках):
    - - - - - -
    + + + + + +
    - - - - - -
    + + + + + +
    - - - - - -  

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

  5. Пользователь передает целое положительное число $N$, выведете на экран последовательность от $1$ до $N$ "ёлочкой", например для $N = 17$:
    1
    2 3
    4 5 6
    7 8 9 10
    11 12 13 14
    15 16 17

    ПРИМЕЧАНИЕ: для вывода очередной строки используйте отдельную подпрограмму.

Видео-пояснения

К этому уроку есть следующие видео-пояснения:

  1. Процедуры и Функции в Паскаль: отличия, возврат значения, перегрузка процедур и функций: https://youtu.be/gUr6SeA7r-E
  2. Процедуры и Функции в Паскаль: передача по ссылке и по значению. Какая разница, пример с указателем: https://youtu.be/201KCCOOtyo
  3. Ещё раз о том, что значит, что функция "возвращает значение", и другие замечания: https://youtu.be/C11m4t2Yv78

Источники и полезные материалы:

  1. Урок 13. Процедуры и функции в Pascal. Часть 2: http://learnpascal.ru/vvedenie-v-paskal/...
vedro-compota's picture

function f1(): integer;
begin
   result := 2 + 3;
end;

procedure sum(x, y: integer); // начало объявления процедуры
var h: integer;
begin
  x := x - y + f1() * 2;
  h := 8;
  writeln(x);
end;


begin // начало тела программы
    a := 1;
    b := 2;
    sum(a,  5 + 7 - f1());
    sum(b, a);


    readln();
end. 

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

  1. Понятие подпрограммы
  2. Отличие между процедурой и функцией и ситуациями их использования
  3. Передача переменных по ссылке и по значению
  4. Область видимости (в Паскаль)
  5. Когда использовать процедуру, а когда функцию ("побочный эффект" указывает что надо использовать процедуру).

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

var
  a, b, c: integer; // глобальные переменные
  p: ^integer; // Тип: указатель на integer

begin

 a := 5;
 writeln('a= ', a);
 // f1(a);
 p := @a; // получаем указатель на переменную a
 writeln('p= ', p^); {смотрим что лежит в области памяти,
 на которую указывает указатель  p }

 p^ := 9; // Запись "по ссылке"
 writeln('p= ', p^);
 writeln('a= ', a);

 readln();
end. 

_____________
матфак вгу и остальная классика =)