Este sitio web usa cookies de terceros para analizar el tráfico y personalizar los anuncios. Si no está de acuerdo, abandone el sitio y no siga navegando por él. ×


Curso de Pascal. Ampliación 1: Otras órdenes no vistas.

A lo largo del curso ha habido órdenes que no hemos tratado, bien porque no encajasen claramente en ningún tema, o bien porque eran demasiado avanzadas para explicarlas junto con las más parecidas.

En primer lugar vamos a ir viendo las que podían haber formado parte de temas anteriores, y después las que faltan.  Tampoco pretendo que esto sea una recopilación exhaustiva, sino simplemente mencionar algunas órdenes interesantes que parecían haberse quedado en el tintero.

Los temas que se van a comentar son:

- Bucles: break, continue.
- Saltos: goto, label.
- Punteros: getmem, freemem, pointer.
- Fin del programa: exit, halt.
- Números aleatorios: rnd, randomize.
- Inc y Dec.
- Acceso a la impresora.

Bucles: break, continue.

En Turbo Pascal 7.0, tenemos dos órdenes extra para el control de bucles, tanto si se trata de "for", como de "repeat" o "until".  Estas órdenes son:

- Break: sale del bucle inmediatamente.
- Continue: pasa a la siguiente iteración.

Un ejemplo "poco útil" que use ambas podría ser escribir los números pares hasta el 10 con un for:


for i := 1 to 1000 do            { Nos podemos pasar } 
   begin 
   if i>10 then break;           { Si es así, sale } 
   if i mod 2 = 1 then continue; { Si es impar, no lo escribe } 
   writeln( i );                 { Si no, lo escribe } 
   end;

Esto se puede imitar en versiones anteriores de TP con el temible "goto".

Goto.

