introduccion a la programacion en pascal

151
Introducci´ on a la Programaci´ on. Pascal. Vicente L´ opez Escuela T´ ecnica Superior de Inform´ atica Universidad Aut´ onoma de Madrid ( [email protected] )

Upload: elmoroco

Post on 07-Jul-2015

687 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Introduccion A La Programacion En Pascal

Introduccion a la Programacion.

Pascal.

Vicente Lopez

Escuela Tecnica Superior de InformaticaUniversidad Autonoma de Madrid

( [email protected] )

Page 2: Introduccion A La Programacion En Pascal

2

Page 3: Introduccion A La Programacion En Pascal

Indice General

1 Esquemas Basicos 71.1 Ordenacion temporal . . . . . . . . . . . . . . . . . . . . . . . 71.2 Componentes basicos . . . . . . . . . . . . . . . . . . . . . . . 81.3 Trafico de informacion . . . . . . . . . . . . . . . . . . . . . . 9

2 Lenguajes 132.1 Procesamiento de informacion: hombre y ordenador . . . . . . 132.2 Formalizacion de los lenguajes . . . . . . . . . . . . . . . . . . 152.3 Las maquinas de Von Neuman . . . . . . . . . . . . . . . . . . 162.4 Breve historia de los lenguajes . . . . . . . . . . . . . . . . . . 172.5 Tipos de lenguajes . . . . . . . . . . . . . . . . . . . . . . . . 20

3 Algoritmos 233.1 Pasos en la resolucion . . . . . . . . . . . . . . . . . . . . . . . 233.2 Uso multiple . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253.3 El ejemplo de Josefo . . . . . . . . . . . . . . . . . . . . . . . 25

4 Pascal 334.1 Caracterısticas . . . . . . . . . . . . . . . . . . . . . . . . . . 334.2 El programa Pascal . . . . . . . . . . . . . . . . . . . . . . . . 344.3 Palabras reservadas y estructuras . . . . . . . . . . . . . . . . 354.4 Instrucciones sencillas y compuestas . . . . . . . . . . . . . . . 374.5 Diagramas de sintaxis . . . . . . . . . . . . . . . . . . . . . . 38

5 Datos 395.1 Variables, datos y direcciones . . . . . . . . . . . . . . . . . . 395.2 Identificadores . . . . . . . . . . . . . . . . . . . . . . . . . . . 405.3 Tipos de datos . . . . . . . . . . . . . . . . . . . . . . . . . . 41

3

Page 4: Introduccion A La Programacion En Pascal

4 INDICE GENERAL

5.4 Constates con tipo . . . . . . . . . . . . . . . . . . . . . . . . 465.5 Inicializacion de los datos . . . . . . . . . . . . . . . . . . . . 465.6 Asignacion de las constantes . . . . . . . . . . . . . . . . . . . 465.7 Asignacion de los distintos tipos de variables . . . . . . . . . . 47

6 Entrada y salida 516.1 Dispositivos de entrada, salida y almacenamiento . . . . . . . 516.2 Las funciones Read y Write . . . . . . . . . . . . . . . . . . . 526.3 Formatos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546.4 Las funciones WriteLn y ReadLn . . . . . . . . . . . . . . . . 55

7 Acciones 597.1 Operaciones basicas. . . . . . . . . . . . . . . . . . . . . . . . 59

7.1.1 Operadores aritmeticos y expresiones aritmeticas. . . . 597.1.2 Funciones aritmeticas. . . . . . . . . . . . . . . . . . . 617.1.3 Aritmetica entera y real. . . . . . . . . . . . . . . . . . 627.1.4 Operadores logicos. . . . . . . . . . . . . . . . . . . . . 657.1.5 Expresiones logicas. . . . . . . . . . . . . . . . . . . . . 687.1.6 Manipulacion de bits. . . . . . . . . . . . . . . . . . . . 70

7.2 Sentencias de control. . . . . . . . . . . . . . . . . . . . . . . . 747.3 Sentencias de repeticion. . . . . . . . . . . . . . . . . . . . . . 797.4 Manipulacion de los datos STRING. . . . . . . . . . . . . . . 85

8 Modularidad 878.1 Dividir para vencer . . . . . . . . . . . . . . . . . . . . . . . . 878.2 Procedimientos . . . . . . . . . . . . . . . . . . . . . . . . . . 888.3 Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 908.4 Ambito de definicion de las variables . . . . . . . . . . . . . . 918.5 Paso de valores por contenido o direccion . . . . . . . . . . . . 928.6 Definicion diferida . . . . . . . . . . . . . . . . . . . . . . . . . 968.7 Modulos y submodulos . . . . . . . . . . . . . . . . . . . . . . 978.8 Recursividad . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

9 Datos con estructura 1039.1 Tipos de datos definidos por el programador . . . . . . . . . . 1039.2 Enumeraciones . . . . . . . . . . . . . . . . . . . . . . . . . . 1059.3 Conjuntos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1069.4 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

Page 5: Introduccion A La Programacion En Pascal

INDICE GENERAL 5

9.5 Registros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1149.6 Uniones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

10 Ficheros 12510.1 Ficheros con Tipo . . . . . . . . . . . . . . . . . . . . . . . . . 12510.2 Procesamiento secuencial y aleatorio . . . . . . . . . . . . . . 13110.3 Ficheros de Texto . . . . . . . . . . . . . . . . . . . . . . . . . 136

11 Punteros 14111.1 Contenidos, direcciones e identificadores . . . . . . . . . . . . 14111.2 Punteros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14211.3 Asignacion dinamica de memoria. . . . . . . . . . . . . . . . . 14511.4 Declaraciones recursivas de tipos de datos . . . . . . . . . . . 147

Page 6: Introduccion A La Programacion En Pascal

6 INDICE GENERAL

Page 7: Introduccion A La Programacion En Pascal

Capıtulo 1

Esquemas basicos delordenador

1.1 Ordenacion temporal

Un ordenador es una maquina disenada para el procesamiento automaticode informacion.

El esquema mas sencillo de un ordenador actual es el siguiente:

Entrada Computadora Salida- -

Se denominan dispositivos de entrada a todos aquellos que hacen posiblela captura de los datos necesarios para realizar las tareas encomendadas alordenador. Ejemplos comunes de dispositivos de entrada son los teclados, lastarjetas perforada, y los ratones, pero tambien lo son los escaners, microfonos,terminales TRC (Tubos de Rayos Catodicos),...

Se denominan dispositivos de salida a todos aquellos que hacen posiblela comunicacion de los resultados de las tareas realizadas por el ordenador.Ejemplos comunes de dispositivos de salida son los terminales TRC, impre-

7

Page 8: Introduccion A La Programacion En Pascal

8 CAPITULO 1. ESQUEMAS BASICOS

soras, y plotters, pero tambien lo son altavoces, actuadores mecanicos,...Es fundamental en un computador la ordenacion temporal de sus opera-

ciones:

Entrada Computadora Salida- -

-

Tiempo

y los componentes se definen exclusivamente a partir de la secuencia de ope-raciones realizadas.

1.2 Componentes basicos

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 salidasegun se grabe o se lea la informacion.

A los componentes fısicos del ordenador se le denomina Hardware y a lainformacion 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 dememoria

Unidadcentral deprocesos

• La unidad de memoria esta formada por cientos, miles o millones deceldas de memoria en las que se puede almacenar informacion y queestan identificadas por su direccion (en el sentido postal).

���������������������������� u u uA 2 4 1 J 3 3

1 2 3 4 5 6 7

Page 9: Introduccion A La Programacion En Pascal

1.3. TRAFICO DE INFORMACION 9

Al contenido de la informacion en general se accede por la direccion dela celda. El contenido tambien puede ser la direccion de una celda conlo que es posible almacenar en memoria la instrucciones que se han derealizar incluyendo el acceso a la informacion de las celdas.

• La unidad central de procesamiento (CPU) dirige y controla el procesa-miento de informacion que realiza el ordenador y consta de dos partes:la unidad de control y la unidad aritmetico – logica.

unidad dememoria

unidaddecontrol

unidadaritmetico–logica

?6

-�

La unidad de control busca, obtiene, y ejecuta las instrucciones delos programas almacenadas en la memoria. Cuando las instruccionesindican la realizacion de operaciones aritmeticas (+, ∗,... ) o logicas (≥ , ≡ , ...) estas se derivan para ser realizadas en la unidad aritmetico– logica.

1.3 Trafico de informacion

Vamos a ver de forma simplificada las acciones a las que da lugar en unordenador las instrucciones de un programa. Es fundamental comprender loinexcusable de la secuencialidad temporal de la instrucciones suministradasal 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);

Page 10: Introduccion A La Programacion En Pascal

10 CAPITULO 1. ESQUEMAS BASICOS

y consideraremos un modelo muy simplificado de un ordenador. Este modelodispone de una U.C.P., con unidad de control y aritmetico logica, y unapequena memoria con 64 posiciones.

Se reservan las posiciones de la 1 a la 50 para almacenar los programasque luego se ejecutaran y las posiciones 51, 52, 53, ... se utilizan para datosintermedios.

En nuestro modelo se inicializan todos los datos a cero al empezar laejecucion del programa y cuando la U.C.P. va a empezar a ejecutar la primerainstruccion las posiciones 51, 52 y 53 contienen un 0. En esas posiciones sealmacenaran los valores de las variables a,b, y c, respectivamente,

0 0 0

51 52 53

La primera instruccion del programa

a := 3;

indica a la U.C. que en la posicion 51 de memoria ha de almacenarse elnumero entero 3.

3 0 0

51 52 53

La segunda,

b := 5;

que en 52 almacene un 5,

3 5 0

51 52 53

y en la tercera, la U.C. realiza las siguientes acciones: obtiene los numerosalmacenados en 51 y 52, los envıa a la U.A.L. para ser sumados y el resultadoque devuelve se almacena en 53.

3 5 8

51 52 53

Page 11: Introduccion A La Programacion En Pascal

1.3. TRAFICO DE INFORMACION 11

En la cuarta instruccion obtiene el numero almacenado en 53 y lo envıa ala U.A.L. junto con el 2 para ser sumados. El resultado devuelto lo almacenade nuevo en 53.

3 5 10

51 52 53

La quinta instruccion implica que la U.C. obtiene el numero almacenadoen 53 y lo envıa junto con el 9 a la U.A.L. para ser comparados. Comode la comparacion la U.A.L. devuelve que es cierto, se envıa al perifericocorrespondiente la orden de sacar al exterior el contenido de la memoria 53.

Page 12: Introduccion A La Programacion En Pascal

12 CAPITULO 1. ESQUEMAS BASICOS

Page 13: Introduccion A La Programacion En Pascal

Capıtulo 2

Lenguajes de programacion

2.1 Procesamiento de informacion: hombre y

ordenador

La informacion que puede procesar un ordenador es distinta a la que puedeprocesar un humano. Aun suponiendo que el procesamiento de informacionque realiza el cerebro humano es comparable al que realiza un ordenador,la diferencia de diseno entre ambos explicarıa la incompatibilidad. Para elhumano resulta comodo expresar y pensar conceptos abstractos. La fraseSumar dos numeros evoca claramente un operacion general que dentro delformalismo matematico carece de ambiguedad:

z = x+ y .

Es equivalente el valor de la variable z a la suma de los valoresde las variables x e y.

El modo en que esta frase puede traducirse en una orden precisa para que larealice un ordenador ha cambiado con el tiempo segun variaban los disenos delos ordenadores. Primitivamente en ordenadores como el MARK I se tratabade una secuencia de tripletes de perforaciones en un cinta. Hoy en dıa setrata de las secuencias de ceros y unos del codigo binario. En el futuro losprogramas podrıan parecerse a los pentagramas de musica actuales.

Una lectura parcial de la expresion matematica anterior puede ser lasiguiente:

13

Page 14: Introduccion A La Programacion En Pascal

14 CAPITULO 2. LENGUAJES

Un valor particular de la variable z se obtiene sumando los valoresde las variables x e y.

En el lenguaje PASCAL la suma de dos numeros correspondiente a estainterpretacion se expresa con la instruccion

z := x + y ;

con una sintaxis muy proxima a la expresion matematica, si bien su semanticaes distinta pues ha de entenderse del siguiente modo:

El valor almacenado en la memoria identificada con el nombre xy el valor almacenado en la memoria identificada con el nombre y,han de sumarse almacenando el resultado en el lugar de memoriaidentificado por el nombre z.

Sin embargo, la informacion que ha de recibir la Unidad Central de Pro-ceso de un ordenador para realizar esta operacion puede ser:

0010 0000 0000 0100

0100 0000 0000 0101

0011 0000 0000 0110

lo que en una lenguaje que establece un compromiso entre ordenador y hom-bre corresponde a

X Y Z@@@R �

LOAD X

ADD Y

STORE Z

Este lenguaje se denomina Ensamblador (Assembler) y casi corresponde auna traduccion de la secuencia de ceros y unos en palabras mas faciles derecordar. Se suele hablar de lenguajes de programacion de bajo y alto nivel,segun se acerquen a lenguaje natural de los humanos. El ensamblador es un

Page 15: Introduccion A La Programacion En Pascal

2.2. FORMALIZACION DE LOS LENGUAJES 15

lenguaje de programacion de bajo nivel y el PASCAL es un lenguajede programacion de alto nivel. A la secuencia binaria que acepta la UCPdel ordenador se le denomina lenguaje maquina.

La desventaja obvia de un lenguaje de bajo nivel es lo costoso que resultala programacion de un ordenador con el. A medida que un lenguaje se acercamas al lenguaje natural, mas sencillo es programar con el y mas accesible apersonas no especializadas. Pero existe otra desventaja: los lenguajes debajo nivel dependen del ordenador. Dado que se han de cenir al disenologico del ordenador, un lenguaje ensamblador solo es valido para familiasde ordenadores con el mismo diseno logico.

2.2 Formalizacion de los lenguajes

Los lenguajes de alto nivel que vamos a estudiar en este curso son el resultadode investigaciones realizadas desde dos enfoques distintos. Por una parte, unlenguaje de programacion es un caso particular de un lenguaje formal; porotra, una solucion al problema de ingenierıa que surge en la construccion demaquinas procesadoras de informacion.

La formalizacion de los lenguajes es un tema de investigacion desde losantiguos griegos. Aristoteles (384–332 A.C.) se puede considerar el padrede la logica formal. Leibniz en el siglo XVII, y Frege en el XIX, intenta-ron construir lenguajes formales sin la imprecision y ambiguedad de lenguajeordinario. Gorge Boole en 1854 proporciono un nuevo intento de forma-lizacion con la introduccion de sımbolos, formulas y axiomas. El metodologico de Boole permitio construir maquinas logicas que podıa resolver au-tomaticamente problemas logicos. Mas tarde, el espanol Leonardo Torresy Quevedo (1852–1939), entre otros disenos mecanicos automaticos, cons-truyo el Ajedrecista, un automata capaz de jugar al ajedrez. A finales delsiglo XIX y en el XX, los lenguajes formales se investigaron con el intentode formalizar las matematicas de un modo similar a como Euclides habıaformalizado la geometrıa. 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 demanipulacion de sımbolos ( la denominada maquina de Turing ) con el que sepuede realizar cualquier computo que hasta ahora podemos imaginar. Estafue una vıa de comunicacion entre los problemas formales de la computaciony de la matematica. La union permitio demostrar que no existe ninguna

Page 16: Introduccion A La Programacion En Pascal

16 CAPITULO 2. LENGUAJES

maquina de Turing que pueda reconocer si una sentencia es o no un teore-ma de un sistema logico formal; pero tambien permitio demostrar que si uncalculo puede explicitarse sin ambiguedad en lenguaje natural, con ayudade sımbolos matematicos, es siempre posible programar un ordenador digitalcapaz de realizar el calculo, siempre que la capacidad de almacenamiento deinformacion sea la adecuada.

Desde el punto de vista de la ingenierıa, los progresos en lenguajes de pro-gramacion han sido paralelos a los disenos de los nuevos ordenadores. Babba-ge ya escribio programas para sus maquinas, pero los desarrollos importantestuvieron lugar, igual que en los ordenadores, alrededor de la segunda guerramundial. Fue en esa epoca (justo despues de finalizada la guerra) cuandoZuse publico su libro Calculo y programacion. En el aparece por primera vezel concepto de operacion de asignacion. Zuse se planteo el problema siguien-te: la expresion z = z + 1 es incorrecta para significar “ El nuevo valor de zse obtiene sumando 1 al antiguo ”, e introdujo la expresion z + 1⇒ z. Estasentencia de asignacion nunca se habıa utilizado antes pues siempre se intro-ducıa una nueva variable cuando se procedıa a una asignacion ( por ejemploy = z+ 1). Este nuevo enfoque es fundamental puesto que el uso sistematicode las asignaciones es lo que distingue la forma de pensar en ciencias de lacomputacion y en matematicas.

2.3 Las maquinas de Von Neuman

Originalmente la programacion de un ordenador era directamente la reorde-nacion de los componentes del ordenador. La idea de producir un programade ordenador que se pudiera almacenarse en la memoria del ordenador sedebe a Von Neuman y aparecio en un informe que hizo sobre el ordenadorEDVAC. Von Neuman considero la posibilidad de que una palabra formadapor 32 bit fuera o bien un numero o bien una instruccion. Una instruccion secodificaba por un grupo de bits adyacentes y considero sumas, multiplicacio-nes, transferencia de contenidos de memoria a registros, test, e instruccionesde bifurcacion. Ası, un programa consistirıa en una secuencia de palabras enforma binaria.

Necesidades practicas muy obvias llevaron a la utilizacion de mnemotecnicospara programar las instrucciones, y posteriormente otro programador tra-ducıa los mnemotecnicos a lenguaje maquina. El paso siguiente debıa serconseguir que fuera el ordenador el que tradujera esas codificaciones y tam-

Page 17: Introduccion A La Programacion En Pascal

2.4. BREVE HISTORIA DE LOS LENGUAJES 17

bien lograr que ciertos codigos correspondieran a mas de una instruccionelemental del ordenador. Al principio de los anos cincuenta se empezaron aconstruir estos Decodificadores o Ensambladores.

El objetivo de los ingenieros que trabajaban en el diseno de los ordena-dores era conseguir que el ordenador aceptara instrucciones con un formatosimilar al matematico, puesto que en aquella epoca la mayorıa de la aplica-ciones giraban alrededor de calculos complejos. Para lograr esto fue necesarioun cambio radical en el enfoque de la operacion de un ordenador.

Datos

ordenador

Programa

ordenador

Programa

?

?

?

?

Resultado

El ordenador debıa considerarse como un procesador de informacion ca-paz de transformar un programa escrito en un lenguaje de alto nivel en unprograma en lenguaje maquina. A su vez, debıa programarse el compiladorcapaz de realizar esta transformacion.

2.4 Breve historia de los lenguajes

En los anos 50 se realizaron varios compiladores primitivos y fue en 1957cuando aparecio el primer compilador de FORTRAN. El compilador de FOR-TRAN (FORmula TRANslator) estaba disenado para traducir a lenguajemaquina expresiones y operaciones matematica, e incluso permitıa la mani-pulacion de matrices. La aparicion del FORTRAN fue un gran cambio para

Page 18: Introduccion A La Programacion En Pascal

18 CAPITULO 2. LENGUAJES

los programadores que no todos aceptaron de buen grado. No les gustabaque sus programas fueran tratados por el ordenador como meros datos, y ar-gumentaban que el codigo maquina generado por el compilador nunca podrıaser tan eficiente como el escrito por ellos directamente. Esto no era general-mente ası, puesto que el FORTRAN no fue disenado pensando en crear unlenguaje bien estructurado sino pensando en crear un traductor de expresio-nes aritmeticas a codigo maquina muy eficiente. Por ello, el diseno logico delordenador IBM 704 para el que fue creado casi puede deducirse del lenguajeFORTRAN. En diferentes versiones, cada vez mas estructuradas, el lenguajeFORTRAN se ha utilizado extensivamente desde que aparecio hasta hoy endıa, y puede considerarse el lenguaje estandard del calculo cientıfico.

Unos anos despues de aparecer el FORTRAN aparecio el lenguaje AL-GOL 60 (Algorithm Language), que fue disenado para ser independiente delordenador con una gramatica bien definida. Tambien de aquella epoca es elCOBOL (Common Business Oriented Language) que se diseno para para lasmanipulaciones de datos normales en aplicaciones de negocios y con un usomayor del lenguaje ingles en sus frases. Las versiones modernas del COBOLsiguen usandose en la actualidad y es el lenguaje estandard en aplicacionesinformaticas bancarias. Desde entonces han aparecido diversos lenguajes dealto nivel entre los que podemos mencionar el BASIC (Beginners All–purposeSymbolic Instructional Code), PL/I , APL, PASCAL, ADA, MODULA , C ,RPG, PROLOG, LISP, ... etc. Alguno de estos lenguajes han sido disenadospara un tipo concreto de aplicaciones. Por ejemplo, el ADA para aplica-ciones relacionadas con defensa, o el RPG para transacciones usuales en losbancos. La evolucion de los lenguajes de programacion ha estado guiada porla evolucion de:

