Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Programación 1
2018
Todas las compilaciones a las que se harán referencia hablan del siguiente programa,
donde los fragmento A y B varı́an a lo largo de la nota.
program comp7 ;
const N = 4;
type
Rango = 1.. N ;
Arreglo = array [ Rango ] of Integer ;
var
i : integer ;
ordenado : boolean ;
tabla : Arreglo ;
begin
... fragmento A ...
... fragmento B ...
if ordenado then writeln ( ’ Ordenado ’) else writeln ( ’ Desordenado ’)
end .
1
están asociados a alguna variable; el tipo de una variable indica las caracterı́sticas de sus
posibles valores, pero nunca un valor.
Podemos leer lo siguiente en la Guı́a de Usuario de Free Pascal1
Error: Variable identifier expected This happens when you pass a constant
to a routine (such as Inc var or Dec) when it expects a variable. You can only
pass variables as arguments to these functions.
Se ha usado un for para cargar todo el arreglo. De esta manera estamos seguros que
todas las celdas serán inicializadas desde la entrada estándar.
A partir de ahora el fragmento A siempre será la siguiente lı́nea:
for i := 1 to N do read ( tabla [ i ]);
Y los restantes fragmentos que aparezcan se corresponden con B.
[Complementarios]$ ./comp7
1 2 3 4
Runtime error 201 at $00000000004002C0
$00000000004002C0 line 17 of comp7.pas
$000000000040018F
El mensaje de error tiene distintas partes; informa que es el error 201, ası́ lo podemos
buscar en el manual y saber qué pasó, y nos dice que aparece en la lı́nea 17 de nuestro
archivo2 , ası́ lo podemos encontrar rápidamente. También aparece otro mensaje, pero que
desde nuestro punto de vista no resulta informativo.
En la Guı́a del Usuario vemos el significado del error.
201 Range check error If you compiled your program with range checking on3 ,
then you can get this error in the following cases:
2
2. Trying to assign a value to a variable outside its range (for instance an
enumerated type).
La lı́nea 17 dice
if tabla [ i ] < tabla [ i +1] then
Por lo tanto, debemos investigar si i e i+1 están siempre en el rango de tabla. El menor
valor que toma i es 1, ası́ que no habrá problemas si N es mayor que uno; y el mayor valor
que toma i es N. Aquı́ si tenemos un problema ya que al final de la iteración preguntaremos
siempre por tabla[N+1], quedando fuera del rango.
Una forma equivocada de resolver este problema es fortaleciendo el condicional de la
siguiente forma
ordenado := False ;
for i := 1 to N do
if ( i + 1 <= N ) and ( tabla [ i ] < tabla [ i +1]) then
ordenado := True ;
Este intento de solución no da error de rango, pero es conceptualmente incorrecta, ya que para
evitar una iteración particular agrega una nueva condición en cada una de las N iteraciones
del for. El intento adecuado pasa por cambiar los lı́mites del bucle.
ordenado := False ;
for i := 1 to N -1 do
if tabla [ i ] < tabla [ i +1] then
ordenado := True ;
Observemos las siguientes ejecuciones del programa.
[Complementarios]$ ./comp7
1 2 3 4
Ordenado
[Complementarios]$ ./comp7
1 2 4 3
Ordenado
[Complementarios]$ ./comp7
999 888 999 888
Ordenado
Resulta que no estamos investigando si todas las parejas adyacentes cumplen la relación
de menor; estamos investigando si alguna pareja la cumple. La única posibilidad para que el
programa escriba Desordenado es que el arreglo sea decreciente.
La observación anterior nos proporciona una idea para corregir el código; investigaremos
si alguna pareja no cumple la relación de orden. La siguiente versión resuelve el problema.
ordenado := True ;
for i := 1 to N -1 do
if tabla [ i ] >= tabla [ i +1] then
ordenado := False ;
Otra posible solución con for serı́a usar ordenado como acumulador.
ordenado := True ;
for i := 1 to N -1 do
ordenado := ordenado and ( tabla [ i ] < tabla [ i +1])
3
Observemos que si ordenado toma el valor False no podrá volver a tomar el valor True.
El problema de decidir si el arreglo es creciente se ha reformulado como el problema de
decidir si alguna pareja adyacente de sus elementos está desordenada; es un problema de
búsqueda en un arreglo. Ya hemos visto que en estos casos la estructura repetitiva a usar
debe permitirnos terminar con el bucle apenas sea posible. Por lo tanto, aunque el código
determine si el arreglo está ordenado o no, el uso del for es un error conceptual importante.
4
i := 1;
while ( i <= N - 1) and not ( tabla [ i ] >= tabla [ i +1]) do
i := i + 1;
Es fácil constatar que este código y la última versión considerada en el último problema son
básicamente los mismos.
2. Compilación
En esta sección miraremos con mayor detalle algunos temas de compilación y ejecución.
Las primeras tres lı́neas del resultado indican la versión del compilador, el copyright, y
el sistema operativo al que se compila. No le prestaremos atención. A partir de la cuarta
lı́nea (Compiling ...) están los mensajes del compilador que nos ayudan a resolver los
problemas. Como se detectaron errores, la penúltima lı́nea nos informa que la compilación
abortó, y la última indica que el compilador avisó del error al sistema operativo. En este
momento solamente nos interesan los mensajes entre las lı́neas cinco y siete que nos ayudan
a arreglar los errores.
La quinta lı́nea informa que en la fila 13 y columna 14 del archivo comp7.pas se encontra-
ron dos errores con el mismo mensaje; ya los hemos resuelto en la primera sección. El último
error reportado en la lı́nea 15 solamente refiere al hecho de que llegó al final del programa
habiendo encontrado dos errores.
El compilador etiqueta cada mensaje como Fatal, Error, Warning, Hint, y Note. Al com-
pilar correctamente no aparecerán ni Fatal ni Error; es bueno entender y eliminar todos
los Warning. Los restantes etiquetados no corresponden a errores ni posibles errores. Pue-
den ver las diferencias entre estas etiquetas en www.freepascal.org/docs-html/current/
user/usersu13.html#x36-430005.1.2.
Como vimos antes, entender los mensajes requiere que busquemos información en la Guı́a
de Usuario.
[Complementarios]$ ./comp7
5
1 2 3 4
Desordenado
[Complementarios]$ ./comp7
1 2 4 3
Desordenado
[Complementarios]$ ./comp7
999 888 999 888
Desordenado