
Captulo 20 - procedures

  Procedure define um conjunto de comandos (rotina) que pode ser executado
uma ou mais vezes. Um procedimento pode ter a mesma estrutura de um progra-
ma, ter declarao de variveis e de constantes, etc, deve ser definido
antes de ser mencionado no programa. Se este procedimento tiver uma cha-
mada de um outro procedimento, este dever ser definido previamente. A sin-
taxe geral de um procedimento pode ser:
PROCEDURE identificador [(parmetros : tipo)]; [EXTERNAL;]
                                               [INTERRUPT;]
                                               [FAR]
                                               [NEAR]  
                                               [EXPORT] 
                                               [FORWARD;]
                                               [TYPE]
                                               [VAR]
                                               [CONST]
BEGIN        
  [comandos;]
END;

  O uso de rotinas predefinidas facilita em muito, a definio de um pro-
grama. Vejamos alguns exemplos:
PROGRAM teste_procedure1;
USES CRT;
VAR
  ch : CHAR;
  n : BYTE;
PROCEDURE 1e_ch;
BEGIN
  REPEAT
    ch := UPCASE (READKEY);
    IF (ch <> N) AND (ch <> S);
    THEN
      WRITE (#7);        {beep}
  UNTIL ch IN [S,N];
  n := n + 1;
END;
                          {programa Principal}
BEGIN
  CLRSCR;
  n := 0;
  REPEAT
    WRITELN (deseja executar esta rotin,novamente S/N ???);
    1e_ch;
    WRITELN (procedure executad,n:2, vez(es));
  UNTIL ch = N;
END.
  Neste exemplo, podemos observar que as variveis so comuns a todo o pro-
grama, neste caso, estas variveis so chamadas de globais e podem ser
referenciadas em qualquer parte do programa, inclusive dentro de um proce-
dimento. Vejamos um nvo exemplo:
PROGRAM teste_procedure2;
USES CRT;
VAR
  ch : CHAR;
  n : BYTE;
PROCEDURE 1E_CH;
VAR
  n : BYTE;
BEGIN  
  n := 0;
  REPEAT
    ch := UPCASE (READKEY);
    IF (ch <> N) AND (ch <> S);
    THEN
      BEGIN
        n := n + 1;
        WRITELN (#7, nmero de erros = , n:);
      END;
  UNTIL ch IN [S,N];
  END;
  BEGIN
    CLRSCR;
    n := 0;
    REPEAT
      WRITELN (deseja executar essa rotina ,novamente S/N ???);
      1e_ch;
      n := n + 1;
      WRITELN (procedure executada  n:2,vez(es));
    UNTIL ch = N;
  END.
  Neste segundo exemplo, podemos perceber claramente que a varivel "n"
declarada no programa principal, nada tem a ver com a varivel ", decla-
rada no procedimento. Esta ltima  chamada de varivel local e seu contedo
 inicializado a cada execuo desta rotina, e tambm sua referncia s 
pode ser local. 
  Vejamos um novo exemplo, utilizando a passagem de parmetros:
PROGRAM teste_procedure3;
USES CRT;
VAR
  ch : CHAR;
  n : BYTE;
PROCEDURE 1e_ch (m : BYTE);  
VAR
  n : BYTE;
BEGIN  
  n := 0;
  REPEAT
    ch := UPCASE (READKEY);
    IF (ch <> N) AND (ch <> S);
    THEN
      BEGIN
        n := n + 1;
        WRITELN (#7, nmero de erros = , n:2);
      END;
  UNTIL ch IN [S,N];
  WRITELN (procedure executada , m:2,vez(es));
END;
BEGIN
  CLRSCR;
  n := 0;
  REPEAT
    WRITELN (deseja executar essa rotina ,novamente S/N ???);
    n := n + 1;
    1e_ch(n);
  UNTIL ch = N;
END.  
  Neste ltimo exemplo, utilizamos da passagem de parmetro para o proce-
dimento "1e_ch".  bom observar que o contedo da varivel global "n"  
passado  varivel "m", declarada no cabealho do procedimento. Mesmo tendo
nomes diferentes, as variveis tem o mesmo contedo e apesar de terem o 
mesmo contedo, no  possvel alterar o contedo da varivel de dentro do
procedimento. 
  Vamos ver mais um exemplo:
PROGRAM teste_procedure4;
USES CRT;
VAR
  ch : CHAR;
  n : BYTE;
procedure 1E_CH(var m : BYTE);
VAR
  n : BYTE;
BEGIN  
  n :=0;
  REPEAT
    ch := UPCASE(READKEY));
    IF (ch <> N) AND (ch <> S);
    THEN
      BEGIN
        n := n + 1;
        WRITELN (#7,nmero de erros = ,n:2);
      END;
  UNTIL ch IN [S,N];
  m := m + 1;
END;
BEGIN
  CLRSCR;
  n := 0;
  REPEAT
    WRITELN (deseja executar essa rotina ,novamente S/N ???);
    1e_ch(n);
    WRITELN (procedure executad, n:2, vez(es));
  UNTIL ch = N;
END.  
  Neste ltimo exemplo, a definio da varivel que  utilizada como par-
metro vem precedida da declarao "VAR". O uso desta declarao indica que o 
local do endereo de memria, usado para a varivel local, dever ser o 
mesmo que o da varivel global passada como parmetro, e assim alterar o 
seu contedo. 
  Vejamos um novo exemplo:
PROGRAM teste_procedure5;
USES CRT;
PROCEDURE writexy (x, y : BYTE; mens : STRING);
BEGIN
  GOTOXY (x,y);
  WRITE (mens);
END;  
BEGIN
  CLRSCR;
  writexy (10,10,linha 10 e coluna 10);
  writexy (10,12,linha 12 e coluna 10);
  writexy (10,20,linha 20 e coluna 10);
  READLN;
END.
  Quando tivermos a necessidade de passar parmetros de tipos diferentes,
estes devem ser declarados separadamente como no exemplo anterior. As vari-
veis "x" e "y" que so do tipo BYTE so declaradas juntas e somente aps 
a declarao destas  que se declara a varivel "mens" do tipo STRING, 
e separadas por ";" (ponto_e_vrgula). Os procedimentos podem ser recur-
sivos, ou seja, um procedimento chamar a ele mesmo. Veja o exemplo:
PROGRAM teste_procedure6;
USES CRT;
PROCEDURE writexy (x, y : BYTE; mens : STRING; repete : BOOLEAN);
BEGIN
  GOTOXY (x,y);
  WRITE (mens);
  IF repete 
  THEN
    BEGIN
      writexy (10,25,pressione algo para continuar,FALSE);
      REPEAT
      UNTIL READKEY <> #0;
      writexy (10,25,             ,FALSE);
    END; 
END;
BEGIN
  CLRSCR;
  writexy (10,10,linha 10 e coluna 10, TRUE);
  writexy (10,12,linha 12 e coluna 10, TRUE);
  writexy (10,20,linha 20 e coluna 10, TRUE);
END.  
  Neste exemplo, fazemos com que o procedimento "writexy" utilize uma chave
lgica (repete), permitindo que a rotina no fique em "looping", pois  
chamada de dentro da mesma. 
  As rotinas devem ser declaradas antes de serem chamadas, porm em alguns
casos, temos a necessidade de declarar uma rotina aps sua chamada e neste
caso, devemos utilizar a declarao"FORWARD". Veja o exemplo:
PROGRAM teste_procedure7;
VAR
  o : BYTE;
PROCEDURE tic (VAR m : BYTE); FORWARD;
PROCEDURE tac (VAR n : BYTE);
BEGIN
  WRITELN (T A );
  m := m - 1;
  IF m > 0 
  THEN
    tic (n);
END;    
PROCEDURE tic;
BEGIN
  WRITELN (T I );
  tac (o);
END;
BEGIN
  WRITELN;
  n := 10;
  tac (n);
END.  