• Los ordenadores y sus sistemas operativos.

• Las aplicaciones.

• Los metodos de programacion.

• Los fundamento teoricos.

• La importancia dada a la estandarizacion.

Podemos resumir la evolucion de los lenguajes de programacion en la siguien-te tabla:

Page 19: Introduccion A La Programacion En Pascal

2.4. BREVE HISTORIA DE LOS LENGUAJES 19

periodo Influencias Lenguajes1950 – 55 Ordenadores primitivos Lenguajes ensamblador

Lenguajes experimentalesde alto nivel

1956 – 60 Ordenadores pequenos, FORTRANcaros y lentos ALGOL 58 y 60Cintas magneticas COBOLCompiladores e interpretes LISPOptimizacion del codigo

1961 – 65 Ord. grandes y caros FORTRAN IVDiscos Magneticos COBOL 61 ExtendidoSistemas operativos ALGOL 60 RevisadoLeng. de proposito general SNOBOL

APL ( como notacion solo)1966 – 70 Ordenadores de diferentes PL/I

tamanos, velocidades, costes FORTRAN 66 (estandard)Sistemas de almacenamiento COBOL 65 (estandard)masivo de datos (caros) ALGOL 68S.O. multitarea e SNOBOL4interactivos SIMULA 67Compil. con optimizacion BASICLeng. estandard , APL/360flexibles y generales

1971 – 75 Micro ordenadoresSistemas de almacenamiento PASCALmasivo de datos pequenos COBOL 74y baratos PL /IProgr. estructuradaIngenierıa del softwareLeng. sencillos

1976 – 80 Ord. baratos y potentes ADASistemas distribuidos FORTRAN 77Prog. tiempo–real PROLOGProg. interactiva CAbstraccion de datosProg. con fiabilidady facil mantenimiento

Page 20: Introduccion A La Programacion En Pascal

20 CAPITULO 2. LENGUAJES

2.5 Tipos de lenguajes

Desde un punto de vista mas general los lenguajes se pueden clasificar enlenguajes de procedimiento o declarativos. En los primeros, con el lenguaje seespecifica paso a paso el procedimiento que ha de realizar el ordenador paraprocesar la informacion, mientras que en los segundos se declaran hechosque han de dirigir las respuestas del ordenador. El PASCAL y el C queestudiaremos en este curso son de procedimiento, mientras que por ejemploel PROLOG, es declarativo.

Una porcion de programa PROLOG es ası:

. . .

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 lasque han de ser coherentes las respuestas del programa.

Exite una diferencia grande en la programacion con un lenguaje u otrosegun 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 dealto nivel a lenguaje maquina se realiza sentencia a sentencia segun se vanejecutando. Un lenguaje es compilado cuando esta trasformacion se realizaen bloque antes de que ninguna instruccion sea ejecutada. Por ejemplo, elBASIC en general se suele interpretar y el LISP siempre. En un lenguajeinterpretado la puesta a punto de un programa ha de realizarse secuencial-mente puesto que las distintas partes del programa no se pueden verificarhasta que entran en ejecucion.

En el caso mas comun de lenguajes compilados, son varios los subprocesosimplicados en la transformacion del codigo de alto nivel en instruccionesejecutables por la UCP.

Page 21: Introduccion A La Programacion En Pascal

2.5. TIPOS DE LENGUAJES 21

Programa

Leng. maquina

Codigo UCP

L. maquinaHHHHH

HHHHHHH���

������

���

COMPILADOR

MONTADOR

����������

������������

A su vez el compilador realiza varias tareas:

• verificacion de la sintaxis

• transformacion a codigo maquina

• optimizacion

Si un programa es incorrecto sintacticamente, el compilador detectara el errory lo comunicara con un mensaje relacionado con la regla del lenguaje quese ha incumplido. Normalmente, estos son los errores mas comunes y masfaciles de detectar.

El montador (Linker) unifica el codigo con el proveniente de otros sub-programas con el que se intercambian datos. Para ello realiza una lista de los

Page 22: Introduccion A La Programacion En Pascal

22 CAPITULO 2. LENGUAJES

datos que comparten todos los programas y asigna las direcciones comunesdonde cada uno debera procesar esos datos. Esta unificacion de direccionessera imposible si algun procedimiento supuestamente existente en otro sub-programa no aparece o aparece de un modo no unıvoco. Tambien sera causade error que algun dato compartido por subprogramas este declarado de mo-do distinto en cada programa. Estos errores son poco comunes y facilmentedetectable con los mensajes de error proporcionados por el montador. Sinembargo, los errores mas comunes y mas tediosos de eliminar son aquellosde programacion que dan lugar a sentencias sintacticamente correctas peroque corresponde a acciones distintas a las deseadas. Desgraciadamente solose 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 unprograma aunque se obtenga el codigo maquina por compilacion. Esta he-rramienta facilita enormemente la depuracion de los programas pues permiteconocer o modificar el valor de los datos manipulados en el programa durantela ejecucion.

Page 23: Introduccion A La Programacion En Pascal

Capıtulo 3

Algoritmos y resolucion deproblemas con el ordenador

3.1 Pasos en la resolucion

Vamos a analizar las caracterısticas del procedimiento de resolucion de unproblema con el ordenador. La mayorıa de las consideraciones son validaspara problemas genericos y muy pocas son especıficas de esta herramienta.

Etapas del procedimiento de resolucion:

1. Analisis del problema.

2. Realizacion de la estrategia ideada para su solucion.

3. Verificacion y analisis del rendimiento del procedimiento.

Cada una de estas etapas consta de varias tareas:

1. Analisis del problema.

• Comprension del problema.

Pues de lo contrario podemos acabar resolviendo magistralmenteun problema distinto.

• Especificacion de los datos de entrada.

23

Page 24: Introduccion A La Programacion En Pascal

24 CAPITULO 3. ALGORITMOS

• Diseno del esquema del algoritmo que satisface las restriccionesdel problema.

ALGORITMO: Procedimiento para resol-ver un problema paso a paso.ALGORITMO: Conjunto de operacionesque secuencialmente conducen a la respuestaa una pregunta en un numero finito de pasos.

• Especificacion del modo de proporcionar la respuesta al problemaplanteado

2. Realizacion de la estrategia ideada para su solucion.

• 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.

Cuando la herramienta que se utiliza es el ordenador, la estrategia seha de realizar en tres pasos:

(a) DISENO.

(b) ESCRITURA.

(c) VERIFICACION.

3. Verificacion y analisis del rendimiento del procedimiento.

• Prueba con casos sencillos.

• Prueba con casos complejos.

• Prueba con casos extremos.

• Analisis del rendimiento en casos poco favorables y en casos tıpicos.

• Refinamiento de los algoritmos.

• Refinamiento de la escritura de los algoritmos.

Page 25: Introduccion A La Programacion En Pascal

3.2. USO MULTIPLE 25

3.2 Uso multiple

El uso multiple de los procedimientos para la resolucion de problemas conel ordenador implica que los procedimientos han de cumplir los siguientesrequisitos:

• La resolucion de un mismo problema con distintos datos y en periodoslargos de tiempo obliga a:

1. Realizacion de procedimientos muy bien verificados.

2. Realizacion de procedimientos muy bien documentados y escritoscon un estilo claro.

• La resolucion de un mismo tipo generico de problemas o variantes delmismo, con reutilizacion de las herramientas desarrolladas, obliga a:

1. Realizacion de procedimientos modulares.

2. Realizacion de procedimientos muy bien documentados y escritoscon un estilo claro.

• El uso del procedimiento dentro de un equipo por distintas personaspara 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 escritoscon un estilo claro.

3.3 El ejemplo de Josefo

Vamos a ver el significado de todas estas consideraciones con un ejemplo:una variante del Problema de Josefo (Flavio Josefo, I DC):

Un grupo de personas prefieren el suicidio a la esclavitud y deci-den colocarse en cırculo eligiendo siempre al siguiente como eje-cutor y asesinando al situado despues del ejecutor. Ası sucesiva-mente hasta que quede un solo ciudadano que deberıa suicidarse.El problema de Josefo es conocer en que lugar ha de colocarse enel corro para quedar el ultimo y reflexionar libremente sobre ladecision colectiva.

Page 26: Introduccion A La Programacion En Pascal

26 CAPITULO 3. ALGORITMOS

Se pretende disponer de un programa en Pascal capaz de proporcionar rapidamentela posicion privilegiada.

1. Analisis del problema.

• Comprension del problema.

Es muy util empezar con un caso sencillo.

&%'$

- 1

23

4

5 6

• Especificacion de los datos de entrada.

En este caso es solo el numero de individuos en el cırculo.

• Diseno del esquema del algoritmo que satisface las restriccionesdel problema.

Si es posible utilizar una estructura de datos de lista circular elalgoritmo es una copia del metodo grafico de resolver el problema.

• Especificacion del modo de proporcionar la respuesta al problemaplanteado

La respuesta es comunicar el numero de orden del ultimo individuoen el cırculo.

2. Realizacion de la estrategia ideada para su solucion.

• Captura de datos.

Page 27: Introduccion A La Programacion En Pascal

3.3. EL EJEMPLO DE JOSEFO 27

{ Lectura del numero de personas en el circulo }

Readln(n);

• Generacion de las estructuras de datos adecuadas para el algorit-mo que se va a utilizar.

Se define la estructura de datos mas adecuada

{ el tipo NODO es un registro que contiene el ordinal y un }

{ enlace al siguiente nodo. Se formara una lista circular de nodos }

type enlace = ^nodo;

nodo = record

numero: integer;

siguiente: enlace

end;

var

j , n : integer;

individuo , temporal: enlace;

y se rellena

{Se construye la lista circular }

{ Se genera el nodo de cabeza y se guarda en TEMPORAL }

{ para luego poder cerrar el circulo }

new(individuo);

individuo^.numero := 1;

temporal := individuo;

{ Se generan los restantes nodos hasta completar los N nodos}

for j := 2 to N do begin

new(individuo^.siguiente);

individuo := individuo^.siguiente;

individuo^.numero := j;

end; {endfor}

{Se cierra la lista circular al apuntar con el n-esimo }

{nodo al primero }

individuo^.siguiente := temporal;

Page 28: Introduccion A La Programacion En Pascal

28 CAPITULO 3. ALGORITMOS

• Especificacion de los algoritmos.

{Algoritmo de eliminacion de individuos de la lista circular}

{Mientras quede mas de un solo nodo en la lista se eliminan }

while ( individuo <> individuo^.siguiente ) do begin

{se salta al ejecutor }

individuo:= individuo^.siguiente;

{se avisaria del individuo que seria eliminado }

{ writeln (individuo^.siguiente^.numero);}

{se almacena el nodo que se va eliminar para luego liberarlo }

{de la memoria}

temporal := individuo^.siguiente;

{Se une el antecesor del nodo fiambre a su sucesor}

individuo^.siguiente := individuo^.siguiente^.siguiente;

{y la liberacion de la posicion de memoria del nodo completa la}

{ejecucion }

dispose(temporal);

end; {endwhile}

• Presentacion de los resultados.

{Se comunica el orden del ultimo en el circulo }

writeln (individuo^.numero);

El programa completo es:

Program Josefo (input,output);

{ el tipo NODO es un registro que contiene el ordinal y un enlace }

{ al siguiente nodo. Se formara una lista circular de nodos }

type enlace = ^nodo;

Page 29: Introduccion A La Programacion En Pascal

3.3. EL EJEMPLO DE JOSEFO 29

nodo = record

numero: integer;

siguiente: enlace

end;

var

j , n : integer;

individuo , temporal: enlace;

begin { Josefo }

{ Lectura del numero de personas en el circulo }

Readln(n);

{Se construye la lista circular }

{ Se genera el nodo de cabeza y se guarda en TEMPORAL para }

{ luego poder cerrar el circulo }

new(individuo);

individuo^.numero := 1;

temporal := individuo;

{ Se generan los restantes nodos hasta completar los N nodos}

for j := 2 to N do begin

new(individuo^.siguiente);

individuo := individuo^.siguiente;

individuo^.numero := j;

end; {endfor}

{Se cierra la lista circular al apuntar con el n-esimo nodo al primero}

individuo^.siguiente := temporal;

{Algoritmo de eliminacion de individuos de la lista circular }

{Mientras quede mas de un solo nodo en la lista se eliminan }

while ( individuo <> individuo^.siguiente ) do begin

{se salta al ejecutor }

individuo:= individuo^.siguiente;

Page 30: Introduccion A La Programacion En Pascal

30 CAPITULO 3. ALGORITMOS

{se avisaria del individuo que seria eliminado }

{ writeln (individuo^.siguiente^.numero);}

{se almacena el nodo que se va eliminar para luego liberarlo }

{de la memoria}

temporal := individuo^.siguiente;

{Se une el antecesor del nodo fiambre a su sucesor}

individuo^.siguiente := individuo^.siguiente^.siguiente;

{y la liberacion de la posicion de memoria del nodo completa la}

{ejecucion }

dispose(temporal);

end; {endwhile}

{Se comunica el orden del ultimo en el circulo }

writeln (individuo^.numero);

end. { Josefo }

3. Verificacion y analisis del rendimiento del procedimiento.

• Prueba con casos sencillos.

Se probarıa con N = 6 para el que se conoce bien el resultado.

• Prueba con casos complejos.

Se probarıa con N grande.

• Prueba con casos extremos.

Se probarıa con N = 1.

• Analisis del rendimiento en casos poco favorables y en casos tıpicos.

En este caso el algoritmo utilizado crece linealmente con el numerode individuos considerado.

• Refinamiento de los algoritmos.

En este caso un analisis mas detallado del problema lleva a unalgoritmo mucho mas eficiente y cuyo costo computacional es in-dependiente del numero N de elementos en el cırculo:

Page 31: Introduccion A La Programacion En Pascal

3.3. EL EJEMPLO DE JOSEFO 31

Si se descompone N de la forma N = 2m + l el ultimo elementoque se elimina es el 2l + 1.

• Refinamiento de la escritura de los algoritmos.

Uso multiple del programa.

• Verificacion.

La verificacion a menudo debe incluir pruebas para detectar el mal usodel programa por parte de un usuario que no esta familiarizado con elprograma o con el problema.

En el programa Josefo la captura de datos de datos podrıa incluirseuna especificacion del dato requerido y una verificacion del valor.

{ Lectura del numero de personas en el circulo }

writeln(’ Teclee el numero de elementos en el cırculo ’);

Readln(n);

if (n <1) then begin

writeln(’ Ha de ser un numero mayor que cero’);

Halt;

end; {endif}

• Modularidad.

• Documentacion.

• Claridad de estilo.

El programa Josefo si se acompana de la adecuada documentacionexterna 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 saltandocada vez M individuos en vez de 2. Aparte de la modificacion en laentrada de datos , la modificacion del algoritmo es mınima y sencillade localizar:

{se salta al ejecutor }

individuo:= individuo^.siguiente;

Page 32: Introduccion A La Programacion En Pascal

32 CAPITULO 3. ALGORITMOS

se modificarıa a:

{se salta al ejecutor }

for j := 1 to ( M -1 ) do begin

individuo:= individuo^.siguiente;

end; {endfor}

Esta modificacion serıa igual de facil para el autor original del programacomo para cualquier otro programador.

Page 33: Introduccion A La Programacion En Pascal

Capıtulo 4

Pascal y Turbo Pascal

4.1 Caracterısticas

El PASCAL es un lenguaje relativamente moderno, desarrollado por NiklausWirth y su grupo de Zurich en 1971. Se trata de un lenguaje de propositogeneral, esto quiere decir que se puede emplear para construir todo tipo deaplicaciones. En la practica tambien quiere decir que se trata de un lenguajeno disenado para desarrollar ningun tipo especıfico de aplicaciones. Pero elPASCAL es especialmente util para algo: para la ensenanza de buenos modosde programacion. El PASCAL es hoy en dıa el lenguaje mas usado para laensenanza de la programacion por varios motivos:

• Posee unas reglas sencillas de sintaxis.

• Es un lenguaje muy estructurado.

• Realiza una comprobacion exhaustiva de tipos de datos.

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 programasdel modo que hoy en dıa se estima correcto.

El compilador de PASCAL es relativamente sencillo de realizar, por loque se ha extendido a muchos tipos de plataformas, desde los ordenadorespersonales a los grandes ordenadores corporativos. Cuando una aplicacionse escribe en PASCAL estandard puede compilarse en cualquier maquina enla que exista compilador de PASCAL , que son la mayorıa.

33

Page 34: Introduccion A La Programacion En Pascal

34 CAPITULO 4. PASCAL

Existen varios dialectos locales del PASCAL , entre los que se encuentra elTURBO PASCAL , que admiten todas las instrucciones del PASCAL estan-dard mas un subconjunto especıfico de instrucciones normalmente pensadaspara aumentar las capacidades del lenguaje en un ordenador particular.

El TURBO PASCAL , de la companıa Borland (Scotts Valley, Califor-nia) es un dialecto del PASCAL que incluye ademas de las instrucciones delPASCAL estandard una serie de instrucciones que permiten desarrollar apli-caciones especıficas para ordenadores IBM PC o IBM PS y compatibles. Noes 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 deeste lenguaje incluye ademas del compilador un entorno integrado de desa-rrollo (IDE) que permite compilar, visualizar errores y depurar los programasdesde un mismo entorno.

4.2 El programa Pascal

Un programa PASCAL es un conjunto de instrucciones que siguen la sintaxisy la estructura del PASCAL . La estructura generica es:

Program nombre (ficheros);. . .declaraciones. . .

Begin. . .sentencias. . .

End.

Todo programa Pascal empieza con la palabra Program seguida de unnombre que elige el programador para identificar el programa. A continuacionentre parentesis se pueden indicar los ficheros que contienen los datos deentrada y salida respectivamente. Estos ficheros son el input y el outputpara indicar entrada desde el teclado y salida al terminal. Si se quierenespecificar estos ficheros la primera lınea de un programa sera:

Program nombre (Input , Output );

Page 35: Introduccion A La Programacion En Pascal

4.3. PALABRAS RESERVADAS Y ESTRUCTURAS 35

y es equivalente a:

Program nombre ;

La primera lınea del programa es una instruccion PASCAL y como todasellas termina con el signo de puntuacion “ ; ” .

Despues de la identificacion del programa se han de situar las instruccio-nes declarativas del programa que sirven para especificar sin ambiguedad elsignificado de los terminos que se utilizaran en el programa. A continuacionhan de aparecer las instrucciones correspondientes al procedimiento que sequiere realizar. Esta instrucciones estan encabezadas por Begin y terminancon End y un punto. El programa mas pequeno y mas inutil que cumple lasreglas de estructuracion del PASCAL es:

Program nulo;{ Programa ejemplo de la estructuramas simple de un programa PASCAL }

Begin

(* No hace falta ninguna instruccionpara no hacer nada *)

End.

En la parte reservada a declaraciones no se incluye nada pues nada senecesita declarar. Todos los sımbolos que se encuentren entre los parentesis{ } son comentarios que sirven para hacer mas legible el programa. Tambienlos sımbolos compuestos (* y *) sirven para delimitar el principio y fin de uncomentario. Al existir dos tipos de delimitadores de comentarios, es posiblerealizar anidacion de comentarios. Por ejemplo,

{ Este es un comentario(* sintacticamente *)

correcto en PASCAL }

4.3 Palabras reservadas y estructuras

Las palabras Program, Begin, End, Input, y Output, y otras que vere-mos mas adelante, son identificadores que permiten al compilador PASCAL

Page 36: Introduccion A La Programacion En Pascal

36 CAPITULO 4. PASCAL

interpretar el programa y no se pueden utilizar con otros fines. Estas palabrasse suelen referir con el termino Palabras reservadas. El compilador interpretaigual mayusculas o minusculas, y por tanto se pueden usar indistintamente.Esta libertad de eleccion debe utilizarse para aumentar la legibilidad de losprogramas. Por ejemplo, podemos empezar siempre con mayuscula las pa-labras reservadas y ası sera mas facil detectar las estructuras del programa.Tambien suele escribirse todo con mayusculas el nombre de las constantescuyo valor no puede alterarse durante el programa. La eleccion de un estilou otro de escritura suele variar pero lo importante es que sea uniforme a lolargo del programa.

En la parte del programa reservada para declaraciones se incluyen diversostipos de declaracion:

{1} Program nombre ;{2} (* Este es un ejemplo de la estructura de la{3} parte declarativa de un programa PASCAL *)

{4} Uses nombre unidades ;

{5} Const{6} nombre constante = valor ;

. . .{7} Type{8} nombre tipo = def tipo ;

. . .{9} Var{10} nombre variable : tipo dato ;

. . .{11} Begin

. . .

