Após ver a existência de pessoal que estava a converter código minimamente bom num código esparguete cheio de Gotos, decidi mostrar uma das maravilhas do Pascal.
Os procedimentos e funções podem-se chamar uns aos outros, mas muitas vezes damos por nós a criar procedimentos ou funções que só são necessários para um(a) outro/a. Para este caso, podemos criar o procedimento, ou a função, dentro do próprio procedimento/função que o necessitar! Este não será acessível ao resto do programa e outros procedimentos e funções que não sejam aquele que o contém.
Bem, isto já parece algo confuso. Um exemplo prático irá esclarecer bem o assunto.
Imaginemos que queremos um procedimento que escreve um texto convertido. A conversão consiste em transformar cada caracter no seu terceiro sucessor. Isto é, A será D, e X será A. Ou seja, quando o caracter é Z, o seu sucessor directo é A (X > Y (1º) > Z (2º) > A (3º)).
Criemos então um procedimento, Escrever, que recebe como argumento o texto a converter, obtido por leitura do utilizador. Este procedimento vai depender um conversor, uma função que recebe o texto a converter e o converte. O seu nome será original - Conversor. Mas o conversor irá depender de uma outra função que lhe irá dar directamente o terceiro sucessor de um caracter. Sendo Succ a função padrão que dá o sucessor directo, o nome da função que devolve o terceiro sucessor será Succ3.
Numa árvore, temos o seguinte:
Aqui vê-se que o programa principal pode aceder a Escrever, mas não pode aceder a Conversor nem a Succ3. Escrever pode aceder a Conversor mas não a Succ3. Conversor pode aceder a Succ3.
Vemos, então, que cada procedimento/função só pode aceder a outros procedimentos/funções que estejam directamente na sua linha de hierarquia ou na seguinte. As superiores são-lhes inacessíveis.
Basta pensar em cada procedimento e função como um pequeno programa com os seus procedimentos e funções. Outro programa externo não pode aceder directamente a esses procedimentos e funções - são seus e não de outrém.
Assim sendo, e dando por terminada a teoria, segue-se a implementação prática.
Em comentário entre {} está o nome do procedimento ou da função a que cada Begin/End se refere para evitar confusões.
{$MODE Delphi} PROGRAM ProcFuncEx; VAR Txt : string[80]; PROCEDURE Escrever(const Texto : string[80]); (* Escreve "Texto" com os seus caracteres convertidos nos seus terceiros sucessores *) function Conversor(const Linha : string[80]) : string; (* Debita "Linha" convertida, cujos caracteres são os seus terceiros sucessores *) var i : byte; Resultado : string[80]; function Succ3(const Caracter : char) : char; (* Função que calcula o terceiro sucessor *) var Res : char; j : 1..3; begin {Succ3} Res := Caracter; for j:=1 to 3 do begin // Terceiro sucessor Res := Succ(Res); if (ord(Res) > Ord('Z')) then Res := 'A'; // Evita caracteres não alfanuméricos end; Result := Res; // Output da função end; {Succ3} begin {Conversor} Resultado := ''; // Inicia a String // Converte caracter a caracter for i:=1 to length(Linha) do Resultado := Resultado + Succ3(Linha[i]); Result := Resultado; // Output da função end; {Conversor} begin {Escrever} // Debita o texto, em maiúsculas, convertido, recorrendo ao Conversor writeln(Conversor(UpCase(Texto))); end; {Escrever} BEGIN (* Bloco Principal *) repeat Write('Txt? '); ReadLn(Txt); Escrever(Txt); // debita texto convertido WriteLn; // parágrafo em branco until (UpCase(Txt) = 'SAIR'); END.