Es una orden que se puede emplear para realizar saltos incondicionales. Su empleo está bastante desaconsejado, pero en ciertas ocasiones, y se se lleva cuidado, puede ser útil (para salir de bucles fuertemente anidados, por ejemplo, especialmente si no se dispone de las dos órdenes anteriores.

El formato es

  goto etiqueta

y las etiquetas se deben declarar al principio del programa, igual que las variables.  Para ello se usa la palabra "label".  Vamos a verlo directamente con un ejemplo:

{--------------------------} 
{  Ejemplo en Pascal:      } 
{                          } 
{    Ejemplo de saltos y   } 
{    etiquetas             } 
{    LABEL1.PAS            } 
{                          } 
{  Este fuente procede de  } 
{  CUPAS, curso de Pascal  } 
{  por Nacho Cabanes       } 
{                          } 
{  Comprobado con:         } 
{    - Free Pascal 2.2.0w  }
{    - Turbo Pascal 7.0    } 
{--------------------------}

program label1;

label 
  uno, dos;

var 
  donde: byte; 
  
begin 
  writeln('¿Quiere saltar a la opción 1 o a la 2?'); 
  readln (donde); 
  case donde of 
     1: goto uno; 
     2: goto dos; 
     else writeln('Número incorrecto'); 
     end; 
  exit; 
uno: 
  writeln('Esta es la opción 1.  Vamos a seguir...'); 
dos: 
  writeln('Esta es la opcion 2.'); 
end. 

Punteros: getmem, freemem, pointer.

Habíamos hablado de "new" y "dispose", en las que el compilador decide la cantidad de memoria que debe reservar.  Pero también podemos obligarle a reservar la que nosotros queramos, lo que nos puede interesar, por ejemplo, para leer cadenas de caracteres de longitud variable.

Para esto usamos "getmem" y "freemem", en los que debemos indicar cuánta memoria queremos reservar para el dato en cuestión.  Si queremos utilizarlos como new y dispose, reservando toda la memoria que ocupa el dato (será lo habitual), podemos usar "sizeof" para que el compilador lo calcule por nosotros:


type 
  TipoDato = record 
     Nombre: string[40]; 
     Edad: Byte; 
     end;

var 
   p: pointer;     { Puntero genérico }

begin 
   if MaxAvail < SizeOf(TipoDato) then 
      Writeln('No hay memoria suficiente') 
   else 
      begin 
      GetMem(p, SizeOf(TipoDato)); 
      { Trabajaríamos con el dato, y después... } 
      FreeMem(p, SizeOf(TipoDato)); 
      end; 
end.

 Por cierto, "pointer" es un puntero genérico, que no está asociado a ningún tipo concreto de dato.  No lo vimos en la lección sobre punteros, porque para nosotros lo habitual es trabajar con punteros que están relacionados con un cierto tipo de datos.

Un ejemplo (avanzado, eso sí) que emplea la palabra pointer se puede encontrar en la ampliación 5, y muestra cómo dibujar figuras que se desplacen por la pantalla sin borrar el fondo (sprites).

Fin del programa: exit, halt.

En el tema 8 (y en los ejemplos del tema 6) vimos que podíamos usar exit para salir de un programa.

Esto no es exacto del todo: exit sale del bloque en el que nos encontremos, que puede ser un procedimiento o una función.  Por tanto, sólo sale del programa si ejecutamos exit desde el cuerpo del programa principal.

Si estamos dentro de un procedimiento, y queremos abandonar el programa por completo, deberíamos hacer más de un "exit".  Pero también hay otra opción: la orden "halt".

Halt sí que abandona el programa por completo, estemos donde estemos. Como parámetro se le puede pasar el "Errorlevel" que se quiere devolver al DOS, y que se puede leer desde un fichero batch.

Por ejemplo: "halt" o "halt(0)" indicaría una salida normal del programa (sin errores), "halt(1)" podría indicar que no se han encontrado los datos necesarios, etc.

Números aleatorios: random, randomize.

Si queremos utilizar números aleatorios (generados al azar) en nuestros programas, podemos emplear la función "random".  Si la usamos tal cual, nos devuelve un número real entre 0 y 1.  Si usamos el formato "random(n)", lo que devuelve es un número entero entre 0 y n-1.

Para que el ordenador comience a generar la secuencia de números aleatorios, podemos usar "randomize", que toma como semilla un valor basado en el reloj, lo que supone que sea suficientemente aleatorio:


{--------------------------} 
{  Ejemplo en Pascal:      } 
{                          } 
{    Ejemplo de números    } 
{    aleatorios (al azar)  } 
{    RANDOM1.PAS           } 
{                          } 
{  Este fuente procede de  } 
{  CUPAS, curso de Pascal  } 
{  por Nacho Cabanes       } 
{                          } 
{  Comprobado con:         } 
{    - Free Pascal 2.2.0w  }
{    - Turbo Pascal 7.0    } 
{--------------------------} 

program random1; 

var i:integer;

begin 
  Randomize; 
  for i := 1 to 50 do 
     Write (Random(1000), ' '); 
end.

Inc y Dec.

Son dos procedimientos que nos permiten aumentar o disminuir el valor de una variable.  Así  Inc(i)  es "casi" lo mismo que  i:=i+1   y  Dec(i) es "casi" lo mismo que i:=i-1.

Lo de "casi" es porque hay un par de diferencias:

Acceso a la impresora.

Acceder a la impresora desde Turbo Pascal es muy fácil:

writeln(lst, 'Hola');

Nada más y nada menos.  Con eso escribiremos "Hola" en la impresora (que está asociada al dispositivo "lst").  Esto está definido en la unidad printer, de modo que deberá nuestra programa deberá comenzar con

uses printer;

Así, un programa ya más completito quedaría:


{--------------------------} 
{  Ejemplo en Pascal:      } 
{                          } 
{    Prueba de la impre-   } 
{    sora                  } 
{    IMPRESOR.PAS          } 
{                          } 
{  Este fuente procede de  } 
{  CUPAS, curso de Pascal  } 
{  por Nacho Cabanes       } 
{                          } 
{  Comprobado con:         } 
{    - Turbo Pascal 7.0    } 
{--------------------------}
program impresor;

uses printer;

begin 
  writeln(lst,'Hola'); 
end.