La palabra reservada Uses de la instruccion {4} se utiliza para especificarel nombre las unidades donde se almacenan otros trozos de codigo PASCALque son necesarias para completar el codigo especificado en este programa.Normalmente se trata de porciones de codigo que forman parte de una librerıade programas. En la instruccion {5} la palabra reservada Const indicaque se ha acabado la parte iniciada por Uses y se empieza la parte dedeclaracion de las constantes que aparecen en el programa. Con Type se

Page 37: Introduccion A La Programacion En Pascal

4.4. INSTRUCCIONES SENCILLAS Y COMPUESTAS 37

inicia la declaracion de tipos de datos definidos por el programador, y conVar la especificacion del tipo de dato que corresponde a las variables que seutilizan en el programa. Finalizada esta parte declarativa, empezarıan lasinstrucciones del procedimiento que se esta programando ({11}). Las lıneasde codigo {1} , {4} , {6} , {8} y {10} corresponden a sentencias PASCALy por tanto acaban con el signo de puntuacion “;”. Aparte de estos tipos dedeclaracion tambien existen las de etiquetas, procedimientos y funciones.

4.4 Instrucciones sencillas y compuestas

El cuerpo de instrucciones del procedimiento esta formado por sentencias quepueden ser sencillas o compuestas. Las sentencias sencillas acaban con “;”y las compuestas empiezan por Begin y acaban con End. Por ejemplo,

{1} If (a > 0) Then

{2} b := a * a * a ;

la sentencia {2} es sencilla y esta delimitada por la palabra reservada Thende la construccion condicional iniciada por If, y por el punto y coma. Estasentencia sencilla es completamente equivalente a la compuesta especificadaentre {4} y {7}:

{3} If (a > 0) Then

{4} Begin

{5} b := a * a ;

{6} b := b * a

{7} End;

El principio de la sentencia es el Begin de {4}, y el final el End de {7}.La sentencia compuesta consta de dos sencillas. La especificada en {5} setermina con la puntuacion “;” mientras que la de {6} no necesita otra fi-nalizacion que el End. Ası mismo, la sentencia compuesta ha de finalizarsecon el ; situado despues del End en {7}. En cualquier lugar de un pro-grama PASCAL donde puede incluirse una sentencia sencilla tambien puedeincluirse una compuesta.

Page 38: Introduccion A La Programacion En Pascal

38 CAPITULO 4. PASCAL

4.5 Diagramas de sintaxis

La forma mas escueta de representar las construcciones sintacticamente validasdel PASCAL es utilizar los diagramas de sintaxis. La especificacion de lasdos opciones que existen, sentencias sencillas o compuestas, serıa ası con undiagrama de sintaxis:

���

EEEEEEEEE���� Instruc. senc.

����

����

���������--

;

JJJ

Instruccion sencilla

Begin End

Este diagrama ha de leerse siguiendo las fechas de izquierda a derecha ysiendo valido cualquier camino en toda bifurcacion. Una construccion estararepresentada por un diagrama de sintaxis cuando empezando por la izquierdase puede salir por la derecha y cada una de las partes de la construccion co-rresponde a las especificaciones que se encuentran en el camino. Por ejemplo,las sentencias presentadas en los ejemplos anteriores son correctas, mientrasque la siguiente:

{4} Begin

{5} b := a * a ;

{6} b := b * a ;

{7} End;

es incorrecta. Si seguimos el diagrama nos encontramos que despues delpunto y coma, al final de {6}, deberıa haber otra sentencia sencilla mientrasque existe un End.

Page 39: Introduccion A La Programacion En Pascal

Capıtulo 5

Datos

5.1 Variables, datos y direcciones

En este tema vamos a ver las instrucciones necesarias en un programa PAS-CAL para especificar los tipos de datos que se van a manejar. Los datos sealmacenaran en la memoria del ordenador en una determinada posicion, peropara referirnos a ellos se utilizan nombres que el programador elige libremen-te. El lenguaje PASCAL permite utilizar comodamente una gran variedadde tipos de datos, pero en este tema solo vamos a ver los mas sencillos.

PI 7161

3.14159

-

6nombre

contenido

direccion

Las primeras instrucciones de un programa han de ser las que indican lostipos de datos que se van a utilizar. Cuando un nombre se utiliza para undato que no va a modificarse se trata de un a constante. Si por el contrariose permite que el contenido de las posiciones de memoria referidas por undeterminado nombre varıen durante la ejecucion del programa, se trata deuna variable.

Program Uno;

Const

39

Page 40: Introduccion A La Programacion En Pascal

40 CAPITULO 5. DATOS

PI = 3.14159;

UNIDADES = ’ radianes ’;

Var

n , m : Integer;

z : Real;

Begin

. . . .

Este es un comienzo valido de programa en el que se especifican datos yvariables que se van a utilizar. La seccion donde se agrupan las definicionesde constantes se encabeza con el indicativo Const, la seccion de variables conVar, y ambas han de preceder el indicativo Begin que anuncia el comienzode las instrucciones del programa que van a manipular los datos. En elapartado de constantes para asignar el valor se utiliza el operador = , enlugar del operador normal de asignacion := .

5.2 Identificadores

Los nombres que se pueden utilizar para referirse tanto a las variables comoa las constantes son todos aquellos que no establezcan conflicto con las pala-bras reservadas en PASCAL para especificar datos o acciones. NO puedenutilizarse:

• Palabras reservadas

Begin 1.23E2 123 While Cos

• Palabras que empiecen por numeros

1YA 2ABC

• Palabras en las que se encuentre alguno de los indicadores de operadoresPASCAL

x+y precio/calidad signo*valor

• Palabras separadas por blancos.

Page 41: Introduccion A La Programacion En Pascal

5.3. TIPOS DE DATOS 41

Se pueden utilizar indistintamente mayusculas o minusculas pero el com-pilador de PASCAL no las distinguira.

Son validos nombres como

a364b46 coco xxx2

pero se deben utilizar nombre que tengan relacion con el dato que van acontener. Por ejemplo,

angulo lado vertice CaraOpuesta

Algunos compiladores de PASCAL solo admiten numeros y letras en la com-posicion del nombre de datos y variables. El TURBO PASCAL tambienadmite otros caracteres. Por ejemplo, permite

Cara_Opuesta Nombre_Compuesto

En el ejemplo Uno podemos ver que el tipo de datos que van a contenerlas constantes se especifica por los valores que se asignan.

Program Uno;

Const

PI = 3.14159;

UNIDADES = ’ radianes ’;

Var

n , m : Integer;

z : Real;

Begin

. . . .

Sin embargo, el tipo de las variables ha de indicarse explıcitamente con indi-cadores PASCAL tales como Integer, o Real. Estos se refieren a dos tiposde datos numericos entre los posibles en PASCAL .

5.3 Tipos de datos

Los tipos de datos sencillos son:

1. Numericos.

• Numeros enteros:

Page 42: Introduccion A La Programacion En Pascal

42 CAPITULO 5. DATOS

– Integer

– Byte

– ShortInt

– Word

– LongInt

• Numeros 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 partedecimal ) con signo. Para una variable Integer se reservan dos bytes(16 bits) en memoria y puede almacenar numeros enteros en el rangoentre

−32, 768(−215) y + 32, 767(215 − 1)

Es el tipo de variable utilizado normalmente para las operaciones aritmeticasentre enteros.

• LongInt

Para aquellos casos en los que es necesario utilizar enteros que excedenel lımite aceptado por el tipo Integer, existe el tipo LongInt para elque se reservan 4 bytes en memoria. Con una variable de tipo LongIntse pueden referenciar numeros enteros con signo en el rango entre

−2, 147, 483, 648(−231) y +2, 147, 483, 647(231−1) .

Page 43: Introduccion A La Programacion En Pascal

5.3. TIPOS DE DATOS 43

• Word

En este tipo de datos se pueden almacenar enteros sin signo. Al igualque para el tipo Integer, para el tipo Word se reservan 2 bytes enmemoria y puede admitir numeros enteros entre 0 y 65, 535.

• Byte

En PASCAL es posible utilizar un tipo de dato llamado Byte, para elque , como su nombre indica, solo se reserva 1 byte de memoria. Enlas variables tipo Byte se pueden almacenar numeros enteros sin signoy por tanto tendran que estar limitados entre 0 y 255(28 − 1).

• Real.

Para almacenar numeros reales ( con parte decimal ) o enteros queexcedan el lımite permitido por LongInt , se ha de utilizar el tipo devariable Real . A este tipo de datos tambien se le conoce con el nombrede coma flotante por el uso que se hace de los 6 bytes que se reservanen memoria para este tipo de datos. Con los 6 bytes y una forma derepresentar el numero algo rebuscada que estudiaremos con los erro-res numericos, se pueden almacenar numeros entre 2, 910−39 y 1, 71038

tanto positivos como negativos. Debido a la representacion internautilizada, se almacenan con igual precision (7 u 8 cifras significativas)todos los numeros reales en el rango permitido.

Las operaciones con numeros en la representacion en coma flotanteson mucho mas lentas que entre numeros enteros representados direc-tamente con su valor en base 2. Un coprocesador matematico (comolos 80X87) se dedica especıficamente a estas operaciones. El TURBOPASCAL permite una coleccion de datos para tratar eficientemente connumeros reales cuando se dispone del coprocesador matematico. Cuan-do no se dispone de el, las operaciones se pueden emular por softwareaunque son mas lentas. Esta coleccion de tipos de datos son:

– Single

El tipo de datos Single es un Real mas corto (4 bytes) con elmismo rango de variacion que el Real , pero con menos cifrassignificativas.

– Double

Page 44: Introduccion A La Programacion En Pascal

44 CAPITULO 5. DATOS

Se trata de un Real largo (8 bytes) que acepta numeros realesentre 10−308 y 10308 y opera con 15 o 16 cifras significativas.

– Extended

Esta es la eleccion si el tiempo de calculo no es problema y primala precision. Se trata de un tipo de dato para el que se reservan10 bytes en memoria y puede almacenar numeros reales desde3.410−4932 y 1.1104932. Se pueden distinguir numeros que tienen19 0 20 dıgitos iguales.

• Boolean

Los valores que puede tomar una variable logica, dentro de la logicaBooleana (George Boole, Inglaterra 1815 – 1864), son Verdadero o Fal-so. En PASCAL se suelen utilizar este tipo de variables para almacenarel resultado comparaciones o el establecimiento de condiciones. Su dosvalores 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. Enese byte se puede almacenar informacion de un caracter alfanumerico.Si bien en la memoria del ordenador se esta almacenando un numeroentero entre 0 y 255, este numero no puede entrar a formar parte deoperaciones aritmeticas con numeros enteros pues se entiende que setrata de un caracter ASCII. El numero almacenado es el ordinal delcaracter en la tabla ASCII.

• String

Cuando se quieren manipular grupos de caracteres ordenados, comopor ejemplo en texto, se dispone del tipo de datos String. En una

Page 45: Introduccion A La Programacion En Pascal

5.3. TIPOS DE DATOS 45

variable del tipo String se pueden almacenar entre 1 y 255 caracteresde los que se almacenan en una variable var . Por tanto el numero debytes que se reservan para este tipo de datos dependera de caso y elprogramador tendra que especificarlo.

En este ejemplo se puede ver como se realiza la especificacion:

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.

El lugar que ocupa en memoria una variable String[N], no son N bytes,sinoN+1. Esto es debido a que en el primer byte se almacena el numeroactual de componentes. En el ejemplo anterior, el espacio reservadopara modulo se distribuye:

4 - X V I % A

Los compiladores PASCAL no inicializan las variables al principio de laejecucion del programa, por lo que en los espacios de memoria reserva-dos y no rellenados se puede encontrar cualquier tipo de informacion.

Si bien se necesita un byte de almacenamiento extra por String, elprocesamiento de estas cadenas de caracteres puede ser muy eficiente.

Page 46: Introduccion A La Programacion En Pascal

46 CAPITULO 5. DATOS

5.4 Constates con tipo

Cuando se quiere utilizar en un programa una variable pero su valor se quiereasignar antes de cualquier operacion, se puede hacer uso de las Constatescon tipo. Se trata mas que de verdaderas constantes, de variables conasignacion inicial de valor. El contenido en memoria de una constante contipo puede modificarse con las instrucciones del programa. Su sintaxis esuna mezcla de la asignacion de tipo de las variables y de la definicion deconstantes. El programa Tres produce el mismo resultado que Dos.

Program Tres;

Const

lugar : String[13] = ’modulo’;

begin

{ ...... }

lugar := lugar + ’ C’+ ’-XVI’;

writeln(’ Sera en el ’,lugar);

{ ....... }

end.

5.5 Inicializacion de los datos

Dado que en PASCAL no se inicializan a cero , falso, o caracteres blancos, lasvariables cuando se define su tipo, hay que tener precaucion de no utilizar elcontenido de posiciones de memoria reservadas y no asignadas. Una medidatajante es inicializar todas las variables.

5.6 Asignacion de las constantes

Cuando se asigna el valor a una constante no se identifica explıcitamente eltipo de dato del que se trata. Esta identificacion se realiza por el contenido deltermino a la derecha del operador =. Tanto en la asignacion de constantes,como en la de variables en el cuerpo del programa, el compilador decide elespacio de memoria que ha de reservar para cada valor por el modo en queesta escrito.

Page 47: Introduccion A La Programacion En Pascal

5.7. ASIGNACION DE LOS DISTINTOS TIPOS DE VARIABLES 47

Const

lugar = ’modulo’;

En este caso, lugar es una constante del tipo String por que le asigna unvalor que es un conjunto de caracteres separados por comas.

Const

facultad = ’C’;

Cuando entre comas se situa un solo caracter, se trata del valor de unaconstante Char . Tambien es sencillo reconocer los datos Boolean porquese les asigna el indicador True o False . En el caso de los numeros, ladistincion se realiza entre enteros y reales. Para las constantes asignadascon numeros reales, el compilador elige el tipo Real, y para los enteros elInteger. La distincion entre numeros enteros y reales se hace por existenciade punto decimal en el valor. Para los numeros reales existe tambien laposibilidad de notacion cientıfica.

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 Asignacion de los distintos tipos de va-

riables

En el cuerpo del programa se suelen asignar valores a variables. En estecaso, a partir de las instrucciones de la seccion destinada a la identificaciondel tipo de variables, se reserva el espacio adecuado de memoria para cadavariable. Por tanto, es importante que en el lado derecho del operador deasignacion (:=) se encuentre un valor correspondiente al tipo de variable delado izquierdo.

Program Cuatro;

const

Calle = ’ Paloma Blanca ’;

Page 48: Introduccion A La Programacion En Pascal

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 variabledel tipo String una constante del tipo Char. No obstante, estas instruc-ciones no dan lugar a error en PASCAL porque el compilador interpreta lasvariables Char como un subconjunto de las String (El espacio reservado en

Page 49: Introduccion A La Programacion En Pascal

5.7. ASIGNACION DE LOS DISTINTOS TIPOS DE VARIABLES 49

memoria para un String acomoda perfectamente un Char ).En el caso de valores numericos,

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.

el compilador interpreta los Integer como un subconjunto de los Real.Para los efectos sintacticos, cualquier valor numerico ( o dato alfanumerico)

en el cuerpo del programa se considera igual que situado en el lado derechoen una asignacion de constante del tipo correspondiente.

Page 50: Introduccion A La Programacion En Pascal

50 CAPITULO 5. DATOS

Page 51: Introduccion A La Programacion En Pascal

Capıtulo 6

Intercambio basico de datos yresultados

6.1 Dispositivos de entrada, salida y almace-

namiento

La comunicacion entre el ordenador y el usuario se realiza a traves de losdispositivos denominados de entrada–salida (E/S , I/O). Todo programa deordenador se comunica con el exterior. Algunas veces la comunicacion serealiza directamente con el usuario a traves del teclado y el terminal TRC.Otras, se utilizan intermediarios como son los dispositivos de almacenamientode informacion (discos, diskettes,...). En este ultimo caso, el programa lee losdatos del archivo donde se guardan y tambien puede escribir los resultadosen el archivo que se halla indicado para el almacenamiento.

Para cada problema concreto habra un modo optimo de comunicacioncon el ordenador.

En aquellos casos en los que se utilicen exclusivamente dispositivos dealmacenamiento intermedio de informacion, se estara descartando la posi-bilidad de un proceso interactivo, es decir, la posibilidad de que el usuariopueda utilizar la informacion generada por el ordenador para proporcionarnuevos datos.

En este tema, se veran los modos basicos de intercambio de informacioncon el ordenador, dirigido desde un Programa PASCAL . Supondremos quelos dispositivos que se utilizan para entrada y salida de datos son el tecla-do y el terminal TRC, respectivamente. En muchos sistemas operativos el

51

Page 52: Introduccion A La Programacion En Pascal

52 CAPITULO 6. ENTRADA Y SALIDA

redireccionamiento necesario para utilizar archivos es trivial.

Las instrucciones de E/S se especifican dentro del cuerpo principal delPrograma PASCAL . Se trata de una accion que permite transmitir informa-cion desde el exterior a la memoria del ordenador, y viceversa. Obviamente,el resultado de una instruccion de salida depende del contenido de la memoriadel ordenador en ese instante.

6.2 Las funciones Read y Write

Para la entrada de datos, PASCAL dispone del procedimiento basico Read(),y para la salida de Write().

Program Uno;

{ Cuadrado de un numero entero }

Var

base , resultado : integer;

Begin

{1} Read(base);

{2} resultado := base * base;

{3} Write(resultado);

End.

La instruccion {1} del programa Uno asigna a la variable base el valorentero suministrado por el usuario. La introduccion del dato se puede rea-lizar tecleando el numero deseado y pulsando despues la tecla de retornode carro. El procedimiento Read(argumento) asigna a la variable argu-mento el conjunto de caracteres que se teclean antes del retorno de carro,convenientemente interpretados de acuerdo con el tipo de dato de la variableargumento.

La instruccion {3} escribe en la pantalla del terminal el resultado deelevar al cuadrado el dato.

Si se teclea el numero 93, se obtiene en pantalla 8649, pero si se teclea93.0 el programa emitira un mensaje de error. Esto es debido a que elprocedimiento Read incluye una verificacion de que el dato suministradocorresponde al tipo de dato definido para la variable.

El modo en que se han de suministrar los datos al programa para quesean aceptados por el procedimiento Read() es muy parecido al modo en

Page 53: Introduccion A La Programacion En Pascal

6.2. LAS FUNCIONES READ Y WRITE 53

que se han de asignar los valores de las constantes dentro de un ProgramaPASCAL . De hecho, es igual salvo dos excepciones:

• Los datos de las variables Char y String NO deben ir entre comillas(’ ’ ).

• Los valores de variables Boolean no pueden leerse.

Tanto Read() como Write() admiten multiples argumentos, separadospor comas.

Program Dos;

Var

resultado, base , altura : Integer;

Begin

{1} Read(base,altura);

{2} resultado := base * altura;

{3} Write(’Area del cuadrado: ’,resultado);

End.

La instruccion {1} del programa Dos lee dos numeros enteros que asigna ala variable base (el primero), y a altura (el segundo).

El modo en el que el usuario puede teclear los datos de entrada es bas-tante flexible. Por ejemplo en este caso, dado que son dos numeros enteros,Read interpretara un entero como una secuencia de caracteres sin ningunblanco intermedio. Supongamos que los datos son los numeros 27 y 31. Lasecuencia de caracteres que teclea el usuario puede ser:

2 7 3 1 ←

El procedimiento Read() interpreta los caracteres hasta el primer blancocomo integrantes del valor que se desea asignar al Integer base. Al segundoargumento se asignara la cadena de caracteres que antecedan al siguienteblanco o caracter de control < CR >. Una vez finalizada la ejecucion de lainstruccion {1} estaran almacenados los valores 27 y 31 en las posicionesde memoria asignadas a las variables base y altura, respectivamente.

El procedimiento Read() espera que se tecleen suficientes caracteres parapoder asignar valores a los argumentos de Read, y los caracteres de control< CR > que se tecleen antes de cumplirse esta condicion son irrelevantes. Por

Page 54: Introduccion A La Programacion En Pascal

54 CAPITULO 6. ENTRADA Y SALIDA

tanto, cualquiera de las dos secuencias siguientes de teclado son equivalentesa la discutida antes.

2 7 ← ← 3 1 ←

← 2 7 ← 3 1 ←

El procedimiento Write escribe en el dispositivo de salida el contenidode las constantes o las variables que se encuentran en el argumento.

• ’Area del cuadrado :’ es una constante del tipo String cuyo valores la ordenacion de los 19 caracteres entre las comillas ’.

• resultado es una variable Integer, y el procedimiento Write() es-cribe su valor: 837.

La salida del programa Dos es :

Area del cuadrado: 837

Entre ambos valores el procedimiento Write() no escribe nada, y el entero,el TURBO PASCAL lo escribe a partir de la primera cifra significativa. Otroscompiladores de PASCAL pueden hacerlo dejando algun blanco a la izquierdade la primera cifra significativa.

6.3 Formatos

