Book of tasks on programming. Old version

 

 by Aliaksandr N. Prykhodzka

 

по программированию, file, FAT, book of tasks on programming, probleme, sheet, многомерный, book, язык программирования, самообучение, assembler
 

for valuable work you must have JavaScript (allow active content)

Pascal. Pa.29. Procedures

Познакомимся с процедурами. Иногда в программе одна и та же последовательность операторов появляется несколько раз. Чтобы несколько раз не писать одно и то же, мы можем поступить следующим образом. Создадим оператор 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. Как описывается процедура понятно из примера. Операторы из процедуры могут использовать все переменные, которые есть в программе. Кроме того, внутри процедуры мы можем описать переменные, которые будут использоваться только внутри данной процедуры.

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

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

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

Пусть, в переменных 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(результат из предыдущего пункта).

 

©   Aliaksandr Prykhodzka    1993 - 2007