Сборник задач по программированию. Старая версия

 

 Приходько А. Н.

 

jsp, задачи, образование, applet, сборник, пролог, функция, учебный материал, html, xsl, по программированию
 

Паскаль. P.27. Процедуры

Познакомимся с процедурами. Иногда в программе одна и та же последовательность операторов появляется несколько раз. Чтобы несколько раз не писать одно и то же, мы можем поступить следующим образом. Создадим оператор Begin..End, который будет содержать данные операторы и дадим ему имя. А затем, каждый раз вместо этих операторов мы будем писать имя данного оператора. Такой оператор называется процедурой. Посмотрим как это выглядит на языке Паскаль.

Пусть у нас имеется следующая программа:

Program BB;
var
    x, y, z : integer;
begin
    x:=1;    y:=2;
    x:=x*x;
    y:=y*y;
    z:=x+y;
    writeln(z);
    x:=1;    y:=2;
    x:=x*x;
    y:=y*y;
    z:=x+y;
    writeln(z);
    x:=1;    y:=2;
    x:=x*x;
    y:=y*y;
    z:=x+y;
    writeln(z);
end.

Введем в эту программу процедуры:

Program BB;
var
    x, y, z : integer;

procedure Friend;
begin
    x:=x*x;
    y:=y*y;
    z:=x+y;
    writeln(z);
end;

begin
    x:=1;    y:=2;
    Friend;
    x:=1;    y:=2;
    Friend;
    x:=1;    y:=2;
    Friend;
end.

Процедура, как и программа, всегда имеет тело, которое является оператором Begin..End. Как опиcывается процедура понятно из примера. Операторы из процедуры могут использовать все переменные, которые есть в программе. Кроме того, внутри процедуры мы можем описать переменные, которые будут использоваться только внутри данной процедуры.

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

Процедуры используются не только для экономии места при написании программы, но и для придания программе большей наглядности.

Напишем программу перемещения человечка по экрану дисплея. Наш человечек будет бежать в направлении, которое определяется нажатой клавишей (вверх, вниз, вправо, влево).

Пусть, в переменнфх x и y хранятся текущие координаты человечка. Чтобы переместить человечка на другое место мы должны выполнить следущую последовательность шагов : 1) стереть человечка там где он находится; 2) изменить текущие координаты человечка; 3) нарисовать человечка на новом месте.

Сначала напишем 2 процедуры. Процедура Man будет рисовать человечка в позиции с координатами из переменных x и y. Процедура NoMan будет стирать человечка в позиции с координатами из переменных x и y.

Человечек будет выглядеть так :         o
                    -0-
                     ^

procedure Man;
begin
    gotoxy(x+1,y);        write('o');
    gotoxy(x+1,y+1);    write('0');
    gotoxy(x+1,y+2);    write('^');
    gotoxy(x,y+1);        write('-');
    gotoxy(x+2,y+1);    write('-');
end;

procedure NoMan;
begin
    gotoxy(x+1,y);        write(' ');
    gotoxy(x+1,y+1);    write(' ');
    gotoxy(x+1,y+2);    write(' ');
    gotoxy(x,y+1);        write(' ');
    gotoxy(x+2,y+1);    write(' ');
end;

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

program BB;
uses crt, dos;
var
    r : registers;
    x, y : integer;
    ch : char;

procedure Man;
begin
    gotoxy(x+1,y);        write('o');
    gotoxy(x+1,y+1);    write('0');
    gotoxy(x+1,y+2);    write('^');
    gotoxy(x,y+1);        write('-');
    gotoxy(x+2,y+1);    write('-');
end;

procedure NoMan;
begin
    gotoxy(x+1,y);        write(' ');
    gotoxy(x+1,y+1);    write(' ');
    gotoxy(x+1,y+2);    write(' ');
    gotoxy(x,y+1);        write(' ');
    gotoxy(x+2,y+1);    write(' ');
end;

begin
    clrscr;    x:=10;    y:=10;    Man;
    repeat
        r.ax:=$0000; Intr($16,r);
        NoMan;
        if (lo(r.ax)=0) and (hi(r.ax)=72) and (y>1) then y:=y-1;
        if (lo(r.ax)=0) and (hi(r.ax)=80) and (y<22) then y:=y+1;
        if (lo(r.ax)=0) and (hi(r.ax)=75) and (x>1) then x:=x-1;
        if (lo(r.ax)=0) and (hi(r.ax)=77) and (x<78) then x:=x+1;
        Man;
    until (lo(r.ax)=27) and (hi(r.ax)=1);