En un principio es deseable controlar exactamente el modo en el que seescribe el valor de las variables en el dispositivo de salida. Esto puede ha-cerse especificando el formato de escritura. En PASCAL cualquier variable oconstante que se incluya en el argumento del procedimiento Write() puedeacompanarse de una especificacion del formato de salida del siguiente modo:

nombre:n:m

donde nombre es el indicativo de la variable o constante, n es el numero deespacios que ha de ocupar cuando se muestra, y m el numero de espacios

Page 55: Introduccion A La Programacion En Pascal

6.4. LAS FUNCIONES WRITELN Y READLN 55

que han de ocupar la parte decimal (despues del punto) cuando el tipo devariable 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 situana la izquierda. En el caso de tratarse de numeros reales, si no se especifica elnumero de cifras decimales, se toma por defecto la notacion cientıfica. Estosson algunos ejemplos de escritura de un numero real:

Write(102030.40:8 ) 1.0E+0005Write(102030.40:10) 1.0E+0005Write(102030.40:12) 1.020E+0005Write(102030.40:14) 1.02030E+0005Write(102030.40:8:1) 102030.4Write(102030.40:10:1) 102030.4Write(102030.40:14:2) 102030.40

6.4 Las funciones WriteLn y ReadLn

La forma que toma la representacion de la salida externa de un ProgramaPASCAL depende tambien de la ordenacion en el sentido vertical. El caracterde control < EOL > ( fin de lınea ) gobierna lo que serıa el salto de carrode una impresora. El PASCAL dispone del procedimiento Writeln() que esequivalente al Write() salvo que despues de escribir los argumentos tambienescribe la secuencia de control< EOL >. Ası, la salida del programa Cuatro

Page 56: Introduccion A La Programacion En Pascal

56 CAPITULO 6. ENTRADA Y SALIDA

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 susargumentos siempre y cuando no encuentre la secuencia de control < EOL >.

Al programa Cinco se han de introducir los datos de modo distinto queal Cuatro. Si se utiliza el teclado, hay que teclear el caracter de control< CR > entre los dos numeros, puesto que < CR > actua tambien comoindicador 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 ASCIIcorrespondiente a la secuencia de control < EOL >.

Por ejemplo, un archivo que se imprime o aparece en pantalla del siguientemodo:

Para vivir no quiero

islas, palacios, torres.

Page 57: Introduccion A La Programacion En Pascal

6.4. LAS FUNCIONES WRITELN Y READLN 57

esta almacenado como:

Para vivir no quiero<EOL>islas, palacios, torres.<EOF>

donde < EOF > es la secuencia de control fin de fichero. El dispositivode salida pertinente se encargara de que aparezcan los dos versos en lıneasdistintas.

El procedimiento Readln() utiliza < EOL > como delimitador de suambito de lectura y lee los argumentos entre los caracteres que se encuentranentre dos < EOL >. Por ejemplo, el resultado del programa Cinco, cuandolee del fichero

3

4

es:

Resultado del calculo.

Area del triangulo: 12

mientras que si el fichero de entrada es:

3 4

5

la salida sera:

Resultado del calculo.

Area del triangulo: 15

porque la instruccion {1} lee el 3 y omite el 4. La instruccion {2} lee el 5.

Page 58: Introduccion A La Programacion En Pascal

58 CAPITULO 6. ENTRADA Y SALIDA

Page 59: Introduccion A La Programacion En Pascal

Capıtulo 7

Acciones

7.1 Operaciones basicas.

Una vez conocidos los modos basicos que existen en PASCAL para almacenardatos en la memoria del ordenador y conocido el modo basico de comunica-cion con el usuario del programa, pasamos a estudiar que operaciones sepueden realizar con los datos.

7.1.1 Operadores aritmeticos y expresiones aritmeticas.

Cuando los datos con los que se realizan operaciones son numeros, lo mascomun es realizar operaciones aritmeticas : suma, resta, multiplicacion, ydivision. En PASCAL estas operaciones se especifican con los operadores +, – , * , y / , respectivamente.

Las instrucciones,

a:= 3. + 5.;

b:= a - 2.;

b:= b * a * 6.;

c:= -b / 12.;

son ejemplos de la utilizacion de los operadores. En el caso mas sencillode asignacion con dos operandos solamente, no hay ambiguedad y con este

59

Page 60: Introduccion A La Programacion En Pascal

60 CAPITULO 7. ACCIONES

formato de instruccion,

variable1 := operando1

+−∗/

operando2;

se asigna a la variable variable1 el resultado de la operacion aritmetica co-rrespondiente con las convenciones usuales de la aritmetica. Tanto operando1como operando2, pueden ser constantes o variables. Cuando se desea operarcon mas de dos datos hay que especificar claramente y sin ambiguedad elorden en que se quieren realizar las operaciones. Para ello, podemos ayudar-nos de los parentesis con el mismo fin con el que se usan en las expresionesaritmeticas. Por ejemplo, la siguiente instruccion

b:= ( -37.0 * (a - 2.) ) / (a + 5.);

carece de ambiguedad. No obstante, el PASCAL tiene una prioridad esta-blecida para el orden de las operaciones:

1. mas y menos monarios.

2. parentesis.

3. multiplicacion y division.

4. suma y resta.

Las siguientes instrucciones son equivalentes:

b:= -27.0 * c + 35. / a + b + c;

b:= ( (-27.0) * c ) + ( 35. / a ) + b + c ;

b:= ( -27.0 * c ) + ( 35. / a ) + b + c ;

y la forma concreta en la que el programador debe escribirla es aquella queresulte menos confusa. Un error comun entre principiantes es escribir lainstruccion {i} queriendo escribir la {ii} :

{i} b:= a * 27.0 / b + c ;

{ii} b:= a * 27.0 / ( b + c ) ;

{iii} b:= ( a * 27.0 / b ) + c ;

Page 61: Introduccion A La Programacion En Pascal

7.1. OPERACIONES BASICAS. 61

7.1.2 Funciones aritmeticas.

En PASCAL estan definidas funciones que permiten realizar calculos ma-tematicos muy frecuentes u operaciones numericas muy utiles para trans-formar expresiones aritmeticas en sentencias PASCAL . En PASCAL lasfunciones son llamadas a procedimientos de calculo que devuelven un valor.Si aparecen en una expresion aritmetica, las operacion se realiza con el resul-tado de evaluar la funcion. Si suponemos que se utiliza la funcion para unaasignacion,

y := F ( x ) ;

los tipos de datos que admiten como argumento, x, los tipos de datos queproporcionan, y, y las funciones que realizan son:

F ( x ) x yAbs ( x ) Real o Integer igual que x Valor absoluto

Arctan ( x ) Real o Integer Real Arco tangenteCos ( x ) Real o Integer Real CosenoExp ( x ) Real o Integer Real Exponenciacion ( ex )Frac ( x ) Real o Integer Real La parte decimal de xInt ( x ) Real o Integer Real La parte entera de xLn ( x ) Real o Integer Real Logaritmo neperiano

Pred ( x ) Integer Integer x− 1Random 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 SenoSqr ( x ) Real o Integer Real Exponenciacion ( x2 )Sqrt( x ) Real o Integer Real

√x

Succ ( x ) Integer Integer x+ 1Trunc ( x ) Real Integer x con la parte decimal eliminada

Las funciones trigonometricas que no estan incluidas, se calculan facilmentea partir estas. Por ejemplo,

tan1 := Sin(x) / Cos(x);

a := Sin(x);

tan2 := a / Sqrt ( 1.0 - a * a ) ;

Page 62: Introduccion A La Programacion En Pascal

62 CAPITULO 7. ACCIONES

7.1.3 Aritmetica entera y real.

El PASCAL realiza una comprobacion escrupulosa del tipo de los datos engeneral, y en particular en el procesamiento de las expresiones aritmeticas.Cuando se programan estas expresiones hay que verificar que se mezclancoherentemente datos reales y enteros.

PASCAL considera Integer el resultado de una expresion aritmeticasiempre que en la expresion aparezcan solo datos de este tipo y no esteimplicada 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.

la instruccion {2} es incorrecta, si bien la salida es 2.00 . Por defecto, elresultado de una expresion aritmetica que no es Integer , es Real . Bastaque haya un solo operando Real o un operador division en una expresionpara que el dato que resulte de la operacion sea real y que toda la expresionse evalue como si todos sus componentes fueran reales.

Cuando se trata de hacer aritmetica de numeros enteros hay que llevarmucho cuidado con el lımite de capacidad del tipo de dato que se utilice.Algunas veces, no es trivial. La salida del programa Dos ,

Program Dos;

Var

i,j : Integer;

z : Real;

Begin

{1} j := 2333;

{2} i := j * 23;

Page 63: Introduccion A La Programacion En Pascal

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

La instruccion {2} es aparentemente correcta, pero como el resultado dela multiplicacion excede la capacidad de un Integer (32767), el resultadode la operacion es un numero entero, pero absurdo. Sin embargo, la {4} esclaramente incorrecta y el compilador PASCAL lo detecta al intentar alma-cenar en el lugar de memoria reservado para i el producto, en vez de generarel codigo para realizar la multiplicacion durante la ejecucion.

La {5} es solo aparentemente correcta, puesto que es similar a la {2}. Sibien el resultado de la operacion se quiere almacenar en una variable Real , elcompilador interpreta que la expresion aritmetica se puede realizar con datosenteros y genera codigo tal que los resultados intermedios se almacenaran enregistros de 2 bytes. El resultado : un desastre, el dato que se almacenafinalmente en la variable real es identico al anterior. Sin embargo, si en laexpresion se incluye cualquier operando Real , el compilador asume que setrata de una operacion que ha de realizarse con aritmetica real, y utilizararegistros apropiados para esa aritmetica. La instruccion {7} es correcta, ysolo difiere de la {5} en la multiplicacion por 1.0, algo matematicamenteirrelevante pero no computacionalmente. Hay que tener siempre presenteque el modo con el que se van a realizar las operaciones de una expresion

Page 64: Introduccion A La Programacion En Pascal

64 CAPITULO 7. ACCIONES

aritmetica no esta determinado por el lado izquierdo de la asignacion ( eltipo de dato que acepta la variable), sino por los operandos.

Cuando aparecen constantes numericas en una expresion aritmetica en laque se quiere realizar un calculo con numeros reales, es aconsejable no olvidarel punto que lo identifica como constante real. Si i es una variable Integerel resultado de estas dos expresiones sera distinto para i > 9.

z := 3600 * i ;

z := 3600. * i ;

Cuando se quieren realizar divisiones respetando la aritmetica de enteroshay que utilizar el operando Div. El resultado de

j Div i

es j/i cuando j es multiplo de i, y la parte de entera de j/i en el casocontrario.

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.

las instrucciones {2} y {4} generan el mismo resultado, pero distinto al de la{6}. La expresion aritmetica en {6} es el argumento de la funcion Trunc()y la presencia del operador / indica que se ha de realizar aritmetica denumeros reales.

Cuando se quieren utilizar datos Real en expresiones con aritmetica denumeros enteros, lo mas apropiado es utilizar la funciones de transformacionde tipo, Round() o Trunc() , para homogeneizar el tipo de los operandos.

Page 65: Introduccion A La Programacion En Pascal

7.1. OPERACIONES BASICAS. 65

Existe otro operador especıfico de numeros enteros que es el operadormod y proporciona el resto de la division entera. El resultado de

j Mod i

es 0 cuando j es multiplo 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.

La salida del programa Cuatro es:

2

14 14

dado que en la instruccion {4} se recupera para m el valor original de i .

7.1.4 Operadores logicos.

Los operadores logicos que proporciona el PASCAL son de dos tipos:

1. Operadores que actuando sobre datos no-Boolean proporcionando undato Boolean.

2. Operadores que actuando sobre datos Boolean proporcionan un datoBoolean.

El primero de estos tipos es muy util para tomar decisiones como resultadode la comparacion de variables. La forma general en la que aparecen estos

Page 66: Introduccion A La Programacion En Pascal

66 CAPITULO 7. ACCIONES

operadores es:

a

=<>><<=>=

b

donde a y b pueden ser numeros reales , enteros o caracteres, mientras queel resultado de la operacion es un dato Boolean (FALSE o TRUE ). La res-striccion obvia es que a y b han de ser constantes o variables del mismotipo.

El resultado de la operacion sera TRUE en los siguientes casos:

Operador Condicion= a = b<> a 6= b> a > b< a < b<= a ≤ b>= a ≥ b

En el caso de que de que a y b sean caracteres, las operaciones de comparacionse 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);

Page 67: Introduccion A La Programacion En Pascal

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. Porejemplo, en la instruccion {10} se asigna a quizas el valor FALSE , si bienlas expresiones utilizadas en las instrucciones {6} y {8} para calcular latangente son matematicamente equivalentes. Debido a la utilizacion de unarepresentacion finita de los numeros reales ambos valores seran ligeramentedistintos. La comparacion para averiguar la similitud de numeros reales sesuele hacer utilizando la diferencia relativa:

quizas := Abs ( (tan1 - tan2) / tan1 ) <= 0.000001;

Con el segundo tipo de operadores logicos se pueden combinar datos Booleanpara realizar operaciones logicas complejas. Uno de ellos es monario y seutiliza segun la forma general:

Not operando

donde tanto operando como el resultado de la operacion son datos del tipoBoolean. El resultado, es la negacion del operando:

a Not aTrue FalseFalse True

El resto de los operadores se utilizan segun la forma:

A

AndOrXor

B

donde A y B son variables Boolean.Las tablas de verdad son las habituales:

Page 68: Introduccion A La Programacion En Pascal

68 CAPITULO 7. ACCIONES

A B A And BTrue False FalseFalse True FalseFalse False FalseTrue True True

A B A Or BTrue False TrueFalse True TrueTrue True TrueFalse False False

A B A Xor BTrue False TrueFalse True TrueTrue True FalseFalse False False

7.1.5 Expresiones logicas.

Denominamos Expresiones logicas a las operaciones que se realizan con da-tos Boolean. Estas operaciones pueden encadenarse de un modo bastantecomplejo. Un ejemplo de utilizacion de estas expresiones es el siguiente:

Supongamos que tenemos que escribir un programa para determinar siun punto se encuentra en la interseccion de dos rectangulos,

Page 69: Introduccion A La Programacion En Pascal

7.1. OPERACIONES BASICAS. 69

B

A

y tambien queremos saber si forma parte de la frontera que la delimita. Elprograma Seis proporciona la respuesta utilizando expresiones logicas:

Program Seis;

Const

(* Coordenadas cartesianas que definen los rectangulos *)

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

Page 70: Introduccion A La Programacion En Pascal

70 CAPITULO 7. ACCIONES

( puntoy >= yb1 ) And (puntoy <= ya2);

{7} Writeln(’ Si se considera el borde : ’,dentro2);

(* Condicion de frontera *)

{8} frontera := dentro2 And ( Not dentro1);

{9} Writeln(’ Frontera: ’,frontera);

end.

Las instrucciones {2} y {3} se podrıan haber condensado en una sola ins-truccion similar a la {6}.

Cuando en una expresion se combinan operadores logicos y aritmeticoshay que utilizar generosamente los parentesis o llevar mucho cuidado con elorden de prioridad establecido por el PASCAL para la aplicacion de opera-dores:

Los operadores aritmeticos se aplican siempre antes que los logicos.

Por ejemplo, la expresion

(37 * 4 > 5 * 24) And Not (65 < 2 * 31)

se evalua a True y los parentesis son estrictamente necesarios. De no existirel primer juego de parentesis el operador And tendrıa a su izquierda un datoInteger y a su derecha un dato Boolean, lo que es incorrecto. De noexistir el segundo juego de parentesis habrıa tambien una disparidad de tiposde datos algo mas compleja que se analizara mas adelante.

Como en el caso de los operadores aritmeticos, en los logicos tambien losmonarios se aplican primero, y en esta expresion el operador Not se aplicaantes que el And.

El uso generoso de los parentesis en las expresiones que mezclan opera-dores logicos y aritmeticos esta recomendado por otra razon mas:

Los operadores And, Or , y Xor pueden ser aritmeticos o logicossegun el tipo de operandos sobre los que actuen.

Esto es ası porque como veremos a continuacion tambien estan pensados pararealizar manipulacion de bits.

7.1.6 Manipulacion de bits.

Existen operadores en PASCAL que permiten modificar directamente losbits que componen los datos enteros. Estos datos estan almacenados en la

Page 71: Introduccion A La Programacion En Pascal

7.1. OPERACIONES BASICAS. 71

memoria del ordenador con su valor binario, y los operadores de manipulacionde bits permiten al programador modificar directamente los componentes dela representacion binaria.

En una expresion

A

AndOrXor

B

donde A y B son datos enteros ( tipo Integer, Byte, ShortInt, Wordy LongInt ), los operadores And, Or y Xor, actuan como operadoresaritmeticos. El resultado de la operacion es otro dato entero que se obtienerealizando la operacion logica correspondiente entre cada uno de los bits delos datos, considerando el 1 como verdadero y el 0 como falso.

Un dato Byte esta representado en memoria por 8 bits correspondientesa la representacion binaria del numero estando el bit mas significativo a laizquierda. Por ejemplo, la representacion interna del dato Byte 77 es:

0 1 0 0 1 1 0 1

y la del dato Byte 62 es :

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 operacionOr el resultado es:

0 1 1 1 1 1 1 1

cuyo valor decimal es 127, y si se realiza la operacion Xor el resultado es:

0 1 1 1 0 0 1 1

Page 72: Introduccion A La Programacion En Pascal

72 CAPITULO 7. ACCIONES

cuyo valor decimal es 115. Estas tres operaciones son las que se realizan enel 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.

Existen otros dos operadores de manipulacion de bits : Shl (Shift left) yShr (Shift right). El resultado de

A

{ShlShr

}n

donde A y n son enteros, es otro entero que resulta de desplazar n bits de Ahacia la izquierda (Shl ) o hacia la derecha (Shr ). Los bits que se introducenen el desplazamiento son nulos. Por ejemplo, si el dato A es,

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;

Page 73: Introduccion A La Programacion En Pascal

7.1. OPERACIONES BASICAS. 73

es,

0 0 0 0 0 0 0 a4

Como resultado de la concatenacion de estas dos operaciones hemos obtenidoun entero cuyo valor es el del quinto bit, empezando por la derecha del enterooriginal.

El programa Ocho escribe un 1 si el numero que recibe (un entero entre0 y 255) es impar, y cero de lo contrario:

Program Ocho;

Var

a , b , c: Byte;

Begin

Readln(a);

b := a Shl 7;

c := b Shr 7;

Writeln(c);

End.

En el caso de los datos Integer ( 2 bytes), que permiten almacenarnumeros enteros con signo, el valor esta almacenado en memoria de un modomas complejo. El bit mas a la izquierda de todo almacena el signo: 1 si esnegativo y 0 de lo contrario. El valor del entero esta almacenado en los 15bits restantes del modo siguiente:

• Positivos: El valor binario del entero con el bit menos significativo a laderecha.

• Negativos: Igual que si fuera positivo pero considerando el valor queresulta de sumar al entero 32768.

Por ejemplo, -32768 se almacena como:

1000000000000000

y -1 como:1111111111111111

mientras que 1 se almacena como

0000000000000001

Page 74: Introduccion A La Programacion En Pascal

74 CAPITULO 7. ACCIONES

y el 32767 como

0111111111111111.

7.2 Sentencias de control.

La mayorıa de los procedimientos que podemos disenar para resolver proble-mas incluyen la eleccion de uno entre los casos posibles en funcion del valorparticular de alguno de los datos. Las sentencias de control en PASCAL sonla condicional simple If y la condicional multiple Case.

La sentencia de control simple tiene la siguiente sintaxis:

If datoBooleanThen

accion1

o bien,

If datoBooleanThen

accion1Else

accion2

donde datoBoolean es una variable Boolean o una operacion cuyo resultadoes una dato Boolean, accion1 y accion2 son instrucciones PASCAL quepueden ser tanto simples como compuestas.

El efecto de esta sentencia de control es el siguiente: si datoBoolean esTrue se procede a realizar la instruccion accion1; en el caso de que sea Falsey este presente la parte Else, se procede a realizar la instruccion accion2.En el primero de los casos el esquema de la bifurcacion serıa:

Page 75: Introduccion A La Programacion En Pascal

7.2. SENTENCIAS DE CONTROL. 75

Boolean

