Documentos de Académico
Documentos de Profesional
Documentos de Cultura
IntroduccionPascal PDF
IntroduccionPascal PDF
on a la Programaci
on.
Pascal.
Vicente L
opez
Escuela T
ecnica Superior de Inform
atica
Universidad Autonoma de Madrid
( vicente.lopez@ii.uam.es )
2
Indice General
1 Esquemas B asicos 7
1.1 Ordenacion temporal . . . . . . . . . . . . . . . . . . . . . . . 7
1.2 Componentes basicos . . . . . . . . . . . . . . . . . . . . . . . 8
1.3 Trafico de informacion . . . . . . . . . . . . . . . . . . . . . . 9
2 Lenguajes 13
2.1 Procesamiento de informacion: hombre y ordenador . . . . . . 13
2.2 Formalizacion de los lenguajes . . . . . . . . . . . . . . . . . . 15
2.3 Las maquinas de Von Neuman . . . . . . . . . . . . . . . . . . 16
2.4 Breve historia de los lenguajes . . . . . . . . . . . . . . . . . . 17
2.5 Tipos de lenguajes . . . . . . . . . . . . . . . . . . . . . . . . 20
3 Algoritmos 23
3.1 Pasos en la resolucion . . . . . . . . . . . . . . . . . . . . . . . 23
3.2 Uso multiple . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.3 El ejemplo de Josefo . . . . . . . . . . . . . . . . . . . . . . . 25
4 Pascal 33
4.1 Caractersticas . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.2 El programa Pascal . . . . . . . . . . . . . . . . . . . . . . . . 34
4.3 Palabras reservadas y estructuras . . . . . . . . . . . . . . . . 35
4.4 Instrucciones sencillas y compuestas . . . . . . . . . . . . . . . 37
4.5 Diagramas de sintaxis . . . . . . . . . . . . . . . . . . . . . . 38
5 Datos 39
5.1 Variables, datos y direcciones . . . . . . . . . . . . . . . . . . 39
5.2 Identificadores . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.3 Tipos de datos . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3
4 INDICE GENERAL
6 Entrada y salida 51
6.1 Dispositivos de entrada, salida y almacenamiento . . . . . . . 51
6.2 Las funciones Read y Write . . . . . . . . . . . . . . . . . . . 52
6.3 Formatos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
6.4 Las funciones WriteLn y ReadLn . . . . . . . . . . . . . . . . 55
7 Acciones 59
7.1 Operaciones basicas. . . . . . . . . . . . . . . . . . . . . . . . 59
7.1.1 Operadores aritmeticos y expresiones aritmeticas. . . . 59
7.1.2 Funciones aritmeticas. . . . . . . . . . . . . . . . . . . 61
7.1.3 Aritmetica entera y real. . . . . . . . . . . . . . . . . . 62
7.1.4 Operadores logicos. . . . . . . . . . . . . . . . . . . . . 65
7.1.5 Expresiones logicas. . . . . . . . . . . . . . . . . . . . . 68
7.1.6 Manipulacion de bits. . . . . . . . . . . . . . . . . . . . 70
7.2 Sentencias de control. . . . . . . . . . . . . . . . . . . . . . . . 74
7.3 Sentencias de repeticion. . . . . . . . . . . . . . . . . . . . . . 79
7.4 Manipulacion de los datos STRING. . . . . . . . . . . . . . . 85
8 Modularidad 87
8.1 Dividir para vencer . . . . . . . . . . . . . . . . . . . . . . . . 87
8.2 Procedimientos . . . . . . . . . . . . . . . . . . . . . . . . . . 88
8.3 Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
8.4 Ambito de definicion de las variables . . . . . . . . . . . . . . 91
8.5 Paso de valores por contenido o direccion . . . . . . . . . . . . 92
8.6 Definicion diferida . . . . . . . . . . . . . . . . . . . . . . . . . 96
8.7 Modulos y submodulos . . . . . . . . . . . . . . . . . . . . . . 97
8.8 Recursividad . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
10 Ficheros 125
10.1 Ficheros con Tipo . . . . . . . . . . . . . . . . . . . . . . . . . 125
10.2 Procesamiento secuencial y aleatorio . . . . . . . . . . . . . . 131
10.3 Ficheros de Texto . . . . . . . . . . . . . . . . . . . . . . . . . 136
11 Punteros 141
11.1 Contenidos, direcciones e identificadores . . . . . . . . . . . . 141
11.2 Punteros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
11.3 Asignacion dinamica de memoria. . . . . . . . . . . . . . . . . 145
11.4 Declaraciones recursivas de tipos de datos . . . . . . . . . . . 147
6 INDICE GENERAL
Captulo 1
Esquemas b
asicos del
ordenador
1.1 Ordenaci
on temporal
Un ordenador es una maquina dise nada para el procesamiento automatico
de informacion.
El esquema mas sencillo de un ordenador actual es el siguiente:
7
8 CAPITULO 1. ESQUEMAS BASICOS
1.2 Componentes b
asicos
Globalmente a los dispositivos de entrada y salida se les denomina perifericos.
Los dispositivos de almacenamiento de informacion como discos, diskettes,
cintas,..., tambien son perifericos que son dispositivos de entrada o salida
seg
un se grabe o se lea la informacion.
A los componentes fsicos del ordenador se le denomina Hardware y a la
informacion que dirige la realizacion de las tareas se le denomina Software.
El ordenador, aparte de los perifericos, consta de dos componentes prin-
cipales: Unidad de memoria y unidad central de procesos.
Ordenador
Unidad
Unidad de
central de
memoria
procesos
A 2 4 1 J 3 3 u u u
1 2 3 4 5 6 7
1.3. TRAFICO
DE INFORMACION 9
unidad de
memoria
6
?
unidad
unidad - aritmetico
de
control
logica
1.3 Tr
afico de informaci
on
Vamos a ver de forma simplificada las acciones a las que da lugar en un
ordenador las instrucciones de un programa. Es fundamental comprender lo
inexcusable de la secuencialidad temporal de la instrucciones suministradas
al ordenador.
Como ejemplo vamos a considerar esta porcion de programa:
{1} a := 3;
{2} b := 5;
{3} c := a + b;
{4} c := c + 2;
{5} if (c > 9) then writeln(c);
10 CAPITULO 1. ESQUEMAS BASICOS
51 52 53
51 52 53
La segunda,
b := 5;
que en 52 almacene un 5,
3 5 0
51 52 53
51 52 53
1.3. TRAFICO
DE INFORMACION 11
51 52 53
Lenguajes de programaci
on
z =x+y .
El modo en que esta frase puede traducirse en una orden precisa para que la
realice un ordenador ha cambiado con el tiempo segun variaban los dise
nos de
los ordenadores. Primitivamente en ordenadores como el MARK I se trataba
de una secuencia de tripletes de perforaciones en un cinta. Hoy en da se
trata de las secuencias de ceros y unos del codigo binario. En el futuro los
programas podran parecerse a los pentagramas de m usica actuales.
Una lectura parcial de la expresion matematica anterior puede ser la
siguiente:
13
14 CAPITULO 2. LENGUAJES
z := x + y ;
X Y Z
@
@
R
@
LOAD X
ADD Y
STORE Z
2.2 Formalizaci
on de los lenguajes
Los lenguajes de alto nivel que vamos a estudiar en este curso son el resultado
de investigaciones realizadas desde dos enfoques distintos. Por una parte, un
lenguaje de programacion es un caso particular de un lenguaje formal; por
otra, una solucion al problema de ingeniera que surge en la construccion de
maquinas procesadoras de informacion.
La formalizacion de los lenguajes es un tema de investigacion desde los
antiguos griegos. Aristoteles (384332 A.C.) se puede considerar el padre
de la logica formal. Leibniz en el siglo XVII, y Frege en el XIX, intenta-
ron construir lenguajes formales sin la imprecision y ambiguedad de lenguaje
ordinario. Gorge Boole en 1854 proporciono un nuevo intento de forma-
lizacion con la introduccion de smbolos, formulas y axiomas. El metodo
logico de Boole permitio construir maquinas logicas que poda resolver au-
tomaticamente problemas logicos. Mas tarde, el espa nol Leonardo Torres
y Quevedo (18521939), entre otros dise nos mecanicos automaticos, cons-
truyo el Ajedrecista, un automata capaz de jugar al ajedrez. A finales del
siglo XIX y en el XX, los lenguajes formales se investigaron con el intento
de formalizar las matematicas de un modo similar a como Euclides haba
formalizado la geometra. Las ideas fundamentales de Russel, Whitehead,
Hilbert, Church, y finalmente Goedel, permitieron establecer la imposibili-
dad de ese proyecto. Turing y Post en 1936 introdujeron un formalismo de
manipulacion de smbolos ( la denominada maquina de Turing ) con el que se
puede realizar cualquier computo que hasta ahora podemos imaginar. Esta
fue una va de comunicacion entre los problemas formales de la computacion
y de la matematica. La union permitio demostrar que no existe ninguna
16 CAPITULO 2. LENGUAJES
2.3 Las m
aquinas de Von Neuman
Originalmente la programacion de un ordenador era directamente la reorde-
nacion de los componentes del ordenador. La idea de producir un programa
de ordenador que se pudiera almacenarse en la memoria del ordenador se
debe a Von Neuman y aparecio en un informe que hizo sobre el ordenador
EDVAC. Von Neuman considero la posibilidad de que una palabra formada
por 32 bit fuera o bien un numero o bien una instruccion. Una instruccion se
codificaba por un grupo de bits adyacentes y considero sumas, multiplicacio-
nes, transferencia de contenidos de memoria a registros, test, e instrucciones
de bifurcacion. As, un programa consistira en una secuencia de palabras en
forma binaria.
Necesidades practicas muy obvias llevaron a la utilizacion de mnemotecnicos
para programar las instrucciones, y posteriormente otro programador tra-
duca los mnemotecnicos a lenguaje maquina. El paso siguiente deba ser
conseguir que fuera el ordenador el que tradujera esas codificaciones y tam-
2.4. BREVE HISTORIA DE LOS LENGUAJES 17
Datos Programa
? ?
ordenador ordenador
? ?
Resultado Programa
Las aplicaciones.
. . .
hijo(X,Y) <- padre(Y,X) , varon (X).
hija(X,Y) <- padre(Y,X) , hembra (X).
abuelo(X,Z) <- padre(X,Y) , padre (Y,Z).
. . .
estableciendo relaciones logicas que determinan una base de verdades con las
que han de ser coherentes las respuestas del programa.
Exite una diferencia grande en la programacion con un lenguaje u otro
seg
un sea interpretado o compilado, si bien esta distincion puede no ser inhe-
rente al lenguaje sino a su puesta en practica en un determinado ordenador.
Un lenguaje es interpretado cuando la transformacion de las instrucciones de
alto nivel a lenguaje maquina se realiza sentencia a sentencia segun se van
ejecutando. Un lenguaje es compilado cuando esta trasformacion se realiza
en bloque antes de que ninguna instruccion sea ejecutada. Por ejemplo, el
BASIC en general se suele interpretar y el LISP siempre. En un lenguaje
interpretado la puesta a punto de un programa ha de realizarse secuencial-
mente puesto que las distintas partes del programa no se pueden verificar
hasta que entran en ejecucion.
En el caso mas com
un de lenguajes compilados, son varios los subprocesos
implicados en la transformacion del codigo de alto nivel en instrucciones
ejecutables por la UCP.
2.5. TIPOS DE LENGUAJES 21
Programa
COMPILADOR
Leng. maquina
H
HH
HH
L. maquina
HH
H
HH
HH
MONTADOR
Codigo UCP
datos que comparten todos los programas y asigna las direcciones comunes
donde cada uno debera procesar esos datos. Esta unificacion de direcciones
sera imposible si alg
un procedimiento supuestamente existente en otro sub-
programa no aparece o aparece de un modo no unvoco. Tambien sera causa
de error que algun dato compartido por subprogramas este declarado de mo-
do distinto en cada programa. Estos errores son poco comunes y facilmente
detectable con los mensajes de error proporcionados por el montador. Sin
embargo, los errores mas comunes y mas tediosos de eliminar son aquellos
de programacion que dan lugar a sentencias sintacticamente correctas pero
que corresponde a acciones distintas a las deseadas. Desgraciadamente solo
se detectan en la ejecucion del programa.
En la actualidad existe la posibilidad de utilizar depuradores de progra-
mas (llamados en ingles debuggers por el origen de los errores en los or-
denadores primitivos ) que permiten seguir la ejecucion paso a paso de un
programa aunque se obtenga el codigo maquina por compilacion. Esta he-
rramienta facilita enormemente la depuracion de los programas pues permite
conocer o modificar el valor de los datos manipulados en el programa durante
la ejecucion.
Captulo 3
Algoritmos y resoluci
on de
problemas con el ordenador
1. An
alisis del problema.
2. Realizaci
on de la estrategia ideada para su soluci
on.
3. Verificaci
on y an
alisis del rendimiento del procedimiento.
1. An
alisis del problema.
23
24 CAPITULO 3. ALGORITMOS
Dise
no del esquema del algoritmo que satisface las restricciones
del problema.
ALGORITMO: Procedimiento para resol-
ver un problema paso a paso.
ALGORITMO: Conjunto de operaciones
que secuencialmente conducen a la respuesta
a una pregunta en un n
umero finito de pasos.
Especificacion del modo de proporcionar la respuesta al problema
planteado
2. Realizaci
on de la estrategia ideada para su soluci
on.
Captura de datos.
Generacion de las estructuras de datos adecuadas para el algorit-
mo que se va a utilizar.
Especificacion de los algoritmos.
Presentacion de los resultados.
(a) DISENO.
(b) ESCRITURA.
(c) VERIFICACION.
3. Verificaci
on y an
alisis del rendimiento del procedimiento.
3.2 Uso m
ultiple
El uso m ultiple de los procedimientos para la resolucion de problemas con
el ordenador implica que los procedimientos han de cumplir los siguientes
requisitos:
La resolucion de un mismo problema con distintos datos y en periodos
largos de tiempo obliga a:
1. Realizacion de procedimientos muy bien verificados.
2. Realizacion de procedimientos muy bien documentados y escritos
con un estilo claro.
La resolucion de un mismo tipo generico de problemas o variantes del
mismo, con reutilizacion de las herramientas desarrolladas, obliga a:
1. Realizacion de procedimientos modulares.
2. Realizacion de procedimientos muy bien documentados y escritos
con un estilo claro.
El uso del procedimiento dentro de un equipo por distintas personas
para resolver un mismo problema o variantes de el, obliga a:
1. Realizacion de procedimientos muy bien verificados.
2. Realizacion de procedimientos modulares.
3. Realizacion de procedimientos muy bien documentados y escritos
con un estilo claro.
1. An
alisis del problema.
3 2
'$
4 -1
&%
5 6
2. Realizaci
on de la estrategia ideada para su soluci
on.
Captura de datos.
3.3. EL EJEMPLO DE JOSEFO 27
end; {endwhile}
Presentacion de los resultados.
{Se comunica el orden del ultimo en el circulo }
writeln (individuo^.numero);
nodo = record
numero: integer;
siguiente: enlace
end;
var
j , n : integer;
individuo , temporal: enlace;
begin { Josefo }
end; {endwhile}
end. { Josefo }
3. Verificaci
on y an
alisis del rendimiento del procedimiento.
Prueba con casos sencillos.
Se probara con N = 6 para el que se conoce bien el resultado.
Prueba con casos complejos.
Se probara con N grande.
Prueba con casos extremos.
Se probara con N = 1.
Analisis del rendimiento en casos poco favorables y en casos tpicos.
En este caso el algoritmo utilizado crece linealmente con el numero
de individuos considerado.
Refinamiento de los algoritmos.
En este caso un analisis mas detallado del problema lleva a un
algoritmo mucho mas eficiente y cuyo costo computacional es in-
dependiente del n
umero N de elementos en el crculo:
3.3. EL EJEMPLO DE JOSEFO 31
Si se descompone N de la forma N = 2m + l el u
ltimo elemento
que se elimina es el 2l + 1.
Refinamiento de la escritura de los algoritmos.
Uso m
ultiple del programa.
Verificacion.
La verificacion a menudo debe incluir pruebas para detectar el mal uso
del programa por parte de un usuario que no esta familiarizado con el
programa o con el problema.
En el programa Josefo la captura de datos de datos podra incluirse
una especificacion del dato requerido y una verificacion del valor.
Modularidad.
Documentacion.
Claridad de estilo.
El programa Josefo si se acompa na de la adecuada documentacion
externa permite su utilizacion para distintos datos y en tiempos futuros.
Su modificacion para variantes del mismo problema es sencilla. Ima-
ginemos que el problema se modifica y se eliminan elementos saltando
cada vez M individuos en vez de 2. Aparte de la modificacion en la
entrada de datos , la modificacion del algoritmo es mnima y sencilla
de localizar:
se modificara a:
Esta modificacion sera igual de facil para el autor original del programa
como para cualquier otro programador.
Captulo 4
4.1 Caractersticas
El PASCAL es un lenguaje relativamente moderno, desarrollado por Niklaus
Wirth y su grupo de Zurich en 1971. Se trata de un lenguaje de proposito
general, esto quiere decir que se puede emplear para construir todo tipo de
aplicaciones. En la practica tambien quiere decir que se trata de un lenguaje
no dise
nado para desarrollar ning un tipo especfico de aplicaciones. Pero el
PASCAL es especialmente u til para algo: para la ensenanza de buenos modos
de programacion. El PASCAL es hoy en da el lenguaje mas usado para la
ensenanza de la programacion por varios motivos:
El hecho de que tenga una estructuracion muy marcada permite que los pro-
gramas sean faciles de leer e interpretar, y facilita la escritura de programas
del modo que hoy en da se estima correcto.
El compilador de PASCAL es relativamente sencillo de realizar, por lo
que se ha extendido a muchos tipos de plataformas, desde los ordenadores
personales a los grandes ordenadores corporativos. Cuando una aplicacion
se escribe en PASCAL estandard puede compilarse en cualquier maquina en
la que exista compilador de PASCAL , que son la mayora.
33
34 CAPITULO 4. PASCAL
Existen varios dialectos locales del PASCAL , entre los que se encuentra el
TURBO PASCAL , que admiten todas las instrucciones del PASCAL estan-
dard mas un subconjunto especfico de instrucciones normalmente pensadas
para aumentar las capacidades del lenguaje en un ordenador particular.
El TURBO PASCAL , de la compa na Borland (Scotts Valley, Califor-
nia) es un dialecto del PASCAL que incluye ademas de las instrucciones del
PASCAL estandard una serie de instrucciones que permiten desarrollar apli-
caciones especficas para ordenadores IBM PC o IBM PS y compatibles. No
es la unica de las versiones de PASCAL existente para estos ordenadores,
pero sin duda la mas extendida y probada. En la actualidad la version 6.0 de
este lenguaje incluye ademas del compilador un entorno integrado de desa-
rrollo (IDE) que permite compilar, visualizar errores y depurar los programas
desde un mismo entorno.
y es equivalente a:
Program nombre ;
Program nulo;
{ Programa ejemplo de la estructura
mas simple de un programa PASCAL }
Begin
End.
{ Este es un comentario
(* sintacticamente *)
correcto en PASCAL }
{5} Const
{6} nombre constante = valor ;
. . .
{7} Type
{8} nombre tipo = def tipo ;
. . .
{9} Var
{10} nombre variable : tipo dato ;
. . .
{11} Begin
. . .
Instruccion sencilla J
J
- J -
E
E
E
E
E
E
E
E
E
Begin Instruc. senc. End
;
{4} Begin
{5} b := a * a ;
{6} b := b * a ;
{7} End;
Datos
3.14159 contenido
6
nombre
PI - 7161 direccion
Las primeras instrucciones de un programa han de ser las que indican los
tipos de datos que se van a utilizar. Cuando un nombre se utiliza para un
dato que no va a modificarse se trata de un a constante. Si por el contrario
se permite que el contenido de las posiciones de memoria referidas por un
determinado nombre varen durante la ejecucion del programa, se trata de
una variable.
Program Uno;
Const
39
40 CAPITULO 5. DATOS
PI = 3.14159;
UNIDADES = radianes ;
Var
n , m : Integer;
z : Real;
Begin
. . . .
5.2 Identificadores
Los nombres que se pueden utilizar para referirse tanto a las variables como
a las constantes son todos aquellos que no establezcan conflicto con las pala-
bras reservadas en PASCAL para especificar datos o acciones. NO pueden
utilizarse:
Palabras reservadas
1YA 2ABC
N
umeros enteros:
42 CAPITULO 5. DATOS
Integer
Byte
ShortInt
Word
LongInt
N
umeros reales:
Real
Double
Single
Extended
2. Caracteres y alfanumericos.
Char
String
3. Valores de la logica de Boole
Boolean
Integer
Es el tipo de variable que se usa para numeros enteros ( sin parte
decimal ) con signo. Para una variable Integer se reservan dos bytes
(16 bits) en memoria y puede almacenar n umeros enteros en el rango
entre
Word
En este tipo de datos se pueden almacenar enteros sin signo. Al igual
que para el tipo Integer, para el tipo Word se reservan 2 bytes en
memoria y puede admitir n umeros enteros entre 0 y 65, 535.
Byte
En PASCAL es posible utilizar un tipo de dato llamado Byte, para el
que , como su nombre indica, solo se reserva 1 byte de memoria. En
las variables tipo Byte se pueden almacenar n umeros enteros sin signo
y por tanto tendran que estar limitados entre 0 y 255(28 1).
Real.
Para almacenar n umeros reales ( con parte decimal ) o enteros que
excedan el lmite permitido por LongInt , se ha de utilizar el tipo de
variable Real . A este tipo de datos tambien se le conoce con el nombre
de coma flotante por el uso que se hace de los 6 bytes que se reservan
en memoria para este tipo de datos. Con los 6 bytes y una forma de
representar el numero algo rebuscada que estudiaremos con los erro-
res numericos, se pueden almacenar n umeros entre 2, 91039 y 1, 71038
tanto positivos como negativos. Debido a la representacion interna
utilizada, se almacenan con igual precision (7 u 8 cifras significativas)
todos los numeros reales en el rango permitido.
Las operaciones con n umeros en la representacion en coma flotante
son mucho mas lentas que entre n umeros enteros representados direc-
tamente con su valor en base 2. Un coprocesador matematico (como
los 80X87) se dedica especficamente a estas operaciones. El TURBO
PASCAL permite una coleccion de datos para tratar eficientemente con
numeros reales cuando se dispone del coprocesador matematico. Cuan-
do no se dispone de el, las operaciones se pueden emular por software
aunque son mas lentas. Esta coleccion de tipos de datos son:
Single
El tipo de datos Single es un Real mas corto (4 bytes) con el
mismo rango de variacion que el Real , pero con menos cifras
significativas.
Double
44 CAPITULO 5. DATOS
Boolean
Los valores que puede tomar una variable logica, dentro de la logica
Booleana (George Boole, Inglaterra 1815 1864), son Verdadero o Fal-
so. En PASCAL se suelen utilizar este tipo de variables para almacenar
el resultado comparaciones o el establecimiento de condiciones. Su dos
valores posibles son True y False.
Var
mayor , menor : Boolean;
{ ...... }
begin
{ ...... }
mayor := True;
menor := False;
{ ...... }
Char
Para un dato del tipo Char se reserva un solo byte de memoria. En
ese byte se puede almacenar informacion de un caracter alfanumerico.
Si bien en la memoria del ordenador se esta almacenando un n umero
entero entre 0 y 255, este numero no puede entrar a formar parte de
operaciones aritmeticas con n
umeros enteros pues se entiende que se
trata de un caracter ASCII. El numero almacenado es el ordinal del
caracter en la tabla ASCII.
String
Cuando se quieren manipular grupos de caracteres ordenados, como
por ejemplo en texto, se dispone del tipo de datos String. En una
5.3. TIPOS DE DATOS 45
Program Dos;
Const
Lugar = modulo;
Var
facultad : Char;
modulo , clase : String[6];
begin
{ ...... }
facultad := C;
modulo := -XVI;
clase := facultad + modulo;
writeln( Sera en el ,Lugar, ,clase);
{ ....... }
end.
4 - X V I % A
Program Tres;
Const
lugar : String[13] = modulo;
begin
{ ...... }
lugar := lugar + C+ -XVI;
writeln( Sera en el ,lugar);
{ ....... }
end.
5.5 Inicializaci
on de los datos
Dado que en PASCAL no se inicializan a cero , falso, o caracteres blancos, las
variables cuando se define su tipo, hay que tener precaucion de no utilizar el
contenido de posiciones de memoria reservadas y no asignadas. Una medida
tajante es inicializar todas las variables.
5.6 Asignaci
on de las constantes
Cuando se asigna el valor a una constante no se identifica explcitamente el
tipo de dato del que se trata. Esta identificacion se realiza por el contenido del
termino a la derecha del operador =. Tanto en la asignacion de constantes,
como en la de variables en el cuerpo del programa, el compilador decide el
espacio de memoria que ha de reservar para cada valor por el modo en que
esta escrito.
DE LOS DISTINTOS TIPOS DE VARIABLES
5.7. ASIGNACION 47
Const
lugar = modulo;
En este caso, lugar es una constante del tipo String por que le asigna un
valor que es un conjunto de caracteres separados por comas.
Const
facultad = C;
Cuando entre comas se sit ua un solo caracter, se trata del valor de una
constante Char . Tambien es sencillo reconocer los datos Boolean porque
se les asigna el indicador True o False . En el caso de los n umeros, la
distincion se realiza entre enteros y reales. Para las constantes asignadas
con numeros reales, el compilador elige el tipo Real, y para los enteros el
Integer. La distincion entre n umeros enteros y reales se hace por existencia
de punto decimal en el valor. Para los n umeros reales existe tambien la
posibilidad de notacion cientfica.
Const
Pi = 3.14159;
PiMedios = 1570.8e-3;
PiGrados = 180 ;
El compilador PASCAL interpreta que PiGrados es una constante Integer
, y las otras dos constantes del tipo Real .
5.7 Asignaci
on de los distintos tipos de va-
riables
En el cuerpo del programa se suelen asignar valores a variables. En este
caso, a partir de las instrucciones de la seccion destinada a la identificacion
del tipo de variables, se reserva el espacio adecuado de memoria para cada
variable. Por tanto, es importante que en el lado derecho del operador de
asignacion (:=) se encuentre un valor correspondiente al tipo de variable de
lado izquierdo.
Program Cuatro;
const
Calle = Paloma Blanca ;
48 CAPITULO 5. DATOS
Direccion = 11 ;
Puerta = B ;
var
nombre : String[40];
numero : Integer;
letra : Char;
begin
{ Asignaciones incorrectas }
(* Asignaciones ilegales
{1} nombre := Direccion;
{2} numero := Calle;
{3} numero := Puerta;
{4} letra := Calle;
{5} letra := Direccion ;
{6} nombre := 98;
{7} numero := Paloma Negra ;
{8} numero := A ;
{9} letra := Paloma Negra ;
{10} letra := 97 ;
*)
(* Asignaciones legales *)
{11} nombre := Puerta;
{12} nombre := C;
{ Asignaciones correctas }
{13} nombre := Calle;
{14} nombre := Paloma Negra ;
{15} numero := Direccion;
{16} numero := 97;
{17} letra := Puerta;
{18} letra := A;
end.
Las instrucciones {11} y {12} son incorrectas porque asignan a una variable
del tipo String una constante del tipo Char. No obstante, estas instruc-
ciones no dan lugar a error en PASCAL porque el compilador interpreta las
variables Char como un subconjunto de las String (El espacio reservado en
DE LOS DISTINTOS TIPOS DE VARIABLES
5.7. ASIGNACION 49
Program Cinco;
const
Doce = 12.0;
Once = 11;
var
i : Integer;
z : Real;
begin
{ Asignaciones incorrectas }
(* Asignaciones ilegales
{1} i := Doce ;
{2} i := 24 ;
*)
(* Asignaciones legales *)
{3} z := Once ;
{4} z := 22 ;
{ Asignaciones correctas }
{5} i := Once ;
{6} i := 24 ;
{7} z := Doce ;
{8} z := 22. ;
end.
Intercambio b
asico de datos y
resultados
51
52 CAPITULO 6. ENTRADA Y SALIDA
Program Uno;
{ Cuadrado de un numero entero }
Var
base , resultado : integer;
Begin
{1} Read(base);
{2} resultado := base * base;
{3} Write(resultado);
End.
2 7 3 1
2 7 3 1
2 7 3 1
Area del cuadrado : es una constante del tipo String cuyo valor
es la ordenacion de los 19 caracteres entre las comillas .
6.3 Formatos
En un principio es deseable controlar exactamente el modo en el que se
escribe el valor de las variables en el dispositivo de salida. Esto puede ha-
cerse especificando el formato de escritura. En PASCAL cualquier variable o
constante que se incluya en el argumento del procedimiento Write() puede
acompa narse de una especificacion del formato de salida del siguiente modo:
nombre:n:m
que han de ocupar la parte decimal (despues del punto) cuando el tipo de
variable o constante lo permita.
Por ejemplo,
Program Tres;
var
resultado, base , altura : Integer;
Begin
{1} Read(base,altura);
{2} resultado := base * altura;
{3} Write(Area del triangulo: :40,resultado:6);
end.
dara como resultado
Area del triangulo: 837
Los espacios que no ocupan el contenido de la variable o constante, se sit uan
a la izquierda. En el caso de tratarse de n
umeros reales, si no se especifica el
n
umero de cifras decimales, se toma por defecto la notacion cientfica. Estos
son algunos ejemplos de escritura de un n umero real:
Write(102030.40:8 ) 1.0E+0005
Write(102030.40:10) 1.0E+0005
Write(102030.40:12) 1.020E+0005
Write(102030.40:14) 1.02030E+0005
Write(102030.40:8:1) 102030.4
Write(102030.40:10:1) 102030.4
Write(102030.40:14:2) 102030.40
Program Cuatro;
var
resultado, base , altura : Integer;
Begin
{1} Read(base,altura);
{2} resultado := base * altura;
{3} Writeln( Resultado del calculo.);
{4} Writeln(Area del triangulo: :40,resultado:6);
end.
para los mismos datos suministrados al programa Tres sera:
Resultado del calculo.
Area del triangulo: 837
Equivalentemente, existe el procedimiento Readln() que lee el valor de sus
argumentos siempre y cuando no encuentre la secuencia de control < EOL >.
Al programa Cinco se han de introducir los datos de modo distinto que
al Cuatro. Si se utiliza el teclado, hay que teclear el caracter de control
< CR > entre los dos n umeros, puesto que < CR > act ua tambien como
indicador de fin de linea.
Program Cinco;
var
resultado, base , altura : Integer;
Begin
{1} Readln(base);
{2} Readln(altura);
{3} resultado := base * altura;
{4} Writeln( Resultado del calculo.);
{5} Writeln(Area del triangulo: :40,resultado:6);
end.
En un archivo, los saltos de carro estan codificados con el caracter ASCII
correspondiente a la secuencia de control < EOL >.
Por ejemplo, un archivo que se imprime o aparece en pantalla del siguiente
modo:
3
4
es:
3 4
5
la salida sera:
Acciones
7.1 Operaciones b
asicas.
Una vez conocidos los modos basicos que existen en PASCAL para almacenar
datos en la memoria del ordenador y conocido el modo basico de comunica-
cion con el usuario del programa, pasamos a estudiar que operaciones se
pueden realizar con los datos.
a:= 3. + 5.;
b:= a - 2.;
b:= b * a * 6.;
c:= -b / 12.;
59
60 CAPITULO 7. ACCIONES
formato de instruccion,
+
variable1 := operando1 operando2;
/
2. parentesis.
3. multiplicacion y division.
4. suma y resta.
y := F ( x ) ;
los tipos de datos que admiten como argumento, x, los tipos de datos que
proporcionan, y, y las funciones que realizan son:
F(x) x y
Abs ( x ) Real o Integer igual que x Valor absoluto
Arctan ( x ) Real o Integer Real Arco tangente
Cos ( x ) Real o Integer Real Coseno
Exp ( x ) Real o Integer Real Exponenciacion ( ex )
Frac ( x ) Real o Integer Real La parte decimal de x
Int ( x ) Real o Integer Real La parte entera de x
Ln ( x ) Real o Integer Real Logaritmo neperiano
Pred ( x ) Integer Integer x1
Random Real Numero aleatorio, y[0, 1]
Random(x) Integer Integer Numero aleatorio, y[0, x]
Round ( x ) Real Integer x redondeado al entero mas cercano
Sin ( x ) Real o Integer Real Seno
Sqr ( x ) Real o Integer Real Exponenciacion
( x2 )
Sqrt( x ) Real o Integer Real x
Succ ( x ) Integer Integer x+1
Trunc ( x ) Real Integer x con la parte decimal eliminada
Las funciones trigonometricas que no estan incluidas, se calculan facilmente
a partir estas. Por ejemplo,
7.1.3 Aritm
etica entera y real.
El PASCAL realiza una comprobacion escrupulosa del tipo de los datos en
general, y en particular en el procesamiento de las expresiones aritmeticas.
Cuando se programan estas expresiones hay que verificar que se mezclan
coherentemente datos reales y enteros.
PASCAL considera Integer el resultado de una expresion aritmetica
siempre que en la expresion aparezcan solo datos de este tipo y no este
implicada una division. El el programa Uno,
Program Uno;
Var
i,j : Integer;
z : Real;
Begin
{1} j := 8;
(*
{2} i := j / 4; Expresion aritmetica invalida
*)
{3} z := j / 4;
{4} Writeln(z:4:2);
end.
Program Dos;
Var
i,j : Integer;
z : Real;
Begin
{1} j := 2333;
{2} i := j * 23;
7.1. OPERACIONES BASICAS. 63
{3} Writeln(i:9);
(*
{4} i := 2333 * 23; Expresion aritmetica invalida
*)
{5} z := j * 23;
{6} Writeln(z:9:0);
{7} z := 1.0 * j * 23 ;
{8} Writeln(z:9:0);
{9} z := 2333 * 23;
{10} Writeln(z:9:0);
end.
es:
-11877
-11877
53659
53659
z := 3600 * i ;
z := 3600. * i ;
j Div i
es j/i cuando j es m
ultiplo de i, y la parte de entera de j/i en el caso
contrario.
En el programa Tres ,
Program Tres;
Var
i,j,k : Integer;
Begin
{1} i := 11; j := 6;
{2} k :=10 * ( (i+j) Div j );
{3} Writeln(k:9);
{4} k := 10 * Trunc ( (i+j) / j );
{5} Writeln(k:9);
{6} k := Trunc (10* ( (i+j) / j ) );
{7} Writeln(k:9);
end.
j M od i
es 0 cuando j es m
ultiplo de i, y el resto de la division j/i en el caso contrario.
Program Cuatro;
Var
i,j,k,m : Integer;
Begin
{1} i := 11; j := 6;
{2} k :=j mod i;
{3} Writeln(k:9);
{4} m := j * (i mod j) + k;
{5} Writeln(i:9, ,m:9);
end.
2
14 14
7.1.4 Operadores l
ogicos.
Los operadores logicos que proporciona el PASCAL son de dos tipos:
El primero de estos tipos es muy util para tomar decisiones como resultado
de la comparacion de variables. La forma general en la que aparecen estos
66 CAPITULO 7. ACCIONES
operadores es:
=
<>
>
a b
<
<=
>=
Operador Condicion
= a=b
<> a 6= b
> a>b
< a<b
<= ab
>= ab
En el caso de que de que a y b sean caracteres, las operaciones de comparacion
se realizan sobre el valor entero del caracter ASCII correspondiente.
Ejemplos de utilizacion de estos operadores son:
Program Cinco;
Var
quizas : Boolean;
letra : Char;
i,j : Integer;
a,tan1,tan2,x : Real;
Begin
{1} i := -11; j := 6; letra := h; x:= 1.3;
{2} quizas := i > j;
{3} Writeln(quizas); (* FALSE *)
{4} quizas := k <= letra ;
{5} Writeln(quizas); (* FALSE *)
{6} tan1 := Sin(x) / Cos(x);
7.1. OPERACIONES BASICAS. 67
{7} a := Sin(x);
{8} tan2 := a / Sqrt ( 1.0 - a * a ) ;
{10} quizas := ( tan1 = tan2 );
{11} Writeln(quizas); (* FALSE *)
end.
Merece la pena recordar una vez mas que no se pueden trasladar directa-
mente las expresiones matematicas a las sentencias de un programa. Por
ejemplo, en la instruccion {10} se asigna a quiz
as el valor FALSE , si bien
las expresiones utilizadas en las instrucciones {6} y {8} para calcular la
tangente son matematicamente equivalentes. Debido a la utilizacion de una
representacion finita de los n
umeros reales ambos valores seran ligeramente
distintos. La comparacion para averiguar la similitud de numeros reales se
suele hacer utilizando la diferencia relativa:
Not operando
donde tanto operando como el resultado de la operacion son datos del tipo
Boolean. El resultado, es la negacion del operando:
a Not a
True False
False True
A B A And B
True False False
False True False
False False False
True True True
A B A Or B
True False True
False True True
True True True
False False False
A B A Xor B
True False True
False True True
True True False
False False False
7.1.5 Expresiones l
ogicas.
Program Seis;
Const
(* Coordenadas cartesianas que definen los rect
angulos *)
xa1 = 2; ya1 = 2; { Esquina inferior de A }
xa2 = 7; ya2 = 6; { Esquina superior de A }
xb1 = 5; yb1 = 4; { Esquina inferior de B }
xb2 = 10; yb2 = 8; { Esquina superior de B }
var
dentro1, dentro2, dentrox , dentroy , frontera : Boolean;
puntox,puntoy : Integer;
Begin
{1} Readln(puntox , puntoy); {Coordenadas del punto problema}
(* Sin considerar la frontera *)
{2} dentrox := ( puntox > xb1 ) And (puntox < xa2);
{3} dentroy := ( puntoy > yb1 ) And (puntoy < ya2);
{4} dentro1 := dentrox And dentroy;
{5} Writeln( Si no se considera el borde : ,dentro1);
(* Considerando la frontera *)
{6} dentro2 := ( puntox >= xb1 ) And (puntox <= xa2) And
70 CAPITULO 7. ACCIONES
7.1.6 Manipulaci
on de bits.
Existen operadores en PASCAL que permiten modificar directamente los
bits que componen los datos enteros. Estos datos estan almacenados en la
7.1. OPERACIONES BASICAS. 71
0 1 0 0 1 1 0 1
0 0 1 1 1 1 1 0
La operacion And entre estos dos datos da como resultado el dato Byte :
0 0 0 0 1 1 0 0
cuyo valor decimal es 12. Si sobre los datos originales se realiza la operacion
Or el resultado es:
0 1 1 1 1 1 1 1
0 1 1 1 0 0 1 1
72 CAPITULO 7. ACCIONES
cuyo valor decimal es 115. Estas tres operaciones son las que se realizan en
el programa Siete :
Program Siete;
Var
a , b , c: Byte;
Begin
a := 77;
b := 62;
c := a And b;
Writeln(c);
c := a Or b;
Writeln(c);
c := a Xor b;
Writeln(c);
End.
a1 a2 a3 a4 a5 a6 a7 a8
B, el resultado de
B := A Shl 3;
es,
a4 a5 a6 a7 a8 0 0 0
y, C, el resultado de
C := B Shr 7;
7.1. OPERACIONES BASICAS. 73
es,
0 0 0 0 0 0 0 a4
y el 32767 como
0111111111111111.
If datoBoolean
Then
accion1
o bien,
If datoBoolean
Then
accion1
Else
accion2
Boolean
?
HH
? H Cierto-
b ""
b
b" ?
Falso accion1
? ?
Continuar
Boolean
?
H?
" a
a
H
? ?
accion2 accion1
-
Continuar
Then
Writeln( Se trata de un numero positivo )
Else
Writeln( Se trata de un numero negativo );
positivo := ( n >= 0 ) ;
If positivo
Then
Writeln( Se trata de un numero positivo )
Else
Writeln( Se trata de un numero negativo );
End.
Program Diez;
Var
x , y : Real;
Begin { Diez }
{ Programa que calcula la raiz cuadrada de un numero }
Writeln( Calculo de la raiz cuadrada. Escriba el numero);
Readln(x);
End. { Diez }
Con esta estructura If ... Then ... Else tambien se pueden realizar de-
cisiones m
ultiples. Un modo muy frecuente de utilizacion es la encadenacion
de estructuras de la forma:
7.2. SENTENCIAS DE CONTROL. 77
If datoBoolean1
Then
accion1
Else
If datoBoolean2
Then
accion2
. . .
En el programa Once se utiliza una concatenacion de estructuras para rea-
lizar una eleccion m
ultiple.
Program Once;
Var
n : Integer;
Begin { Once}
{ Programa que reescribe con letras un numero del 1 al 5 }
Writeln( Teclear un numero del 1 al 5);
Readln(n);
If n = 1 then
Writeln( Uno )
Else If n = 2 Then
Writeln( Dos )
Else If n = 3 Then
Writeln( Tres )
Else If n = 4 Then
Writeln( Cuatro )
Else If n = 5 Then
Writeln( Cinco )
Else
Writeln( Numero fuera de rango);
End. { Once }
Este tipo de bifurcacion m ultiple puede llegar a ser difcil de leer y el
PASCAL proporciona una estructura mas legible para aquellos casos en los
que la bifurcacion multiple se realiza mediante comparacion de datos sencillos
ordinales (por tanto ni Real, ni String). Esta es la estructura Case que
tiene la siguiente sintaxis:
78 CAPITULO 7. ACCIONES
Case variable Of
caso1 : accion1
caso2 : accion2
. . .
End;
o bien,
Case identificador Of
caso1 : accion1
caso2 : accion2
. . .
Else
acciond
End;
donde identificador es una variable del tipo Integer, Byte, o Char, las
acciones accion1,... son instrucciones sencillas o compuestas, y los casos
caso1, ... son la especificacion de los valores. Esta especificacion se puede
hacer separando valores con comas o bien mediante el rango, si se trata de
valores consecutivos. Un rango se especifica mediante el valor inicial y final
separados por dos puntos. El programa Doce es equivalente al Once pero
mucho mas legible y eficiente.
Program Doce;
Var
n : Integer;
Begin { Doce}
{ Programa que reescribe con letras un numero del 1 al 5 }
Writeln( Teclear un numero del 1 al 5);
Readln(n);
Case n Of
1 : Writeln( Uno );
2 : Writeln( Dos );
3 : Writeln( Tres );
4 : Writeln( Cuatro );
5 : Writeln( Cinco );
Else
7.3. SENTENCIAS DE REPETICION. 79
End. { Doce }
Program Trece;
Var
c : Char;
n : Byte;
Begin { Trece}
{ Programa que identifica un caracter }
Writeln( Teclear el caracter);
Readln(c);
Case c Of
a..z, A..Z : Writeln(Letra);
0..9 : Writeln(Numero);
*,/,+,- : Writeln(Operador aritmetico);
>,<,= : Writeln(Operador logico);
Else
Begin
n := Ord(c);
Writeln(Simbolo ASCII ,n)
end;
End;
End. { Trece }
donde la funcion intrnseca del PASCAL Ord() es una funcion que devuelve
el valor ordinal de cualquier argumento escalar, incluyendo los Char.
puede programarse en una instruccion simple para que sea el ordenador quien
lo haga repetidas veces. De hecho, las sentencias de repeticion son general-
mente las responsables de la utilidad del ordenador. Se trata de instrucciones
que gobiernan la realizacion de tareas repetitivas mientras no sea cierta la
condicion que se imponga para la finalizacion.
En PASCAL existen tres estructuras de repeticion que son las construc-
ciones For Do, Repeat Until, y While Do.
La primera de ellas, la construccion For Do, tiene la siguiente sintaxis:
Program Catorce;
Var
z : Real;
n ,i : Integer;
Begin
Writeln(Calculo del factorial (introducir el numero));
Readln(z);
n := Round(z);
If n > 33
7.3. SENTENCIAS DE REPETICION. 81
Then
Writeln( Solo se puede calcular hasta 33!)
Else
Begin
z := 1.;
For i:=1 to n do
z:= z * i;
Writeln(El Factorial de ,n:2, es : );
Writeln(z:40:0)
End;
End.
Program Quince;
Var
i : Char;
Begin
(* Programa que escribe el alfabeto al reves *)
Writeln();
For i:=Z Downto A do
Write( ,i);
End.
i,n : Integer;
Begin
Writeln(Escribo los numeros de dos en dos);
Writeln(Empezando en 1 y acabando en ?);
Readln(n);
n := n - (n Mod 3) ;
For i:=1 to n do
Begin
Writeln(i);
i := i +2
End;
End.
Repeat
accion1;
accion2;
. . .
Until DatoBoolean
Program Diecisiete;
Var
n ,i : Integer;
Begin
Writeln(Adivina el numero que he generado ( del 1 al 9 ));
Writeln( Teclea 0 para terminar );
7.3. SENTENCIAS DE REPETICION. 83
Randomize;
Repeat
i := Random(8);
Writeln(Dime un numero );
Readln(n);
If i+1 <> n
Then
Writeln( No acertaste, era el ,i+1)
Else
Writeln( Si );
Until n = 0 ;
End.
While DatoBoolean Do
accion
Program Dieciocho;
Var
n ,i : Integer;
Begin
Writeln(Adivina el numero que he generado ( del 1 al 9 ));
Writeln( Teclea 0 para terminar );
Randomize;
Writeln(Dime un numero );
Readln(n);
While n <>0 do
84 CAPITULO 7. ACCIONES
Begin
i := Random(8);
If i+1 <> n
Then
Writeln( No acertaste, era el ,i+1)
Else
Writeln( Si );
Writeln(Dime un numero );
Readln(n);
End; {endwhile}
End.
Cuando se ha de programar un procedimiento repetitivo, la eleccion de una
de las tres estructuras se hara siempre considerando la claridad y facilidad
de programacion.
En PASCAL tambien existe la sentencia de control no estructurado Goto,
pero no la consideraremos pues en este curso se pretende que el alumno
ejercite la programacion estructurada. Sin embargo, si que consideramos la
funcion Exit cuya efecto es interrumpir la ejecucion del bloque en la que
se encuentra. Si se trata del programa principal, producira la interrupcion
de la ejecucion del programa. En el programa Diecinueve se modifica el
Diecisiete para interrumpir el juego haciendo uso de la funcion Exit.
Program Diecinueve;
Var
n ,i : Integer;
Begin
Writeln(Adivina el numero que he generado ( del 1 al 9 ));
Writeln( Teclea 0 para terminar );
Randomize;
Repeat
i := Random(8);
Writeln(Dime un numero );
Readln(n);
If n = 0 Then Exit;
If i+1 <> n
Then
Writeln( No acertaste, era el ,i+1)
DE LOS DATOS STRING.
7.4. MANIPULACION 85
Else
Writeln( Si );
Until n = 0 ;
End.
7.4 Manipulaci
on de los datos STRING.
Las sentencias de repeticion son u
tiles para manipular el contenido de los da-
tos String accediendo a cada uno de los caracteres que componen la cadena.
Como vimos en su da, si s es un dato String ( una ordenacion consecutiva
de datos del tipo Char) el caracter almacenado en s[0] indica el n umero
de caracteres almacenados en el dato. Ese caracter, como cualquier otro, se
puede convertir a dato entero utilizando la funcion Ord(). Igualmente, se
puede modificar la longitud asignando un nuevo caracter a s[0]. Los carac-
teres almacenados en s tambien se pueden modificar uno a uno y se accede
a ellos mediante s[i] donde i es un entero que corresponde a su n umero de
orden dentro de la cadena. Por ejemplo,
s[2] := b;
hace que el segundo caracter almacenado en s sea el caracter b.
En el programa Veinte tenemos un ejemplo sencillo de manipulacion de
los caracteres de una cadena:
Program Veinte;
Var
s : String[10];
longitud, i : Integer;
Begin
s := ABCDEF;
longitud := Ord(s[0]) ;
Writeln(La longitud original es : ,longitud);
For i:=1 to longitud Do
writeln(Componente ,i:2, : ,s[i]);
s[0]:= Char(3);
s[2] := b;
Writeln(Despues de truncada y modificada: , s);
End.
86 CAPITULO 7. ACCIONES
La longitud original es : 6
Componente 1 : A
Componente 2 : B
Componente 3 : C
Componente 4 : D
Componente 5 : E
Componente 6 : F
Despues de truncada y modificada: AbC
Captulo 8
Modularidad
i=0 1r
y el esquema que podemos trazar para el programa es el siguiente:
Suma de la progresion:
(1) Lectura de datos
(2) Calculo de la expresion
(3) Salida de resultados
A su vez, el calculo de la expresion matematica no es inmediato puesto que
es necesario calcular rn donde r es real y n entero. Tambien podemos des-
componer la tarea (2) en:
87
88 CAPITULO 8. MODULARIDAD
Program SumaProgresion;
Var
n : Integer;
r,a,suma : Real;
(* Declaracion de procedimientos y funciones *)
. . . . . . . . . . . . . . . . . . . .
(* Fin de la parte declarativa *)
Begin { SumaProgesion }
{ Se utiliza la expresion: suma = a (1-r**n) / (1-r) }
LeerDatos(n,a,r);
CalcularExpresion;
SacarResultados(suma);
End. { SumaProgresion}
8.2 Procedimientos
La sintaxis con la que se especifican estos procedimientos es similar a la de
un programa PASCAL pero se usa la palabra reservada Procedure para
indicar que se trata de un procedimiento parcial:
Parte declarativa
Begin
Bloque de sentencias del procedimiento
End;
8.3 Funciones
Muy parecida a la estructura Procedure es la estructura Function y se
utiliza para aquellos casos en los que se desea que el dato que se calcula en el
modulo independiente pueda aparecer en cualquier instruccion PASCAL en
el mismo lugar en el que aparecera el dato. Este es el caso de las funciones
intrnsecas del PASCAL que ya se han visto. La sintaxis de la estructura
Function es:
En el argumento se especifican las dos variables con las que nos vamos a
referir al exponente y a la base, el exponente ha de ser un valor entero y
la base puede ser real. A continuacion, se especifica que el valor que ha de
devolver la funcion al bloque donde ha sido llamada es Real. Para realizar
el calculo se necesitan otras dos variables y se definen en la parte declarativa.
En las instrucciones {2}, {5} y {11}, aparece el nombre de la funcion en
la parte izquierda de una asignacion y es en ellas donde se especifica el valor
que puede devolver la funcion. La llamada a Poten desde el procedimiento
CalcularExpresi on :
End; { CalcularExpresion }
8.4
Ambito de definici
on de las variables
Las variables que se definen en la parte declarativa de un procedimiento
o una funcion existen solamente para ese modulo. Se reservan lugares de
memoria para acomodarlas cuando se requiere el calculo del modulo y se
liberan cuando se termina la ejecucion de los algoritmos especificados en
el modulo. Por tanto, si en alg un otro modulo del programa, o en la parte
principal, se utilizan esas variables, el compilador avisara de que no se conoce
el tipo de dato de esos identificadores. Por otro lado, se pueden utilizar
los mismos nombres para variables definidas en distintos modulos ya que el
compilador interpretara correctamente el hecho de que con cada nombre se
refiere al lugar de memoria reservado para el dato que se va a manipular en
cada modulo. El u nico modo que hay para pasar valores de datos desde un
92 CAPITULO 8. MODULARIDAD
Program SumaProgresion;
Var
n : Integer;
r,a,suma : Real;
{ Lectura de datos }
Procedure Leerdatos( Var numero: Integer;
Var primero , razon : Real );
Begin {Leerdatos}
Writeln ( Primer termino de la serie? );
Readln (primero);
Writeln ( numero de terminos? );
Readln (numero);
Writeln ( Razon de la serie? );
Readln (razon);
End; {Leerdatos}
z := base;
For i := 2 to exponente Do
z := z * base;
Poten := z
End;
End; { Poten }
End; { CalcularExpresion }
Begin { SumaProgesion }
{ Se utiliza la expresion: suma = a (1-r**n) / (1-r) }
LeerDatos(n,a,r);
CalcularExpresion;
SacarResultados(suma);
End. { SumaProgresion}
Program Uno;
Var
a , b ,c : Integer;
8.5. PASO DE VALORES POR CONTENIDO O DIRECCION 95
Begin
{1} a := 3; b := 5; c:= 7;
{2} Writeln( Antes : , a:4 , b:4 , c:4 );
{3} Escribe(Durante: , a , b );
{4} Escribe(Durante: , a , b );
{5} Writeln(Despues: , a:4 , b:4 , c:4 );
End.
8.6 Definici
on diferida
El compilador transforma las ordenes PASCAL a lenguaje maquina empe-
zando por el principio del programa y acabando por el End. Por tanto,
cualquier procedimiento o funcion ha de declarase antes de ser utilizado para
que el compilador cuando llegue al identificador correspondiente sepa inter-
pretar que instrucciones de la Unidad Central de Proceso debe generar. En
general esto implica un orden mnimo a la hora de escribir el programa y lle-
var cuidado de no definir modulos en lneas posteriores a las que los utilizan.
Sin embargo, puede haber ocasiones en las que se requiera que un modulo
llame a otro modulo y que a su vez llame al primero. En este caso sera im-
posible definir los dos antes de referirlos y por tanto PASCAL proporciona la
palabra reservada FORWARD para seguir al nombre y argumentos de un
procedimiento o funcion cuyo contenido se especificara en lineas posteriores.
En el programa Dos se ilustra el uso de FORWARD :
Program Dos;
Procedure A ( c : Char);
Begin { A }
If c < Z Then B (c);
Write ( c )
End; { A }
Procedure B ( c : Char);
Begin { B }
A ( Succ (c) )
End; { B }
8.7. MODULOS
Y SUBMODULOS 97
Begin { Dos }
A ( A );
End. { Dos }
8.7 M
odulos y subm
odulos
Al igual que para un programa se pueden definir modulos, tambien para un
modulo se pueden escribir otros modulos. Es decir declaraciones de proce-
dimientos cuyo significado solo conoce el modulo en el que se definen. Por
ejemplo en el programa Tres la funcion Final es local al procedimiento Eco.
Program Tres;
Procedure Eco;
Var
s : String;
Begin { Tres }
{1}
{2} Eco;
End. { Tres }
If Final Exit;
que se haya escrito un programa que realice un bucle infinito. Esta posibilidad
existe puesto que el PASCAL permite la recursividad en la programacion:
algo que bien utilizado puede aumentar la legibilidad de los programas.
8.8 Recursividad
La definicion de muchos objetos abstractos se realiza mediante recursion. La
recursion aparece generalmente o bien en la definicion de estructuras con
autosemejanza o en la descripcion de procedimientos de calculo matematico.
Se dice que una definicion es recursiva cuando el objeto definido aparece
en la recursion. Este es un modo de definir objetos muy com un y util. Por
ejemplo, cuando estudiamos el problema de Josefo, se definan los nodos
que componan el crculo como componentes que se identificaban por un
numero y tenan un enlace con otro nodo. Como veremos posteriormente, la
recursividad es muy u til para definir estructuras de datos.
La recursion tambien se utiliza para definir procedimientos de calculo.
En este caso, hay que llevar cuidado en transformar la definicion recursiva
en un algoritmo que se realice en un n umero finito de pasos. Por ejemplo,
consideremos la definicion del factorial de un n umero que se deriva de la
siguiente expresion:
n! = n(n 1)!
Esta igualdad matematica no es un procedimiento de calculo. Para que as
lo sea, hay que a
nadir algo mas. En este caso, se trata de algo tan sencillo
como una condicion de principio o fin. Si consideramos las dos igualdades:
n! = n(n 1)!
1! = 1
veremos que ya disponemos de un procedimiento para calcular el factorial.
Para calcular, por ejemplo, 4! utilizaramos la secuencia de igualdades:
4! = 4 3! = 4 3 2! = 4 3 2 1! = 4 3 2 1 = 24
La condicion de finalizacion.
El PASCAL , como cualquier lenguaje moderno de programacion permi-
te la programacion recursiva: en la definicion de un modulo, Procedure
o Function, puede aparecer una llamada a el mismo. El programa para
calcular el factorial podra ser:
Program Factoriales;
Var
m :Integer;
Begin
Writeln(Calculo de factorial. Introducir el numero:);
Read( m );
If m > 7 Then
Writeln(El numero es demasiado grande.)
Else
Writeln (El factorial de, m:2 , es , Fac (m) )
End.
Como se utilizan datos Integer este programa solo sera capaz de calcular
hasta el factorial de numeros peque nos pues crece muy rapidamente y a partir
de 7! se desborda la capacidad de almacenamiento de ese dato. Por lo demas,
se trata de un programa de facil lectura. En la instruccion {2} consideramos
el valor de terminacion de las llamadas recursivas. Sin ella, el programa no
acabara nunca. En la instruccion {4} estamos diciendo que en esa llamada
se asigne a la funcion Fac el valor que se obtiene multiplicando el valor actual
8.8. RECURSIVIDAD 101
Type
Indentificador1 = Untipo1;
Indentificador2 = Untipo2;
. . .
103
104 CAPITULO 9. DATOS CON ESTRUCTURA
Program Uno;
Type
Entero = Integer;
Var
i,n : Entero;
. . . . . .
Program Uno;
Type
Nota = 0..10;
Var
i : Nota;
Begin
Writeln(Teclear la nota (0 a 10):);
Readln(i);
Case i Of
0..4 : Writeln(Suspenso);
5..10 : Writeln(Aprobado)
End;
End.
del programa. Con esta opcion, si se teclea un dato fuera del rango definido
para Nota aparecer? un mensaje de error Run time. Sin esa opcion del
compilador, no aparecera ning
un mensaje de error.
9.2 Enumeraciones
Los tipos de datos Integer, Char y Byte son ejemplos de tipos de datos
en los que se puede almacenar un n umero limitado de datos. En el tipo
Byte, por ejemplo, n umeros entre el 0 y el 255. Si el programador necesita
utilizar un conjunto limitado de datos puede referirse a ellos estableciendo
explcitamente una relacion entre cada dato y uno de los valores que pue-
de tomar un tipo de dato limitado. Por ejemplo, si queremos referirnos a
los meses de a no en un programa se puede establecer una relacion entre un
numero y el mes, empezando con el 1 para Enero y siguiendo hasta 12 con
el orden del calendario. Dado el uso cotidiano de esta relacion resultara
muy facil escribir y leer programas en los que se utilizara una variable mes
del tipo Byte. Siempre que mes tomara el valor 2 el programador inme-
diatamente interpretara ese valor como el mes de Febrero. Sin embargo, en
otras muchas ocasiones no existira tal correlacion cotidiana entre ordinales
y objetos. Por ejemplo, si en un programa se quiere operar con datos del
tipo color, considerando las posibilidades Rojo , Amarillo , Naranja, Verde
, y Azul, no es facil elegir una ordenacion entre ellos que permita establecer
una relacion facilmente comprensible entre un n umero, por ejemplo del 0 al
4, y cada color. Para estos casos el PASCAL permite establecer esa relacion
en la definicion de un tipo y el programador puede olvidarse de ella durante
el programa. Un tipo de dato enumerado se especifica con el conjunto de
posibilidades entre parentesis y separadas por comas. En el programa Dos
tenemos un ejemplo de su utilizacion:
Program Dos;
Type
Color = (Rojo , Amarillo , Naranja, Verde , Azul);
Var
i : Color;
Begin
i := Amarillo;
Case Succ(i) Of
Amarillo : Writeln(Se trata de Amarillo);
106 CAPITULO 9. DATOS CON ESTRUCTURA
Writeln(Ord(i));
End.
i:= Color(1);
9.3 Conjuntos
Un conjunto de datos del tipo Cualquiera se define con la siguiente sintaxis:
Type identificador Set Of Cualquiera
donde identificador es el nombre elegido para el nuevo tipo de dato, y cual-
quiera es el tipo de dato de los elementos que forman el conjunto. Los
elementos pueden ser cualquier tipo de dato ordenado, y entre ellos los enu-
merados.
9.3. CONJUNTOS 107
End.
El operador In se utiliza para determinar si un elemento se encuentra dentro
de un conjunto, con la siguiente sintaxis:
108 CAPITULO 9. DATOS CON ESTRUCTURA
NomElemento In NomConjunto
donde NomElemento es el nombre del elemento sobre el que se inquiere y
NomConjunto el conjunto. El resultado de esta operacion es un dato Boo-
lean, y se evalua a True solo si el elemento pertenece al conjunto.
En el programa Tres tambien se ilustra la asignacion de valores a los
conjuntos, si bien falta anadir que tambien se puede asignar el conjunto
vaco ([] ).
Los operadores aritmeticos y logicos cuando act
uan entre conjuntos tienen
un significado nuevo. Si A, B y C son conjuntos de elementos del mismo tipo,
las operaciones permitidas son :
C := A + B {C : conjunto union de A y B}
C := A * B {C : conjunto interseccion de A y B}
C := A - B {C : conjunto diferencia de A y B}
Tambien se pueden comparar los conjuntos con los operadores logicos dando
lugar a un dato Boolean. Si A y B son dos conjuntos de elementos del
mismo tipo y verdad un dato Boolean, las comparaciones siguientes son
posibles:
verdad := A = B {verdad es True si A y B son iguales}
verdad := A <> B {verdad es True si A y B son distintos}
verdad := A <= B {verdad es True si A es subconjunto de B}
verdad := A => B {verdad es True si B es subconjunto de A}
teniendo en cuenta que el conjunto vaco es subconjunto de todo conjunto.
Tambien hay que tener en cuenta que el n umero de elementos que pueden
formar un conjunto en PASCAL esta limitado a un maximo de 256.
9.4 Arrays
Cuando se tiene que seguir la pista a un grupo o de datos es muy u til re-
ferirse a todos ellos con un mismo nombre y distinguir entre los elementos
mediante el lugar que ocupan en el grupo. En realidad de trata de ampliar la
conveniencia de los conjuntos estudiados anteriormente a grupos de datos de
cualquier tipo. En el Array los elementos del grupo se ordenan asignandose
a cada elemento un n umero de orden o direccion. El tipo de dato Array (
tabla ) es uno de los datos con estructura mas importantes de un lenguaje.
Esto es as, porque corresponde a una ordenacion de datos similar a la que se
9.4. ARRAYS 109
Type
vector = Array [1..30] Of Real;
Var
texto : Array [0..3000] Of Char;
Program Primos;
Const
MAX = 1000;
{ Calculo de los numeros primos entre 1 y MAX
utilizando el algoritmo de la Criba de Eratostenes }
110 CAPITULO 9. DATOS CON ESTRUCTURA
Var
esPrimo : Array [1..MAX] of Boolean;
i,j : Integer;
Begin { primos }
{Se inicializa la tabla}
esPrimo[1] := False;
For i := 2 to MAX Do esPrimo[i] := True;
{En la criba de Eratostenes se parte de todos los numeros
y se van eliminando todos los multiplos de los primos
elegidos. Seran primos elegidos aquellos que , en orden
ascendente, no hayan sido marcados como multiplos }
estas tablas multiples se puede realizar separando con comas los ndices de
cada una de las dimensiones.
El siguiente procedimiento MultMatriz se puede utilizar para multipli-
car matrices.
Program Cuatro;
Const
MAXDIM = 20;
Type
Numeros = Real;
Matriz = Array[1..MAXDIM,1..MAXDIM] Of Numeros;
Var
n : Integer;
A,B,C : Matriz;
Procedure Leematriz ( Var X : Matriz); FORWARD;
Procedure Escribematriz ( X : Matriz); FORWARD;
Procedure MultMatriz ( dim : Integer;
Var
A1 , A2 , M : Matriz );
Var
i,j,k : Integer;
x : Numeros;
Begin { MultMatriz }
For i := 1 To dim Do
For j := 1 To dim Do
Begin
x:= 0.0;
For k := 1 To dim Do
x := x + A1 [i,k] * A2 [k,j];
M[i,j] := x;
End; {End del doble For}
End; { MultMatriz }
{ Aqui se encontrarian las definiciones de los }
{ dos procedimientos que se han omitido }
Begin
Writeln(Dimension de las matrices: );
Readln(n);
Leematriz(A); Leematriz(B);
112 CAPITULO 9. DATOS CON ESTRUCTURA
MultMatriz(n,A,B,C);
Writeln(La Matriz producto es:);
Escribematriz(C);
End.
x := x + A1 [i][k] * A2 [k][j];
Program Cinco;
Const
MAXDIM = 300;
{ Los caracteres se guardan en enteros como su ordinal }
Type
Cadena = Array[0..MAXDIM] Of Integer;
Var
A,B : Cadena;
Procedure LeeCadena (Var x : Cadena);
9.4. ARRAYS 113
Var
i : Integer;
c : Char;
Begin { LeeCadena }
i:= 1;
Repeat
Read(c);
x[i] := Ord(c);
i := i+1;
Until ( EOLN );
x[0] := i - 1;
{ Lee los caracteres ASCII 13 (CR) y 10 (LF)
que delimitan el fin de linea }
Read(c);Read(c);
End; { LeeCadena }
Var
dim1 , i : Integer;
Begin
dim1 := A1[0];
For i := 1 To A2[0] Do
A1[ dim1 + i ] := A2[i];
A1[0] := dim1 + A2[0];
End;
Begin
Writeln();
114 CAPITULO 9. DATOS CON ESTRUCTURA
LeeCadena(A);
LeeCadena(B);
Concatena(A,B);
Writeln();
EscribeCadena(A);
End.
9.5 Registros
La situacion encontrada en el problema planteado anteriormente de manipu-
lacion de cadenas es muy com un. Lo mas frecuente es encontrarse en una
situacion en la que se quiere representar en un tipo de dato una informacion
que posee estructura interna y es heterogenea, es decir, los campos en los que
se subdivide el dato no son todos del mismo tipo. Para ello el PASCAL, como
otros lenguajes de programacion actuales, suministra los datos tipo registro
(en ingles records).
Un registro es un tipo de dato definido por el programador en el que
puede especificar su estructura interna.
El programador da nombre al nuevo tipo de dato y a cada uno de los
campos que lo componen, y especifica el tipo de dato que puede ocupar cada
uno de los campos. La sintaxis para estas especificaciones es:
Type
nombre =
Record
NombreCampo1 : TipoDato1 ;
NombreCampo2 : TipoDato2 ;
. . .
End;
Program Seis;
Type
Fecha =
Record
mes : 0 .. 12; { 0 seria para indicar que no se conoce la fecha}
dia : 1 .. 31;
agno : Integer ;
End;
Var
alta , baja : Fecha;
Begin
With alta Do
Begin
dia := 27 ;
mes := 2 ;
agno := 1992;
baja.mes := mes + 2;
End;
....
La eleccion del uso de la estructura With se suele hacer en cada caso par-
ticular segun la legibilidad que a
nada al programa.
Ya hemos dicho que los campos de los registros pueden contener datos que
son del tipo registro. En ese caso, como siempre, habra que llevar cuidado en
definir los tipos de datos en el orden adecuado para que nunca aparezca en
una declaracion un tipo de dato que no ha sido declarado en pasajes anteriores
del programa. Si ampliamos el ejemplo anterior hacia la construccion de una
base de datos con los alumnos y sus notas, un programa de captacion de
datos podra empezar as:
Program Siete;
Type
Fecha =
Record
mes : 0 .. 12; { 0 seria para indicar que no se conoce la fecha}
dia : 1 .. 31;
agno : Integer ;
End;
Alumno =
Record
nombre : String;
apellidos : String;
9.5. REGISTROS 117
nacimiento : Fecha;
nota : Real;
End;
Var
uno,otro : Alumno ;
Begin
Writeln(Nombre : ) ; Readln(uno.nombre);
Writeln(Apellidos : ); Readln(uno.apellidos);
Writeln(Agnno de nacimiento : ); Readln(uno.nacimiento.agno);
Writeln(Mes de nacimiento: ); Readln(uno.nacimiento.mes);
Writeln(Dia de nacimiento: ); Readln(uno.nacimiento.dia);
Writeln(Nota del examen: ); Readln(uno.nota);
. . . . . . . . . . . . . .
y vemos que la referencia a los campos de registros que son a su vez campos
de un registro se realiza concatenando con puntos los identificadores de los
campos.
Para crear una base de datos que contuviera informacion de los alumnos
de una clase lo logico sera ordenar los alumnos en una lista. Para ello, se
puede crear una estructura Array cuyos elementos sean los registros defini-
dos para almacenar la informacion de los alumnos. Se podra por ejemplo
a
nadir en la parte declarativa del programa Siete el siguiente tipo de dato:
{ Type }
Lista =
Array[1..100] of alumno;
{ Var }
primero : Lista;
primero[1] := uno;
If (Primero[1].nacimiento.mes = 12 ) Then ......
118 CAPITULO 9. DATOS CON ESTRUCTURA
Program Ocho;
Const
MAXDIM = 300;
Type
Ristra = Array [1..MAXDIM] of Char;
Cadena =
Record
longitud : Integer;
contenido : Ristra;
End;
Var
A,B : Cadena;
Procedure LeeCadena (Var x : Cadena);
Var
i : Integer;
c : Char;
Begin { LeeCadena }
i:= 1;
With x Do
Begin
Repeat
Read(c);
contenido[i] := c;
i := i+1;
9.5. REGISTROS 119
Until ( EOLN );
longitud := i - 1;
End;
{ Lee los caracteres ASCII 13 (CR) y 10 (LF)
que delimitan el fin de linea }
Read(c);Read(c);
End; { LeeCadena }
Var
dim1 , i : Integer;
Begin
dim1 := A1.longitud;
For i := 1 To A2.longitud Do
A1.contenido[ dim1 + i ] := A2.contenido[i];
A1.longitud := dim1 + A2.longitud;
End;
Begin
Writeln();
LeeCadena(A);
LeeCadena(B);
Concatena(A,B);
Writeln();
EscribeCadena(A);
End.
debe estar mucho mas claro el sentido de los conceptos tipo de dato y va-
riable. Una variable, es un identificador que utiliza el programador para
referirse a un dato y poder realizar operaciones con el. El tipo de dato ha de
especificarse para que el compilador pueda generar codigo UCP en el que se
utilice una cantidad de memoria suficiente para ese dato y estructurada del
modo adecuado. Cuando el programador se enfrenta a la resolucion de un
problema puede pensar en variables para cualquier concepto abstracto que
piense que sea u til para resolver el problema de un modo claro y comunica-
ble, lo que muchas veces quiere decir de un modo lo mas proximo posible al
lenguaje natural. La restriccion obvia es poder explicitar sin ambig uedades
la gestion de la memoria del ordenador que ha de realizar el compilador para
almacenar y manipular ese dato. Mediante la estructura Record y Array
el PASCAL ofrece la posibilidad de definir tipos de datos muy proximos a
los utilizados en el lenguaje natural y que son una organizacion precisa de
tipos de datos mas sencillos. En u ltima instancia, los atomos que van a for-
mar esas estructuras mas complejas son los tipos de datos fundamentales del
PASCAL : Byte , Integer , .... Al final, para una variable, el compilador
reservara lugar en memoria para almacenar un n umero determinado de bits
de informacion (una sucesion de ceros o unos). El tipo de dato definido para
esa variable va a determinar el modo en el que esos bits van a intervenir en
las operaciones y tambien el modo con en el que el programador se podra
referir a todos esos bits de golpe o a subconjuntos de ellos.
9.6 Uniones
Comprendido lo anterior no debe resultar difcil entender dos posibilidades
avanzadas que permite el PASCAL en la manipulacion de registros, y que
son los registros con variante ( o uniones con discriminacion) y las uniones
libres. En PASCAL es posible dar una definicion dinamica de la composicion
de un registro. Es decir, que los campos que lo componen varen seg un el
valor de un parametro. Para ello se utiliza la siguiente modificacion de la
estructura Case dentro de la definicion del registro:
Case
nombre : TipodeDato Of
caso1 : ( Especificacion1 );
caso2 : ( Especificacion2 );
. . .
9.6. UNIONES 121
Program Nueve;
Type
Fecha =
Record
mes : 0 .. 12; { 0 seria para indicar que no se conoce la fecha}
dia : 1 .. 31;
agno : Integer ;
End;
Alumno =
Record
nombre : String;
apellidos : String;
nacimiento : Fecha;
Case final : Boolean Of
False : ( nota : Real );
True : ( notaFinal : Real;
calificacion : String[14] );
End;
Var
uno,otro : Alumno ;
Begin
.........................................
122 CAPITULO 9. DATOS CON ESTRUCTURA
uno.nota:= 6.8 ;
como,
uno.calificacion := Notable;
Case
TipodeDato Of
caso1 : ( Especificacion1 );
caso2 : ( Especificacion2 );
. . .
donde caso1, caso2,... son valores posibles del tipo de dato especificado Ti-
podeDato. Es equivalente a un Registro con variante en el que se omite el
identificador de la variable que gobierna las distintas alternativas.
Esta posibilidad de acceso variable al contenido de un registro es coherente
con lo resumido anteriormente sobre el sentido de variables y tipos de datos.
El compilador reserva para el dato en la memoria un espacio suficiente para
almacenar aquella de las variantes del registro de mayor tama no. Se rellenara
el espacio de memoria del modo que en cada momento desee el programador y
la eleccion se realiza usando un campo u otro. Igualmente, la interpretacion
de los bits almacenados en esas posiciones de memoria tambien depende
del campo del registro que se utilice, en el caso de que distintos campos
correspondan a distintos tipos de datos.
9.6. UNIONES 123
Las Uniones Libres han de usarse con precaucion para evitar confusio-
nes en la lectura de los programas, pero a veces son las adecuadas para hacer
un programa legible. En el siguiente ejemplo la union entre el tipo de dato
Char y Byte se utiliza para escribir una funcion que convierte un caracter
en el correspondiente n umero de orden ASCII.
Program Diez;
Var
dato : Char;
Begin { Diez }
Readln (dato);
Writeln ( El caracter ,dato , corresponde al ASCII numero : ,
ElAscii(dato) );
End. { Diez }
Ficheros
125
126 CAPITULO 10. FICHEROS
Program Uno;
Var
almacen : File of Byte;
num1,num2,num3,num4 : Byte;
Begin
{1} num1 := 72; num2 := 79;
{2} num3 := 76; num4 := 65;
{3} Assign(almacen,uno.sal);
{4} Rewrite(almacen);
{5} Write(almacen,num1,num2);
{6} Write(almacen,num3,num4);
{7} Close(almacen)
End.
Program Dos;
Var
almacen : File of Char;
num1,num2,num3,num4 : Char;
Begin
Assign(almacen,uno.sal);
Reset(almacen);
Read(almacen,num1,num2);
Read(almacen,num3,num4);
Close(almacen);
Writeln(num1,num2,num3,num4);
End.
HOLA
Program Tres;
10.1. FICHEROS CON TIPO 129
Begin { Tres }
nomArchi := Archi.dat;
Writeln(Nombre : ) ; Readln(uno.nombre);
Writeln(Apellidos : ); Readln(uno.apellidos);
Writeln(A~
no de nacimiento : ); Readln(uno.nacimiento.agno);
Writeln(Mes de nacimiento: ); Readln(uno.nacimiento.mes);
Writeln(Dia de nacimiento: ); Readln(uno.nacimiento.dia);
End; {endif}
End. { Tres }
Program Cuatro;
{ Utilidad para listar el archivo de alumnos }
Type
Fecha = Record
mes : 0 .. 12;
dia : 1 .. 31;
agno : Integer ;
End;
Alumno = Record
nombre : String;
apellidos : String;
nacimiento : Fecha;
End;
Var
carpeta : File of Alumno;
uno : Alumno ;
nombreCarpeta : String;
Begin { Cuatro }
Writeln( Nombre del archivo donde se almacenan : );
Readln(nombreCarpeta);
Assign(carpeta,nombreCarpeta);
Reset(carpeta);
While Not Eof(carpeta) do begin
Read(carpeta,uno);
With uno Do
Begin
Write(apellidos,, ,nombre);
10.2. PROCESAMIENTO SECUENCIAL Y ALEATORIO 131
Begin { IniciaLista }
Writeln(Inicializaci
on de un archivo de alumnos);
Writeln(Nombre del archivo: ); Readln(NomArchi);
Assign(carpeta,nomArchi);
Rewrite(carpeta); {Se crea el archivo}
otro.numeroTotal := 0; {Se inicializa a 0 el numero de orden }
Write(carpeta,otro);
Close(carpeta);
End. { IniciaLista }
En el programa IniciaLista se procede a inicializar la base de datos: se
crea el archivo con el nombre indicado por el usuario y se escribe en el
primer registro el Integer 0 para indicar que no hay todava ning
un alumno
incluido. Como almacen se tiene que definir como un File Of alumno para
poder escribir un entero en el primer registro tenemos que recurrir a una
union libre del registro.
El programa que puede a nadir un alumno en la base de datos es :
Program AumentaLista;
10.2. PROCESAMIENTO SECUENCIAL Y ALEATORIO 133
Writeln(Nombre : ) ; Readln(uno.nombre);
Writeln(Apellidos : ); Readln(uno.apellidos);
Writeln(A~
no de nacimiento : ); Readln(uno.nacimiento.agno);
Writeln(Mes de nacimiento: ); Readln(uno.nacimiento.mes);
Writeln(Dia de nacimiento: ); Readln(uno.nacimiento.dia);
Seek(carpeta,0); { Al principio }
otro.numeroTotal := otro.numeroTotal + 1;
Write(carpeta,otro);
Close(carpeta);
End; {EndIf}
End. {AumentaLista}
En este programa, para llegar al final del fichero simplemente se saltan los
registros indicados al principio, y se escribe el nuevo. Despues, se vuelve al
principio para aumentar en 1 el contador de registros almacenados.
El listado de los alumnos en la base de datos sera :
Program ListaLista;
{ Utilidad para escribir el archivo de alumnos }
Type
Fecha =
Record
mes : 0 .. 12; dia : 1 .. 31; agno : Integer ;
End;
Alumno =
Record
Case Boolean of
True : ( nombre : String;
apellidos : String;
nacimiento : Fecha );
False :
( numeroTotal : Integer );
End;
Var
i : Integer;
carpeta : File of Alumno;
uno,n : Alumno ;
nombreCarpeta : String;
Begin { ListaLista }
Writeln( Nombre del archivo donde se almacenan : );
Readln(nombreCarpeta);
Assign(carpeta,nombreCarpeta);
Reset(carpeta);
Read(carpeta,n);
10.2. PROCESAMIENTO SECUENCIAL Y ALEATORIO 135
For i := 1 To n.numeroTotal Do
Begin
Read(carpeta,uno);
With uno Do
Begin
Write(i:3, ,apellidos,, ,nombre);
If nacimiento.mes <> 0 Then
Writeln( (,nacimiento.dia,/,nacimiento.mes,/,
nacimiento.agno,));
End
End; {endfor}
Close(carpeta);
End. { ListaLista }
Con esta nueva definicion de la base de datos de alumnos resulta muy sen-
cillo escribir un programa para corregir errores en alguno de los registros
almacenados.
Program ModificaLista;
{ Utilidad para modificar un alumno en la lista }
Type
Fecha =
Record
mes : 0 .. 12; dia : 1 .. 31; agno : Integer ;
End;
Alumno =
Record
Case Boolean of
True : ( nombre : String;
apellidos : String;
nacimiento : Fecha );
False : ( numeroTotal : Integer );
End;
Var
elemento :Integer;
carpeta : File of Alumno;
uno,otro : Alumno ;
136 CAPITULO 10. FICHEROS
Respuesta : Char;
nomArchi : String;
Begin {ModificaLista}
Writeln(Nombre del archivo: ); Readln(NomArchi);
Writeln(Numero de orden: ); Readln(elemento);
Writeln(Nombre : ) ; Readln(uno.nombre);
Writeln(Apellidos : ); Readln(uno.apellidos);
Writeln(A~
no de nacimiento : ); Readln(uno.nacimiento.agno);
Writeln(Mes de nacimiento: ); Readln(uno.nacimiento.mes);
Writeln(Dia de nacimiento: ); Readln(uno.nacimiento.dia);
Program siete;
Uses Dos;
Var
almacen : Text;
x : Real;
i : Integer;
h1,m1,s1,c1,h2,m2,s2,c2 : Word;
Begin
Assign(almacen,siete.sal);
Rewrite(almacen);
GetTime(h1,m1,s1,c1);
10.3. FICHEROS DE TEXTO 139
Writeln(h1,:,m1,:,s1,:,c1);
For i := 1 to 10000 Do Begin
x := Random;
Writeln(almacen,x);
End; {endfor}
GetTime(h2,m2,s2,c2);
Writeln(h2,:,m2,:,s2,:,c2);
Close(almacen)
End.
Punteros y asignaci
on din
amica
de memoria
Program Uno;
Var
a , b : Integer;
Begin { Uno }
{1} Readln(a);
{2} b := a;
{3} Writeln(a:4, ,b:4);
End. { Uno }
en el que se definen las variables a y b para almacenar datos del tipo In-
teger. En la instruccion {3} se especifica que el dato almacenado en la
141
142 CAPITULO 11. PUNTEROS
11.2 Punteros
En ning un momento se ha hecho explicito en la sintaxis del lenguaje que un
dato esta identificado internamente por una posicion de memoria. Sin em-
bargo, es muy util poder manipular los datos realizando algoritmos en los que
tambien interviene la direccion de los datos. Para ello el PASCAL permite
que en los programas aparezca un tipo de dato que son las direcciones de los
datos. Estas direcciones se llaman normalmente punteros, y en un programa
PASCAL pueden intervenir las direcciones de datos que esten definidos. Se
especifica que una variable es un puntero a un tipo de dato con la ayuda del
calificador que se antepone a un identificador.
El dato ^tipodato es el puntero a un dato del tipo tipodato. Por
ejemplo en el segmento de programa :
Type
Fecha =
Record
dia : Integer;
mes : Integer;
End;
Var
a: Integer;
px : ^Real;
pa : ^Integer;
pHoy,pAyer : ^Fecha;
. . .
. . .
pHoy^ := pAyer^;
. . .
implica que se almacene en el lugar de memoria indicado por pHoy el dato
almacenado en el registro al que apunta pAyer. Para completar la herra-
mienta es necesario un operador que sea capaz de extraer de una variable su
direccion, y este es el operador que se representa por @. La asignacion:
pa := @a;
es correcta porque pa es el puntero a un Integer y el resultado de operar @
sobre a (que es un Integer ) es tambien el puntero a un Integer.
Una version sofisticada del programa Uno es la siguiente:
Program Dos;
Var
a ,b : Integer;
pb : ^Integer;
Begin { Dos }
{1} a := 10 ;
{2} pb := @a ;
{3} b := pb^ ;
{4} Writeln(a:4, ,b:4);
End. { Dos }
Program Tres;
Var
a : String;
pa,pb : ^String;
Begin { Tres }
a := Hola; { en a se almacena Hola }
pa := @a; { pa apunta a}
pb:= pa; { pb apunta a}
writeln(a);
pb^ := Adios;
Writeln(a); { el contenido de a es Adios }
End. { Tres }
Program Cuatro;
Type pinte = ^Integer;
Var
a ,b ,c: Integer;
DINAMICA
11.3. ASIGNACION DE MEMORIA. 145
Begin { Cuatro }
a := 2 ;
b := 3 ;
c := 4 ;
Cuacua(@a,b,c);
Writeln(a:6, ,b:6, ,c:6);
End. { Cuatro }
es,
4 3 16
11.3 Asignaci
on din
amica de memoria.
Una utilidad de los punteros es poder crear programas que ocupen la can-
tidad de memoria del ordenador adecuada a cada caso seg un se determina
durante la ejecucion del programa. Cuando un programa se va a ejecutar, se
carga en la memoria del ordenador y la memoria ocupada por el programa
esta estructurada en varias partes o segmentos. El codigo para la UCP se
carga en memoria en el llamado segmento de codigo. Los datos definidos
en el programa se cargan en el llamado segmento de datos, y hay un tercer
segmento llamado pila (stack) que se reserva para los datos que se han de
146 CAPITULO 11. PUNTEROS
Program Cinco;
Var
pa,pb : ^String;
Begin { Cinco }
New(pa);
pa^ := Hola;
pb:= pa;
writeln(pa^);
pb^ := Adios;
Writeln(pa^);
Dispose(pb);
End. { Cinco }
Program CincoIncorrecto;
Var
pa,pb : ^String;
Begin { Incorrecto }
New(pa);
pa^ := Hola;
New(pb);
pb:= pa;
writeln(pa^);
pb^ := Adios;
Writeln(pa^);
Dispose(pb);
Dispose(pa);
End. { Incorrecto }
Primero, el programa dara un error en la ejecucion. La u ltima instruccion
intenta liberar un lugar de memoria que ya ha sido liberado en la llamada an-
terior a Dispose. Por otra parte, es un ejemplo claro de mal uso de la gestion
dinamica de memoria. La memoria reservada para el programa mediante la
tercera instruccion (256 bytes) no se puede liberar puesto que hemos perdido
la pista de cual era. Es una practica poco recomendable escribir programas
que cuando acaban dejan sin liberar memoria que reservaron del monton.
Enlace = ^Nodo;
Nodo =
Record
clave : Integer;
siguiente : Enlace
End;
Nil
Program Seis;
Type
enlace = ^Nodo;
Nodo =
Record
clave : Integer;
siguiente : Enlace
End;
Var
y,z : enlace;
i : Integer;
Begin
{ Se inicializa la lista }
New(z);
z^.siguiente := Nil; {El ultimo elemento apunta a Nil}
y^.siguiente := z;
z := y;
Readln(i)
End;
{Se escribe la lista}
While (y^.siguiente <> Nil ) Do
Begin
Writeln(y^.clave) ;
z := y^.siguiente;
Dispose(y);
y := z;
End;
Dispose(z)
End.
y la eliminacion de un nodo :