end.

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

Program CC;
var
    x, y, z : integer;

procedure NN;
var
    m : integer;
begin
    for m:=2 to 3 do
        if x mod m=0 then z:=z+x
        else z:=z+y
end;

begin
    z:=0;    y:=0;
    for x:=1 to 3 do begin
        y:=y*3+1;
        NN
    end;
    writeln(z)
end.

Попытайтесь определить, какое число будет выдаваться на экран дисплея.

Очень часто использование процедур предполагает передачу им каких-либо параметров. Раньше мы использовали процедуры Man и NoMan. Данные процедуры должны рисовать или стирать человечка в позиции экрана, определяемым некоторыми координатами. Эти координаты мы передавали через переменные x и y, описанные в основной программе. Давайте попытаемся немного усовершенствовать механизм процедур.

Чтобы нарисовать человечка в позиции с координатами (10,5) мы можем поступить так.

    x:=10;    y:=5;
    Man;

Введем внутри процедуры Man свои внутренние переменные xx и yy для координат и попытаемся их использовать для опеределения места на экране дисплея.

procedure Man;
var
    xx, yy : integer;
begin
    gotoxy(xx+1,yy);        write('o');
    gotoxy(xx+1,yy+1);    write('0');
    gotoxy(xx+1,yy+2);    write('^');
    gotoxy(xx,yy+1);        write('-');
    gotoxy(xx+2,yy+1);    write('-');
end;

    xx:=10;        yy:=5;
    Man;

Однако, переменные xx и yy описаны внутри процедуры Man и не могут использоваться вне ее. Попытаемся написать так.

    Man(xx:=10,y:=5);

Такой записью мы хотим сказать, что перед запуском процедуры Man в ее внутренние переменные xx и yy необходимо поместить значения 10 и 5. На языке Паскаль такая ситуация оформляется следующим образом.

procedure Man(xx, yy : integer);
begin
    gotoxy(xx+1,yy);        write('o');
    gotoxy(xx+1,yy+1);    write('0');
    gotoxy(xx+1,yy+2);    write('^');
    gotoxy(xx,yy+1);        write('-');
    gotoxy(xx+2,yy+1);    write('-');
end;

    Man(10,5);

Переменные xx и yy называются формальными параметрами.

Мы можем использовать и следующую запись.

    x:=10;    y:=5;
    Man(x,y);

Здесь, перед запуском процедуры в переменные xx и yy копируются значения, из переменных x и y.

Пример программы, которая вводит с клавиатуры число x и вычисляет полином x + x**2 + x**3 + x**4:

Program CC;
var
    x, s, z, j : integer;

procedure Q(xx,n : integer);
var
    i : integer;
begin
    z:=1;
    for i:=1 to n do z:=z*xx
end;

begin
    readln(x);
    s:=0;
    for j:=1 to 4 do begin
        Q(x,j);
        s:=s+z;
    end;
    writeln(s)
end.

Иногда, функциональное назначение процедуры предполагает не только получение некоторых начальных значений в виде параметров, но и возврат результата работы этой процедуры. В вышеприведенном примере, процедура Q возвращает результат возведения числа xx в степень n. Результат возвращается через общую переменную z. Мы можем описать 3-ю переменную- параметр и возращать результат через него. В этом случае, программа будет выглядеть следующим образом:

Program CC;
var
    x, s, z, j : integer;

procedure Q(xx,n : integer; var zz : integer);
var
    i : integer;
begin
    zz:=1;
    for i:=1 to n do zz:=zz*xx
end;

begin
    readln(x);
    s:=0;
    for j:=1 to 4 do begin
        Q(x,j,z);
        s:=s+z;
    end;
    writeln(s)
end.

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

Program CC;
var
    x, s, j : integer;

function Q(xx,n : integer) : integer;
var
    i, zz : integer;
begin
    zz:=1;
    for i:=1 to n do zz:=zz*xx;
    Q:=zz
end;

begin
    readln(x);
    s:=0;
    for j:=1 to 4 do s:=s+Q(x,j);
    writeln(s)
end.

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

Функция может возвращать только одно значение.

Пример еще одной программы с функциями:

Program CC;
var
    s : integer;

function N(x : integer) : integer;
begin
    N:=x*x
end;

begin
    s:=N(N(3)+N(N(2)))
end.

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

 

©   Александр Приходько    1996 - 2006