HHH"""b

bb���

?

accion1

Continuar

?

-

?

? ?�

Cierto

Falso

y en el segundo caso, cuando esta presente la parte Else de la estructura:

Boolean

aa��HH""?

accion1accion2

Continuar

?

??

- �

?

En el programa Nueve tenemos un ejemplo de utilizacion de esta construc-cion. Ambas son equivalentes: en la primera se realiza la comparacion en laconstruccion If, mientras que en la segunda se utiliza una variable Booleanauxiliar.

Program Nueve;

Var

positivo : Boolean;

n : Integer;

Begin

Readln (n);

If n >= 0

Page 76: Introduccion A La Programacion En Pascal

76 CAPITULO 7. ACCIONES

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.

Las acciones que se ejecutan despues de la comprobacion del dato Booleanpueden ser instrucciones sencillas o compuestas. En el programa Diez po-demos ver un ejemplo de utilizacion con una instruccion compuesta:

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);

If x > 0.0 then

begin

Writeln(’ Raiz cuadrada: ’);

y := Sqrt(x);

Write(y)

end

Else

Writeln(’ Numero negativo.’);

End. { Diez }

Con esta estructura If ... Then ... Else tambien se pueden realizar de-cisiones multiples. Un modo muy frecuente de utilizacion es la encadenacionde estructuras de la forma:

Page 77: Introduccion A La Programacion En Pascal

7.2. SENTENCIAS DE CONTROL. 77

If datoBoolean1Then

accion1Else

If datoBoolean2Then

accion2. . .

En el programa Once se utiliza una concatenacion de estructuras para rea-lizar una eleccion multiple.

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 multiple puede llegar a ser difıcil de leer y elPASCAL proporciona una estructura mas legible para aquellos casos en losque la bifurcacion multiple se realiza mediante comparacion de datos sencillosordinales (por tanto ni Real, ni String). Esta es la estructura Case quetiene la siguiente sintaxis:

Page 78: Introduccion A La Programacion En Pascal

78 CAPITULO 7. ACCIONES

Case variable Ofcaso1 : accion1caso2 : accion2

. . .End;

o bien,

Case identificador Ofcaso1 : accion1caso2 : accion2

. . .Else

acciondEnd;

donde identificador es una variable del tipo Integer, Byte, o Char, lasacciones accion1,... son instrucciones sencillas o compuestas, y los casoscaso1, ... son la especificacion de los valores. Esta especificacion se puedehacer separando valores con comas o bien mediante el rango, si se trata devalores consecutivos. Un rango se especifica mediante el valor inicial y finalseparados por dos puntos. El programa Doce es equivalente al Once peromucho 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

Page 79: Introduccion A La Programacion En Pascal

7.3. SENTENCIAS DE REPETICION. 79

Writeln(’ Numero fuera de rango’);

End;

End. { Doce }

Un uso mas complejo de la estructura Case se puede ver en el siguienteejemplo:

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 intrınseca del PASCAL Ord() es una funcion que devuelveel valor ordinal de cualquier argumento escalar, incluyendo los Char.

7.3 Sentencias de repeticion.

Hay quien opina que la programacion es una actividad que nunca puede resul-tar tediosa o repetitiva, ya que todo aquello que ha de hacerse repetidamente

Page 80: Introduccion A La Programacion En Pascal

80 CAPITULO 7. ACCIONES

puede programarse en una instruccion simple para que sea el ordenador quienlo haga repetidas veces. De hecho, las sentencias de repeticion son general-mente las responsables de la utilidad del ordenador. Se trata de instruccionesque gobiernan la realizacion de tareas repetitivas mientras no sea cierta lacondicion 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:

For identificador := principio To final Doaccion

donde identificador es una variable que puede almacenar un dato ordinal,principio es el valor que se le asigna a esa variable antes de realizar la accion,final es el valor maximo que puede alcanzar la variable antes de finalizar laaccion, y accion es la instruccion, simple o compuesta, del PASCAL que serepetira incrementando en uno cada vez el valor de identificador. Si se tratade una sentencia compuesta, tendra que utilizarse la estructura Begin-Endpara identificar el principio y el fin.

Existe tambien la opcion equivalente

For identificador := principio Downto final Doaccion

en la que el valor del identificador se decrementa en uno cada vez que serealiza la accion.

En el programa Catorce tenemos la aplicacion de esta estructura parael calculo del factorial.

Program Catorce;

Var

z : Real;

n ,i : Integer;

Begin

Writeln(’Calculo del factorial (introducir el numero)’);

Readln(z);

n := Round(z);

If n > 33

Page 81: Introduccion A La Programacion En Pascal

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.

La limitacion basica de la estructura For-Do es que la accion que implıcitamentese realiza cada vez es simplemente el aumento o decremento de una varia-ble ordinal. No obstante, hay que tener presente que variables ordinales noson solamente los Integer. En el programa Quince vemos como se puedeutilizar la estructura con una variable Char.

Program Quince;

Var

i : Char;

Begin

(* Programa que escribe el alfabeto al reves *)

Writeln(’’);

For i:=’Z’ Downto ’A’ do

Write(’ ’,i);

End.

La variable que se utiliza como contador en la estructura For-Do puedemodificarse tambien en la accion que se repite, pero hay que ser extremada-mente cuidadoso porque de lo contrario podemos generar un bucle infinito.Si en el siguiente programa no se realizara la modificacion a un multiplo detres, se podrıa caer en un bucle infinito (con probabilidad 0.33333).

Program Dieciseis;

Var

Page 82: Introduccion A La Programacion En Pascal

82 CAPITULO 7. ACCIONES

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.

Aceptando que el programa anterior es siempre correcto, es facil deducirsi la comprobacion sobre el estado del ındice se realiza antes o despues deincrementar el ındice.

Una estructura muy similar a la For-Do pero mas versatil es la Repeat-Until. Su sintaxis es:

Repeataccion1;accion2;. . .

Until DatoBoolean

y con ella se especifica que se repita el conjunto de acciones situado entreel Repeat y el Until mientras que no sea True el valor de DatoBoolean .Las acciones se realizan al menos una vez porque la verificacion sobre el datoBoolean se hace despues que las acciones. Ası, en el siguiente programael juego no se interrumpe inmediatamente despues de teclear el 0. Por elcontrario la jugada se repite y luego se termina.

Program Diecisiete;

Var

n ,i : Integer;

Begin

Writeln(’Adivina el numero que he generado ( del 1 al 9 )’);

Writeln(’ Teclea 0 para terminar ’);

Page 83: Introduccion A La Programacion En Pascal

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.

Sin embargo, en la estructura While-Do se realiza la comprobacion dela condicion que ha de finalizar la repeticion antes de ejecutarse la accion.Su sintaxis es:

While DatoBoolean Doaccion

donde DatoBoolean es una expresion cuyo resultado es un dato Boolean,y accion es una instruccion PASCAL (sencilla o compuesta) que se repetiramientras DatoBoolean se evalue a True.

El programa Dieciocho es una modificacion del Diecisiete en el quecon el uso de la estructura While-Do se verifica la condicion de fin del juegoantes de sortear el numero.

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

Page 84: Introduccion A La Programacion En Pascal

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 unade las tres estructuras se hara siempre considerando la claridad y facilidadde programacion.

En PASCAL tambien existe la sentencia de control no estructurado Goto,pero no la consideraremos pues en este curso se pretende que el alumnoejercite la programacion estructurada. Sin embargo, si que consideramos lafuncion Exit cuya efecto es interrumpir la ejecucion del bloque en la quese encuentra. Si se trata del programa principal, producira la interrupcionde la ejecucion del programa. En el programa Diecinueve se modifica elDiecisiete 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)

Page 85: Introduccion A La Programacion En Pascal

7.4. MANIPULACION DE LOS DATOS STRING. 85

Else

Writeln(’ Si ’);

Until n = 0 ;

End.

7.4 Manipulacion de los datos STRING.

Las sentencias de repeticion son utiles para manipular el contenido de los da-tos String accediendo a cada uno de los caracteres que componen la cadena.Como vimos en su dıa, si s es un dato String ( una ordenacion consecutivade datos del tipo Char) el caracter almacenado en s[0] indica el numerode caracteres almacenados en el dato. Ese caracter, como cualquier otro, sepuede convertir a dato entero utilizando la funcion Ord(). Igualmente, sepuede 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 accedea ellos mediante s[i] donde i es un entero que corresponde a su numero deorden 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 delos 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.

Page 86: Introduccion A La Programacion En Pascal

86 CAPITULO 7. ACCIONES

y la salida que produce es:

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

Page 87: Introduccion A La Programacion En Pascal

Capıtulo 8

Modularidad

8.1 Dividir para vencer

Con las estructuras vistas hasta ahora del PASCAL se podrıan construirprogramas que realizaran tareas muy complejas pero con escasa legibilidad.Un modo muy comun, y generalmente muy efectivo, de resolver un problemaes desmenuzarlo en una serie de problemas mas sencillos y resolver despuescada uno de ellos. Es la estrategia que ha recibido el nombre dividir y vencero diseno Top-Down. Desde el punto de vista de la legibilidad es deseableque un programa de ordenador pueda estructurarse siguiendo lo mas posibleel esquema conceptual que se ha pensado utilizar para resolver el problema.Por ejemplo, supongamos que se trata de escribir un programa que calculela suma de los n primeros terminos de una sucesion geometrica de razon r ycuyo primer termino es a. Para ello pensamos utilizar la expresion:

n−1∑i=0

ari =a(1− rn)

1− r

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 quees necesario calcular rn donde r es real y n entero. Tambien podemos des-componer la tarea (2) en:

87

Page 88: Introduccion A La Programacion En Pascal

88 CAPITULO 8. MODULARIDAD

(2) Calculo de la expresion(2.1) Obtener rn

(2.2) Realizar multiplicaciones y divisiones.

A traves de la descomposicion modular que permite el PASCAL con lasconstrucciones Procedure y Function es posible escribir el programa deun modo muy similar al pseudo codigo anterior. El cuerpo principal delprograma sera simplemente:

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}

y en el espacio reservado para declaraciones en el programa se especificaraque tareas se han de realizar en los procedimientos LeerDatos, Calcula-rExpresion, y SacarResultados, definidos por el programador.

8.2 Procedimientos

La sintaxis con la que se especifican estos procedimientos es similar a la deun programa PASCAL pero se usa la palabra reservada Procedure paraindicar que se trata de un procedimiento parcial:

Procedure nombre ( argumentos ) ;

Page 89: Introduccion A La Programacion En Pascal

8.2. PROCEDIMIENTOS 89

Parte declarativaBegin

Bloque de sentencias del procedimientoEnd;

La parte declarativa del procedimiento tiene el mismo fin que en un progra-ma y en ella se definen tipos de datos, variables y constantes como en unprograma y tambien, si ası se requiere, procedimientos y funciones que seannecesarios para la realizacion de este Procedure. En el bloque principaldel procedimiento se escriben las sentencias PASCAL que constituyen el al-goritmo que ha de realizar, y en el se pueden utilizar datos definidos en suparte declarativa, en la parte declarativa del programa principal o bien queaparecen como argumentos del procedimiento. Estos argumentos se utilizanpara comunicar valores de datos al procedimiento desde el bloque donde hasido llamado. Cuando se llama al procedimiento, estos argumentos van se-parados por comas. En la declaracion del procedimiento los argumentos seespecifican de un modo muy parecido a como se especifica el tipo de datosen la declaracion de las variables de un programa. Los datos de un mismotipo van separados por coma y se utiliza el punto y coma para separar datosde distinto tipo. A continuacion de los argumentos se especifica el tipo devariable. Por ejemplo, al procedimiento SacarResultados se le llama con elargumento suma que es un dato Real. Este procedimiento se puede escribirası:

Procedure SacarResultados(resultado : Real);

Begin { SacarResultados }

Writeln(’’);

Writeln(’La suma de la series es: ’, resultado:10:6);

End; { SacarResultados }

En el argumento se especifica el nombre que se va a utilizar en el procedi-miento y tambien de que tipo de dato se trata. El nombre no ha de coincidircon el utilizado en el bloque original, puesto que la identificacion de datos larealiza el compilador por el orden en el que aparecen en el argumento y nopor el nombre.

Page 90: Introduccion A La Programacion En Pascal

90 CAPITULO 8. MODULARIDAD

8.3 Funciones

Muy parecida a la estructura Procedure es la estructura Function y seutiliza para aquellos casos en los que se desea que el dato que se calcula en elmodulo independiente pueda aparecer en cualquier instruccion PASCAL enel mismo lugar en el que aparecerıa el dato. Este es el caso de las funcionesintrınsecas del PASCAL que ya se han visto. La sintaxis de la estructuraFunction es:

Function nombre ( argumentos ) : Tipodato ;Parte declarativa

BeginBloque de sentencias de la funcion

End;

y en el bloque se especifica el valor que debe devolver la funcion asignandoseloal nombre utilizado para nombrar la funcion. Por ejemplo, en el procedi-miento CalcularExpresion debemos incluir el calculo de la potencia de unnumero real a un exponente entero. Esta operacion, que puede aparecer enmuchos otros programas, merece la pena que se escriba en un modulo aparte,y dado que el resultado es un dato que suele aparecer en expresiones aritme-ticas, es razonable que se escriba como Function. A la funcion le llamamosPoten:

{Funcion que eleva un numero real a un potencia entera }

Function Poten ( base : Real;

exponente : Integer ) : Real;

Var

i : Integer;

z : Real;

Begin { Poten }

{1} If exponente <= 0 Then

{2} Poten :=1

{3} Else

{4} If exponente = 1 Then

{5} Poten := base

{6} Else

{7} Begin

{8} z := base;

Page 91: Introduccion A La Programacion En Pascal

8.4. AMBITO DE DEFINICION DE LAS VARIABLES 91

{9} For i := 2 to exponente Do

{10} z := z * base;

{11} Poten := z

{12} End;

End; { Poten }

En el argumento se especifican las dos variables con las que nos vamos areferir al exponente y a la base, el exponente ha de ser un valor entero yla base puede ser real. A continuacion, se especifica que el valor que ha dedevolver la funcion al bloque donde ha sido llamada es Real. Para realizarel 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 enla parte izquierda de una asignacion y es en ellas donde se especifica el valorque puede devolver la funcion. La llamada a Poten desde el procedimientoCalcularExpresion :

{Calculo de la expresion para la suma de la serie }

Procedure CalcularExpresion ;

Begin { CalcularExpresion }

suma := a * ( 1.0 - Poten(r,n) ) / ( 1.0 - r) ;

End; { CalcularExpresion }

se realiza dentro de una expresion aritmetica.

8.4 Ambito de definicion de las variables

Las variables que se definen en la parte declarativa de un procedimientoo una funcion existen solamente para ese modulo. Se reservan lugares dememoria para acomodarlas cuando se requiere el calculo del modulo y seliberan cuando se termina la ejecucion de los algoritmos especificados enel modulo. Por tanto, si en algun otro modulo del programa, o en la parteprincipal, se utilizan esas variables, el compilador avisara de que no se conoceel tipo de dato de esos identificadores. Por otro lado, se pueden utilizarlos mismos nombres para variables definidas en distintos modulos ya que elcompilador interpretara correctamente el hecho de que con cada nombre serefiere al lugar de memoria reservado para el dato que se va a manipular encada modulo. El unico modo que hay para pasar valores de datos desde un

Page 92: Introduccion A La Programacion En Pascal

92 CAPITULO 8. MODULARIDAD

modulo a otro, es a traves de los argumentos del Procedure o Function.Sin embargo, desde el bloque principal se pueden pasar datos a los proce-dimientos o funciones : cualquier variable o constante definido en la partedeclarativa del bloque principal es accesible a todos los modulos declaradospara el programa (tanto para conocer su valor como para modificarlo). Poreso, el Procedure CalcularExpresion sin tener ningun argumento puedeacceder al valor de los datos almacenados en las variables n,a y r. Conesta posibilidad parece logico preguntarse el porque de utilizar argumentosen los modulos. En particular, el porque de los argumentos en la funcionPoten. Pues bien, la ventaja de utilizar los argumentos base y exponente

es que, aparte de mejorar la legibilidad, el mismo codigo puede utilizarseen otros programas independientemente de como se llamen las variables queintervienen en el calculo.

8.5 Paso de valores por contenido o direccion

Lo dicho anteriormente sobre las variables definidas en las partes declarativasde los modulos, tambien es cierto para los argumentos: se reservan paraesos datos nuevos lugares de memoria cada vez que se llama a los modulos,se copia a ellos los datos almacenados en los argumentos, se utilizan en elprocedimiento y luego se liberan. Por tanto, dentro de un modulo no se puedealterar el valor de las variables definidas para el bloque que llama al modulo.Cuando se desee modificar en el modulo el valor de una variable pasadacomo argumento hay que especificarlo y ası sera accesible al modulo no soloel contenido de la variable sino tambien su direccion en la memoria. Laespecificacion se realiza anteponiendo a estas variables la palabra reservadaVar. Por ejemplo, en el procedimiento Leerdatos

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}

Page 93: Introduccion A La Programacion En Pascal

8.5. PASO DE VALORES POR CONTENIDO O DIRECCION 93

se especifica que las variables numero, primero, y razon, son argumentospasados al modulo por referencia o direccion y no por contenido o valor.Los datos que almacena el procedimiento en numero, primero, y razon, enrealidad se estan almacenando en los lugares de memoria que el programaprincipal reservo para n, a, y r.

El programa completo que realiza la suma de la progresion es:

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}

{Funcion que eleva un numero real a un potencia entera }

Function Poten ( base : Real;

exponente : Integer ) : Real;

Var

i : Integer;

z : Real;

Begin { Poten }

If exponente <= 0 Then

Poten :=1

Else

If exponente = 1 Then

Poten := base

Else

Begin

Page 94: Introduccion A La Programacion En Pascal

94 CAPITULO 8. MODULARIDAD

z := base;

For i := 2 to exponente Do

z := z * base;

Poten := z

End;

End; { Poten }

{Calculo de la expresion para la suma de la serie }

Procedure CalcularExpresion ;

Begin { CalcularExpresion }

suma := a * ( 1.0 - Poten(r,n) ) / ( 1.0 - r) ;

End; { CalcularExpresion }

Procedure SacarResultados(resultado : Real);

Begin { SacarResultados }

Writeln(’’);

Writeln(’La suma de la series es: ’, resultado:10:6);

End; { SacarResultados }

Begin { SumaProgesion }

{ Se utiliza la expresion: suma = a (1-r**n) / (1-r) }

LeerDatos(n,a,r);

CalcularExpresion;

SacarResultados(suma);

End. { SumaProgresion}

El ambito de las variables y la diferencia entre el paso de argumentos porreferencia o contenido se puede apreciar bien con el siguiente programa Uno:

Program Uno;

Var

a , b ,c : Integer;

Page 95: Introduccion A La Programacion En Pascal

8.5. PASO DE VALORES POR CONTENIDO O DIRECCION 95

Procedure Escribe ( texto : String;

Var x : Integer;

y : Integer );

Begin { Escribe }

x := 2 * x ;

y := 2 * y ;

Writeln (texto, x:4 , y:4 , c:4 );

End; { Escribe }

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.

que produce la siguiente salida:

Antes : 3 5 7

Durante: 6 10 7

Durante: 12 10 7

Despues: 12 5 7

La variable c la conoce el procedimiento Escribe porque esta declaradacomo variable global para todo el programa. La variable y se pasa porcontenido y por tanto su multiplicacion por 2 en el procedimiento no altera elvalor del dato almacenado en la variable global b. Sin embargo, el argumentox se pasa por referencia y por tanto cada vez que se llama al procedimientose multiplica por 2 el valor almacenado en la variable global a. Cuandouna variable se pasa por referencia el compilador ha de interpretar que cadavez que se asigne un nuevo valor a esa variable se esta almacenando unnuevo valor en el contenido de la direccion de memoria que corresponde aesa variable. Por eso se dice que se esta transmitiendo al procedimiento ladireccion de la variable.

Comprendiendo lo anterior esta claro que las constantes no pueden sertrasmitidas como argumentos pasados por referencia: las constantes estas enposiciones en las que no se puede escribir durante la ejecucion del programa.Por ejemplo, si el procedimiento Escribe se hubiera definido

Page 96: Introduccion A La Programacion En Pascal

96 CAPITULO 8. MODULARIDAD

Procedure Escribe ( Var texto : String;

Var x : Integer;

y : Integer );

el compilador avisarıa de que en la instruccion {3} se espera como primerargumento del procedimiento una variable.

8.6 Definicion 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 paraque el compilador cuando llegue al identificador correspondiente sepa inter-pretar que instrucciones de la Unidad Central de Proceso debe generar. Engeneral esto implica un orden mınimo a la hora de escribir el programa y lle-var cuidado de no definir modulos en lıneas posteriores a las que los utilizan.Sin embargo, puede haber ocasiones en las que se requiera que un modulollame a otro modulo y que a su vez llame al primero. En este caso serıa im-posible definir los dos antes de referirlos y por tanto PASCAL proporciona lapalabra reservada FORWARD para seguir al nombre y argumentos de unprocedimiento o funcion cuyo contenido se especificara en lineas posteriores.En el programa Dos se ilustra el uso de FORWARD :

Program Dos;

Procedure B ( C : Char); FORWARD;

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 }

Page 97: Introduccion A La Programacion En Pascal

8.7. MODULOS Y SUBMODULOS 97

Begin { Dos }

A ( ’A’ );

End. { Dos }

El procedimiento B es necesario para definir el contenido de A, y a su vezA es necesario para definir el algoritmo siniestro que se explicita en B. Elcirculo vicioso se rompe adelantando al compilador que B es un Procedureque toma como argumento un dato Char. Cuando el compilador luegoanaliza el procedimiento A reconoce el identificador B y el hecho de quetome un argumento Char. Entonces, podra generar codigo de la UCP en elque redireccione el calculo a la direccion de memoria que ya tiene reservadapara el modulo B. Posteriormente, cuando analice la especificacion de lospasos a realizar en el modulo B generara el codigo UCP que constituirael calculo que se ha de realizar en el procedimiento B. Si todo esto pareceenrevesado mas lo es el modo en que se ha programado el algoritmo querealiza el programa Dos. Ademas, carece de ningun comentario para quese pueda calificar como un claro ejemplo de mala programacion. El alumno,realizando las instrucciones del programa a mano tardara algun minuto enconocer cual es la salida del programa.

8.7 Modulos y submodulos

Al igual que para un programa se pueden definir modulos, tambien para unmodulo se pueden escribir otros modulos. Es decir declaraciones de proce-dimientos cuyo significado solo conoce el modulo en el que se definen. Porejemplo en el programa Tres la funcion Final es local al procedimiento Eco.

Program Tres;

Procedure Eco;

Var

s : String;

Function Final : Boolean;

Var

c : Char;

Begin { Final }

Page 98: Introduccion A La Programacion En Pascal

98 CAPITULO 8. MODULARIDAD

Writeln(’ Acabo de hacer el ecooooo ? (s/n) ’);

Readln(c);

If

(c = ’s’) Or (c = ’S’)

Then

Final := True

Else

Final := False

End; { Final }

Begin { Eco }

Repeat

Readln(s);

Writeln(s);

Until Final;

End; { Eco }

Begin { Tres }

{1}

{2} Eco;

End. { Tres }

de modo que si en la linea etiquetada 1 del cuerpo del programa principal seanade la instruccion:

If Final Exit;

para que el usuario pueda acabar tras la primera pregunta, el compiladoravisara de que el identificador Final no esta definido. Esta funcion estadefinida localmente para el procedimiento Eco exactamente como tambienes local a el la variable s. Esta posibilidad de anidamiento en la definicionde modulos no se debe utilizar salvo en raras ocasiones pues es origen demuchas confusiones y es mejor optar por un estilo homogeneo en el que solose definen modulos para el programa principal

Un error muy comun en la definicion del contenido de las funciones es elolvidar asignar un valor al identificador de la funcion. Generalmente no setrata de una negligencia sintactica sino del olvido de una posibilidad cuandose hacen asignaciones condicionales. Pero los efectos de este error son menosalarmantes que los de utilizar el identificador de la funcion en la parte derechade una asignacion en el cuerpo de la funcion. En ese caso, lo mas probable es

Page 99: Introduccion A La Programacion En Pascal

8.8. RECURSIVIDAD 99

que se haya escrito un programa que realice un bucle infinito. Esta posibilidadexiste 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. Larecursion aparece generalmente o bien en la definicion de estructuras conautosemejanza o en la descripcion de procedimientos de calculo matematico.

Se dice que una definicion es recursiva cuando el objeto definido apareceen la recursion. Este es un modo de definir objetos muy comun y util. Porejemplo, cuando estudiamos el problema de Josefo, se definıan los nodosque componıan el cırculo como componentes que se identificaban por unnumero y tenıan un enlace con otro nodo. Como veremos posteriormente, larecursividad es muy util 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 recursivaen un algoritmo que se realice en un numero finito de pasos. Por ejemplo,consideremos la definicion del factorial de un numero que se deriva de lasiguiente expresion:

n! = n(n− 1)!

Esta igualdad matematica no es un procedimiento de calculo. Para que asılo sea, hay que anadir algo mas. En este caso, se trata de algo tan sencillocomo 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! utilizarıamos la secuencia de igualdades:

4! = 4× 3! = 4× 3× 2! = 4× 3× 2× 1! = 4× 3× 2× 1 = 24

La definicion recursiva, y una receta para conocer un valor particular, nos haproporcionado un metodo muy claro para calcular el factorial de cualquiernumero entero n ≥ 1. En general una definicion recursiva de un algoritmoincluye:

Page 100: Introduccion A La Programacion En Pascal

100 CAPITULO 8. MODULARIDAD

• La relacion con el caso mas pequeno.

• La condicion de finalizacion.

El PASCAL , como cualquier lenguaje moderno de programacion permi-te la programacion recursiva: en la definicion de un modulo, Procedureo Function, puede aparecer una llamada a el mismo. El programa paracalcular el factorial podrıa ser:

Program Factoriales;

Var

m :Integer;

Function Fac ( n : Integer ) : Integer;

{ Utiliza la definicion n! = n (n-1)! }

Begin

{1} If n <= 1 Then

{2} Fac := 1

{3} Else

{4} Fac := n * Fac ( n - 1 )

End;

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 calcularhasta el factorial de numeros pequenos pues crece muy rapidamente y a partirde 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} consideramosel valor de terminacion de las llamadas recursivas. Sin ella, el programa noacabarıa nunca. En la instruccion {4} estamos diciendo que en esa llamadase asigne a la funcion Fac el valor que se obtiene multiplicando el valor actual

Page 101: Introduccion A La Programacion En Pascal

8.8. RECURSIVIDAD 101

de n por el resultado que se obtenga al llamar a la funcion Fac con el valordecrementado en 1.

Generalmente, la recursividad mejora la facilidad de escritura de algo-ritmos y su legibilidad. Sin embargo, los programas que resultan suelen sermenos eficientes que aquellos que hacen la misma tarea sin usar la recursi-vidad (en el programa Catorce del tema anterior vimos el caso no recursi-vo). Muy frecuentemente, se utiliza el algoritmo recursivo como una primeraaproximacion a la resolucion del problema. Posteriormente, un analisis masprofundo de este, puede llevar a otro algoritmo no recursivo y que se ejecutacon menos gasto de recursos. La primera version recursiva, conceptualmentemas sencilla, siempre sirve para comparar los resultados del algoritmo maselaborado.

Como se menciono anteriormente, la posibilidad de recursividad que ofre-ce el PASCAL puede dar lugar a errores de programacion con resultados mo-lestos. Si por error en una funcion aparece el nombre de una funcion en ellado derecho de una asignacion, el compilador no avisara de tal error, puessintacticamente corresponde a una llamada recursiva, y es muy probable quese obtenga un bucle infinito.

Page 102: Introduccion A La Programacion En Pascal

102 CAPITULO 8. MODULARIDAD

Page 103: Introduccion A La Programacion En Pascal

Capıtulo 9

Datos con estructura

Un programa de ordenador esta constituido por algoritmos que manejan lainformacion almacenada en la memoria del ordenador. El modo en el queesta informacion puede ser referenciada por el programador es esencial parala eficacia y legibilidad de los algoritmos. Hasta ahora hemos visto tipos dedatos muy elementales. En este tema se consideran opciones mas avanzadasal estudiar los tipos de datos definidos por el programador y datos que poseenestructura interna.

9.1 Tipos de datos definidos por el progra-

mador

Ya se han estudiado tipos de datos elementales como los Integer, Real,Char, etc. En este tema se estudiaran otros tipos de datos definidos enPASCAL . Pero tambien puede el programador definir tipos de datos a lamedida de sus necesidades. Con la palabra reservada Type se puede informaral compilador sobre la interpretacion de variables que van almacenar el nuevotipo de dato. Esta definicion de nuevos tipos de datos se incluye en la partedeclarativa del programa, antes de que se referencie ese nuevo tipo de dato,y con la siguiente sintaxis:

TypeIndentificador1 = Untipo1;Indentificador2 = Untipo2;. . .

103

Page 104: Introduccion A La Programacion En Pascal

104 CAPITULO 9. DATOS CON ESTRUCTURA

donde Indentificador1,Indentificador2, etc., son los nombres que se han asig-nado a los nuevos tipos de datos , y Untipo1,Untipo2, etc., es la especificacionde que tipo de dato se trata.

La utilizacion mas trivial que se puede pensar para esta posibilidad es lade renombrar la denominacion de los tipos de datos estandard. Por ejemplo,

Program Uno;

Type

Entero = Integer;

Var

i,n : Entero;

. . . . . .

con estas declaraciones se informa al compilador de que cuando se definen lasvariables i,n como Enteros , nos referimos a datos Integer. Obviamente,la posibilidad de definicion de tipos de datos existe para realizar cosas masutiles que simplemente renombrar. Por ejemplo, se puede utilizar para definirvariables enteras con un rango acotado. En el programa Uno se utiliza estaposibilidad:

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.

Se define el tipo de dato Nota que es un entero en el rango entre 0y 10. La primera de las instrucciones del programa es una orden para elcompilador de TURBO PASCAL , que le indica que genere codigo de UCPen el que se realice comprobacion de rangos de variables durante la ejecucion

Page 105: Introduccion A La Programacion En Pascal

9.2. ENUMERACIONES 105

del programa. Con esta opcion, si se teclea un dato fuera del rango definidopara Nota aparecer? un mensaje de error Run time. Sin esa opcion delcompilador, no aparecerıa ningun mensaje de error.

9.2 Enumeraciones

Los tipos de datos Integer, Char y Byte son ejemplos de tipos de datosen los que se puede almacenar un numero limitado de datos. En el tipoByte, por ejemplo, numeros entre el 0 y el 255. Si el programador necesitautilizar un conjunto limitado de datos puede referirse a ellos estableciendoexplıcitamente una relacion entre cada dato y uno de los valores que pue-de tomar un tipo de dato limitado. Por ejemplo, si queremos referirnos alos meses de ano en un programa se puede establecer una relacion entre unnumero y el mes, empezando con el 1 para Enero y siguiendo hasta 12 conel orden del calendario. Dado el uso cotidiano de esta relacion resultarıamuy 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 interpretarıa ese valor como el mes de Febrero. Sin embargo, enotras muchas ocasiones no existira tal correlacion cotidiana entre ordinalesy objetos. Por ejemplo, si en un programa se quiere operar con datos deltipo color, considerando las posibilidades Rojo , Amarillo , Naranja, Verde, y Azul, no es facil elegir una ordenacion entre ellos que permita estableceruna relacion facilmente comprensible entre un numero, por ejemplo del 0 al4, y cada color. Para estos casos el PASCAL permite establecer esa relacionen la definicion de un tipo y el programador puede olvidarse de ella duranteel programa. Un tipo de dato enumerado se especifica con el conjunto deposibilidades entre parentesis y separadas por comas. En el programa Dostenemos 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’);

Page 106: Introduccion A La Programacion En Pascal

106 CAPITULO 9. DATOS CON ESTRUCTURA

Naranja : Writeln(’Se trata de Naranja’);

End;

Writeln(Ord(i));

End.

El tipo de dato Color se define como la enumeracion de esos cinco colores.La variable i se define como un Color y por tanto puede tomar el valorAmarillo. El compilador establece una relacion unıvoca entre cada uno delos posibles valores y un numero. Por tanto sobre este tipo de dato se puedeoperar con las funciones que admiten argumentos ordinales, entre otras Succy Pred. Este programa escribira primero : Se trata de Naranja porque elsucesor del valor Amarillo es Naranja. De hecho, la relacion que estableceel compilador entre valores y numeros es sencillamente el numero de orden,empezando por 0, en el que aparece cada valor en la enumeracion que seutiliza para declarar el tipo. Por tanto, el programa acabara su ejecucionescribiendo el numero 1.

Este tipo de datos enumerado se suele utilizar para facilitar la tarea deprogramar (escritura y lectura), y no se pueden leer o escribir. Por ejemplo,la instruccion Readln(i); no serıa valida en el programa Dos. Sin embargo,se puede establecer la relacion entre un ordinal y el valor de un tipo de datoenumerado que aparece en ese lugar en la definicion. Por ejemplo, la primerainstruccion del programa Dos se podrıa reemplazar por

i:= Color(1);

Otra utilidad de los tipos de datos enumerados es la formacion de conjun-tos con la posibilidad que ofrece el PASCAL de operaciones entre conjuntos.

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. Loselementos pueden ser cualquier tipo de dato ordenado, y entre ellos los enu-merados.

Page 107: Introduccion A La Programacion En Pascal

9.3. CONJUNTOS 107

La especificacion de los miembros de un determinado conjunto se realizaescribiendo los elementos, uno a uno, o mediante rangos, entre parentesiscuadrados. El el programa Tres se ilustra el uso de los conjuntos:

Program Tres;

Type

Meses = ( enero , febrero , marzo , abril , mayo , junio,

julio , agosto , septiembre , octubre,

noviembre, diciembre );

Estacion = Set Of Meses;

Var

n : Integer;

mes : Meses;

otogno,invierno,primavera,verano,cambio: Estacion;

Begin

invierno := [diciembre ,enero .. marzo ];

primavera := [marzo .. junio];

verano := [junio .. septiembre];

otogno := [septiembre .. diciembre];

{ Los meses de cambio de estacion son la suma de las

interseciones de las estaciones }

cambio := invierno * primavera + primavera * verano +

verano * otogno + otogno * invierno;

Writeln(’teclear en numero del mes (de 1 a 12):’);

Readln(n);

mes := Meses( n - 1);

If mes In cambio Then Write(’ Cambia la estacion : ’);

If mes In verano Then Write(’ verano ’ );

If mes In otogno Then Write(’ otogno ’ );

If mes In invierno Then Write(’ invierno ’ );

If mes In primavera Then Write(’ primavera ’ );

Writeln(’’);

End.

El operador In se utiliza para determinar si un elemento se encuentra dentrode un conjunto, con la siguiente sintaxis:

Page 108: Introduccion A La Programacion En Pascal

108 CAPITULO 9. DATOS CON ESTRUCTURA

NomElemento In NomConjuntodonde NomElemento es el nombre del elemento sobre el que se inquiere yNomConjunto 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 losconjuntos, si bien falta anadir que tambien se puede asignar el conjuntovacıo ([] ).

Los operadores aritmeticos y logicos cuando actuan entre conjuntos tienenun 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 dandolugar a un dato Boolean. Si A y B son dos conjuntos de elementos delmismo tipo y verdad un dato Boolean, las comparaciones siguientes sonposibles:

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 vacıo es subconjunto de todo conjunto.Tambien hay que tener en cuenta que el numero de elementos que puedenformar 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 util re-ferirse a todos ellos con un mismo nombre y distinguir entre los elementosmediante el lugar que ocupan en el grupo. En realidad de trata de ampliar laconveniencia de los conjuntos estudiados anteriormente a grupos de datos decualquier tipo. En el Array los elementos del grupo se ordenan asignandosea cada elemento un numero 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

Page 109: Introduccion A La Programacion En Pascal

9.4. ARRAYS 109

realiza en la memoria central del ordenador. Se puede pensar que un Arrayes un conjunto de celdillas contiguas, en cada una de ellas se puede almace-nar un dato simple, y cada dato simple esta identificado por la posicion queocupa en esa tabla. La ventaja de esta estructura es que se tarda el mismotiempo en acceder a cualquier elemento, ya que se accede a el exclusivamentepor su direccion. La desventaja, es que se trata de un estructura estatica enel sentido de que la longitud maxima de la tabla se ha de especificar a priori.Para definir el tipo de dato Array se utiliza la siguiente sintaxis:

Array [ rango ] Of tipodonde tipo es el tipo de datos que se almacena en cada una de las posicionesde la tabla y rango la especificacion del rango de variacion del ındice (entero)que identifica las posiciones de los elementos de la tabla. Este rango seconcreta especificando el primer y ultimo ındice separados por dos puntosconsecutivos. Solo se permite un rango consecutivo.

La especificacion de Array puede aparecer tanto en una definicion detipo de dato, por ejemplo,

Type

vector = Array [1..30] Of Real;

o directamente en la declaracion de una variable, por ejemplo,

Var

texto : Array [0..3000] Of Char;

El ındice que sirve para especificar la posicion de los elementos no tieneporque empezar en 0 o 1. Si para el programa tiene sentido utilizar un rangocomo [127..345], es perfectamente valido. Para acceder a un elemento deun Array se utiliza el identificador seguido de su ındice entre parentesiscuadrados.

En el programa Primos tenemos un ejemplo de utilizacion de esta estruc-tura de datos. Se trata de la determinacion de numeros primos utilizando elfamoso algoritmo de la criba de Eratostenes.

Program Primos;

Const

MAX = 1000;

{ Calculo de los numeros primos entre 1 y MAX

utilizando el algoritmo de la Criba de Eratostenes }

Page 110: Introduccion A La Programacion En Pascal

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 }

For i := 2 To MAX Div 2 Do

For j := 2 To MAX Div i Do

esPrimo[i*j] := False;

{Se cuenta el numero de primos encontrados }

j:= 0; For i := 1 To MAX Do If esPrimo[i] Then j := j + 1;

Writeln(’Entre 1 y ’,MAX:5,’ se han encontrado ’, j:3,’ primos’);

For i := 1 To MAX Do If esPrimo[i] Then Write(i:4);

End. { primos }

Se define el Array esPrimo para almacenar datos Boolean que permitenseguir la pista de los numeros que son multiplos de otros. En este programase hace un uso apropiado de la ventaja ofrecida por la estructura de datoArray. Se utiliza un tiempo constante para acceder a cualquier elemento dela tabla, independientemente de que se trate del primero o el ultimo. Ademasse puede incluir en el programa una relacion ventajosa entre la posicion deun elemento en la tabla y su significado.

La estructura Array se usa muy a menudo en el calculo cientıfico, puesse trata de la realizacion de un vector, si cada elemento de la tabla se inter-preta como un componente del vector. Igualmente, se pueden definir tablasde tablas (Array bidimensional) para manipular matrices, y Array multi-dimensionales para los tensores.

La especificacion del rango, cuando se declaran, en los Array multidi-mensionales se puede realizar separando con comas los rangos de cada unade las dimensiones. Igualmente, el acceso al contenido de una posicion de

Page 111: Introduccion A La Programacion En Pascal

9.4. ARRAYS 111

estas tablas multiples se puede realizar separando con comas los ındices decada 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);

Page 112: Introduccion A La Programacion En Pascal

112 CAPITULO 9. DATOS CON ESTRUCTURA

MultMatriz(n,A,B,C);

Writeln(’La Matriz producto es:’);

Escribematriz(C);

End.

Pero la definicion de los Array miltidimensionales tambien se puede hacercomo una tabla de tablas. Por ejemplo, el tipo de dato Matriz se podrıahaber definido del siguiente modo:

Matriz = Array[1..MAXDIM] Of Array [1..MAXDIM] Of Numeros;

e igualmente los componentes de este tipo de datos se pueden referir como:

x := x + A1 [i][k] * A2 [k][j];

Ambas definiciones y utilizaciones son equivalentes. Las limitaciones de lasestructuras Array definidas de este modo estan en la capacidad de almacena-miento. Una estructura Array no puede ocupar toda la memoria disponibleen el ordenador por muchos motivos que se estudiaran en el tema de gestionde memoria. Basta con uno de ellos: en TURBO PASCAL no se puede crearun Array que ocupe mas de un segmento de memoria (216 = 65, 536 bytes ).

La estructura de datos String es simplemente un caso especial de tabla dedatos tipo Char en el que se reserva la posicion de ındice cero para almacenarel caracter correspondiente al numero que indica los elementos almacenados.Ya vimos en su dıa que el tipo de datos String tiene su capacidad limitada a255 caracteres. El programador puede muy facilmente definir un tipo de datosimilar al String con capacidad superior. En este caso, tendra que definirsus propias funciones para manipularlos. La siguiente funcion Concatenapodrıa ser la funcion que uniera dos de estas cadenas de caracteres.

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);

Page 113: Introduccion A La Programacion En Pascal

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 }

Procedure EscribeCadena ( x : Cadena);

Var

i: Integer;

Begin { EscribeCadena }

For i := 1 to x[0] Do Write(Chr( x[i] ));

End; { EscribeCadena }

{ Procedimiento para unir a la cadena A1 la cadena A2 }

Procedure Concatena ( Var

A1 , A2 : Cadena );

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(’’);

Page 114: Introduccion A La Programacion En Pascal

114 CAPITULO 9. DATOS CON ESTRUCTURA

LeeCadena(A);

LeeCadena(B);

Concatena(A,B);

Writeln(’’);

EscribeCadena(A);

End.

Se aprecia en la funcion Concatena que el hecho de poder acceder a lalongitud de la cadena permite escribir algoritmos muy eficientes de cadenasde caracteres. Sin embargo, esta estructura definida para las cadenas decaracteres es ineficiente en cuanto almacenamiento. Se estan almacenandolos caracteres ASCII en 2 bytes mientras que serıa suficiente uno solo.

9.5 Registros

La situacion encontrada en el problema planteado anteriormente de manipu-lacion de cadenas es muy comun. Lo mas frecuente es encontrarse en unasituacion en la que se quiere representar en un tipo de dato una informacionque posee estructura interna y es heterogenea, es decir, los campos en los quese subdivide el dato no son todos del mismo tipo. Para ello el PASCAL, comootros 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 quepuede especificar su estructura interna.

El programador da nombre al nuevo tipo de dato y a cada uno de loscampos que lo componen, y especifica el tipo de dato que puede ocupar cadauno de los campos. La sintaxis para estas especificaciones es:

Typenombre =

RecordNombreCampo1 : TipoDato1 ;NombreCampo2 : TipoDato2 ;. . .

End;

donde nombre es el identificador elegido para el registro, y NombreCam-po1 , NombreCampo2 , ... son los identificadores elegidos para los distintos

Page 115: Introduccion A La Programacion En Pascal

9.5. REGISTROS 115

campos. TipoDato1 , TipoDato2, ... son la especificacion del tipo de datoque se va a almacenar en cada uno de los campos. Esta especificacion puedecorresponder a un tipo de dato estandard del PASCAL , la enumeracion o elrango de los posibles valores, u otro tipo de dato declarado con anterioridad.

Por ejemplo, hay casos en los que puede ser conveniente definir un tipo devariable para almacenar la informacion de una fecha. Una posible definiciones la siguiente:

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;

El modo en el que se especifica refiriendose a una variable del tipo Recordun determinado campo, es anadiendo al nombre de la variable el nombredado al campo, y unidos por un punto. El ejemplo anterior podrıa continuardel siguiente modo

Begin

alta.dia := 27 ;

alta.mes := 2 ;

alta.agno := 1992;

baja.mes := alta.mes + 2;

....

Tambien el PASCAL permite la comodidad de la estructura With para ac-ceder a los valores de los campos de los registros. La sintaxis de la estructuraWith es la siguiente :

With nombre Do accion

donde nombre es la especificacion de la variable ( o las variables separadas porcomas ) del tipo Record a la que se refiere la instruccion PASCAL accion

Page 116: Introduccion A La Programacion En Pascal

116 CAPITULO 9. DATOS CON ESTRUCTURA

que se encuentran a continuacion del Do. Si se trata de una instruccioncompuesta se encontrara, como siempre, horquillada entre un Begin y unEnd. En la instruccion del With podemos especificar los distintos datosdel registro con solo el nombre de los campos. Por ejemplo, las instruccionesanteriores, se podrıan haber escrito del siguiente modo:

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 anada al programa.

Ya hemos dicho que los campos de los registros pueden contener datos queson del tipo registro. En ese caso, como siempre, habra que llevar cuidado endefinir los tipos de datos en el orden adecuado para que nunca aparezca enuna declaracion un tipo de dato que no ha sido declarado en pasajes anterioresdel programa. Si ampliamos el ejemplo anterior hacia la construccion de unabase de datos con los alumnos y sus notas, un programa de captacion dedatos podrıa 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;

Page 117: Introduccion A La Programacion En Pascal

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 camposde un registro se realiza concatenando con puntos los identificadores de loscampos.

Para crear una base de datos que contuviera informacion de los alumnosde una clase lo logico serıa ordenar los alumnos en una lista. Para ello, sepuede crear una estructura Array cuyos elementos sean los registros defini-dos para almacenar la informacion de los alumnos. Se podrıa por ejemploanadir en la parte declarativa del programa Siete el siguiente tipo de dato:

{ Type }

Lista =

Array[1..100] of alumno;

y tambien una variable de este tipo:

{ Var }

primero : Lista;

El acceso a los elementos del Array es el habitual. Por ejemplo, el programaSiete podrıa continuar del siguiente modo:

primero[1] := uno;

If (Primero[1].nacimiento.mes = 12 ) Then ......

Page 118: Introduccion A La Programacion En Pascal

118 CAPITULO 9. DATOS CON ESTRUCTURA

En la primera de estas instrucciones se asigna al elemento primero del Arrayprimero el dato almacenado en uno (con todos sus campos de una solavez). En la segunda, se comprueba el valor que tiene el dato almacenadoen el campo mes del campo nacimiento de la variable del tipo Alumnoalmacenado en la posicion primera del Array primero.

Tambien existe, obviamente, la posibilidad inversa: la de definir registrosen los que sus campos sean datos con la estructura Array. Podemos retomarahora el problema estudiado anteriormente de cadenas de caracteres y uti-lizando registros disponer de una estructura de datos con aprovechamientoeficiente de la memoria. El tipo de dato Cadena se define ahora como unregistro con un campo que es el numero de caracteres almacenados y el otrocampo el Array de caracteres. Ası, para la longitud utilizamos un Integery para cada caracter un solo byte.

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;

Page 119: Introduccion A La Programacion En Pascal

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 }

Procedure EscribeCadena ( x : Cadena);

Var

i: Integer;

Begin { EscribeCadena }

For i := 1 to x.longitud Do Write(x.contenido[i] );

End; { EscribeCadena }

{ Procedimiento para unir a la cadena A1 la cadena A2 }

Procedure Concatena ( Var

A1 , A2 : Cadena );

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.

Despues de estudiar todos estos tipos de datos definidos por el usuario

Page 120: Introduccion A La Programacion En Pascal

120 CAPITULO 9. DATOS CON ESTRUCTURA

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 parareferirse a un dato y poder realizar operaciones con el. El tipo de dato ha deespecificarse para que el compilador pueda generar codigo UCP en el que seutilice una cantidad de memoria suficiente para ese dato y estructurada delmodo adecuado. Cuando el programador se enfrenta a la resolucion de unproblema puede pensar en variables para cualquier concepto abstracto quepiense que sea util para resolver el problema de un modo claro y comunica-ble, lo que muchas veces quiere decir de un modo lo mas proximo posible allenguaje natural. La restriccion obvia es poder explicitar sin ambiguedadesla gestion de la memoria del ordenador que ha de realizar el compilador paraalmacenar y manipular ese dato. Mediante la estructura Record y Arrayel PASCAL ofrece la posibilidad de definir tipos de datos muy proximos alos utilizados en el lenguaje natural y que son una organizacion precisa detipos de datos mas sencillos. En ultima instancia, los atomos que van a for-mar esas estructuras mas complejas son los tipos de datos fundamentales delPASCAL : Byte , Integer , .... Al final, para una variable, el compiladorreservara lugar en memoria para almacenar un numero determinado de bitsde informacion (una sucesion de ceros o unos). El tipo de dato definido paraesa variable va a determinar el modo en el que esos bits van a intervenir enlas operaciones y tambien el modo con en el que el programador se podrareferir a todos esos bits de golpe o a subconjuntos de ellos.

9.6 Uniones

Comprendido lo anterior no debe resultar difıcil entender dos posibilidadesavanzadas que permite el PASCAL en la manipulacion de registros, y queson los registros con variante ( o uniones con discriminacion) y las unioneslibres. En PASCAL es posible dar una definicion dinamica de la composicionde un registro. Es decir, que los campos que lo componen varıen segun elvalor de un parametro. Para ello se utiliza la siguiente modificacion de laestructura Case dentro de la definicion del registro:

Casenombre : TipodeDato Of

caso1 : ( Especificacion1 );caso2 : ( Especificacion2 );. . .

Page 121: Introduccion A La Programacion En Pascal

9.6. UNIONES 121

donde nombre es el identificador elegido para la variable cuyo valor deter-mina la composicion del registro, TipodeDato el tipo de dato de la variablenombre, caso1,caso2, ... los valores o rango de valores que daran lugar a lasdistintas especificaciones del contenido del registro Especificacion1, Especifi-cacion2,... La enumeracion de las opciones no acaba con un End; por queexiste la restriccion de que las variantes se han de colocar en la ultima partede la definicion de un registro y por tanto acaban con el End; del fin de ladefinicion del registro.

Como ejemplo de la utilizacion de los registros con variante vamos a con-siderar el caso visto anteriormente de la base de datos de alumnos. Suponga-mos que en el campo de la nota podemos querer guardar en alguna ocasionen vez de un dato Real una calificacion global como Aprobado y elegimospara ello un dato String. Una posibilidad es la siguiente modificacion delcaso anterior:

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

.........................................

Page 122: Introduccion A La Programacion En Pascal

122 CAPITULO 9. DATOS CON ESTRUCTURA

Instrucciones validas de este programa serıan tanto

uno.nota:= 6.8 ;

como,

uno.calificacion := ’Notable’;

y al programador le queda toda la responsabilidad de utilizar una u otra.Realmente, esta estructura del PASCAL no es muy feliz en el sentido de queel compilador no verifica el valor de la variable que da acceso a las variacionesen los campos y su figura es meramente recordatoria para el programador.Sea cual sea el valor de la variable utilizada para la bifurcacion del tipode dato, se puede acceder a la informacion almacenada en el registro concualquiera de las variantes. Es responsabilidad exclusiva de programadorutilizar cada campo cuando esta definido. Con las Uniones libres se hacemas explıcito que la utilizacion de los campos alternativos es pura respon-sabilidad del programador y no se indica identificador para la variable quegobierna las opciones. Para definir una Union Libre dentro de la definicionde la estructura Record se especifica la alternativa del modo siguiente:

CaseTipodeDato 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 elidentificador de la variable que gobierna las distintas alternativas.

Esta posibilidad de acceso variable al contenido de un registro es coherentecon lo resumido anteriormente sobre el sentido de variables y tipos de datos.El compilador reserva para el dato en la memoria un espacio suficiente paraalmacenar aquella de las variantes del registro de mayor tamano. Se rellenarael espacio de memoria del modo que en cada momento desee el programador yla eleccion se realiza usando un campo u otro. Igualmente, la interpretacionde los bits almacenados en esas posiciones de memoria tambien dependedel campo del registro que se utilice, en el caso de que distintos camposcorrespondan a distintos tipos de datos.

Page 123: Introduccion A La Programacion En Pascal

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 hacerun programa legible. En el siguiente ejemplo la union entre el tipo de datoChar y Byte se utiliza para escribir una funcion que convierte un caracteren el correspondiente numero de orden ASCII.

Program Diez;

Var

dato : Char;

Function ElAscii ( x : Char ) : Byte;

Type

Atomo =

{ Union libre de un Char con un Byte }

Record

Case Integer Of

1 : ( car : Char);

2 : ( num : Byte );

End;

Var

y : Atomo;

Begin

y.car := x;

ElAscii := y.num

End;

Begin { Diez }

Readln (dato);

Writeln (’ El caracter ’,dato , ’ corresponde al ASCII numero : ’,

ElAscii(dato) );

End. { Diez }

En la funcion ElAscii el tipo de dato Atomo se define como la union librede un Char y un Byte. En este caso, ambos tipos de datos ocupan elmismo espacio en memoria ( un byte ). La variable y ocupa pues un byte

Page 124: Introduccion A La Programacion En Pascal

124 CAPITULO 9. DATOS CON ESTRUCTURA

de memoria, pero la sucesion de bits que lo componen puede interpretarse obien como un Char o un Byte, dependiendo de como se referencie.

Page 125: Introduccion A La Programacion En Pascal

Capıtulo 10

Ficheros

La entrada y salida de datos desde un programa no tiene porque realizarseutilizando los dispositivos estandard de entrada y salida (teclado y terminal),sino que puede realizarse a traves de cualquier periferico. Tambien es posible,y de hecho es lo mas frecuente, utilizar los dispositivos de almacenamientointermedio de datos. Estos dispositivos de almacenamiento de datos recibenel nombre de archivos o ficheros. Se trata generalmente de porciones de discosmagneticos donde se guarda informacion y se identifican con un nombre cuyoformato depende del sistema operativo.

10.1 Ficheros con Tipo

Para poder referir todas las entradas y salidas, el PASCAL utiliza un tipo dedato que se denomina File. Con este tipo de dato se pueden direccionar lasentradas y salidas de los programas a impresoras, dispositivos auxiliares,...y tambien a archivos. El valor de un dato del tipo File es esencialmenteuna direccion a donde se debe dirigir la UCP para transferir datos. El va-lor concreto es irrelevante para el programador puesto que las instruccionesque a el se refieren nunca requieren conocerlo. El PASCAL provee un pro-cedimiento que permite asignar a una variable del tipo File la direccion deldispositivo de entrada o salida que el programador pretende utilizar. Este esel procedimiento Assign que tiene dos argumentos. El primero es el nombrede la variable definida del tipo File y el segundo es un dato tipo String quecontiene el nombre con el que el sistema operativo identifica el fichero que sequiere utilizar. En la instruccion {3} del programa Uno se especifica que

125

Page 126: Introduccion A La Programacion En Pascal

126 CAPITULO 10. FICHEROS

con la variable almacen nos referimos al archivo que el sistema operativoreconoce como Uno.sal . La variable almacen se ha declarado como Fileof Byte. En la declaracion se especifica que los datos que se van a leer oescribir en ese dispositivo son del tipo Byte.

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.

El tipo de dato que va a intercambiarse con un dispositivo especificado conuna variable del tipo File puede ser tanto basico del PASCAL o definido porel usuario. La transferencia de datos que se puede realizar es tanto entradacomo salida. Para la salida se utilizara el procedimiento Write y para laentrada el Read. Ambos procedimientos tendran un argumento extra, siem-pre el primero, que es la variable del tipo File que contiene la identificaciondel periferico al que nos referimos. Por ejemplo, en la instruccion {5} se es-criben los valores almacenados en num1 y num2 en el periferico identificadocon almacen, es decir en el archivo uno.sal .

En el programa Uno tambien aparecen las llamadas a dos procedimien-tos: Rewrite y Close, relacionados con las tareas que se realizan en unordenador para transferir datos. Con el primero se especifica que el dispo-sitivo identificado con almacen se va a utilizar para salida de datos. Estaorden implica la realizacion de tareas que dependen del tipo de dispositivo alque nos estamos refiriendo. En el caso de archivos se ha de proceder a crearel archivo. Cuando el dispositivo se va a utilizar como entrada de datos, lasinicializaciones necesarias se realizan con el procedimiento Reset que tam-bien tiene como argumento la variable del tipo File que se quiere inicializar.Tambien se utiliza Reset para salida de datos a archivos que ya existen.

Page 127: Introduccion A La Programacion En Pascal

10.1. FICHEROS CON TIPO 127

Cuando se acaba de transferir los datos del programa a un archivo hayque realizar tareas simetricas a las que se realizaron en la inicializacion y quevan dirigidas a liberar el archivo del control ejercido por el programa. Enla instruccion {7} del programa uno se procede a realizar esta liberacioncon el procedimiento Close, que cierra el canal de comunicacion abiertoanteriormente con el procedimiento Reset o Rewrite.

En todo programa que se realiza una entrada o salida de datos a un dis-positivo que no es el estandard se han de incluir las ordenes correspondientesa la asignacion de dispositivo, inicializacion y cierre. El esquema siempre es

Var. . .identificador File Of TipoDato. . .

Begin. . .Assign( identificador, FichString);. . .Rewrite( identificador) { caso de arch. nuevo }{ o Reset( identificador) (* caso de arch. existente *) }. . .Close( identificador)

En un mismo programa se puede leer y escribir utilizando diferentes disposi-tivos y el numero maximo de archivos que se pueden estar utilizar al mismotiempo esta impuesto por el sistema operativo y no por el lenguaje PASCAL. Las palabras Rewrite y Reset tienen su origen en el uso de los dispo-sitivos antiguos de almacenamiento intermedio de informacion, que todavıase utilizan hoy en dıa. Fundamentalmente se trataba de cintas magneticasque el operador debıa o bien poner al principio para ser leıdas ( Reset ),o bien poner al principio y anadir el anillo que por seguridad era necesariopara poder escribir en una cinta ( Rewrite ).

Cuando se escriben datos en un archivo, la informacion se escribe exac-tamente del mismo modo que se almacena en la memoria del ordenador. Porejemplo, el dato del tipo Byte 7, se escribira como la secuencia de cerosy unos 00000111. Por tanto, cuando se lee un dato, se pueden almacenardirectamente en memoria, sin ninguna traduccion, los bits leıdos. En la de-finicion del identificador de la variable del tipo File, el tipo de datos quese van a transferir se especifica, y esta informacion la utiliza el compilador

Page 128: Introduccion A La Programacion En Pascal

128 CAPITULO 10. FICHEROS

para verificar que no se procede a la lectura o escritura de datos de tipos dis-tintos al anunciado en la declaracion. Por supuesto, es responsabilidad delprogramador leer apropiadamente los bits almacenados en un archivo. Porejemplo, si la informacion escrita en una archivo declarado como File OfByte se lee en otro programa distinto declarando el archivo como File OfChar se obtendra una traduccion de numeros enteros a los caracteres ASCIIcorrespondientes. Exactamente lo contrario se consigue si el programa dosutiliza el mismo archivo uno.sal escrito con el programa Uno como entradade datos.

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.

La salida del programa dos es :

HOLA

Exactamente el mismo saludo es el que se puede leer en el fichero uno.salcuando se edita con un editor de ficheros ASCII como el del Entorno Integradode Desarrollo del TURBO PASCAL .

Un dispositivo de entrada-salida se puede definir como File Of cualquiertipo de dato, incluyendo los definidos por el usuario. Son especialmente utileslos archivos del tipo registro, pues en ellos se pueden almacenar facilmentedatos con la estructura interna requerida por el usuario. Por ejemplo, en elproblema esbozado en el tema anterior sobre una base de datos con infor-macion sobre alumnos, el mantenimiento de dicha base podrıa proceder delsiguiente modo:

Program Tres;

Page 129: Introduccion A La Programacion En Pascal

10.1. FICHEROS CON TIPO 129

{ Utilidad para actualizar el archivo de alumnos }

{ Solo sirve para agnadir uno nuevo }

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;

End;

Var

carpeta : File of Alumno;

uno,otro : Alumno ;

respuesta,c : Char;

nomArchi : String;

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);

Writeln(’Desea incorporalo a la base de datos ? (s/n) :’);

Readln(respuesta);

If (respuesta = ’s’) Or (respuesta = ’S’) Then

Begin

Assign(carpeta,nomArchi);

Reset(carpeta);

While Not Eof(carpeta) Do Read(carpeta,otro);

Write(carpeta,uno);

Close(carpeta);

Page 130: Introduccion A La Programacion En Pascal

130 CAPITULO 10. FICHEROS

End; {endif}

End. { Tres }

En este programa se utiliza la funcion Eof que tiene como argumento lavariable del tipo File carpeta. Esta es una funcion del tipo Boolean quedevuelve el valor True si se alcanzado el fin del fichero al que apunta suargumento. La funcion se utiliza en el programa Tres para recorrer todo elarchivo hasta el final y despues anadir el nuevo registro.

El listado de todos los alumnos incluidos en la base de datos se podrıarealizar mediante el siguiente programa:

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);

Page 131: Introduccion A La Programacion En Pascal

10.2. PROCESAMIENTO SECUENCIAL Y ALEATORIO 131

If nacimiento.mes <> 0 Then

Writeln(’ (’,nacimiento.dia,’/’,nacimiento.mes,’/’,

nacimiento.agno,’)’);

End

End; {endwhile}

Close(carpeta);

End. { Cuatro }

10.2 Procesamiento secuencial y aleatorio

Tanto en el programa Tres como en el Cuatro se esta realizando un proce-samiento secuencial de los archivos. Se inicia la lectura por el primer registroy se procede hasta llegar al deseado o al final. En el caso del programaTres este tipo de procesamiento ha obligado, para llegar hasta el ultimo delos registros, a transferir a memoria el contenido de todos los registros. Laestructura interna de un archivo es lineal y muy parecida a la estructuraArray del PASCAL . Por tanto, deberıa ser posible acceder a los diferentesregistros sin necesidad de leerlos a la memoria RAM. Esta posibilidad es laque permite el procedimiento del PASCAL Seek que tiene dos argumentos:el primero un dato tipo File, y el segundo LongInt. El efecto de esta fun-cion es preparar el archivo identificado por el dato File para la lectura oescritura a partir del numero de registro que contiene la variable LongInt.De hecho, dado que los registros se empiezan a contar con el 0, se colocarapasado el registro indicado por el numero LongInt. Por ejemplo, si ficherose define como File Of Integer, la llamada Seek (fichero, 23) hara quela siguiente lectura realizada sobre fichero transfiera a la memoria del or-denador el dato Integer con el numero de orden 24; se han saltado 46 bytesdel fichero.

Con la posibilidad brindada por el procedimiento Seek se puede realizarlo que se llama procesamiento aleatorio de ficheros. A pesar del nombre,esto no tiene nada que ver con el azar, sino que implica leer o escribir enarchivos en un orden distinto que el secuencial. Para explicar la utilidad yservidumbres de este tipo de procesamiento, vamos a modificar el diseno dela base de datos de alumnos sugerida anteriormente. El objetivo es colocaral principio del fichero un numero que nos indique la cantidad de alumnosincluidos en la lista.

Program IniciaLista;

Page 132: Introduccion A La Programacion En Pascal

132 CAPITULO 10. FICHEROS

{ Utilidad para inicializar una lista 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

carpeta : File of Alumno;

otro : Alumno ;

nomArchi : String;

Begin { IniciaLista }

Writeln(’Inicializacion 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: secrea el archivo con el nombre indicado por el usuario y se escribe en elprimer registro el Integer 0 para indicar que no hay todavıa ningun alumnoincluido. Como almacen se tiene que definir como un File Of alumno parapoder escribir un entero en el primer registro tenemos que recurrir a unaunion libre del registro.

El programa que puede anadir un alumno en la base de datos es :

Program AumentaLista;

Page 133: Introduccion A La Programacion En Pascal

10.2. PROCESAMIENTO SECUENCIAL Y ALEATORIO 133

{ Utilidad para agnadir una alumno a una lista }

{ Solo sirve para agnadir UNO }

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

carpeta : File of Alumno;

uno,otro : Alumno ;

respuesta : Char;

nomArchi : String;

Begin {AumentaLista}

Writeln(’Nombre del archivo: ’); Readln(NomArchi);

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);

Writeln(’Desea incorporarlo a la base de datos ? (s/n) :’);

Read(respuesta);

If (respuesta = ’s’) Or (respuesta = ’S’) Then

Begin

Assign(carpeta,nomArchi);

Reset(carpeta);

Read(carpeta,otro);

Seek(carpeta,otro.numeroTotal+1); {Al final}

Write(carpeta,uno);

Page 134: Introduccion A La Programacion En Pascal

134 CAPITULO 10. FICHEROS

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 losregistros indicados al principio, y se escribe el nuevo. Despues, se vuelve alprincipio para aumentar en 1 el contador de registros almacenados.

El listado de los alumnos en la base de datos serıa :

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);

Page 135: Introduccion A La Programacion En Pascal

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 registrosalmacenados.

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 ;

Page 136: Introduccion A La Programacion En Pascal

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);

Writeln(’Desea incorporalo a la base de datos ? (s/n) :’);

Read(respuesta);

If (respuesta = ’s’) Or (respuesta = ’S’) Then

Begin

Assign(carpeta,nomArchi);

Reset(carpeta);

Read(carpeta,otro);

Seek(carpeta,elemento);

Write(carpeta,uno);

Close(carpeta);

End; {EndIf}

End. {ModificaLista}

En este programa se accede directamente al registro que se quiere modificary el usuario lo identifica con el numero de orden que aparece en el listado.Esta labor hubiera sido mucho mas difıcil de realizar con un procesamientomeramente secuencial del archivo.

10.3 Ficheros de Texto

Como se menciono anteriormente, el uso de ficheros de un tipo de dato de-finido, permite que la informacion se almacene en los archivos del mismomodo que se escribe en la memoria del ordenador. Por tanto, no es necesarioninguna traduccion para pasarlos a la memoria RAM. La ventaja de usareste tipo de archivos es la rapidez en la transferencia de informacion entrememoria RAM y dispositivos de almacenamiento. El inconveniente es la falta

Page 137: Introduccion A La Programacion En Pascal

10.3. FICHEROS DE TEXTO 137

de compatibilidad: para leer correctamente la secuencia de bits escrita porun programa PASCAL en un fichero con tipo es necesario u otro programaPASCAL o un programa muy sutil en otro lenguaje que tenga en cuentala estructura interna de los datos PASCAL . El modo estandar actual paratransferir informacion es utilizar el codigo de caracteres ASCII almacenadosen un byte con el bit menos significativo a la derecha. Por tanto, si se quiereescribir en un archivo informacion que sea legible por la mayorıa de las uti-lidades que existen comunmente hoy en dıa hay que utilizar los datos Chardel PASCAL . Ademas tambien es estandar el modo en el que se especificael salto de lınea.

El PASCAL suministra el tipo de fichero llamado Text para definir dis-positivos externos a los que se transfiere toda la informacion traducida acaracteres ASCII. Por ejemplo, los dispositivos estandar de entrada y sali-da (teclado y terminal TRC) son un ejemplo de Text. Los procedimientosReadln y Writeln, que no se podıan utilizar con los ficheros con tipo sepueden utilizar con los ficheros de texto y son los que se encargan de ges-tionar los caracteres ASCII de cambio de lınea (codigos 10 y 13 del ASCII).Un fichero Text es algo mas que un File Of Char puesto que el compila-dor se encarga de traducir las ordenes de escritura de todo tipo de datos acaracteres ASCII y con los formatos que indique el programador.

El programa siguiente:

Program Cinco;

Var

almacen : Text;

saludo : String;

Begin

Assign(almacen,’uno.sal’);

Reset(almacen);

Readln(almacen,saludo);

Writeln(saludo);

Close(almacen)

End.

tiene la misma salida al terminal que el programa Dos cuando el archivoUno.sal es el escrito por el programa Uno. Ejemplos de manipulacion deficheros con texto son todos los programas vistos hasta este tema puesto quetoda la entrada y salida de datos se realizaba sobre los dispositivos Input yOutput que son ficheros del tipo Text.

Page 138: Introduccion A La Programacion En Pascal

138 CAPITULO 10. FICHEROS

La ventaja de portabilidad de los ficheros del tipo Text es a costa detiempo de procesamiento y espacio de disco. Antes de pasar un dato de lamemoria a un archivo o viceversa se ha de realizar la traduccion de caracteresASCII. Con los dos siguientes programas:

Program Seis;

Uses Dos;

Var

almacen : File Of Real;

x : Real;

i : Integer;

h1,m1,s1,c1,h2,m2,s2,c2 : Word;

Begin

Assign(almacen,’seis.sal’);

Rewrite(almacen);

GetTime(h1,m1,s1,c1);

Writeln(h1,’:’,m1,’:’,s1,’:’,c1);

For i := 1 to 10000 Do Begin

x := Random;

Write(almacen,x);

End; {endfor}

GetTime(h2,m2,s2,c2);

Writeln(h2,’:’,m2,’:’,s2,’:’,c2);

Close(almacen)

End.

y,

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);

Page 139: Introduccion A La Programacion En Pascal

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.

se puede comprobar la diferencia entre los dos tipos de transferencia de in-formacion. En el Seis se escriben los datos Real en un fichero File OfReal y en el Siete en un fichero Text. El procedimiento GetTime, que seencuentra en la unidad Dos, devuelve el tiempo en horas, minutos, segundosy centesimas. Este procedimiento es el que se utiliza en ambos casos paradetectar el tiempo que se emplea en escribir 1000 datos Real. Con la salidade estos dos programas se puede comprobar que el segundo programa empleacasi el doble de tiempo que el primero en escribirlos. Ası mismo, el archivoSiete.sal que se crea ocupa casi tres veces el espacio ocupado por el ficheroSeis.sal. Este ultimo, solo ocupa 60000 bytes puesto que cada Real estaformado por 6 bytes, y Siete.sal ocupa 190000 bytes puesto que se necesitan19 caracteres ASCII para describir con el formato estandard cada dato Real(17 para el numero y 2 para el salto de lınea).

Otra desventaja adicional de los ficheros de texto es que solo aceptanprocesamiento secuencial y NO aleatorio.

Page 140: Introduccion A La Programacion En Pascal

140 CAPITULO 10. FICHEROS

Page 141: Introduccion A La Programacion En Pascal

Capıtulo 11

Punteros y asignacion dinamicade memoria

11.1 Contenidos, direcciones e identificado-

res

Hasta ahora hemos considerado que los datos almacenados en la memoriapueden accederse a traves del nombre de variables y constantes. Asumimosque el nombre de la variable es el indicador que permite al compilador de-terminar a que dato nos referimos y generar codigo UCP para operar con el.Cada dato esta almacenado en una posicion de memoria y su contenido sepuede modificar a traves de la relacion unıvoca que existe entre el nombrede la variable y la posicion que el dato ocupa en la memoria del ordenador.

Consideremos un programa tan sencillo como el siguiente:

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

Page 142: Introduccion A La Programacion En Pascal

142 CAPITULO 11. PUNTEROS

posicion de memoria a la que nos referimos con la variable a ha de alma-cenarse tambien en la posicion de memoria a la que nos referimos con lavariable b.

11.2 Punteros

En ningun momento se ha hecho explicito en la sintaxis del lenguaje que undato esta identificado internamente por una posicion de memoria. Sin em-bargo, es muy util poder manipular los datos realizando algoritmos en los quetambien interviene la direccion de los datos. Para ello el PASCAL permiteque en los programas aparezca un tipo de dato que son las direcciones de losdatos. Estas direcciones se llaman normalmente punteros, y en un programaPASCAL pueden intervenir las direcciones de datos que esten definidos. Seespecifica que una variable es un puntero a un tipo de dato con la ayuda delcalificador ˆ que se antepone a un identificador.

El dato ^tipodato es el puntero a un dato del tipo tipodato. Porejemplo en el segmento de programa :

Type

Fecha =

Record

dia : Integer;

mes : Integer;

End;

Var

a: Integer;

px : ^Real;

pa : ^Integer;

pHoy,pAyer : ^Fecha;

. . .

se esta declarando que px es un puntero a un dato Real, pa un punteroa un Integer, y pHoy y pAyer punteros a registros de Fecha. El mismocalificador ˆ sirve para especificar que queremos utilizar el dato almacenadoen la direccion de memoria especificada por el puntero, pero esta vez se anadeal final del identificador. Por ejemplo, cuando aparece en una parte posteriordel programa citado anteriormente pHoy^ estamos indicando el contenidodel registro del tipo fecha apuntado por el puntero pHoy. La asignacion

Page 143: Introduccion A La Programacion En Pascal

11.2. PUNTEROS 143

. . .

pHoy^ := pAyer^;

. . .

implica que se almacene en el lugar de memoria indicado por pHoy el datoalmacenado en el registro al que apunta pAyer. Para completar la herra-mienta es necesario un operador que sea capaz de extraer de una variable sudireccion, 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 }

en la que se obtiene exactamente el mismo resultado que en Uno pero conel uso explıcito de direcciones de variables. La variable pb es un puntero aun Integer, es decir la direccion de un dato Integer, y en la instruccion{2} se determina que es exactamente la misma que la de la variable Integera. En la instruccion {3} se asigna a la variable b el dato almacenado enla direccion que habıamos almacenado en el dato ( puntero ) pb. El datoalmacenado en b sera pues el mismo que el almacenado en a. Las instruc-ciones {3} y {4} de programa Dos producen el mismo resultado que la {2}del programa Uno recorriendo un camino mas largo y con una sintaxis me-nos clara. Pero si este tipo nuevo de dato se introduce en el lenguaje no espara hacer complicado lo sencillo, sino para aumentar las posibilidades dellenguaje tal como comentaremos en este tema.

Antes de seguir adelante puede ser ilustrativo considerar el siguiente pro-grama,

Page 144: Introduccion A La Programacion En Pascal

144 CAPITULO 11. PUNTEROS

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 }

en el que se modifica el valor del String a indirectamente a traves del con-tenido del puntero pb. Las direcciones de memoria que se almacenan enlos datos del tipo puntero, dependeran de cada tipo de ordenador, y en ge-neral, el programador puede olvidarse de esos detalles, pues solo utilizaralos punteros para manipular los datos a los que apuntan y evitara asignardirectamente valores numericos a los punteros. Generalmente se asigna a unpuntero el contenido de otro. Hay una excepcion: se trata del valor Nil, yaque no corresponde a un lugar de memoria y se utiliza para identificar que unpuntero no apunta a ningun lugar de la memoria. A un puntero, apuntandoa cualquier tipo de dato, siempre se le puede asignar el valor Nil.

Las operaciones que se pueden realizar con los punteros, son asignar ycomparar por igualdad o desigualdad. Con estas comparaciones se puedediscernir la equivalencia de direcciones. Sin embargo, no se pueden compararlos punteros con los operadores > y <.

Vamos a verificar el motivo de llamar argumentos por referencia o direc-cion a los argumentos antecedidos por Var en las funciones y procedimientos.La salida del programa Cuatro,

Program Cuatro;

Type pinte = ^Integer;

Var

a ,b ,c: Integer;

Page 145: Introduccion A La Programacion En Pascal

11.3. ASIGNACION DINAMICA DE MEMORIA. 145

Procedure Cuacua ( x : pinte;

y : Integer;

Var z : Integer

);

Begin

x^ := x^ * x^;

y := y * y ;

z := z * z ;

End;

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

El valor de la variable b no se modifica como resultado de la llamada a lafuncion porque es una argumento pasado por contenido. La variable c semodifica porque se pasa por referencia, y la variable a tambien modifica suvalor porque el argumento es la direccion de a y por tanto en la funcion depuede modificar el contenido de esa direccion.

11.3 Asignacion dinamica de memoria.

Una utilidad de los punteros es poder crear programas que ocupen la can-tidad de memoria del ordenador adecuada a cada caso segun se determinadurante la ejecucion del programa. Cuando un programa se va a ejecutar, secarga en la memoria del ordenador y la memoria ocupada por el programaesta estructurada en varias partes o segmentos. El codigo para la UCP secarga en memoria en el llamado segmento de codigo. Los datos definidosen el programa se cargan en el llamado segmento de datos, y hay un tercersegmento llamado pila (stack) que se reserva para los datos que se han de

Page 146: Introduccion A La Programacion En Pascal

146 CAPITULO 11. PUNTEROS

manipular temporalmente durante la ejecucion del programa, por ejemplo,para almacenar los valores de las variables que se han de crear para reali-zar un procedimiento. El resto de la memoria se gestiona como un monton(heap) y tambien puede estar disponible para el programa.

La funcion New es la que gestiona la captacion para el programa de lamemoria del monton. El argumento de la funcion ha de ser un puntero aun tipo de dato del PASCAL o definido por el programador, y la funcionNew asigna a ese puntero el valor de una direccion de memoria del montoncon el tamano adecuado para almacenar un dato del tipo al que apuntasu argumento. En el momento en el que esa porcion de memoria ya nosea necesaria para el algoritmo codificado en el programa, puede liberarsedel control del programa con la funcion Dispose, que tiene por argumentoel puntero donde se almacena la direccion de la porcion de memoria quese quiere liberar. A esta gestion de la memoria del ordenador durante laejecucion del programa se le llama asignacion dinamica de la memoria.El programa Cinco es una modificacion del Tres en el que la memoriautilizada para almacenar los saludos no esta en el segmento de datos sino enel Heap.

Program Cinco;

Var

pa,pb : ^String;

Begin { Cinco }

New(pa);

pa^ := ’Hola’;

pb:= pa;

writeln(pa^);

pb^ := ’Adios’;

Writeln(pa^);

Dispose(pb);

End. { Cinco }

Se reserva la memoria con New antes de almacenar ningun valor en esadireccion. La ultima instruccion hubiera igualmente podido ser Dispose(pa)porque ambos punteros almacenan la misma direccion de memoria que selibera con Dispose. Es mas, la siguiente modificacion es incorrecta porvarios motivos.

Page 147: Introduccion A La Programacion En Pascal

11.4. DECLARACIONES RECURSIVAS DE TIPOS DE DATOS 147

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 darıa un error en la ejecucion. La ultima instruccionintenta 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 gestiondinamica de memoria. La memoria reservada para el programa mediante latercera instruccion (256 bytes) no se puede liberar puesto que hemos perdidola pista de cual era. Es una practica poco recomendable escribir programasque cuando acaban dejan sin liberar memoria que reservaron del monton.

11.4 Declaraciones recursivas de tipos de da-

tos

La asignacion dinamica de memoria permite crear estructuras de datos quepueden crecer y disminuir segun los requerimientos que el programa detectadurante la ejecucion. La mas sencilla de ellas es la llamada lista unida. Me-diante definicion de punteros a datos en la memoria y uniendolos entre ellos,se obtienen listas de objetos sin tamano especıfico. Pueden ser listas vacıaso contener miles de datos, crecer y menguar durante la ejecucion del progra-ma. Son estructuras de datos recursivas que se comprenden facilmente conesquemas, pero primero veremos un ejemplo de como se definen en PASCAL.

Type

Page 148: Introduccion A La Programacion En Pascal

148 CAPITULO 11. PUNTEROS

Enlace = ^Nodo;

Nodo =

Record

clave : Integer;

siguiente : Enlace

End;

Primero se define el puntero Enlace como la direccion a un dato (todavıasin definir) Nodo y despues se declara cual es el significado del tipo de datoNodo. Este es un registro que en su primer campo puede almacenar unentero y en el segundo un puntero, Enlace, a un dato del mismo tipo Nodo.

La recursividad esta obviamente en la autorreferencia durante la definicion.Merece la pena destacar que el caso de los punteros es unico en el PASCALen cuanto a que es posible definir un tipo de dato a partir de otro quetodavıa no esta definido. Esta flexibilidad es necesaria para poder generar larecursividad.

Las variables del tipo Nodo van a ser los ladrillos con los que se construirauna lista unida de numeros enteros. Cada uno de ellos puede almacenar unnumero entero y la direccion del siguiente en la lista.

La lista mas pequena que podemos tener es de un solo elemento. Paraidentificar que nadie le sigue podemos recurrir al valor Nil.

Nodo Nodo Nodo- -HHHHHj

Nil

Enlace

El dibujo es muy ilustrativo de la estructura de datos llamada lista unida.Cada elemento de la lista puede almacenar informacion relevante para el

Page 149: Introduccion A La Programacion En Pascal

11.4. DECLARACIONES RECURSIVAS DE TIPOS DE DATOS 149

problema en la que se utiliza y tambien el enlace con el siguiente vagon.Para cada elemento de la lista habra que reservar memoria, tanto para lainformacion que se quiere guardar, como para el puntero que sirve de enlace.

Vamos a utilizar en el programa Seis una lista unida para almacenaren la memoria del ordenador cuantos numeros enteros teclee el usuario parapoder luego listarlos en el orden inverso al que se teclearon. La memoria delordenador que necesitara el programa Seis para ejecutarse dependera de losnumeros que se tecleen. Si son unos pocos sera muy poca la memoria quetomara, y, el lımite superior de numeros que se pueden teclear dependera dela memoria RAM instalada en el ordenador. Si en vez de una lista unidahubieramos utilizado una estructura Array para almacenar los enteros, lamemoria deberıa determinarse al escribir en el programa el rango de variaciondel ındice del Array.

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}

{Se leen los datos y se incluyen en la lista }

Readln(i);

While i >= 0 Do { Un numero negativo finaliza el proceso}

Begin

New(y);

y^.clave := i;

Page 150: Introduccion A La Programacion En Pascal

150 CAPITULO 11. PUNTEROS

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.

Para detectar el final de la lista, recurrimos a la direccion Nil. Cuando reco-rremos la lista para escribir el contenido, nos detenemos cuando un nodo (elultimo) apunta a esa constante. No hay que olvidar nunca reservar memoriadel Heap para cada elemento nuevo de la lista. De lo contrario, se puedenobtener resultados impredecibles. Cuando se escribe informacion en la direc-cion de memoria dictada por un puntero que no ha sido convenientementeinicializado estaremos escribiendo en un lugar descontrolado y los resultadosson imprevisibles. Dado que los numeros tecleados por el usuario se van incor-porando a la lista segun se teclean, y no guardamos la pista sobre donde estael primer elemento almacenado en memoria, solo podemos listar los numerosen el orden inverso al que fueron tecleados. Para listar los numeros en elmismo orden en el que fueron tecleados existen varias posibilidades pero suanalisis queda fuera de los objetivos de este curso. Sin ahondar mucho masen las estructuras de datos que se pueden generar con los punteros merece lapena resaltar la simplicidad y eficiencia de cierta operaciones que se realizancomunmente sobre listas unidas. El insertar un nuevo elemento en el lugarelegido de la lista puede ser algo tan sencillo como :

{un nuevo nodo se crea a continuacion del apuntado por y}

New(z);

z^.clave := i;

z^.siguiente := y^.siguiente;

y^.siguiente := z;

Page 151: Introduccion A La Programacion En Pascal

11.4. DECLARACIONES RECURSIVAS DE TIPOS DE DATOS 151

y la eliminacion de un nodo :

{Se elimina el nodo a continuacion del apuntado por y}

z:= y^siguiente;

y^.siguiente := y^.siguiente^.siguiente ;

Dispose(z);

Estructuras de datos como listas doblemente unidas, circulares y arboles, sonmuy comunes en la realizacion de algoritmos eficientes.

A estas alturas del curso podemos entender perfectamente el programallamado Josefo que se estudio en el Tema 3. No obstante, el alumno nodebe esperar que con los conocimientos sobre programacion adquiridos hastaahora deberıa haber disenado un programa similar a Josefo para resolverel problema. Tales disenos no aparecen generalmente por intuicion sino co-mo resultado del estudio de las estructuras de datos y algoritmos que sehan desarrollado para diferentes problemas tipo planteados a la ciencia dela computacion. El objetivo de esta parte del curso era que el alumno com-prendiera un programa como el citado y sobre todo que en los programas queescriba, sean los problemas que resuelvan mas o menos sencillos, utilice laherramientas aprendidas siguiendo las normas de claridad y estilo referidascontinuamente.