Ampliación 1. Otras órdenes no vistas.
Curso: Curso de Pascal, por Nacho Cabanes
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.
- Funciones: abs, sin, cos, arctan, round, trunc,
sqr, sqrt, exp, ln, odd, potencias.
- 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:
}
{ - 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:
}
{ - 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:
- La ventaja es que con Inc, el compilador genera un código algo más eficiente, con lo que ganamos en velocidad.
- Los dos inconvenientes son:
- No es estándar, así que es muy probable que no funcione en otro compilador.
- Sólo se puede usar con tipos de datos ordinales (números enteros, char, etc., pero no con reales, por ejemplo).
Funciones: abs, sin, cos, arctan, round, trunc, sqr, sqrt, exp, ln, odd, potencias.
La mayoría de las que vamos a ver son funciones matemáticas que están ya predefinidas en Pascal. Muchas de ellas son muy evidentes, pero precisamente por eso no podía dejarlas sin mencionar al menos:- Abs: valor absoluto de un número.
- Sin: seno de un cierto ángulo dado en radianes.
- Cos: coseno, análogo.
- ArcTan: arco tangente. No existe función para la tangente, que podemos calcular como sin(x)/cos(x).
- Round: redondea un número real al entero más cercano.
- Trunc: trunca los decimales de un número real para convertirlo en entero.
- Int: igual que trunc, pero el resultado sigue siendo un número real.
- Sqr: eleva un número al cuadrado.
- Sqrt: halla la raíz cuadrada de un número.
- Exp: exponencial en base e, es decir, eleva un número a e.
- Ln: calcula el logaritmo neperiano (base e) de un número.
- Odd: devuelve TRUE si un número es impar.
- Potencias: no hay forma directa de elevar un número cualquiera a otro en pascal, pero podemos imitarlo con "exp" y "ln", así:
{--------------------------}
{ Ejemplo en Pascal: }
{ }
{ Elevar un número real }
{ a otro }
{ ELEVAR.PAS }
{ }
{ Este fuente procede de }
{ CUPAS, curso de Pascal }
{ por Nacho Cabanes }
{ }
{ Comprobado con: }
{ - Turbo Pascal 7.0 }
{--------------------------}
program elevar;
function elevado(a,b: real): real;
begin
elevado := exp(b *ln(a) );
end;
begin
writeln(elevado(2,3));
end.
La deducción de esta fórmula es fácil, conociendo las propiedades de los logaritmos y las exponenciales
a^b = exp ( ln ( a^b )) = exp ( b * ln ( a ))
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.
Actualizado el: 20-07-2013 11:19