6. Procedimientos y funciones

6.1. Procedimientos.

Hemos visto cómo hacer que se repita un bloque de programa, usando estructuras como "for", "while" o "repeat". Pero cuando un fragmento de programa se debe repetir en varias partes de nuestro fuente, el resultado puede seguir siendo redundante. Por ejemplo, podemos escribir varias frases "subrayadas" con asterisco así:

(* PROC01.PAS, procedimientos: acercamiento *)
(* Parte de CUPAS5, por Nacho Cabanes       *)
 
program Proc01;
 
var
    i: byte;
 
begin
    { Primer texto }
    writeLn( 'Primer texto' );
 
    { Escribimos 20 asteriscos y avanzamos de linea }
    for i := 1 to 20 do
        write('*');
    writeLn;
 
 
    { Segundo texto }
    writeLn( 'Y un segundo texto' );
 
    { Escribimos 20 asteriscos y avanzamos de linea }
    for i := 1 to 20 do
        write('*');
    writeLn;
 
 
    { Tercer texto }
    writeLn( 'Texto de despedida' );
 
    { Escribimos 20 asteriscos y avanzamos de linea }
    for i := 1 to 20 do
        write('*');
    writeLn;
end.  

(* 
Resultado:
Primer texto
********************
Y un segundo texto
********************
Texto de despedida
********************
*)

Esto sigue siendo claramente repetitivo, a pesar de utilizar "for". Para mejorarlo, podemos crear un "bloque" llamado "Escribir20asteriscos" y que sirva como una "abreviatura" que nos permita no tener que teclear tantos código repetitivo. Además, el repetir menos hace que el programa sea menos propenso a errores, ya sea en el momento de teclear o cuando vayamos a ampliarlo o corregirlo (por ejemplo, si queremos cambiar los 20 asteriscos por 18, corremos el riesgo de olvidar hacerlo en alguno de los bloques). Quedaría así:

(* PROC02.PAS, procedimientos: uso real *)
(* Parte de CUPAS5, por Nacho Cabanes   *)

program Proc02;

procedure Escribir20asteriscos;
var
    i: byte;
begin
    { Escribimos 20 asteriscos y avanzamos de linea }
    for i := 1 to 20 do
        write('*');
    writeLn;
end;

begin
    writeLn( 'Primer texto' );
    Escribir20asteriscos;
    writeLn( 'Y un segundo texto' );
    Escribir20asteriscos;
    writeLn( 'Texto de despedida' );
    Escribir20asteriscos;
end.  

(* 
Resultado:
Primer texto
********************
Y un segundo texto
********************
Texto de despedida
********************
*)

Estos bloques, que llamaremos "procedimientos" (y que en otros lenguajes de programación se conocen como "subrutinas") ayudarán a que nuestro programa sea menos repetitivo y resulte más fácil de leer.

En este programa, "i" es una variable local: se declara dentro del procedimiento "Escribir20asteriscos" y sólo es accesible dentro de él. Si en el cuerpo del programa intentamos hacer algo como "i:=2;" el programa no compilará, porque la variable no existe en esa zona. Debemos buscar conseguir que tantas variables como podamos sean locales. Sólo deberán ser "globales" (compartidas por todo el programa, y declaradas fuera de procedimientos) las variables que realmente se vayan a utilizar desde varias zonas distintas.

Ejercicio propuesto 6.1.1: Crea un procedimiento llamado "Escribir10guiones", que escriba 10 guiones (el símbolo de la resta) en pantalla. Empléalo en un programa.
Ejercicio propuesto 6.1.2: Crea un procedimiento llamado "DibujarRectanguloAsteriscos", que muestre en pantalla un rectángulo de 10 asteriscos de ancho y 5 de alto. Utilízalo en un programa.
Ejercicio propuesto 6.1.3: Crea un procedimiento "EscribirVector", que escriba en pantalla los datos de un vector de números reales de 3 elementos. Los datos deben aparecer separados por comas, y debe haber un paréntesis abierto antes del primer dato y un paréntesis cerrado tras el tercer dato. El vector a mostrar será una variable global llamada "datos". Aplícalo a un programa que pida los datos al usuario y luego los muestre.