Академический Документы
Профессиональный Документы
Культура Документы
==i
rr u7#'r.*if*rl ]
M." TeresL---v=,---{r: *- Lena Atonso
^
lntroduccin CT
a[a programaclon:
probtemas
resuettos
en Pascat
IIC
/\ firorial universitaria
H
E Ramn Areces
u Servicio
de
Publicaciones
-'
f::
U
Cu "
\--{ 3
II.{TRODUCCTX A LA PROGRAMACIN:
PROBLEMAS RESUETTOS EN PASCAL
s{*
universitaria
@airotial
-g Ramn Areces
Uil::."",
Indice
Prlogo xxv
1 Conceptos de programacin 1
1.1 Computadora u ordenador 1
1.2.1 Problema I
1.2.2 Algoritmo 2
1.2.3 Problemas, algoritmos y programas 4
I .3 Lenguajes'y paradigmas de programacin 4
1.3.1 Lenguajes de programacin 1
1.3"2 Evolucin de los lenguajes de programacin . 6
1.3.3 Paradigmas de programacin . 8
1.1 Ingeniera del software 8
v1l
Nurcn
20
2.6.2 Conversin exPlcita
21
2.1 Elementos bsicos del lenguaje
21
2.1.1 Vocabulario
23
2.1 .2 Constantes Y variables
23
2.7 .3 Instrucciones bsicas: asignacin. escritura y lectura
26
2.1 .1 Estructura de un Programa
29
2.8 Cuestiones de tiPo test
29
2.8.1 Enunciados
30
2.8.2 Soluciones
32
2.9 Problemas
32
2.9.1 Expresiones
32
2.9.2 Tipo y valor .
32
2.9.3 Sintaxis
2.9.1 Escritura -1 -)
34
2.9.5 Lectura
34
2.9.6 Algoritmo radianes Y grados
31
2.9.1 Programa radianes Y grados
35
2.9.8 Segundos
35
2.9.9 Cilindro
35
2.9.10 Ecuacin de segundo grado
35
2.9.1 1 Hern de Aleiandra .
35
2.9.12. Carrera de caballos
36
2.9.13 TransPortes
36
2..9.11 A mayscultrs
36
7.t0 Soluciones
36
2.10.1 Expresiones
31
2.10.2 Tipo y valor .
31
2.10.3 Sintaxis
39
2.10.4 Escritura
39
2.10.5 Lectura
39
l. 10.6 ,\lgoritmo radianes Y grados
40
1.10.7 Programa radianes Y grados
.11
2.10.8 Segundos
12
1.10.9 Cilindro
_tl
1.10.10 Ecuacin de segundo grado
13
1 Hern de Alej andra
1 . 1 0. 1
44
1.10.12 Camera de caballos
47
1.10.13 Transportes
48
2.10.14 A maYsculas
L
Nnrcr ix
Instrucciones estructuradas 49
3.1 Instruccincompuesta Iu
3.2 Instrucciones de seleccin 19
3"3 Instrucciones de iteracin 52
3.4 Recomendaciones {1
3.5 Cuestiones de tipo test 55
3.5.1 Enunciados 55
3.5.2 Soluciones 51
3.6 Problemas 51
3.6.1 Nivel medio de ruido 51
3.6.2 Clculo del prstamo bancario 58
3.6.3 La calculadora 58
3.6.4 Esquema de recorido 58
3.6.5 Esquema de bsqueda 58
3.6.6 La hora cada diez minutos 58
3.6.7 El mximo comn divisor 59
3.6.8 El nmero perfecto 59
3.7 Soluciones 59
3.7.1 Nivel medio de ruido 59
3.7.2 Clculo del prstamo bancario 60
3.7 .3 La calculadora 61
3.1.4 Esquema de recorrido 62
3.7.5 E,squema de bsqueda 62
3.1.6 La hora cada diez minutos 63
3.7.7 El mximo comn divisor 64
3.7.8 El nmero perfecto 65
B3
4.11.2 Otro toro
83
4.1 I .3 Nuevo toro
83
4.1 1.4 Traza y comPrensin
84
4- I 1.5 Mtodo Cesar .
85
4.11.6 Emores
81
4.11.1 Nmeros romanos
8B
4.11 .8 Multiplicacin con Lpiz y papel
89
4.11.9 Palndromo
.+.1 1 .10 Nmero de la suerte
90
90
4.l 1.l 1 Calculaclora
91
4.ll.l2 Calculadora de comPlejos
91
4.1 1.l3 Primalidad
92
t 4.1 1 .14 Sucesiones
92
4.1 1.15 Trayectoria
93
4.1 1.16 Funcin seno aProximada
93
1.ll.ll Suma de nmeros Prlmos
93
4.r1.l8Pi
93
4.1 1.19 Capica
93
94
4.t2
94
4.12.1 Toro .
96
4.12.2 Otro toro
9B
4.12.3 Nuevo toro
101
4.12.4 Traza y comPrensin
103
4.12.5 Mtodo Cesar .
106
1.12.6 Errores
107
1.12.1 Nmeros romanos
111
-t. 12.8 Multiplicacin con lpiz y papel
113
1.12.9 Palndromo
4.12.10 Nmero de la suerte
tt4
4.t2.ll Calculadbra fi6'
TL7
4.12.t2 Calculadora de cornPlej os
126
4.12.13 Primalidafl
I2B
4.12.14 Sucesione
131
4.12.75 Trayectorib
IJJ
4.12.16 Funcin selro aProximada
f.
xrcr ri
Registros 287
9.1 Descripcin del tipo registro 281
9.2 Operaciones 288
9.2.1 Acceso a los campos de un registro 288
9.2.2 Asignacin 289
9.3 Registros como parmetros 29o
9.4 La instruccin WITH 29t
9.5 Registrosvariantes 292
9.6 Arrays parcialmente llenos 293
9.7 Cuestiones de tipo test 293
9.7.1 Enunciados 293
9.1.2 Soluciones 295
9.8 Problemas 296
9.8.1 Declaracin de un tipo registro simple 296
9.8.2 Declaracin de un tipo registro con pafte variante 296
9.8.3 Visualizacin del contenido de un registro 297
9.8.4 Correccin de erores 297
9.8.5 Clases de aerobic 29',|
9.8.6 Mensajes en un telfono mvil 298
9.8.7 Evitando la recursividad 299
9.9 Soluciones 300
9.9.1 Declaracin de un tipo registro simpie 300
9.9.2 Deelaracin de un tipo registro con parte variante 300
9"9.3 V'isualizacin del contenido de un regisiro 301
9.9"4 Crrreccin de emores 307
9.9.5 Ciases de aerobic 309
9"9.6 Mensajes en iln teldfono mvii .1 I I
10 Ficheros
xorcn
331
10.1 Ficherooarchivo? . . . 331
10.2 Deflniciones . 332
10.3 Nombre lgico y nombre fsico de un fichero J 1/.
10.4 Tipos de ficheros en Pascal -r -1 -)
.393
Pnnteros y estructuras de datosdinmicas
11.1 Punteros . . i. 393
11.1.1 Manejo de memoria dinmica 395
11.1.2 Simulacin de paso por referencia 396
11.2 Estructuras de datos dinmicas 397
NnrcB xVrt
\.
unrcr xix
13.7.4 Formalizacin
-i-57
13.1.5 Especificacin tbrmal de funciones 5-i 8
13.1.6 Verif,cacin de un bucle s5B
13.1.1 Derivacin formal de un bucle 558
13.7.8 Suma de los trminos de una sucesin s59
13.1.9 Vector Alvanzado I 559
13.7.10 Nmero Perfecto -5-59
I
l3.7.11Horas trabajadas 559
13.1.12 Vector Cimitbrme 560
f3.1.13 Las Dobles Parejas -560
l3.l.l4Horastrabajadas2 ... 560
13.7.15 Dif'erencia entre nmero de valores positivos y negativos de un
vector 56t
13.7.16 Suma de los divisores estrictos de un nmero 561
13.7.11 Vector Alvarizado 2 .. 561
13.8 Soluciones a los problemas
562
13.8.1 Enunciados lgicos 562
13.8.2 Clculo de precondiciones 562
13.8.3 Ordenacin de predicados 564
13.8.4 Formalizacin 564
13.8.5 Especificacin formal de funciones 565
13.8.6 Verificacin de la invarianza de un bucle 568
13.8.7 Derivacin fbrmal de un bucle 569
13.8.8 Suma de los trminos de una sucesin 570
13.8.9 Vector Alvarizado 1 5tt
13.8. 10 Nmero Perfecro 574
13.8.1 1 Horas trabajadas 1.. . 578
13.8. 12 Vector Cimiforme 581
13.8.13 Las Dobles Parejas 583
13.8.14Horas trabajadas 2 .
. . 585
13.8.15 Diferencia entre nmero de varores positivos y negativos de un
vector 586
i3.8.16 Suma de los divisores estrictos de un nmero 5gg
l3.B.lTVectorAlvarizado2 .. .590
Bibliografa 594
1.1 Ejemplos de objetos que se pueden modelar con arays: (a) tablero de
ajedrez, (b) vector en el espacio 208
1.2 Acceso a los elementos de un array: (a) bidimensional de dimensiones
MxN, (b) unidimensional 2Og
7.3 Array parcialmente lleno 2ll
7 .4 El juego de "las cuatro en raya" 222
xxi
xxli xotcp DE FTGURAS
t,
l
t
Indice de tablas
1.1 Toro 82
4.2 Trazay comprensin B5
4.3 Mtodo Cesar 85
4.4 Problema sobre errores 87
4.5 Equivalencia de nmeros romanos 88
4.6 Trazay comprensin 103
4.1 Problema sobre errores 106
xx1ll
Prlogo
Nos es grato presentar esta obra, que nace con el nimo de complementar los conteni-
dos tericos expuestos en el aula en las asignlturas universitarias de introduccin a la
programacin.
El texto est dirigido fundamentalmente a alumnos. pero tambin a prof-esores. de
asignaturas relacionadas con la introduccin a la programacin estructurada y modular
que utilizan el lenguaje Pascal. La motivacin inicial fue 1a de apoyar las asignaturas de
programacin de los primeros cursos de las ingenieras informticas de la Universidad
Rey Juan Carlos, donde los autores imparten docencia. Sin embargo, gran parte de los
contenidos expuestos son comunes a las asignaturas de introduccin a la programacin
de otras titulaciones cientfico-tcnicas.
E,stas asignaturas poseen un carcter marcadamente prctico, de fbrma que el alumno
no slo debe limitarse a coleccionar en su memoria una serie de conceptos tericos, sino
tambin aplicarlos a la resolucin de problemas. Es decir. no es suficiente con conocer
v comprender los aspectos metodolgicos, lbrmales y de diseo de la programacin
estructurada. sino que adems, es absolutamente necesario saber cmo aplicarlos a casos
prcticos. S1o en ese momento cobran sentido y utilidad las hemamientas conceptuales
aprendidas.
Los autores son profesores del rea de Lenguajes y Sistemas Infbrmticos del De-
partamento de Infbrmtica, Estadstica y Telemtica de la Universidad Rey Juan Carlos
de Madrid. Todos ellos tienen experiencia docente en las asignaturas de pro-eramacirn
de los primeros cllrsos de dicha universidad. En concreto, en Metodologa y Tecnolo-ea
de la Programacin de la titulacin de Ingeniera Tcnica en Infbrmtica de Sistemas e
Ingeniera Tcnica en Informtica de Gestin, y en las asignaturas de lntroduccin a la
Programacin, Estructuras de Datos y Metodologa de la Programacin de la titulacin
de lngeniero en Infbrmtica. Las cuestiones y ejercicios planteados en este texto estn
ertrados. en su mayora, de los ejercicios, prcticas y exmenes propuestos en dichas
titulaciones.
Los contenidos estn dedicados fundamentalmente a afianzrr los contenidos tecno-
1gicos de la introduccin a la programacin. Sin embargo, los autores han considerado
necesario complementarlos con la inclusin de algunas cuestiones metodolgicas. como
1a especificacin, derivacin y verificacin fbrmal de algoritmos. El libro se organiza
por captulos, y cacla uno de ellos se dedica a un concepto relevante de la programacin
xxvi Pnloco
estructurada. En cada captulo, se han organizado los contenidos en tres secciones bien
dif-erenciadas: teoro, cuestiones tle test y troblemeu.
En la seccin de teora se exponen muy brevemente y a modo de recordatorio los
principales conceptos metodolgicos y tcnicos necesarios para abordar los problemas
del tema. acompaados de algunos ejemplos. Es necesario aclarar aqu, que este texto
no tiene vocacin de libro autosuficiente para el aprendizaje de la programacin, silto
que su objetivo es servir de complemento prctico.
Las cuestiones de tipo tsl tienen como objetivo qLle el alumno compruebe y valore
sus conocimientos tericos. no slo en un nivei puramente memorstico, sino haciendo
especial hincapi en las dificultades relacionadas con la comprensin de los conceptos.
Un uso adecuado delas cuesticnes de tipo test ayudarir al lector a detectar sus carencias
en cuanto a 1o que sabe c no sabe, pero tambin en cuanto a 1o que entiende y no entiende.
La seccin de probLemas constituye la parte ms extensa de cada captulo. Est de-
dicada a la propuesta, resolucin y discusin de una amplia coleccin de problemas. Un
uso adecuado del material presentado en esta seccin est supeditada a la participacin
activa del lector. En este sentido, para el coffecto aprovechamiento del libro, es necesa-
rio que, en primer lugar, el lector se esfuerce en resoiver los problemas que se proponen.
El uso de las soluciones propuestas slo tiene sentido una vez que el alumno ha detec-
taclo carencias en sus eonocimientos o para cotejar o comparar sus soluciones con las
propuestas.
El lenguaje Pascal ha sido. y sigue siendo, uno de los lenguajes de alto nivel preferido
por muchos prof-esores de introduccin a la programacin. Fue creado por Niklous Wirth
(1934-). Coino lenguaje de programacin imperativa, cubre todos sus aspectos funda-
mentales de una manera sencilla y limpia. Tiene un sistema rgido de comprobacin de
tipos, una entrada/salida simple, una sintaxis reducida y condiciona al programador a
organizar el cdigo. A su vez, permite la declaracin de tipos definidos por el usuario y
el uso de punteros. En versiones extendidas se aaden conceptos abstractos tales como
unidades o mdulos precompilados y soporte para programacin orientada a objetos.
Desde su concepcin, Pascal es un lenguaje pensado para la enseanza de la pro-
gramacin estructurada, y como tal, para este libro se ha hecho uso de 1. Los autores
de este libro son conscientes de que el lenguaje Pascai ha sido criticado duramente. La
ms famosa crtica corri a cargo del coautor del lenguaje C. Brian W. Kemighan, en
su artculo "Wl' Pttscal Is Nrt My Favourite Programming Lunguage" (1981). Sin em-
bargo. estos ataques no estaban dirigidos a la adecuacin de Pascal como lenguaje para
ensear a pro-qramar. De hecho. la mayora de las quejas formuladas se basaban en las
limittcione-s cosmticas de Pascal. como las restricciones sobre ia codifrcacin de los
progr-antas. pero qlle necesarialnente obligan al programador novel a concentrarse en los
algoritmos.
En dehnitit'a. presentamos este texto con la esperanza y el deseo sincero de que sea
til a nriestros alumnos y a todos aquellos que se acerquen a 1.
[,o.s autrres
Captulo 1
Conceptos de programacin
Para aprender a programar es necesario tener claros ciertos conceptos generales y espe-
cficos de todo 1o que envuelve el proceso de la programacin. En este captulo se trata
de dar una visin general de la programacin y alavez exponer los conceptos clave para
la resolucin de problen-ras por medio de 1a computadora u ordenador.
1.2.1 Problema
Un problema es una proposicin encaminada a averiguar el modo de obtener un resul-
tado. cuando se conocen ciertos datos de partida.
Los problemas se pueden dividir en tres tipos, dependiendo de las soluciones que
lenBa. que son:
7
CoNcnptos DE PRocR.u,cr,
!t1rgrilil
tr{E},I-;}ll-{
Sin solucin o irresolubles: esos problemas no pueden ser solucionados con los me-
dios disponibles. Por ejemplo, el clsico problema de la cuadratura del crculo:
"Daclo un crculo. construir un cuadrado de igual rea que el crculo utilizando
solamente regla y comps" (la mencionada regla es no graduada y solo sirve para
trazar rectas ).
Determinados: los problemas tienen solucin y adems es nica. Por ejemplo, encon-
trar un nmero natural x que resuelva la ecuacin 2x=4.
Indeterminados: estos poseen un nmero indelinido de soluciones. Por ejemplo, hallar
dos nmeros enteros x. y que cumplen el siguiente sistema de ecuaciones: 2x-y=l;
iLv-)v=
,,-.J -)'
2. Especi.ficcrt.irirt del problema: consiste en dar una descripcin precisa del problema
con los datos cle partida y el resultado. Esta descripcin se puede hacer con len-
guaje natural. que con frecuencia es ambiguo, o con lenguajes fbrmales, como las
mate 1nticas o 1a lgica.
1.2.2 Algoritmo
Eristert varias definiciones para el concepto de algoritmo. Entre ellas destacan:
Definicin 1: descripcin precisa de los pasos que nos llevan a la solucin de un pro-
ble na planteado.
Pnonr,Bnrls, ALGoRITMoS y pRoGRAMAS
Definicin 2: rntodo tal, que partiendo de los datos apropiados, conduce sistemti.r-
mente a los resultados requeridos en la especificacin del problema.
Lenguajes algortmicos
Sirven para describir un algoritmo. Son ms precisos que el lenguaje natural, pero me-
nos rgidos (o fbrmales) que un lenguaje de programacin. Se les considera lengua-
.jes intermedios y tienen cierta independencia de los lenguajes de programacin y del
computador donde se escribir el programa. Ejemplos de lenguajes algortmicos son e1
pseudocdigo. los organigramas y los diagramas de Nassi-Schneiderman (N-S) tambin
conocidos por diagramas de Chapin. Estos dos ltimos son representaciones grficas de
n algoritmo.
El tseudocridigo es una variacin del lenguaje natural en el que se han elirninado
1us posibles ambigedades mediante el uso de un vocabulario restringido y unas reglas
;intcticas de construccin de sentencias. Este ser el recurso utilizado para verificar y
derivar programas en el captulo 13.
.\spectos de un algoritmo
Para construir un programa hay que seguir un mtodo. La ingeniera del software se
encarga del estudio y la aplicacin de los distintos mtodos existentes para desamollar
,-ompletamente aplicaciones informticas. En eI apartado 1.4 se da una explicacin ms
anpiia de la ingeniera del software.
L
LnNcu,tJps y pARADTGMAS DE pRocRAuRcrN
Existen varias fbrmas de especificar la sintaxis. Entre ellas destacamos las gram-
ticas (BNF o Backus-Naur Form) y los diagramas sintcticos.
CoNcrpros DE PRocRlntRcrN
l--.ttto evolucin natural surgi un nuevo lenguaje llamado ensamblador, donde a tlr
.:uencia de ceros y Llnos se le asocia un nombre nemotcnico. Estos nombres necesitun
.:Juccin. que se realiza mediante un proglama que se llama como el lenguaje: ensam-
:Lldor. Aunque lue un gran avance, todava es necesario conocer cmo est constituida
. .11r recursos tiene la computadora.
\{s tarde se fueron asociando nombres a conjuntos de instrucciones que realizaban
-.nt tarea compleja determinada, y a programar de manera independiente a la compu-
..rJora dinde se iba r ejecutar el cdigo. A los lenguajes que incluyen estas caractersti-
- . se les denomina lenguajes de alto nivel, porque se encuentran ms cercano a la forma
-l: pensar de los humanos que al lenguaje que entiende la mquina.
Los lenguajes de programacin han ido evolucionando gracias a cuatro causas o
rr,rrtores que impulsan esta evolucin, que son:
\bstraccin: proceso mental por el que el ser humano extrae las caractersticas esen-
ciales de algo, e ignora los detalles superfluos. Es esencial para modelar el mundo
real. En un principio se hacan programas pensando como una computadora. En
la actualidad se solucionan los problemas sin conocer la mquina doncle va a ser
ejecutado el programa.
Encapsulacin: proceso por el que se ocultan los detalles de las caractersticas de una
abstraccin. En pro-gramacin es esencial para reutilizar cdigo. Si se ocultan
los detalles de cmo est hecho Lln programa pero se conoce el modo de funcio-
namiento, se puede utilizar en cualquier otro programa sin ms qlle respetar su
especifrcacin.
\Iodularidad: proceso de descomposicin de un sistema en un conjunto de elementos
poco acoplados (independientes) y cohesivos (con significado propio). Es esencial
para abordar 1a resolucin de problemas extensos o complicados.
A medida que se fueron aadiendo estas caractersticas fueron surgiendo 1os si_suien-
r'. estilos de programacin:
son:
Las ventajas de aadir estas propiedades a los lenguajes de programacin
o Mejor comPrensin del Programa.
r Mejor legibilidad.
o Mayor facilidad en el mantenimiento del programa'
Frog. orie,,td,*da
c ajefns
Prog. LIP
Funcional Hope
(P.Dsclarativa)
Prog.
Lgica Prolog
(P.Declarativa)
C Ada
Smalltalk
Prog. pAscAL
Pasca] FC
Delfi
C++
Imperativa Fortan
Java Eiffel
Planificacin
:: -rllificar es determinar
las necesidacles de programacin, estimar la cantidad de recur-
' '1
\ Se&fl tcnicos como humanos necesarios para el desarrollo, predecir de manera
:|Ll.\imada el coste y el tiempo que llevara realizarlo y por
ltimo, determinar si el
-:.nollo del software es viable econmicamente.
rnlisis de requisitos
Diseo
Codificacin
En este paso se escriben los algoritmos de los distintos mdulos en el lenguaje de pro-
gramacin elegido. Una vez que se han implementado se integran las partes para que
fbrmen un programa completo.
Validacin
Mantenimiento
Aqu se redacta la documentacin actualizada de todos los pasos. Se inicia la explota-
cin del software, ponindolo en funcionamiento real. Se detectan y subsanan errores
cometidos en etapas anteriores y si es necesario se adapta la aplicacin a nuevos requi-
sitos.
I
Captulo 2
Una vez conocidas las nociones bsicas sobre algoritmos, se pasa a presentar cmo se
reizan programas sencillos siguiendo el paradigma imperativo. Para ello se utiliza el
lenguaje de programacin denominado Pascal, debido a que fue diseado para la ense-
anza de la programacin. Es esencial aprender a programar de manera correcta, legible
y eflciente. Si se adquieren unos buenos hbitos, el paso a otro lenguaje de programacin
imperativa es sencillo. En este captulo se aprendern los elementos bsicos del lenguaje
y se har hincapi en la metodologa parala corecta construccin de programas senci-
llos.
11
t2 Elrurrros sisrcos os P.r,sc.-r.l-
Caractersticas de Pascal
o Es un lenguaje de alto nit,el. Los lenguajes de alto nivel son aquellos en los que
las instrucciones o sentencias son escritas con palabras similares a las de los len-
guajes humanos (en la mayora de los casos, el ingls). Esto f'acilita la escritura y
comprensin del cdigo aI programador.
o Es de protsito generolya que es aplicable a una gran cantidad de problemas de
diversa naturaleza: matemtica. fsica. de gestin, de ocio,...
. Es strltcturado en los datos y en el control del flujo de los datos.
o Es modular, ya que permite dividir los problemas en partes. que se pueden resolver
mediante mdulos o subprogramas independientes entre s.
o Es c:orupcrclo y t'ic:il de aprencler debido a que posee muy pocas instrucciones
bsicas.
La mayora de los traductores son compiladores, lo que 1o hace un lenguaje corn -
pilado.
Fue diseado para \a enseanzct de Ia programacin. Es un lenguaje fuerternente
tipado lo que implica que no va a permitir mezclar expresiones de distintos tipos.
Tipos ordinales
Entre 1os tipos c1edatos bsicos se pueden distinguir dos grupos: los ordinales y los
reu1e., Se cienomjnan ordinales porque pueden enulnerar sus dominios asignando a sus
elL'1rel.rto\ un nrrnero de posicin y todos sus posibles valores poseen un elemento si-
Surente r. un eler.nento anterior (excepto el primero y el ltimo). Los tipos integer,
:.-... \ 'i. - -=,.,. que se estudiarn a continuacin, cumplen esa propiedad. Poseen fun-
cior.r.'. predehnidas en el lenguaje para saber su posicin y el valor siguiente y anterior.
Trpos DE DATos rsrcos t3
La funcin ord(x), que es propia de estos tipos de datos, devuelve eI nmero de posicin
del argumento x en su dominio. Las funciones pred(x) y succ(x) son tambin exclusi-
vas de los tipos ordinales y devuelven el predecesor y el sucesor de x respectivamente.
Por ejemplo, pred(2)=1 y succ(2)=1.
Las funciones que actan sobre enteros y devuelven un nrmero entero se pueden
\.er en la tabla 2.2. Las tres ltimas funciones y los operadores +, - y * estn lirnitados
por el rango de integer. por 1o que hay posibilidad de desbordamiento si el valor que
Jevuelven supera el lmite superior o inferior.
t4 ELEMENTOS BSICOS DE PASCAL
o En coma fija e] nmero tiene una parte entera y una parte tiaccionaria separadas
con
por un punto. Puede estar prececlido por el signo. Ejemplos de nmeros reales
esta notacin son el 3.25, el - 3.0 y el + 666'414'
nmero
Lits funciones aritmticas que operan sobre un nmero real y devuelven un
real se lnllestran en Ia tabla 2.4.
pascal carece cle algunas funciones estndar matemticas. Para hallarlas se pueden
r-rti i i z ar 1 i'rs func iones predefini das anteriores.
Trpos DE DATos Bsrcos 15
Para expresar que un dato variable es de tipo carcter se utiliza la palabra char.
3 l En':l ot tEr{t
# ri? 4:l Il 9tr l ,:
+ + End trasrrit 6rl ++ D Itlll { '1
'lf
5 05 Enquir! aa 'f q t 6! ,I5 E 1tl1 65 E
rj l:16 ,cknD$,|dgE J tr & Trl 4 E 10? 66 t
? [T ,qudilrlE h*ll t! 1 77 t? E 1r:r3 6? ,J
Backsl:ate 4n .]Fl 1a' 49 H 1rl+ EE h
'
! [l!] Horir':'rrtaltall dl lta 1 ?3+rr 1n5 6r i
1ll llA Lirre f ee,l t H ?{+AJ 1DE EA -l
11 E !/,=rti'],?ltEtr +:J E + ?5+EH 1tl? 68 k
13 0f Fr'rtrr feed { 'Jt- ?6 {rl L
13 tlt (:rriirl rtrturn 45 ZI] ?? {tr H 1ll9 ED fil
1{ l:lE Shift rrLlt {b lE ?F +E I,] 11L-r r5E rl
15 L-]F ljhift in
ra 'rF ! ?!r 4F O 111 6F ,:,
1 6 1! DHt,e link esrpe 48 l {l E0 str F 11? ?D p
1f 11 []eviEe'llrntr'll 1 {9 1 I 11 81 51 t 11f ?1 q
1E LZ [,,:\]ice t:,:,ntrol i 532Z 11{ ?? r
M3 DE\r,ic r:r:lrrtrol 3 ,]I JJ ;' tt tJ =
Z tl 1+ [],l,iLlB ,::nntr,:,| 4 52 3+ 4 { 54 T 116 ?{ r
?7 15 l,lEl]. a|:[,:rrLl\rvler]gr-' 5 35 5 E5 55 LI 1l? ?5 u
ZZ 16 5r:|1uridle 5,1 16 6 tr 6 .56 U 118 ?6 r/
3 1T End tranr hl,l,ll': :' J i I E? 5? 1 l1r '?'l r
v AU iJ
4 1B CEncel }E JI' EI
5 1!1 End
':t
mrliurrr 5? :l-1 I 89 5!r T 171 ?q r
!:r-l 5L Z i a,i, tL
3 r lA SuhBtitl{tion
1E q1 5F r 13 ?E {
3 ? EraF,l
r: 3C -; a qr \ ra aT I
ZB 1C Fil Bpart,lr
I
I
I
I
I
I
I
I
I
I
I
I
I
t
Trpos DE DATos nsrcos 17
.F tr r, tr T \Jlf
^nF\m r ------' J- NOT T+F
^t\Tn
T' .F + rF
T uI( -L -------7 -L
^\TTl
Las funciones predef,nidas que operan sobre un valor booleano y devuelven un valor
booleano se pueden ver en Ia tabla 2.8.
Evaluacin perezosa
Estos operadores sirven para comparar nicamente elementos del mismo tipo y devuel-
ven un valor booleano como resultado de la comparacin. Son operadores binarios y se
escriben en notacin infija. En la tabla 2.9 se muestran todos los operadores relacionales
de Pascal estndar.
2.4 Expresiones
LIna expresin puede estar formada por constantes, variables. funciones aplicadas a una
expresin y operaciones entre expresiones o una combinacin adecuada de estas. El
concepto de variable y constante se define en el apartado 2.7 .2.
Cada expresin tiene un tipo de dato que depende de los operandos, operadores, funcio-
nes, etc., que componen la expresin. El tipo de la expresin correctamente formada se
halla evaluando eI tipo de cada subexpresin y funcin de acuerdo a la precedencia de
1as operaciones. Si el argumento de una funcin o del operando de un operador es una
expresin, entonces el tipo de dato de la expresin ha de coincidir con eI tipo de dato
requerido para el argumento. Como nica excepcin tenemos la conversin autom-
tica de nmeros enteros a nmeros reales. En el proceso de compilacin, el compilador
comprueba la correccin de tipos y avisa si se produce un error.
prximo a x
Carcter a Enteri ord(c) Devuelve el no de orden ord('A )4 65
en la tabla ASCII del ca-
rcter c
Entero aCarctet chr(n) Derrrelve el carctet chr(72)3'+r'
correspondiente al no rz
en la tabla ASCII
- =rr r FniPrn ord(b) Demelve el nmero de ord(tnun)e 1
Los lenguajes de programacin. al igual que el lenguaje natural, tiene palabras, cada una
con un significado. Afortunadamente los lenguajes de programacin poseen un conjunto
pequeo de palabras, lo que facilita su aprendizaje y comprensin. En esta seccin
se muestra el vocabulario del lenguaje Pascal as como las instrucciones bsicas para
empezar a realizar programas sencillos.
2.7.1 Vocabulario
Palabras reservadas
Las palabras reservadas de Pascal son aquellas que tienen un significado predefinido en
este lenguaje de programacin. Por orden alf'abtico tenemos para Pascal estndar:
AND, ARRAY, BEGIN, CASE, CONST, DIV, DO, DOWNTO, ELSE, END, F]LE,
FOR, FORWARD, FUNCTION, GOTO, IF, IN, LABEL, MOD, NIL, NOT, OF,
OR, PACKED, PROCEDURE, PROGRAM, RECORD, REPEAT, SET, THEN, TO,
TYPE, IINTIL, VAR, WHILE y W]TH.
Identificadores
oNosedistingueentreletrasmaysculasyminsculas'Porejemplo.Casaesel
mismo identificador que CASA y que cAsA'
pri-
oLalongitudmximaesdel2TCaracteres.deellossolosonsignificativoslos
meros 63.
Smbolos esPeciales
concreto para el lenguaje los si-
Se consideran smbolos especiales con un significado
guientes:
Literales
Sonconstantesannimas,quenoposeenunnombrecomo'porejemplo'lascadenasde
caracteres (que son secuencias de caracteres
delimitados por apstrof'es ""')' los nme-
predef,nidas. Ejemplos de literales son
ros, 1os caracteres y las constantes booleanas ,d,y
,Esto es una cadena de caracteres,,'Los 256 caracteres ASCtrI,, FALSE' 3.1654,
-45.
Cornentarios
fuente con objeto de aclarar su
Los comentiuios son texto intercalado en el programa
contenido.Sonnecesariosparaelprogramadoryposeenlassiguientescaractersticas:
Plrl escr.jbir.un corxentario es necesario ponerlo entre 1os caracteres "1x" , "*)"
entre { } "i" Ejemplosdecomentariosson:
*:s:3 es un comentario*)
::--::anbin es un comentario)'
o\tr:epueclenanidar,esdecir,nopuedehaberuncomentariodentrodeotro'
Elnmruros ssrcos DEL LENGUAJE 23
Constantes
o Annimas: se ponen de manera literal. Por ejemplo: 5, 3.14, 'a' (son literales).
o Predefinidas: su valor viene dado por el lenguaje: pI , MAXINT, TRUE, FALSE.
o Definidas por el programador: El programador se encarga de darles un nombre
y un valor.
Variables
Son elementos que pueden cambiar su valor a lo largo de la ejecucin del programa. Son
definidas por el programador y el valor o valores que pueden contener depende del tipo
de dato con el que se define.
Las constantes definidas por el programador y 1as variables se caracterizan por tener las
si guientes caractersticas :
Asignacin
variable' La sintaxis
La instruccin de asignacin sirve para dar o cambiar el valor
a una
nombreDeVariable : = expresron
base : = 10.0
altura : = 20.0
area := base * alLura I 2
contador := contador + I
x := (--b + sqrt(sqr(b) -- 4 *a* c) ) / (2 * a)
Escritura
de datos' La salida podr ser a
Las instrucci.ones de escritura son instrucciones de salida
un dispositivo de salida
panralla. a impresora o a fichero en disco. Se asume por omisin
estndar l,fit'hero oLttpltt) que suele ser el monitor'
E stas instrucciones son en realidad procedimientos
predefinidos (ver el captulo '! de
subproqramas ). Tienen el siguiente formato:
o writeln: acta igual que write pero cuando termina de escribir el resultado
aade un salto de lnea.
Escritura formateada: para darle fbrma a la salida se puede utilizar una serie
de parmetros junto con los argumentos (expresiones) de los procedimientos write y
writeln.
write(expresion:m, .. .)
writeln(expresion:m, . .. )
Solo para expresiones reales: por omisin, Pascal muestra los nmeros reaies en
notacin cientfica. Si quiere ver ios nmeros en coma fija (con coma decimal) debe
formatear la salida. Para ello hay que aadir un nuevo modifrcador.
write(expresion:m:n, . . . )
writeln(expresion:m:n, . .. )
Lectura
Las instrucciones de lectura son instruccin de entracla de datos'
La entrada de datos
o por det-ecto
podr ser por teciado o tlisco. Se asume un dispositivo cle entrada estndar
(fichero input) qu'e suele ser el teclado.
(ver el captulo 4 de
Estas instrucciones son en realiclad procedimientos predefinidos
subprogramas). Tienen el siguiente formato:
Ejemplo:
VAR
a: char;
.i r1-aaav.
fl . rlruuYu!/
BEGIN
writeln ('rntroduzca una letra' ) ;
readln(a); {si ef usuario pulsa p e INTRO - -2 a.- P l - -.-l^/\
Encabezamiento
Declaraciones y definiciones
Se deben declarar los objetos que se van a utilizar y que no estn predefinidos en el
lenguaje. Si no se va a utilizar ningirn objeto esta parte puede omitirse del programa.
Entre los tipos de objetos que se pueden aadir estn las unidades, las constantes, las
variables, los procedimientos y las funciones.
Las declaraciones permiten al compilador reservar espacio de memoria para cada
identificador, asociar un tipo de datos (si es necesario) y veriflcar el comecto uso de los
objetos dentro del programa. El equivalente en notacin matemtica a una declaracin
es: "Sean n Entero, x R, Pi=3.14..."
Cada uno de 1os objetos se declara de la siguiente manera:
USES
ident i f i cadorUnidadl ;
ident i f i cadorUnidad2 ;
ErntrnNtos nsrcos r P'q'scA'r'
clon<leidentifrcadorUnidadeselnombredelrnduloquesevaautilizar'Se
puedenponervariosidentiflcadoresenlamismalneaseparadosporComa'','..Se
12'
estucliaran con mayor detalle en el captulo
LUI\
^^nf-m D I
identif icadorConstantel = valorl ;
= vator2
:1:".ttt",dorConstanLe2
VAR
identif icadorVariablel : tiPol ;
identif icad'orVariabl e2 : LtPo2 ;
ia;1t:-ticadorVariable4' idVariable5 : tipo3 ;
Cuerpo
que se van a ejecutar. EmPieza con
El cuerpo del programa contiene ias instrucciones
END y un Punto ".". Un
h paia reservada BEGrN y finalrza con la palabra reservada Las instrucciones (si haY
prog.*u en Pascal debe contener obligatoriamente esta parte'
ar O" una) se separan con el carcter
";"'
Cursrrours DE TrPo rEST 29
BEGIN
Instruccin1;
Instruccin2 ;
END.
3. Cul de estas afitmaciones nos indica la forma correcta de actuar cuando hay un
error?
5. El operador = es:
(a) a todos sus elementos se les puede aplicar la funcin elevado al cuadrado
(sqr ( ) ).
(b) a todos sus elementos se les puede aplicar la funcin sucesor (succ 0 ), ex-
cePto al ltimo.
(c) todos sus elementos tienen un predecesor y un sucesor'
(d) a todos los elementos se les puede asociar un nmero de orden.
2.8"2 Soluciones
l. La (b) y la (c) son correctas. La (a) es de tipo integer ya que por las prioridades
de los operadores
(3+2) - 5,
5 DIV 2 = 2,
2*5=10
FALSE<>TRUE =+ TRUE.
La (b):
NOT TRUE + FALSE.
FALSE OR FALSE =3 p-,{lp y
FALSE <= FALSE:=+ TRUE.
La (c) es falsaya que 6 DIV 2 + 3y 3 < 1 + FALSE. La (d) es falsatambin.
ya que ORD('a') < 25-5 (nmero de snbolos en ASCII) y 255 + l0 > -500..+
FALSE.
3. La (b) es correcta.
,.1
-rl Br-Brrnxros ssrcos on P.sc'r-
2.9 Problemas
2.9.1 Expresiones
1.x=y
2. odd(k) 0R odd(succ(k))
3.P = rRue
4.10DIv3=10/3
5.p , succ(p)
6.p=qORr
7. odd(n* (n-1) )
1. MAXINT _ (I{AX]NT + 1)
2. t5 Drv 2
3. 15 MoD 2
4.7s I 2
5. abs (-MAXINT)
6.sqrlsqrt(23 + 2))
-. :::: -sq:{sqrt (23 + 2))
i. -:: s:,sqr(2))
lr.:::'l:,./5-6*3+10)
__
," _ r =*r;pf3))
2.9.4 Escritura
Qu observar en pantalla cuando se ejecuten por separado los siguientes fragmentos
de cdigo?
2.9.5 Lectura
Sea el siguiente programa en Pascal. Realice una traza
completando las columnas vacas
de la tabla 2.1 2 teniendo en cuenta las entradas que
introduce el usuario.
PROGRAM Test;
VAF
d, b, c: integer;
d: real;
1, m, n: char;
BEGIN
{ii
t-l read(}, a);
{ii }
L -- l
readln (b, d, m) ;
t, {iii} read(n, c) ;
{ i"} readln;
{"} readln(a, b, c);
{"i } read (d) ;
END.
Tabla2.l2: Lectura
2.9.8 Segundos
Escriba un algoritmo y un programa en Pascal que calcule el nmero de segundos que
hay en una edad expresada en aos. das, horas, minutos y segundos.
2.9.9 Cilindro
Escriba un algoritmo y un programa en Pascal que calcule el rea y el volumen de un
cilindro que tiene de radio y altura dos nmeros enteros introducidos por teclado.
afb*c / ctib*r'
2 t, (2.t)
2.9.L3 TransPortes
para repartir sus productos' En
una empresa de transporte posee una flota cle camiones
en kilmetros. los litros de -oasolina
cada viaje. el concluctor anota la distancia recorrida
del camin' Para realizar
usados. el coste de la gasolina y los costes de mantenimiento
para cada camin y para cada
la contabilidad, eI controlador necesita calcular y registrar
viaje y el coste por kilometro'
viaje. los kilmetros recon'idos por litro, el coste total clel
para un camin y un viaje
Realizar Lln programa en Pascal que lleve a cabo estos clculos
adecuado a las salidas)'
y los presente de manera fcil de entender (clando el fbrmato
2.9.14 A maYsculas
y el programa imprima
Realice un programa que picla al usuario una letra minscula
dicha letra en mayscuias. Se suponclr que el usuario
introduce una letra coffecta (en
minscula y sin acento).
2.10 Soluciones
2.10.1 Expresiones
Carac-
l. Es corecta si ios tipos de datos que se comparan son: Boolean=Boolean'
Entero=Real. El valor ser
ter=Caracter.Real=Real, Entero=Entero, Real=Entero,
lilfsilasclosvariablescontienenelmismovaloryFALSEenelcasocontrario.
l. E,ccorecta si k Entero. El resultado es siempre TRUE'
Es correcta si p Boolean y el valor es TRUE si p vale
TRUE'
l.
-1. La expresin es correcta y el valor es FALSE'
5.EscorectasipBooleanopCaracteropEntero,elresultadoesFALSE.
L
Sor-ucrouns JI
1. La expresin es errnea debido a que el operador pred solo acta sobre tipos
ordinales y la expresin ( -sqr (sqrt (23+2) ) ) es de tipo real'
8. La expresin es entera y el valor que devuelve es I 7.
2.10.3 Sintaxis
{r} rnocnaM erroR
Contiene un error ya que falta ; aI final.
{ri
L'l
rnp
Es correcta.
{e} tetra:char;
Es correcta.
r38 ELEMENTOS BSICOS DE PASCAL
f o \ orr:rrr
l, J ulurr!
Es correcta.
tr } readln (div) ;
{
Es errnea ya que div no es un identificador vIido. Si se
hubiera cambiado por otro identificador vlido Ia instruccin
sera correcta.
T, ^
j rl I 1
ALPna: =:;
Es correcta.
{ t: } Beta: =alpha + 1;
Es correcta.
Es correcta.
{ rl } suma: =letra+45;
Es errnea. La expresin letra+45 es errnea, ya que intenta
sumar un carcter y un nmero.
{zr} ruo
Contiene un error. Falta un punto final.
2.10.4 Escritura
Si el carcter b representa un espacio en blanco, se mostrar por pantalla:
l. bbb23 .46
3. bb4 5
0.004Obbbbbb77
3.7500000000E+01
2.10.5 Lectura
La tabla 2. 13 est completa con los resultados de la traza del programa propuesto.
RAD]ANES A GRADOS
VAR]ABLES
Grados: numero real;
Radianes: numero real;
IN]CIO
40 ELEMENTOS BSICOS DE PASCAL
I m n Entrada Salida
Instr a b c d
'l :') :') 'l
(r'
;'l ')
b'
;'l
(J'
0 (r' (J'
b' L'
,,) :'l
(,' ;'l ,a, J
'
..)
Ll a5'7 5 +'
I 5 l,' (J'
a i) 5.0
,a, +J 'l hola .-
5 (,' (J'
l1
5 1 1 5.0
,a, J 31 43 51 *'
111
,a, J
lV 5 1 1 5.0
5.0
,a, J 10 20 80 +-
10 20 80
80 0.3e4 'a' +r -) 0.3e4 +-
Vi 10 20
Leer radianes; lI
grados=radianes* 18o / i
Calcular grados equivalentes {
Mostrar grados
FIN
GMDOS A RADIANES
VARIABLES
Grados: numero reaf;
Radianes: numero rea];
INIClO
Leer grados; . "^- ,- - al
Calcularradianesequivalentes{radianes=grados*PIl180}
Mostrar radianes
FIN
PROGRAM Radianes2Grados ;
VAR
grados, radianes: real;
i
Sor,ucroNrs 41
PROGRAM Grados2Radianes ;
VAR
grados, radianes: rel;
VAR]ABLES
Aos, dias, horas, minutos, segundos: numeros enteros;
IN] C IO
LCCI :no.
^] -^
Leer UI4D, -
LECI horas;
Leer minutos;
LCCI segundos;
2.10.9 Cilindro
Algoritmo:
CONSTANTES
PI = 3.14;
VARlABLES
Radio: Nmero entero;
A1tura: Nmero entero;
at.'-r^
AI ed : I\ Ll..rCI U ra:'
! Eo- .
7
Volumen:Nmero real-;
]NICIO
Leer eI valor del radio;
Leer eI valor de Ia altura;
Calcular eI area; {area=2*PI*radio*altura}
Mostrar el valor del area;
CaIcular el volumen; {volumen= PI*altura*radio2}
Mostrar e1 valor del volumen;
FIN
Programa en Pascal:
PROGRAI{ Ci L:-ndro;
-: l::-::r:-re PI esta predefinida en eI lenguaje por lo que no
:a:: :a-:a declararla de nuevo)
-:-:
:ij- - alcura: inceger;
-.:aa , ,.:olumen: real ;
readln (radio) ;
writeln('Introduce el- valor de la altura:
readln (altura) ;
area := 2 * PI * radio * altura;
writeln('EI area es: ', area:0:0);
volumen := PI * altura * sqr(radio);
writeln('El volumen es: ', volumen:0:0);
ENIJ . tPrograma prlnctpal J
PROGRAM PolinomioGrado2 ;
VAR
1, d2, a0, p, x: integer;
BEGIN {Programa principal}
writeln ('Teclea 3 valores enteros correspondientes a los
'3 coeficientes de un polinomio de grado 2: ') ;
readln(a0, d1, a2\;
writeln('EI polinomio es ', d2, 'x^2+' , aI, 'x+' , a0);
write('Teclea un valor entero para x: ');
readln (x) ;
p:=a2 *sqr(x) +a1 *x+a0;
writeln(' E] valor de P(', x,') es: ', p);
END. {Programa principal}
VARIABLES
, b, ct s/ aux:numeros reales;
INICIO
Leera,bYc;
Calcular aux;
J",,--/:+h+c)
"' l2
esLe valor se d'enomina semipermetro)
ldu^-\ur!
Calcular S;
(vaux* (aux-a) * (aux-b) * (aux-c) ) }
,
El Programa en Pascal:
VAR
- 1^ qeminerimetro, superficie: real;
<tt Pt u, uuLLr!.!'
readln\?, b, c\;
semiperimetro := (a + b + c) I *
(semiperimetro - a) *
superficie: = sQrt (semiperimetro *
- b) (semiperimetro
(semiperimetro
11:3 ) ;
writeln ('La superficie es: ' ' superficie:
END. {Programa PrinciPa}J
Algoritmo:
CONSTANTES
e1 14%)
PARA_GOBIERNO=0.14; {UI gobierno se queda con
PARA_HIPODROMO = 0.09; {rr nipoaromo con ef e%)
PARA GANADOR = 0'5; {lara
el ganador un 50%}
i*"-ttr = o.r, in"' eI sesundo un un
3o%)
VARIABLES
LotalAPostado, totalPrimero, totalsegundo'
\
T
Sorucroqus 45
-NICIO
Leer rotalApostado;
Leer numPrimero y apPrimero;
Leer numSegundo y apSegundo;
Leer numTercero y apTercero;
Calcular el dinero que se reparte;
{paraRepartir: = totalApostado - tota}Apostado*PARA GOBIERNO
totalAposLado* PARA_HI PODROMO i
Calcular el dinero para los que han apostado al prmero ;
{totalerimero := paraRepartir * PAM_GANADOR}
Calcular eI dinero para los que han apostado al segundo ;
{totalsegundo := paraRepartir * PAM_SEGUNDO}
Calcular el dinero para 1os que han apostado aI tercero ;
{total.Tercero := paraRepartir * PARA_TERCERO}
Calcular el dinero que gana una persona que haya apostado 20
euros al primero;
{ganaPrimero := totalPrimero*APUESTA/aplrimero} ;
Calcular eI dinero que gana una persona que haya apostado 20
euros a1 segundo;
{ganaSegundo : = totalsegundo*APUESTA/apSegundo} ;
Calcular el dinero que gana una persona que haya apostado 20
euros aI tercero;
{ganaTercero := totalTercero*APUESTA/aptercero} ;
Mostrar numeros de caballos ganadores, {numPrimero,
numsegundo, numTercero) y Io que gana cada caballo
{ganaPrimero, ganaSegundo, ganaTercero}
FIN
Programa en Pascal:
CONST
PARA_GOBIERNO = 0.14; {eI gobierno se queda con e1 14?}
PARA*HIPODROMO = 0.09; {rf nipOaromo con eI 9?}
PARA_GANADOR = 0.5; {nara eI ganador un 5O?}
PARA*SEGUNDO = 0.3; {fara el segundo un 30%}
PARA_TERCERO = 0.2; {lara el tercero un 2O?;}
APUESTA = 200;
VAR
totalApostado, premios, apuestaPrimero: real;
paraPrimero, apuestaSegundo, paraSegundo,
apuestaTercero, paraTercero : real ;
premioPrimero , premioSegundo, premioTercero : real ;
idPrimero, idSegundo, idTercero: integer;
:=r:-:- _jlercero) ;
,,,--:= '=::ribe la cantidad apostada a cada uno: ') i
: =, : -:-
': ::staPrimero / apuesraSegundo, apuestaTerCero)
*
;
:i:.:-.s := totalApostado - totalApostado PARA_GOBIERNO -
totalApostado * PARA_HIPODROMO;
:::al:-:::19 1= premios * PARA_GANADOR;
c=:=:=:*:jc ;= premios * PARA SEGUNDO;
ia:a-..:=re '= premios * PARA TERCERO;
\
Sor,ucroNBs 11
2.10.L3 Transportes
Se necesita saber:
PROGRAM EmpresaCamiones ;
{SafiAa: La saliCa ser una lista que muestre los km. por
litro, el coste total y el coste por km.)
11 D
2.10.14 A maYsculas
PROGRAM CambioMaYusculas ;
{Ontrada: una letra minscu1a}
a mayscu1a}
{Proceso: Cambiar una letra minscula
{satiaa: La salida ser la leLra mayscula}
CONST
DIFERENCIA = ord('a') - ord('A');
VAR
mnuscula, maYuscula: char;
BEGIN {Programa PrinciPal}
write('Escribe Ia letra en minscula: ');
readln iminuscula) ;
:lt-"-s--:-a := chr(ord(minusculal - DIFERENCIA) ;
',';:r::-: '-a letra en mayscula es: ' ' mayuscula) ;
-- - - i - -
Instrucciones estructuradas
3.1 Instruccincompuesta
La instruccin compuesta permite describir un bloque de instrucciones. En Pascal em-
pieza por la palabra BEGIN, seguida de una secuencia de instrucciones separadas por
e1 carcter ";" y flnaTiza con la palabra END. Esta instruccin se suele utilizar en com-
binacin con instrucciones de seleccin y de iteracin (que se vern en las siguientes
secciones de este captulo). La figura 3.1 muestra dos bloques anidados, donde el bloque
I .1 es una instruccin compuesta que forma parte del bloque 1.
Este tipo de instrucciones son estructuras de ccntroi que perrniten eiegir ciinmieameilte
(en tiempo de ejecucin) entre ciil'erentes secuencias de instrucciones. Fascal propor-
ciona dos instrucciones de este tipo: IF' y CASE.
49
50 INSTRUCCIONES ESTRUCTURADAS
bloque 1: 4 instruccianes
BEGIN {bloque 1}
wrrte{'Introduzca x. y');
readln(x, y).
BEGIN {L,lcque 1 1}
AUX,=X, _= _.-I
"'
Y.=OU i
END; {bloque I 1}
writeln{'x, Y =',x,',',Y)
END; {bloque ll- |
iul"q*rc
Figura 3. 1 : Instrucciones compuestas anidadas.
La instruccin IF
La sintaxis de esta instruccin es la siguiente (las expresiones entre corchetes son opcio-
nales):
:!GIN
-=aJ--- ^t I t
I
::--_-,
,. -t.
at,- -:.,
: -s:
::: -:.
I
I tl
i;:r:e-n('81 mximo es ', max);
I
i:
t
INsrnuccroNES DE snrBccrN 51
uun lnrcnl
END;
La instruccin CASE
CASE <expresin_selectora> OF
<etiquetal> : <Instruccin1>;
<etiqueta2> : <Instruccin2> ;
<etiquetaN> : <InstruccinN> ;
IELSE
< InstruccinELSE> ;l
END {CASE}
CASE opcion OF
1. .15: writeln ('Primera Quincena' ) ;
76 t writeln ('Primera Prueba') ;
l1 . .29: BEGIN
writeln ('EsLo es una instruccin compuesta') ;
writeln ('Segunda Quincena' )
END;
30,31: writeln ('segunda Prueba' ) ;
ELSE
writeln('valor erroneo' ) ;
END icASE)
52 INSTRUCCIONES ESTRUCTURADAS
Instruccin WHILE
WHILE <exPresin-booleana> DO
< instruccin>
sea cierta
La semntica de esta instruccin es: mientras que <expresin-booleana>
se ejecuta <instruccin>. Este tipo de bucles se
denominan bucles preprobados (son
el cuerpo) y permiten la
bucles que primero se er,ala la condicin y luego se ejecuta
(si la primera vez que se evala la
posibilidad de que su cueryo no se llegue a ejecutar
el clculo de la suma de
condicin es falsa). El siguiente fragmento de cdigo muestla
los n primeros nmeros meciiante un bucle WHILE. La
variable suma almacena la suma
el nmero a sumar'
parcial en cada iteracin rlei bucle y 1a variable contador almacena
BEGrN ibroqueJ
::eacln iir :
-.:-aa):: := -;
,:-- E concador <= n D0
--Il-\r
SUmA "= SUTL -' COnCadOr;
contador := conLador + -L
Instruccin REPEAT
REPEAT
<instruccin1>;
<instruccinN>;
L\ITIL <expresin booleana>
La semntica de esta instruccin es que se ejecutarn las instrucciones del cuerpo del
bucle hasta que <expresin_booleana> sea cierto. Este tipo de bucles se denominan
postprobados (son bucles que primero ejecutan las instrucciones de su cuerpo y luego
comprueban su condicin de finalizacin) y aseguran que su cuerpo se ejecutar siempre
(como mnimo una vez). A continuacin se muestra un fragmento de cdigo que utiliza
esta instruccin.
BEGIN {nroque}
readln (n) ;
qllm: '= n'
contador : = 1;
REPEAT
Suma := stlllld + contador;
conLador := contador + 1
UNTIL contador > n;
writeln ( suma)
eND {b}oque}
Instruccin FOR
La sintaxis de esta instruccin es la siguiente:
.- n.
bULllA -_ u,
FOR contador := 1 T0 n D0
suma := suma + contador;
writeln (suma)
END; {nfoque}
Las expresiones <expres in-ini -
La variable contador slo puede ser de tipo ordinal'
de la variable
cial> y <expresin_fina1, deben sei tipos compatibles con el tipo
contador.
PascalproporcionaunaversindeFoRqueenlugardeincrementarlavariable
la siguiente (note que cambia
contador en cada iteracin la decrementa. Su sintaxis es
la palabra reservada TO por DOWNTO):
3.4 Recomendaciones
a la hora de utiltzar instrucciones
Algunas recomendaciones prcticas que se proponen
estructuradas son:
6.Elegirlainstrucciniterativaadecuadasiguiendolassiguientesreglas:
3.5.1 Enunciados
Las siguientes cuestiones pueden tener una o ms respuestas correctas:
IF Condicin1 THEN
IF Condicin2 THEN
Instruccin1
ELSE
InsLruccin2
VAR
varResul: -nLeger;
varlndi : r:e I;
BEG]N
varRes.rl . - 1,
FOR varindi := 1 T0 3 D0
varR.esul := varResul * 2;
writeln (va.rResul ) ;
END.
-'.- ,,
WHILEA<5DO;:
a := a + 1;
(a) 5.
(b) 3.
(c) lnfinitas'
(d) Ninguna.
(a)SlounaVeZdebidoaqueelsegundolFestf'ueradelbucleFORy,porlo
tanto, se tealiza una nica vez'
(b)NoseejecutanuncaporqueproduceunelTordecompilacin(faltaBEGINy
:l'T al bucle FOR).
r ) Se ejecuta
c dos veces'
(d) Se ejecuta tres veces'
6. Qu muestra por
pantalla el siguiente cdigo?
I"IAR
a. integer;
char;
Pnosr,rN{as 57
BEGIN
i := 10;
FOR c := 'd' DOWNTO 'a' D0
BEGIN
- := i - i;
write(i:3)
END
END.
3.5.2 Soluciones
Las respuestas correctas son:
1.b.
2.d.
3.a y d.
4.c. Notar que el cuerpo del bucle I/HILE est vaco.
5.c.
6.c.
7.d.
3.6 Problemas
3.6.1 Nivel medio de ruido
Para calcular el nivel de ruido de una calle de una ciudad se realizan 4 medidas, una cada
8 horas, en un punto concreto. Si la media de las medidas del nivel de ruido supera la
mxima admitida (por ejemplo, MAXIMA = 4) signif,ca que el ruido es nocivo para la
J
58 I,{srnuccroNES ESTRUCTURADAS
salud. Escriba un programa que calcule el nivel medio de ruido de una calle y determine
si el nivel de ruido es nocivo o es admisible.
Un banco antes de conceder un prstamo a 20 aos comprueba los ingresos del solici-
tante. Si los ingresos son superiores a 12000 euros anuales el crdito se concede. Si
los ingresos son inferiores a 12000 euros anuales pero superiores a 10000 euros y est
soltero el crclito se concede. Tambin se le concede si tiene ingresos entre 12000 y
10000 euros y est casado sin hijos. Escriba Lrn programa que pida los ingresos anuales,
el estaclo civil del solicitante y si tiene hijos y diga si se 1e da el crdito o no.
3.6.3 La calculadora
Implemente un programa que simule una calculadora. Mostrar el men siguiente:
l. Sumar
2. Restar
3. Multiplicar
4. Dividir
0. Terminar
Escriba un programa que imprima los 20 primeros numeros impares y sus cuadrados.
Escriba un pro-srama que lea y sume hasta que haya sumado 10 valores de datos o hasta
que lea un valor negativo, cualquiera que sea el primer valor.
3.7 Soluciones
3.7.1 Nivel medio de ruido
PROGRAM NivelRuido;
{Ca1cu1a el nivel de ruido y determina su peligrosidad}
{uNtRana, 4 medidas del nivel sonoro}
iSALIDA: Si el nivel es nocivo o admisiblei
I _ ___
-_
CONST
NIVELMAXIMA = 4;
VAR
ruidol , ruido2, ruido3, ruido4 : reI;
media : real;
BEGIN {Programa Principa}}
writeln ('Escribe 1a primera medida: ');
readln (ruidol);
writeln ('Escribe 1a segunda medida: ' ) ;
readln (ruido2);
writeln ('Escribe Ia tercera medida: ');
readln (ruido3);
60 INsrnuccroNEs ESTRUCTURADAS
PROGRAM Banco;
{catcula si se concede un prestamo}
{rurntoa, sueldo, estado civi1, n" hijos}
{salrna, Concesin o denegacin}
CONST
INGRESOS= 12OOO; {ingresos sufic:-entes}
INGRESOSMIN= lOOOO; {lngresos mnimos imprescindibles}
VAR
sueldo: real; {rngresos brutos anuales}
casado: boolean; {estado civi'l),
hijos: integer; {Nmero de hijos)
letra: char;
iT,GtI\
':--'e-n ('EsLado civit (s-Soltero' c-casado) ');
::acrn (letra);
.-:,saio : = (Ietra='c' ) OR (letra = 'C') ;
-: l;CT casado THEN
'",:lteln ('Se le concede eI crdito')
:-S E
:r l:ll
writeln ('Numero de hij os I ') ;
:eadlnrhrjos);
Sor,ucroNns 61
rF rhijos = o) THEN
writeln ('Se le concede el prstamo')
ELSE
writeln ('Crdito denegado' )
3.7.3 La calculadora
PROGRAM Calculadora;
{Simula una calculadora con las 4 operaciones bsicas}
{ullrnaoa: operacin y operandos}
{Salroa, resultado de Ia operacin}
VAR
vPr
^^^.i^-.
JUrr . ^1"--.
urrq! ,
ios 20 nmeros impares). Se ha utilizado un bucle FOR porque se sabe a priori el nmero
exacto de iteraciones (no cambia en tiempo de ejecucin)'
PROGRAM ImPares;
{uscribe los 20 primeros impares y sus cuadrados
usando}
inNtRaoa, i
{sarroa, 20 primeros impares y sus cuadradosi
VAR
cont: integer;
BEGIN {Programa PrinciPa-i
writein ('Nmero, Cuadrado') ;
FOR cont:=0 TO 19 D0
writeln(!*gont+1:4, sqr(2 * cont + 1) :9);
read.ln;
:'-'.J . Progran, princrPa- )
;!.OGRAM SumaNumeros;
Suma los 1-0 primeros numeros o hasta que se introduzca
.rn numero negativo)
:NTRADA: Ios nmeros)
:ALIDA: La suma de los nmeros)
--D
:-ROGMM HorasyMinut.os ;
,'rmprimir las horas del da de 10 en 10 minutos)
iuurntna' )
iSalfOa: una tabfa con todas las posibles horas y 10 minutos
del da agrupados en 6 columnas. )
CONST
llopAMAY- ',t .
'
MINUTOSMM= 60;
VAR
hora, minutos: integer;
mediodia: char;
64 INSTRUCCIONES ESTRUCTURADAS
BEGIN
minutos : = 0;
WHILE minutos < MINUTOSMAX DO {escribe una hora)
BEGIN
write (hora:2,':');
IFminutos=0THEN
write ('00' )
ELSE
write (minutos) ;
write (' ' ,mediodia' ' .M. ');
minutos := minutos + 10;
END; {minutos}
writeln;
hora := hora + 1;
IF (hora > HORAMAX) AND (mediodia='A') THEN
BEGIN
hora: =1;
n'.edrodia:='P'i
END;
END; iwurlnJ
readln;
END. {Programa PrincrPal}
PROGRAM Mcdiv;
algoriLmo de Euclides}
eI
{ttallar el m.c.d. mediante
inn'tnora, dos enteros Positivos) nmeros)
ir*roo, eI no m.c'd' de los dos
VAR
dividendo, divisor, resto: integer;
auxiliar: integer; {eara hacer el ntercambio}
BEGIN {Programa PrinciPal}
REPEAT {Co*p.'eU' que los dos
son positivos}
SolucroNns 65
{comienza en e1 Posible
divisor mayor excluido 1i
FOR indiceDiv := (indice div 2)
+1DOWNTO1DO
if (indice mod indiceDiv = o) THEN
Subprogramas: procedimientos y
funciones
61
68 SunpnocnAMAS: PRocEDrMrENTos Y FUNCToNES
sucesivos)'
para hallar un algoritmo sencillo que los solucione (mtodo de refinarnientos
algorit-
Una vez llegado a este punto se escriben subprogramas que implementn estos
para resolver el problema ori-
mos y se cornbinan de manera adecuada en un programa
cada
ginal. Este mtodo se combina con el diseo modular, que consiste en solucionar
un problema
iubproblema de manera independiente al resto, para hallar la solucin a
complejo y/o extenso.
para realizar de manera correcta el diseo descendente y modular de un programa se
han de seguir los Pasos siguientes:
que
l. Escribir un algoritmo, posiblemente con pasos c1e alto nivel de abstraccin,
resuelva el problema. Este algoritmo ser el programa principal'
paso complejo ser
2. Descomponer catla paso complejo en otros ms simples. Cada
un subprograma.
3. Descomponer sucesivamente los pasos ms simples (tambin sern subprogra-
Pascal (o
mas), hasta que la traduccin de los pasos sea "inmediata" al lenguaje
a
4.2 Subprogramas
para facilitar
La utilizacin de subpoglilmes nos permite agrupar y ocultar infbrmacin
realizar estas tareas
el clesarrollo Y el mantenimiento c1e un programa. Para que se puedan
se cleben curnplir 1os siguientes princrpios:
o Evitar escribir ttn mismo conjunto de instrucciones en varias zonas del programa
principal.
o Poder trabajar en equipo.
o Verificar la correccin de un subprograma, independientemente del resto de sub-
programas y del programa principal.
. :.OGRAM NombrePrograma ;
]]NST
{neclaracin de const.antes} ;
-'- 5
{Dec}aracin de variab}es} ;
pueden ver como variables propias de los subprogramas (locales), que se van
a utilizar para guardar temporalmente los datos que se reciben.
o si la respuesta es ilo, entonces los datos que necesita se obtienen dentro del
subprograma. bien por teclado, o bien por clculos internos. se declaran
como variables locales.
Al final de este paso est en condiciones de escribir las cabeceras de los subpro-
gramas.
pensar qu
Una vez que se tienen claros los plllltos primero y segundo' se pasa a
instruc-
pasos o qr inrtru..iones se tienen que ejecutar en el subprograma. Estas
ciones constituyen el llamado ('ue rpo del subprograma'
o Encabezamiento de subPrograma'
o Declaraciones.
o Cuetpo del subPrograma.
las siguientes
Bsicamente (r,er figura.1. I ) es como la estructufa de un programa, con
diferencias:
ieclaraciones )
:IGIN {idenrunc}
{cuerpo de insLrucciones }
:liD; {idenrunc }
Para un procedimiento se sigue la siguiente sintaxis:
_l
BEGIN i }denProc ]
{cuerpo_l de instrucciones}
END; tldenProcJ
IdenFuncin [ (l,istaparmetros) ]
IdenProc [ (ListaParmetros) ]
de una expresin' Cuando
La llamaria de tnafunciir se realiza generalmente dentro
llamada a una funcin' se de-
un programa (o s,bprgrama) en Prscai se encuentra una
y se inicia la ejecucin de
tiene cle manerr temp.',ial (1a ejecucin se queda suspendida)
clescle e1 BEGIN del cuerpo de la
1a tnncin. La fnnciln ejecuta iockts las instrucciones
es el ltimo valor dado al
funcrrin hasta que encuentra el END. El valor que devuelve
la funcin devolver valores ba-
nontbre de Ia tuncin. si no se le asocia ningn valor.
de la funcin' se sustituye
sllrir (\ elttles desconociclos). Una vez terminada la ejecucin
principal (o subprograma) de
1 lluntada por el'nalor clevuelto y continua el programa
m i-1n e l i,i l-tt-,ttll a1.
como una lnstrucclon en
Lr, Llrladr a tn p1tceclimientt (ver figura 4.2.) se tealiza
pascrl. en un1 lnea el programa (t). Cuando el pro-erama encuentra una llamada a un
proce drnriento. eI programa principal se queda suspendido y se inicia 1a ejecucin del
desde el BEGIU hasta
p.oc.-,,1i,li.nto (2). El procedimiento ejecuta toclas las instrucciones
Plnurrnos -1
t-)
l END. Una vez terminada la ejecucin (3), el programa principal recupera el control y
continua normalmente.
trRGR}I,1
de*laraci<:nes
FE*EOF.E P tparametr&l l
I
decLara*i<:n*s I t
I 1
BEIt'l
tli I t
instru*ci.an*s I I
* 1
1 i1.]
BEGIH
{jJ 1
t
I
P{};- ---}
END.
1.4 Parmetros
Los parmetros son el medio natural de paso de infbrmacin entre subprogramas. Siem-
tre que se requiera algn dato externo al subprograma o que se vayan a exportar datos
hay que hacerlo mediante el paso de parmetros. Estos elementos esenciales en la pro-
_sramacin modular se pueden clasiflcar segn varios criterios. Si la divisin se hace
.Ltendiendo al h"rgar donde se encuentren se tienen:
oEnlallamada:pueilenservariables,Constantesoexpresionesdelmismotipo
(vercaptulo6apartado6.6deCompatibilidaddetipos)queelparmetroCorres-
pondienteqo",""n.,"ntraenlacabecera.SihayvariosvanseparadosporComas.
las variables:
o En la cabecera del subprograma: se declaran igual que
identificadorParametro : tipo
Sihayvariosparmetrosdedistintostiposvanseparadosporpuntoycoma',;''
Comosemuestranenestascabecerasdesubprogramas:
En la llamada: deben ser variables de tipo idntico (ver captulo 6 apartado 6.6
de compatibilidad de tipos) que el parmetro correspondiente que se encuentra en
la cabecera. Si hay varios van separados por comas.
[:. En la cabecera del subprograma: igual que las variables, pero ante-
se declaran
cedidos de la palabra reservada VAR.
Ipo Si hay varios parmetros de distintos tipos van separados por punto y coma ";"
hr..t-
como por ejemplo:
B[:'r1S.
Como se observa en el segundo ejemplo, si los parmetros son del mismo tipo van
E-: . separados por coma ",".
4.5 Bloques
i' -Lores Se considera bloque al fragmento de cdigo que est entre la cabecera del programa y el
|
-,,,-t .. final del programa, o al fragmento que se encuentra entre la cabecera del subprograma
f =,.*u y el flnal del subprograma. Por 1o tanto, existen tantos bloques como subprogramas ms
:r.rda, el bloque del programa principal.
[
ts- tros
oldentiflcadoresglobales:seencuentranenlapartededeclaracionesdelprograma
princiPal.
se encllentran o en la
cabecera o en
o Identificadores locales a un subprograma:
subprograma'
la parte de declaraciones del
oldentificadoresnolocalesaunsubprograma:estosidentiflcadoressoloexisten
cuandoseproduceuniu*i"ntodesubprogranras(un^subprogramaSeencuentra ex-
qu" cleclaratlos en un subprograma
dentro de otro). Los identificaclores "rin interno'
no locales al subprograma
terno son identificatlores
el paso de parme-
Serlicequesehaproducidounefectcllateral.o*d::".l'ovocauncambioenunao
subprograma sin utilizar
o no locares a un
r.arias r,ari.bies globales valores a variables
tros. por 1o ranro solo ocurren
denrro;;';" ;";p;grama al asignar
.\ternas a este subprosrama
ou
'u'iui"'
et""^r"'l::::*:T:'#,"1,""it"3t:'::
se usan siempre paral
.rrnsisue si cientro e un subprograma
:ubPrtr clallla'
(a) Todas las variables que se manejen en el procedimiento deben ser globales.
(b) Todas las variables que se manejen en e1 procedimiento deben ser locales al
mismo.
(c) La comunicacin del subprograma con el exterior se debe realizar exclusiva-
mente mediante parmetros.
(d) Slo deben utilizarse parmetros si hay conflictos de nombre con los varia-
bles globales.
3. Los subprogramas:
(a) Sirven nicamente para complicar ia programacin.
(b) Se deben poder verificar. probar y depurar independientemente.
(c) Siempre tienen, al menos. un parmetro, ya sea por ref-erencia o por l'alor.
(d) La llamada a los subprogramas se realiza siempre en el programa principal.
1. Si se quiere realizar un subprograma que reciba dos cantidades enteras y depen-
diendo del valor de una variable booleana pasada como parmetro. sume o reste
a la primera cantidad la segunda, y devuelva esta primera cantidad actualizada. ia
cabecera ms apropiada ser:
boolean)
saldo(cantidad: integer; ingreso:
;
(c) FUNCTION
(a)Lavigenciadeunavariablecorrespondealbloqueenelquesehadefinido.
y exteriores a 1'
y a todos uqoJlo' bloques interiores
(b)E1mbito(lavisibilidad)deunavariablecorrespondealbloqueenelque
l que no contengan
se ha definid"l V i".r
quellos bloques interiores a
" un objeto con el mismo nombre'
una declaraciOn e
(c)Lavigenciadeunavariablecorrespondealbloqueenelquesehadefinido.
exteriores a l'
y a todos aquellos bloques
(d)E,lmbito(lavisibilidad)deunavariablecorespondealbloqueenelque
bloques interiores a 1'
se ha deflnido, y u too' aquellos
(son) correcta(s)?
siguientes afirmaciones es
6. Cul(es) de las
(a)Lavigenciadeunavariablecorrespondealbloqueenelquesehadefinido.
(b)Elmbito(lavisibilidad)deunavariablecorespondealbloqueenelque
a 1, independientemente
se ha definiio; o ioo, aquellos bloques inreriores
delidentificadordelosobjetosqu".nnt"nganlosbloquesinteriores.
siempre coinciden'
(c) La vigencia y el mbito de una variable
(d)Eimbito(lavisibilidad)cleunavariablecorespondealbloqueenelque
seha<lefinido,siempreycuandonoexistaotravariabledefinidaenunbloque
exterior a 1'
de una variable coinciden
cuando:
7. La vigencia y ei mbito
(a)LavariableestarleflnidaenunbloquequenoContieneningnbloqueinterior
a 1.
que puede-contener otros bloques
(b) La variable esta definida en un bloque
interioresal,yestosnocontienen,nu".tu.u.indeunidentificadorigual.
(c t SiemPre'
ld) Nunca'
??CCEDURE lncrementarC ;
. .= succ(c) ;
CuBsrroNBS DE TrPo rEST
END;
:(
\
(a) Es un procedimiento sintcticamente correcto y evita los efectos laterales.
(b) Es un procedimiento incorrecto y lo detecta el compilador'
(c) Se produce un efecto lateral al modiflcar una variable no local'
(d) Puede ser incorrecto si c es una variable entera y tiene un valor negativo'
BEGIN
write (c) ;
C := C + 1
END;
erclclo (a, r)
El
write (a, r) ;
, rl
END. {Programa Prfnclpar I
Y FUNCIONES
80 SUBPROGRANIAS: PROCEDIN,IIENTOS
ercicio (n k)
(a) La llamada a E ercicio es incorrecta' Debera ser: Ej '
'
correcta/s:
t2. Seale la/s afirmacin/es que sean
a un procedimiento los parmetr"'t"".t":.::: sustituidos por
(a) En una llamada por los de
los parmetros lbrmaies y 1os parme"o' po' valor son sustituidos
referencia.
(b)Enunallamadaaunprocedimientotodoslosparmetrosrealessonpasados
por valor.
parmetros pueden ser por valor o
(c) En una llamada a un proceclirniento los
por referencia'
los parmetros por valor son copiados
a
(t1) En una llamada a un procedimiento
tlna nueva zona de memoria'
(a)Sonmuyconvenientesporquemejorannotablementeladepuracinyverifl.
cacin de Programas'
(b)Seproducenalasignarvaloresavariablesglobalesono-localesaunsubpro-
grar]1a dentro del subPrograma'
{C)ocurrensiemprequeserealiceunallamadaaunatuncindesdeelcuerpo
de un Procedimiento'
td)Ocurrencuandounsubprogramainfluyedirecmmenteenelestadodecmput,.
deotrossinqueestosef'ectosseanproducidosporelpasodeparmetros.
1.10.2 Soluciones
l.Larbi'la(c)soncortectas.La(a)estotalmentecontrariaalasrecomendaciones.
(b) evita ios ei-ectos laterales" por io tanto
\ a qrl. produce et'eetos laterales. I-a
CuBsrroNBs DE TrPo rEST 81
es cor:recta. La (c) garantiza que los subprogramas sean autnomos, por lo que es
correcta. La (d) es errnea, ya que el uso de parmetros no depende de que existan
o no conflictos de nombre. sino del intercambio de informacin.
4. La (b) es cor:recta. La (a) es falsa porque los subprogramas nunca empiezan por la
palabra reservada PROGRAM. La (c) es errnea debido a que la funcin solo recibe
una cantidad entera (cantidad) y segn el enunciado debe recibir dos. La (d) es
poco apropiada ya que que todos los parmetros son por referencia. lo que indica
que todos van a ser modifrcados 1o cual, segn el enunciado, es falso.
5. La (b) es colTecta. La (a) y la (c) son errneas debido a que una variable no esta
siquiera definida en los bloques exteriores. La (d) es falsa, ya que una variabie no
es visible dentro de un bloque interno que contenga otra variable o un parmetro
con el mismo identificador.
7 . La (a) y la (b) son correctas. La (c) y la (d) son errneas ya que existen casos en
Ios que coinciden y tambin existen casos en los que no.
8. La (c) es correcta. La (a) falla porque no evita los efectos lateraies al modificar
una variable que no es local. La (d) es falsa debido a que si la variable c es entera,
el procedimiento es correcto para cualquier valor de c negativo.
9. La (a) y (c) son correctas. I-a (b) y ia (d) son incorrectas porque justamente
1a
en el caso de que el subprograma tenga un rnico parmetro de salida (indepen-
dientemente de su tipo, excepto para tipos compuestos o complejos todava no
estudiados) se r:ecomiencla el uso de una funcin.
10. La (d) es correcta. EI procedimiento Pro posee un parmetro por referencia, por
1o que en la llamada debe ser hecha con una variabie. En la trlamada Pro (4 ) , el 4
es una constante, por lo que el compilador al realizar la comprobacin 1o detecta
SuspnocnANIAS: PRoCEDIN{IENTos y t t\cIoNES
t2. La (c) y la (d) son correctas. La (a) es errnea ya que los parmetros por valor no
se sustituyen por los parmetros por referencia. La (b) falla. pues los parmetros
pueden ser por valor y por referencia, pero no nicamente por valor.
13. La (c) es correcta. Las variables no-locales a un subprograma surgen cuando hay
anidamiento de subprogramas. Estas variables se pueden usar entre otros sitios,
en el bloque en las que estn declaradas, 1o que hace a (d) falsa. Pueden causar
ef'ectos laterales si se modiflcan dentro del subprograma sin paso de parmetros.
Por lo que (a) es errnea.
4.ll Problemas
4.11.1 Toro
Implemente un programa en Pascal que escriba por pantalla la siguiente palabra: TORO.
La palabra debe aparecer en vertical:
T
o
R
o
y cada letra debe estar compuesta por el carcter 'O' segn la tabla 4.1
T o R o
00000 000 0000 000
0 00 0 0 00
0 o0 0000 o0
0 oo 00 00
0 000 0 0 000
PROGRAM Secuencial;
{Onletivo: Probar procedimientos}
VAR
=
4t
1-,. i--^^^-.
p.
result: integer;
PROCEDURE Primero (VAR suma: integer; num, num2:integer);
{Onjetivo: Devolver l-a suma de num - r,,-rl
{eRn, uinguna}
{losr: suma=num+num2}
BEGIN {erimero}
_ SUma := num + nUm2;
END; { erimero}
read-Lnia, D);
*^-,,1r .- L,
Segundo (result) ;
writeln (result) ;
Primero(resuit, a, b)
writeln (result) ;
END. {Programa PrinciPal}
Couoejemplo,lapaiabraEXAMENcifradaconesaclaveesltsEQiR'
para 1a resolucin simplihcada del problema se supondr que todas las
letras irn en
atfabtico'
ma'sculas v no habr ningn smbolo que no sea
Pnonr,Buls 85
. ..,
4 4 4 L!
5
6
1
B
9
10
A B C D E F U V w x Y Z
E F G H I J Y Z A B C D
a) Realice un subprograma llamado Cifrar, que reciba una letra y la clave de cifrado
y devuelva la letra codificada.
NOTA: Puede ser til implementar una funcin llamada sucesor para que dada una
letra devuelva su sucesora en orden alfabtico, siendo el sucesor de'Z' la' A .
4.11.6 Erreres
Dado el siguiente prograrna incompleto:
86 SunpnocnAMAS: pRocEDrMrENTos y FUNCToNES
{zr} frrt"rrro(7, b) ;
El programa contiene etrores, que pueden ser tanto sintcticos, semnticos o referentes a
la pragmtica y recomendaciones dadas en el libro. La siguiente lista def,ne los posibles
tipos de "errores":
Utilice la tabla 4.4 pararelacionar el nmero de cada sentencia incorrecta con el tipo
de error que contienen (ver lista de arriba), justiflcando brevemente (en una frase) su
decisin. Por supuesto, a la hora de identif,car las sentencias incorrectas slo se pueden
tener en cuenta las declaraciones e instrucciones explcitas.
Tener en cuenta la tabla 4.5 de equivalencias entre los nmeros romanos y arbigos.
M D C L x v I
1000 500 100 50 10 5 1
Como es una labor complicada, otros programadores han realizado parte de la tarea.
Estos trabajadores dan los siguientes subprogramas, que funcionan de manera correcta
y que usted puede utilizar:
4.11.9 Pa{ndrorno
Considere ei siguiente mtodo:
Dado un nmero, se suma a su reverso. Si esta suma es un palndromo o capica,
entonces parar'; si no, repetir el proceso con el nmero obtenido de dicha suma, hasta dar
con un palndromo.
7
4.1l.ll Calculadora
deber tener los si-
Escriba un programa que simule una calculadora. Este programa
guientes procedimientos :
disponibles'
MostrarMenu: Sacar por pantalla el menu con las operaciones
el resultado de sumarlos'
Sumar: Recibir dos nmeros reales y mostrar por pantalla
el resultado de restarlos'
Restar: Recibir dos nmeros reales y mostrar por pantalla
multiplicacin'
\lultrpLcar: Recibir dos nmeros reales y mostrar por pantalla su
el resultado de divi-
Dir ir,1ir: Recibir dos nmeros reales y mostrar por pantalla
segundo nmero es
dirlts. Antes de utilizar este procedimiento se comprobar que el
drstrnto de 0.
que sern dos nmeros reales'
Lee rDosNumeros: Tendr dos parmetros de salida,
Elprogramaprincipaldebermostrarelmen,pedirunaopcinydependiendodela
Esto se repetir
opcin escosida. eecuiar los procedimientos descritos corespondientes'
hasta que el usuario decida terminar el programa'
Pnosr,rN,rls 9t
4.l1..l3 Primalidad
Considere las siguientes propiedades relacionadas con la primalidad de un nmero:
n2 mod24 = 1.
Realice un programa que pida al usuario que introduzca un nmero entero y le devuelva
un mensaje avisndole si el nmero introducido es primo o no utilizando los subprogra-
mas anteriores.
92 SUSpnOCNAMAS: PROCEDIMIENTOS Y FUNCIONES
4.11.14 Sucesiones
Considere las sucesiones cuyos trminos estn def,nidos de1 siguiente modo:
i. : 9l+
l),,=l'.,t l -
,, t1, : -Vn -3
Se observa, que para avanzar a travs de sus trminos, basta con hacer rodar dos de
ellos consecutivos. Por ejemplo, si se toman como los dos primeros trminos 2 y 3, se
obtienen los siguientes 2,3,2,1 ,1,2,3,... que, slo por casualidad, son todos nmeros
enteros. Por otra parte, es fcil verihcar que, para dos trminos iniciales cualesquiera de
9t*, la sucesin generada mediante la relacin recurrente anterior es cclica,
V by.b2 9t+, !peN: V n ) 1,b,,+p=b,,
Es decir, considerando los trminos consecutivos cl y c2 (con valores iniciales b1 y
b2), basta con hacerlos aYanzaf hasta que se tenga, nuevamente , c,, = bt Y cn+1 = bz, Y el
perodo p ser el nmero de avances efectuados. Se pide:
1. Escriba un subprograma que calcule el perodo de una sucesin dados sus dos
primeros elementos.
3. Escriba un programa que permita hacer los clculos implementados en los dos
subprogramas anteriores mediante un men de opciones.
4.LL.l5 Trayectoria
Se quiere impiementar un programa para calcular la trayectoria de una pelota de tenis en
un sistema de referencia bidimensional, donde el eje x son las abcisas (eje horizontal) y
el eje y son las ordenadas (vertical). Supngase que en t = 0 segundo, la pelota de tenis
es lanzada desde la posicin inicial dada por el punto (xo, )o) con una velocidad inicial
cuya magnitud es Ve (m/seg) y formando un ngulo de 0 grados con la horizontal. Las
ecuaciones para la posicin de la pelota para cualquier tiempo t (siendo G=9,8 m/seg2
la aceleracin de la gravedad terrestre) son:
\rtr =,rr-r + V0 * COs (0) * t;
\ir -r, , + Vo x sen (0) * t- ll2 (g*r2);
S: pi.le:
.r Reelizar un subprograma que vaya generando la trayectoria x(t) e y(0 para inter-
..
- . . re rLempo de 0,5 segundos y devuelva la distancia mxima recorrida por la pelota
D r e,:r:ntpo(t)queestenel aire,dadoslaposicininicial(xo,)o), lavelocidaddelan-
zan-Lienro \i ngulo 0 expresado en grados. (La distancia mxima (x) se alcanza
v e1
euando 1a peiota cae al suelo (y<=0)).
Pnonrnntas 93
4.11.18 Pi
Escribe un programa que permita calcular el valor de t mediante las siguientes series:
n = ll2 sqrt(2zl+ 24122+ 24132+24142+ ...)
lt = 2* * 413'* 415 . 615 . 6lJ ),1 811 . ...
211 ,r 213
EI programa deber pedir el nmero de trminos que debe calcular en cada serie y
mostrar los resultados respecti\,os.
4.11.L9 Capica
Escribe un subprograma en Pascal que reciba un entero y diga si es capica o no. Escribe
un programa que Lrtilice el subprograma anterior.
4.11.20 Rotar
Escribe un subprograma que reciba tres nmeros enteros y ios devuelva rotados circu-
larmente hacia ia izquierda. Escribe un programa que cornpruebe ei funcionamiento deI
subprograma"
94 SuspnocnAMAS: pRocEDIMIENToS Y FUNCIoNES
Ejemplo: si a=2 b=5 y c=7 ,wta vez ejecutado el subprograma se tiene a=5 b=7 Y
c=2. Y si se ejecuta de nuevo el subprograma para a=5b=7 y c=2 se obtendr a=7 b=2
y c=5.
4.12 Soluciones
4.12.1 Toro
Anlisis del problema: no es necesario ningn dato de entrada por parte de usuario, y
la salida debe ser la que se pide en el enunciado.
Esre procedimiento debe escribir lnea a lnea, en orden adecuado los caracteres 'O'
iriv---.1r',,. i para tbrmar ia letra T. No se necesita ninguna variable local.
escribir ( '00000' );
escribir(' O')
escribir(' o')
escribir(' 0')
escribir(' 0')
Sor,ucronrs 95
Como cada linea tiene una traduccin directa al lenguaje de programacin no hace
falta refinar ms.
Se sigue idntico razonamiento para el resto de subprogramas.
Implementacin:
PROGRAM Escrj-birToro ;
{Onietivo: Sacar por pantalla la palabra TORO escrita en
vertical y con eI carcter 'O')
PROCEDURE EscribirT;
{Uo se aade ningn parmetro, ni hace falta poner
parntes i s)
BEGIN {Escribirr}
writeln ('00000, ) ;
writeln (' 0' ) ;
writ.eln (' o') ;
wrireln(' O');
writeln (' o' ) ;
END; {rscribirr}
PROCEDURE EscribirO;
{Onletivo: Escribir una O con caracteres 'O'}
{eRr: uinguna}
{nOSf: Saca por panta}Ia cinco Ineas que
representan una O)
BEGIN {rscribir0 }
writeln (' 0OO') ;
writeln ('o 0, ) ;
writeln ('0 o' ) ;
writeln ('0 O' ) ;
writeln (' OOO' ) ;
END; { uscribirO }
PROCEDURE EscribirR;
tUOletIVo: Escrrblr una R con caracteres 'O')
T ^. ,
SUNPNOCNAMAS: PROCEDIMIENTOS Y
FUNCIONES
96
{eRu, Ninguna)
{eOst:Saca por pantalla
cinco }neas que
representan una R)
, " _),
RtrGTN i ESCrrblTR i
writern ('oooo' )
writeln ('0 o'
wrrteln ('0000' )
writeln ('o 0' )
writeln ('o o'
. .. ' .\
END; {Escrrbrrxl
todos }os subprogramas' puede
{Una vez que ha escrito
usarlos de manera adecuada en ef programa principal)
Sor,ucroNrs 91
hace un estudio ms detallado, se observa que basta con: escribir una T, escribir
Si se
una O. y escribir una R, ya que escribir una O, escribir T y escribir R se repiten. Igual
que en el ejercicio anterior solo se tiene que crear un nico subpro-qrama para cada letra
y utilizarlo las veces que haga falta.
Segundct paso: Como estas instrucciones (escribir una letra tan grande) no existen
en PASCAL. debe crearlas. La forma de disear los subprogramas es idntica a la ex-
presada en el ejercicio anterior por 1o que se omite.
Implementacin:
PROGRAM EscribirOtroToro ;
BEGIN {Escribirt}
writeln ('O0OOO' ) ;
writeln (' o') ;
writeln (' o') ;
writeln (' o') ;
writeln(' O');
END; {Uscribirt}
PROCEDURE EscribirO;
{Onietlvo: Escribir una O con caracteres 'o' )
{enn' uinguna}
tPOST: Saca por pantalla cinco 1neas que representan una
I _ ^
-_
O)
BEGIN {Escribiro}
writeln (' OO0' ) ;
writeln ('0 O' ) ;
writ.eln('O 0');
wrireln ('0 0' ) ;
writeln (' ooo' ) ;
I
END; {uscribirO}
PROCEDURE EscribirR;
LOber--ro: Escribrr una R con caracteres '0'-|
: N Inguna
t rRE
\
J
BEGIN {EscribirR}
writeln ('0000' ) ;
writeln ('o o' ) ;
writeln ('0ooo' ;
writeln ('0 O' ) ;
writeln ('0 0' ) ;
END; {EscribirR}
[ ^7 h rl].
!'^vi
!Uul h vrl'.
v!! ,
EscribirO;
E s cribi rR;
!ur Mrw i
>
En este e.jercicio se pueden observar las ventajas de la subprogramacin: Evita la dupli-
cidad de cdi_so. clarifica el programa principal y facilita el mantenimiento (debido a que
<i re equivoca al escribir una letra. solo tiene que mirar el subprograma que se encarga
Je e 1l.i ,.
Implementacin:
PROGRAM EscribirToro2 ;
{Onletivo: Sacar por pantalla la palabra TORO escrita en
vertical y con el carcter elegido por el usuario)
VAR
Iecra: char; {Para almacenar eI caracrer}
SunpnocnAMAS: PRocEDTMIENToS Y FUNCIoNES
EscribirT (caracter:char) ;
'?,OCEDURE
,CbjeLivo: Escribir una T con el caracter)
l
lPRhl : Nrnguna.l
inOSf, Saca por pantalla cinco 1neas que representan una
T)
BEGIN tEscrlbrr.L')
writeln (caracter, caracter, caracter, caracter, caracter) ;
END; iEscrlblr'.1' ] ip
PROCEDURE EscribirO (caracLer: char) ;
{onietivo: Escribir una O con caracteres} ..
{tRu' Ninguna} .i
{lOSt: Saca por pantalla cinco Ineas que representan una O} ':
BEGIN {Escribiroi =
writeln (' ' , caracter, caracter, caracter) ;
:
writeln (caracter, ", caracter) ;
writeln (caracter, ' ' , caracter) ;
writeln (caracter, ' ' , caracter) ;
writeln (' ' , caracter, caracter, caracter) ;
END; {uscribirO}
BEGIN {uscribirn}
writeln ( caracLer, caract.er, caracLer, caracter) ;
writeln(caracter, ",caracter) ;
writeln (caracLer, caracLer, caracter, caracter) ;
writeln (caracter, ", caracter) ;
r+riteln (caract,er, ",caracter) ;
E{l; {uscribira}
iuna vez que ha escrito todos los subprogramas, puede
usarlos de manera adecuada en eI programa principal)
Sor,ucroNBs 101
Las instrucciones se empiezan a ejecutar a partir del ercrl\T del programa principal.
Cuando en el programa se encuentra una llamada a un subprograma, el programa se
suspende temporalmente y pasa e1 control al subpro-grama. El subprograma funciona
como un programa. empezando a ejecutarse a partir del sClN del subprograma y fina-
iizando en el END; . una vez terminado el subprograma, el programa se reanuda en Ia
siguiente instruccin donde se detuvo. Por 1o que el orden de ejecucin queda:
PROGRAM Secuencial;
{Onetivo: Probar procedimientos}
VAR
a, b: integer;
resultado: integer;
VAR
aux: integer;
BEGIN {Segundoi
_5_ aux := num + 1;
_6_ writeln ('El resultado incrementado es igual a ' , aux) ;
END; {Segundo}
Apartado b)
Hay dos instrucciones que son llamadas a procedimientos definidos por el usuario, r
son: Segundo (resultado) ; y Primero (resultado, a, b) ;
Apartado c)
No son llamadas a procedimientos todas las asignaciones. Es decir, existen tres instruc-
ciones que no son llamadas a procedimientos (se consideran llamadas a procedimientos
las instrucciones de entrada/salida, ya que son llamadas a subprogramas predefinidos en
el lenguaje).
Apartado d)
Sr :e introduce por teclado 5y 11,1os valores de las variables quedan a:=5 Y b:=14. El
l'i :r'.1I1).r Iltr,:lri.rru l() siguiente:
,{partado e)
Apartado f)
Apartado g)
Apartado h)
) l.ra--il I
^
VAR
.l 'l ranar.
f . tlluuYU! /
cifrada: char;
BEGrN {cifrar}
crfrada := letra;
FOR i := 1 TO (c1ave-l) D0
cifrada := Sucesor(cifrada) ;
Cifrar := cifrada;
END; {cifrar}
Apartado b)
descifrada: char;
BEGIN {antecesor}
IF (1et = ,'4',
THEN
Antecesor := "Zu
ELSE
Antecesor = pred (1ec )
END; {antecesor}
BEGIN ioescifrar)
descifrada := letra;
FOR i := 1 TO (clave-l) D0
descifrada : = antecesor(descifrada)
Descifrar : = descifrada
END; {Oescifrar}
Apartado c)
PROGRAM Cesar:
VAR
opcion, 1etra, resultado: char;
cfave: integer;
END; {cesr}
rrFtr) OR (opcion-rt f 'r )'
UNTIL (opcion =
:ND. {Programa PrinciPali
4.12.6 Errores
La solucin se halla enlatabla 4'7 '
B-reve
expticacin
modifl-
i
tanl" giobul'
da deber ser
El segundo Parmetro
una variable (paso pot tefutencia)' .
ffieunparme-
d mismo
Interno existe Y es vlsl
puede
y-", e*,"*o. Fuera de su mbito no
y debe ser lnvo-
"srnprocedimiento
cado fuera de una expresil
solo de-
29
vuelve valores en 10! i'agmetrgs'
30
3l ffitaldebe
invocada dentro d" ut3jl!t"ti*
errores
Tabla4.7: Problema sobre
Sor,ucroNBs t07
PROGRAM NumerosRomanos ;
PROCEDURE Romano2Arabigo ;
{lee por teclado un nmero romano correcto de menos de 15
cifras y/o terminado en un punto, devolviendo su valor por
pantalla, por 1o que no son necesarios ningn parmetro)
VAR
cont: int.eger; {contador de cifras}
acum: integer; {guarda 1a suma parcial}
ns, nc: integer; {valor del siguiente y del actual}
cart sig: char; {Carcter actual y siguiente}
FUNCTION VaIor(c: char): integer;
{necibe un carcter y devuelve el valor equivalente. Si no
corresponde con ninguna cifra romana devuelve cero.|
BEGIN {va:.or}
CASE c OF
'M' , 'm': Valor := 1000;
'D' , 'd' : Valor := 500;
'C' , 'c' : Valor := 100;
'L' , 'L' : Valor := 50;
108 SunPnocnAMAS: PROCEDIMIENTOS Y FUNCTONES
BEGIN {Romano2Arabigo)
aCUm = 0;
:
Cont : = 1;
en un Punto ( ' ) ') ;
writeln ('Introduce el ntmero romano acabado
read (car) ;
WHILE (car <> ' '') AND (cont <=
15) DO BEGIN
read (sig) ;
flC := valor(car);
ns := valorrsig) ; hay que restar}
IF (nc < ns) THEN {si el siguiente es mayor
BEGIN
aCUm := acum 1 (nS-nC); los dos}
read(car); {lee otro carcter pues ha procesado
cont := cont + 1; {aumenta e1 contador}
END
o igual}
ELSE {si la cifra siguiente es menor
BEGIN
acum := dCUfil + (nc);
Car := Sig;
END;
cont := conL + 1;
END; {wurlu}
writeln (' equivale a ' , acum'
t
en notacin arbiga') ;
F.ND ; {Romano2Arabigo }
Cc::recto: boolean;
: ,l,CTlCl;
teclado Y comprueba si es correcto
{tee un nmero romano Por enunciado, devolviendo
o no de acuerdo con Ia reglas dadas en eI
TRUE si es correcto Y FALSE en
caso contrario )
VAR
cont, cmr cd, c}, cv, cx, cc' ci : integer;
car : char;
fin : boolean;
t
Solucrours 109
BEGrN {correcto}
Cm:= O;
cd := 0;
cI := 0;
ar .= 0'
v .-
CC := 0;
ci := 0;
nnl- .- T.
writeln ('Introduce eI nmero romano acabado en un punto (.) ') ;
I read (car);
.F.i- - +-'t^^.
!frt .- rafDgi
I^iHILE (car <>'.') AND (cont<=15) AND (UOT f in) D0
BEGIN
CASE car OF
,M,,,M, : BEGIN
.- m r -l .
CM
fin ._ LILL 2
f.
J,
END;
,D,, ,d, : BEGIN
rA .- l r T
trfl .- !u 2 f ,
END;
t (1 t t at
BEG]N
uu .- gL 1.
T r,
fin .= \ 1.
END;
,L" 'I' : BEGIN
el .= l +' 'l
+t
f in .= l : l.
END;
tyt tyl
BEGIN
lY '= eY + "l'
c:-
t-Ll-t := ux > J;
END;
,Y" 'V' : BEG]N
CV := CV + 1;
f in .= r\r : I.
END;
!t : BEGIN
^. .- ^.1 1-
110 SuspnocnAMAS: pRocEDIMIENToS Y FUNCIoNES
fin := ci > 3;
END;
ELSE
fin := true;
END; {casr}
read (car) ;
cont := coflt + 1;
END; {wurlu}
correcto := NOT fin;
END; {Correctoi
END; {uenu}
'1' : Romano2Arabigo;
'2' : IF Correcto THEN
writeln ('El nmero es correct.o')
ELSE
writeln ('El nmero es incorrecto');
,3, : BEGIN
writeln ('fin' ) ;
readln;
END;
:LSE
writeln ('Opcin no vlida' ) ;
,l. oo lj
l!sre
-l:l-- :ccion = '3' ;, ]
:-.- . l::Iama pIlnclpa1
-- J
Sor,ucroNrs 111
VAR
, b, aux: longint; {Numeros a muttipticar}
productoParcial: Iongint; {fara el producto parcial}
suma, productoDesplazado: real;
cont: integer; {contador}
FIr'IJCTION NumeroCif ras (num: Iongint ) : integer;
{uora' Esta funcin no necesita desarrol}arser pero se hace para
que el lector tenga una idea clara de 1o que realiza)
,loon. i
I
{eOSf: NumeroCifras = nmero de cifras de num}
{untrada: un nmero entero l"argo}
{Satiaa: el nmero de cifras del ,imo-^l
VAR
cont : integer;
BEGIN iUumeroCifras)
.-nl .- 1.
WHILE num > 10 D0 BEGIN
Cont := cont + 1;
num := flUII] DIV 10;
END; {WUrlU}
NumeroCifras : = cont;
END; {UumeroCifrasi
VAR
i : integer;
aUX: real;
BEGIN {oesPlazatzquierda}
aux := num;
FOR i:= 1 TO nveces DO
VAR
acum: Iongint;
i : integer;
BEGrN {t'luftiPfica}
aCUm : = 0;
FOR i := 1 TO digito DO
acum := C1]fl + num;
MuttiPlica : = acum
END; {t'luftlPflca}
::ai-r (a, b) ;
-! a<O)OR(b<0)THEN
-,r:::iteln (' iDeben ser positivos I ') ;
-l:--- a >= 0) AND 1 b >= 0) ;
-:.-::z'--za 1a variables)
ise usa para no modif icar eI segundo
operandoJ
1-::. '.= i;
._ 1.
cont-1);
{Acumula e1 resu}tado}
suma := slr + productoDesplazado;
{Rctualiza eI multip}icando}
aux := aux DIV 10;
END; {ron}
wriLeln(a, , b, ',=', , suma:0:0)i ',*',
END. {lrograma principa}i
4.I2.9 Palndromo
PROGRAIVI Capicua;
VAR
numero/ nreverso/ suma: integer;
f ,t*******ADADrf^nn /. I *******x I
L '. l
acumula := 0;
WHILE (temp > 0) D0 BEGIN
acumula := acumula * 10 + (temp MOD 10);
temp := temp DfV 10;
END; {wHrlr}
ReverSO : = acumula
END; {Reverso}
114 SuspnocRAMAS: PRocEDIMIENToS Y FUNCIoNES
{
********APARTADO (b) ******** }
--
FUNCTION Palindromo(n: integer) : boolean;
^)
{ PRE: n>=u 1
{losr: palindromo= TRUE si n es capica
FALSE en caso contrario)
BEGIN {ealindromo}
palindromo := I1 = reverso(n) ;
END; {palindromo}
{
********4pARTADO (c) ******** }
readln (numero) ;
::r:: -
:-r_,_:l::- = 3000;
.rj
l-:, :.=s, anno/ numerosuerte: integer;
Sor,ucroNns 115
BEGIN {Sumaoigitos}
UULLLP .-
lamn ._ r.
11 ,
SUma : = 0;
WHILE (temp > 0) D0 BEGIN
Suma := Sufll + temp MOD 10;
temp := temp DIV 10;
END; {WUrlU}
SumaDigitos : = suma
END; {SumaDigicos}
4.L2.11 Calculadora
Una posrble solucin es:
PROGRAM Calculadora;
VAR
a, b: integer;
opcion: char;
BEGIN {restar}
writeln ('La resta
,
nT
lla
a\
tlLl I
END; {restari
PROCEDURE Multiplicar (n1, n2 :
'lrllLUYU!
-r^^^?\ / /
BEGIN
writeln (' La multiplicacin es: ' , nL * n2);
1
END; lmultlpllcarl
mrD; tdividir)
PROCEDIIRE MostrarMenu ;
BEGIN
writeln;
writeln(' rntroduzca una opcin:
Sor,ucroNns 111
writeln('1.- Sumar');
writ.eln('2.- Restar' ) ;
writeln('3.- Multiplicar' ) ;
writeln('4.- Dividir' ) ;
writeln ('0. - Finalizar ') ;
'.'-i r^1 -.
END; {ttenu}
Existen varias formas de enfocar el problema. En una de ellas, los subprogramas realizan
la operacin y devuelven el resultado. Se ha tomado este enfbque para realizar 1a primera
solucin propuesta. La segunda solucin se basa en que los subprogramas realizan la
operacin y muestran por pantalla eI resultado. En la tercera propuesta los subprogramas
realizan la operacin y el resultado se devuelve en el primer operando, La diferencia
entre ellas est en el paso de parmetros (y en la consecuente llamada).
Primera solucin propuesta. Los subprogramas guardan el resultado de la operacin
en otro nmero complejo.
PROGRAM Complejosl;
FUNcToNES
118 SurpnocnAMAS: PRocEDrMrENTos Y
VAR
, b, c, d, res1, res2: real;
opcion: char;
error: boolean;
readln(i);
END; {LeerComPlej oi
{eRn, NingunaJ
Ia suma de dos complejos
{losr: resR = Parte real de de la suma de dos complejos]
resr = Parte imaginaria
BEGIN {SumaComPlejos}
resR := re1 + re2;
resl im1 + im2;
'=
END; {SumaComPlejos}
{eRr, Ninguna}
fonqr. resR = Parte real de la resta de dos complejos
complejosi
resr = Parte imaginaria de la resLa de dos
BEGIN
resR := re1 - re2
resl := iml - im2;
END; {restaComPlejos}
ProdComplej"' (::1'
ruDr' .'::.,:"'
1i:''-::.,
PROCEDURE
VAK IesK' ruq!' /
j
?P., :;-:guna)
.?:S., :esR = Parte rea} del producto de d.os complejos
:esr = Parte imaginaria del producto de dos
comptejos)
:::-1.
t::?. := (re1 * re2 - im1 * im2);
1^-. trei * im2 + im1 * re2);
:ll-; :::1lc:r-ejosJ
Sor,ucroNss 119
BEGIN
REPEAT
r^ri 1-o"l -.
writeln (Im:0:2,,i,) ;
END; {MostrarComplejo}
REPEAT
error := FALSE;
opcion : = Menu;
IF (opcion >= '1') AND (opcon<='4') THEN BEGIN
LeerComplejo (a, b) ;
T aarfanmnl
lEE!uvLtryruJv oia
ftv, d\
u/ ,
r-AeF'
vI!!vt/U nnr-i6n QP
, 1, : BEGIN
END;
,3, : BEGIN
ProdComplejos(a, b, c, d,res1/ res2);
writeln ('EI resultado de multiplicar ')
END;
'4' : BEGfN
IF (c <> 0) OR (d <>
0) THEN BEGIN
DivComplejos(a, b, c, d, res1, res2);
writ.eln ('El resultado de dividir ')
END
ELSE BEGIN
error := TRUE;
writeln (' DrvrsrN POR CERO I I I I ',)
END;
END;
END; {cesE}
IF NOT error THEN BEGIN
MostrarComPlejo(a, b) ;
MostrarComplejo (c, d) ;
writeln ('es : ') ;
MostrarComPlejo (res1, res2) ;
:Yn .
r'-- l rul
-, ]
-*^] t .
utrull ^- - u
^t t
' ' - l
-_ - -.- -...^ ^.yrlnclpa-L
-,.- ---r-a
]
PROGRAM Complejos2;
VAR
d, b, ct d: real;
opcion: char;
END; {sumaComplejos}
END; {ProdComplejos}
PROCEDURE DivComplejos(a, b, c d:
BEGIN
write r ,La divisin de , , a:5:2 , '
\^iri rp(e\v.J./"\.) ttt /irLl ac.
\ ^.(., EJ.
Te
,l
writeln (' rntroduzca una opcin: ') ;
* writeln('1.- sumar');
4
wriceln('2.' Restar' ) ;
writeln('3.- Multiplicar' ) ;
$
{t writeln('4.- Dividir' ) ;
$
T]
writeln ('0. - Finalizar ') ;
ral n.
It '.'r.i
YvI!LUr1f,
* readln(c);
'.'r.i ral n.
- -rvIr - v
:"- -. _-.
___ :-
^...- r__,tcrpaI
=-. ^-i, ]
Sor,ucroNBs 123
PROGRAM Complejos3;
{ calculadora }
VAR
d, b, c, d, resl, res2: real;
opcion : char;
error: boolean;
PROCEDURE LeerComplejo(VAR r, i: real);
BEGIN{LeerComp}ejoi
write ('Escribe 1a parte real: ,) ;
readln (r) ;
write ('Escribe la parte imaginaria: ,
) ;
readln (i) ;
END; {LeerComp}ejoi
END; (ProdComplelos)
VAR Bi
lamn.
uUItLy. rarl
!tqf,
vac) roT. r r .
BEGIN
temp := sqr(re2) + sqr(im2);
resR := (re1 * re2 + im1 * im2) / temp;
reSI := (im1 * re2 - re1 * im2) / temp;
ro1 .
= rcqP.
rml .- raq
END; {Divcomplejos}
readln (c) ;
IF (c < '0') OR (c > '4') THEN
writeln ('opcin no vlida' ) ;
..'v.i tal n.
END;
,3, : BEGIN
ProdComplejos(a, b, c, d);
writeln ('El resultado de multiplicar ,)
END;
,4, : BEGIN
IF (c <> O) OR (d <> O) THEN BEGIN
DivComplejos(a, b, c, d);
writeln ('EI resulLado de dividir ,)
END
ELSE BEGIN
error := TRUE;
writeln (' DIVISIN POR CERO I I I I
,)
END;
END;
END; {case}
IF NOT error THEN BEGIN
writeln ('es : ') ;
MostrarComplejo (a, b) ;
END;
END; {tr}
UNTIL opcion = '0' ;
l_
LjNIJ . t Programa prlnclpal -}
{'/
126 SunpnocnAMAs: pRocEDrMrENTos y FUNCIoNES
4.12.13 Primalidad
Una posible solucin es:
PROGRAM primalidad;
{otrjetrvo: Este programa sirve para saber si un numero es primo}
I -^- r I zndolo mediante un algoritmo 'inteligente' i
{rntrada: Un numero entero positivo}
{Satiaa: Mensaje sobre la primalidad del numero introducido)
VAR
numero: integer;
{
********pARTADO 3 ******** }
I *********ADADTlnn i ******** 1
t'
i *********ApARTADO 2********** )
BEGIN {rsnrimo}
IF (n <= 3) runl {et r, eI 2 y el 3 son primos )
EsPrimo : = TRUE
ELSE IF EsPar (n) THEN {Si es par, no es primo
)
EsPrimo : = FALSE
ELSE IF NOT Propiedad(n) THEN
{Si no cumple Ia propiedad, no es primo}
EsPrimo : = FALSE
jLSE tsr no es par y cumple }a propiedad, miramos
si tiene divisores entre f y sqrt (n) )
Esprimo := NOT TieneDivisores(n);
END; {Uslrimo}
4.12.14 Sucesiones
PROGRAM Sucesiones;
rnxr^rrrn. trcia programa sirve para calcular el periodo y Ia
sucesin dada por ra
l"-;=u""l"r"r"ir1*uros rrminos d.e una
formula recurrente b (n) = ( (n-1) +1) /b
(n-2 ) para n>3 ]
escoger que se quiere calcular'
{untrada: Una opcin para 1a suma' el
los dos primeros trrinos y si va a calcul-ar
numero de trminos)
escogida' el periodo o Ia
{satiaa: Dependie"o a" }a opcin
suma de los i Primero trminos)
VAR
opcion:char; {para elegir e1 calculo}
bt, b2:real; {1os dos primeros trminos de lacalcular la
sucesin)
para suma)
terminos: integer; {numero de trminos
B.ID; iComParaneal)
BEGIN ileriodo)
c2:=n\ ;
Sor,ucroNns t29
-l .- n)-
:cntador : = 0;
?,EPEAT
a1 .- ),
') .- 2.
c3 := (c2 + 1) I ct;
contador := contador +
^1 ^a ^) ^^--^l ^_ --- -l
LI, CZ, UJ, PdIUId.I: ICCi-L;
cont: integer;
::GIN {Suma}
{inicialmente parcial va}e la suma de los dos primeros}
parcial := numl + num2;
^1 -.- .,1 .
!r LlUtLtr,
a)
az .-
. - r,,ml
tf uLtL /.
.-
. - aa.
gJ,
^a
-L
END; {ron}
Suma := parcial;
:ND; {Suma}
/AR
'irraaar.
f 1!ugYU!,
3EGIN {NumeroTerminos }
REPEAT
130 SurpnocnAMAS: pRocEDIMrENTos y FUNCToNES
1.12.15 Trayectoria
Una posible solucin es:
PROGRAM Trayectoria;
{Oe.fnffvO: Conocer datos sobre la trayectoria de una pelota
Ianzada desde una posicin inicial (x0, y0) / con una
velocidad inicial V0 y con un ngulo de salida)
{Enrradas: Posicin inicial, velocidad inicial en m/seg y
ngulo en grados )
.Salidas: DisLancia recorrida, altura mxima y tiempo en eI aire)
]CNST
G= 9.8; {Aceleracin de Ia gravedad en m/s^2}
INCREMENTO = 0.5; {Intervalos de tiempo de cada medicin}
AR
xInic, ylnic, vlnic, anglnic: real;
dist, tiempo: redl;
.-x********** ApARTADO al ************i
.:CCEDURE DistanciaTiempo (x0, y0, vO, ang: real;
VAR disMax, t.Aire: real) ;
ii,E: y0>=0 La altura inicial es no negativa)
.lST: disMax= Distancia recorrida sera: x final - x inicial
tAire = tiempo en ef aire )
r-:.
t', Y , LL : ---redr;
- l
_-_-_ t_
: ---N { JJIStanclaI'Iempo.l
t''
.- q-,y
a^ * ,I
D-
/ IEU; teonverslon a radlanes-|
132 SuspRocRAMAS: PROCEDIMIENTOS Y FUNCIONES
t._
^.
REPEAT
t:=t + INCREMENTO;
y:= y0 + v0 * sin(ang) * 1-L - lal * sqr
\U (t) I z) ;
-t
*
x:= x0 + v0 cos (ang) * t;
TT\TTTT, \t - A-
4.t2.
disMax := x - xo; {oistancia mxima= xfinal-xiniciali
lAirc .= l. i: Ill
- -\J ; i lJIStancla'l-'Iempo t:o\
)
- .:lCi
.r*rx********* ApARTADO b) ************) - gri
-.'AR
y, yAnr,t:real; :.--
3IGIN {alturatvtax} , t-
r
f
.-
'-
rr.
lvt
-:
REPEAT ...
t :=t + INCREMENTO;
-'ll
ynrru ._ )r
y := y0 + v0 * sin(ang) * t (G * sqr(t) I 2) i
UNTIL y a= yAnt;
AlturaMax = yAnt;
END; {alturalvtax}
PROGRAM Senol;
{onjetivo: Este programa sirve para carcurar e1 varor de sen(x)
mediante una serie con n trminosi
{Untrada: Numero de trminos y e1 valor de x en grados}
{Satiaa: El valor de sen(x) calculado por la computadora
y el valor calculado por la serie)
VAR
nt.erminos : integer;
v. ral .
:l,l;
{rOni
la-culaSeno: =suma; BEGIN {
l-
:lI: iCalculaSenoi t InIcra
FOF
:::-l', {Programa PrinciPal }
i;:ite1n ('Introduzca el ngu1o en grados');
r dL
::adln (x) ;
i;riteln ('Introduzca el nmero de Lrminos: ') ; END; {l
::ad.ln (nterminos ) ;
'r;riteln('EI valor de seno(', X:0"2,') eS:'); FT]NCTIC
:.:=P1/180*x; { enn,
f onc.n
',;::-teln('medianLe }a computad,ora ', sin(x) :0:6) ; i ! vu r ,
.
:eadln pot:
:l,l . {Programa PrinciPa} }
i: i
BEGIN ]
Seno2; FOR
':.l3RAM
etivo: Este programa sirve para calcular el valor de
1c..1
sen (x) I
mediante una serie con n trminos) IF
::-::ada: Numero de trminos y eI valor de x en grados) I
S,-rda: EI valor de sen(x) calculado por Ia computadora Pot<
y e1 valor calculado Por ta serie) END; {t
FOR i:,
:-]:::ION CalculaSeno (angulo: real; n: integer): real-;
l,
f
:-]::--ON FacLorial (num: integer): real; t,^ -,
---..
----l L^l
t::: nUm>=O ) ,',1_LLer.
--^^lt
_:durrl -
' -Sl: Factorial=numl )
:.EPEAT
BEGIN {ractorial}
{rniciatizacin deI buc}e}
-^
rqu -_
.'
r.
!t
i := 2 T0 n DO
FOR
fac := fac * i;
Factorial : = fac;
END; {ractoria}}
{losr : Potencia=base^exponente}
VAR
nar . ra
!uuf l
yvL. ,
'l i raaar.
t]]uUY9!,
BEG]N {eotencia}
{rniciatizacin det bucle}
^F . f1 ,.
PUL . --
BEGIN {CaIcuIaSeno}
{rniciatizacin de1 bucle}
crrm. -.
readln (nterminos) ;
UNTIL (nterminos > O) ;
PROGRAM NumerosPrimos ;
VAR
num,priml, prim2: integer;
encontrados: boolean;
VAR
a, b : int.eger;
SigPrimo: =a;
END; {siglrimo}
:IGIN {EncontrarDosPrimos}
{pr y p2 son e1 primer nmero primo excluyendo e} 1}
nl .-
.- ).
't
^a ,_ a.
zt
P' '-
WHILE ( (p1 + p2) < n) D0 BEGIN
{Se aeia p1 fijo y se cambia p2 hasta que p1+p2>=n}
WHILE ((pl + p2) < n) Do
p2 := SigPrimo(p2) ;
- -: -- | {Una vez terminado el bucle, p1+p2>=n}
{Si pf+pZ>n entonces cambia p1 at siguiente nmero primo,
., -^,al-'a ,- a empezar 1nlc1ando p2 aI nuevo valor de p1)
readln;
END. {Programa PrinciPalJ
4.12.18 Pi
Una posible solucin es:
PROGRAM CalculaPi;
{Programa que calcula
e} nmero Pl mediante dos series)
mayor que 0 que indica eI nmero de
{uNrnnoa, Un nmero entero
trminos de las series)
-^--:lc>
de }as ser ^^1
{salrna, Por pantalla }os resultados
J
VAR
nTerminos: integer;
S'*:.a: feal;
l--ar.
--- -'Ye' /
--:r-'- :- qcriel ]
:-*.::=3;
:-: -:= 1 TO n DO
s*:a := suma + (1/i)*(1/i); que para
.:::: ,1/i)*(1/i) en vez de 1/sqr(i) es debido a 33!24'
- -v.Ft=s de i (i>181) por ejemplo sqr(182) --
SorucronBs 139
1.12.19 Capica
Una posible solucin es:
?ROGRAM Capicua;
.Cbjetivo:
Programa que calcula si un nmero es capica)
ENTRADA: Un nmero entero)
,.SALIDA: Por pantalla si es capica o no)
SuspnocnAMAS: PROCEDIMIENTOS Y FUNCIONES
VAR
num: integer;
END; {usCapicua}
4.12.20 Rotar
Una posible solucin es:
PROGRAM RoTAr;
{oUjetivo: Programa que pide 3 nmeros enteros y los devuelve
rotados a 1a izquierda)
{ml'rraoa: 3 nmeros enteros}
{sa-lrna, Por pantalla los nmeros rotados}
VAR
tl, 12, 13 : inLeger;
Sor-ucrors t41
END; {rotarizda}
lntroduccin a la Recursin en
PASCAL
ttl
. ( l. sir:0
-
t rx(n-l)l' si rr >0
donde se observa que en la definicin de n/ aparece (n-l)l La representacin del
:lculo de 4! en forma directa sera 4! : 4 * 3 * 2 * | : 24. y en fbrma recursiva:
_l-*?t _aA
2 t-l*r l -a
)l-r*1 I -)
1r=1*01 =1
0l=1
t43
t44 INTRoDUCCIN A LA RECURSIN EN PASCAL
Para entender mejor la recursividad en la tabla 5.1 se ilustra la ejecucin del clcuit'
del factorial de 4.
En esa tabla se puede observar que:
1. Cada llamada recursiva genera una nueva copia en memoria de sus datos, como se
puede ver en las dos ltimas columnas de la tabla.
Fact(2) 2 ?
Fact(3) -l ?
Fact(4) 4 1
Fact:= n*Fact(n-1) Fact(1) 1 I
(Fact:= 1* 1) Fact(Z) 2 ?
Fact(3) J ?
,l
Fact(4) 4
Fact:= n*Fact(n-1) Fact(2) 2 2
(Fact:= 2xl) Fact(3) -') ?
Fact(4) 4 ?
Fact:= n*Fact(n-1) Fact(3) -1 6
(Fact:= 3*2) Fact(4) 4 'l
Fact:= n*Fact(n-1) Fact(4) 4 24
(Fact:= 4"6)
oEsteprocesoserepite,hastaquesellegueauncasotrivial(cuandoelsubprograma
sin haber hecho una llamada al
propio subprograma)'
termina
l.Casotrivial(base)'Esuncasodonde'enlaexpresindelasolucinnoapafecei
a] suUnro8llTi,t^-l-
Es decir' no se genera una llamda
nombre del subprograma'
devuelveelcontrolalsubprogramaquecauslallamada.LossiguientesSofleJeni-
plos de soluciones triviales: Factorial
:= 1' Encontrado := cierto' Su:'
:= s,Prodesc := a[1]*b[11,F := Factorial(n)l
2.Castnotrivial(recurrente).Eselquenotienelascaractersticasanteriores.E.
ttrbli:q:T:"'..,:-
el nombre
decir, en la expresin de la solucin aparece 9"l
solucing"n",u.,nuomsllamadasrecursivas.Lallamada(ollamadaSfeCUfSl\':
sedebehacerconunosparmetros,pcLrrnefrossucesors,mScefcanosalc..
valores que identilican un caso trivial'
no triviales:
Los siguientes son ejemplos de soluciones
Factorial := n* Factorial(n - 1),Potencia(a, n - 1'
a*s)'
5.6 Recursividadlineal
Un subprograma es recursivo lineal cuando cada llamada recursiva genera como mximo
'tra llamada recursiva.
Las funciones Fact, de 5.2, y sumalenta, cuyo cdigo se presenta a continuacin,
.on recursivas lineales.
3EGIN
IFN=OTHEN
FacFinal : = f
ELSE
FacFinal := FacFinaI(n - 1, f * n)
END; {racrinal}
El siguiente cdigo es el resultado de aplicar el algoritmo de transformacin.
f . vae l
3EGIN
n : = nlni;
f c-:
I := LII.I-L;
WHILEn>0D0
BEGIN
f := f * n;
n:= fi - 1
END;
FacFinalltr := f
:ND; {FacFinaIfter}
Teniendo en cuenta que, para que ese algoritmo calcule el factorial, el parmetro
iormal nlni debe recibir la constante 1, se ve que dicho parmetro no es necesario si
:e hace que la asignacin inicial sea el valor de esa constante. Tambin se observa
que el primer parmetro, una vez hecha la asignacin inicial no vuelve a aparecer en
ei algoritmo, es decir, que si se renombra dicho parmetro con su nombre original y se
quita la sentencia de asignacin el resultado de1 clculo ser el mismo.
El siguiente cdigo es el resultante de estas simplificaciones
Post:FacFinalIter = nl )
-:l D
F-
!: -^-1.
IEAI,
3EGIN
c1
WHILEn>ODO
BEG]N
150 INrnoruccrN . r-. RncunsrN nN PASCAL
F.-
I.- fI * n.
n:= n - 1
END;
F'aCf ]-nallter := I
END; {FacFinaIIcer}
FOR i := n DOitlNTO 1 D0
f!.- ._
!
* lti
END;
FacFinallter : = f
END; {FacFinaIIcer}
FORi:=1TOnD0
f := f * i;
END;
h'act"]-nal1ter : = I
END; {FacFinalIter}
E,l resultado de aplicar este algoritmo al cle la funcin Fact. cle 5.2, es el siguiente
- ,digo:
. -i rl-ao- "
resultado: real,;
:: IIN
n : = nlni;
I{HILEn>0DO
n := n-l;
r:esultado : = 1;
hjHILE n <> nini D0
BEGII]
n ;- n + i;
tT
resultado := resultado * n
END;
Factlter : = resultado
END; {FactIter}
{ Pcsr
' FacL = nlni I}
VAR
If , f'iraaar.
rlusYU! ,
::esultado: re a1 ;
BEG:N
--1 ._
. - n.
u r
::sultado := 1;
,1iHI-En<nIni D0
BEGIN
n := n+1;
resulcado := resultado * n
END;
Factlter := resultado
END; {FactIter}
resultado: reaf;
BEG]N
resultado : = 1;
FOR N : = ]- TO NlNi DO
resultado := resultado * n;
Factlter : = resultado
END; ifactfter)
Se podra, incluso,
Cr,lnrolo vERSUS EFTcTENCTA 153
resultado: real;
BEGIN
resultado : = 1;
FOR i := 1 T0 n DO
resultado := result.ado * i;
Factlter : = result.ado
END; {Factfter}
Ntese que el resultado final es el mismo en ambos casos y que es el que nor-
malmente se encuentra en la literatura como ejemplo de algoritmo iterativo para calcular
el factorial de un nmero.
Fib(5)
Fib(4) + Fib(3)
Fib(3) + Fib(2) Fib(2) + Fib(1)
Fib(2) + Fib(1) Fib(1) + Fib(0) Fib(1) + Fib(0) 1
lib(1)+Fib(0) 1 1 1 1 1
11
154 INrnoouccrN , r-n RncunsrN pN PASCAL
En Pascal el proceso de compilacin exige que para poder utilizar un identificador ,',
va est declarado. Esto representa un problema para implementar la recursin mutua. -
que si dos subprogramas se tienen que llamar mutuamente, uno de ellos tendr QUe ::
llamado antes de su declaracin. Para solucionar este problema hay que predeclarar ,
egLrndo subprograma con la palabra reservada FORWARD. La sintaxis es:
go-
ena
5.13 Cuestiones de test
iva,
ma
5.13.1 Enunciados
). l. La recursividad por la cola se produce cuando:
rel
resultado:= ejemplo (a) ;
(resultado) ;
l:]."r"
B,
En pantalla aparecer:
I
r56 Ixrnoouccru a u Rncunsrn nN PASCAL
(a') 4.
(b) 2
(c) No aparece nada porque da lugar a infinitas llamadas recursivas.
(d) Un valor sin sentido, porque en el caso base no hay asignacin al nombre de
1a funcin.
a
Qu es la recursividad por la cola?
r alor a la luncin por 1o que el resultado de la ltima llamada y de las anteri, -, :.-'ribi
ser un resultado "basura".
-_:do r
L
Pnonr,nnrls 151
-). La respuesta correcta es la (c). La (a) es incorrecta porque un caso base es que no
tiene una llamada recursiva. La (b) es la def,nicin de recursividad mutua. La (d)
porque el ser recursiva por la cola no depende de donde est la llamada sino
de
que su resultado no se combine con nada producir el resultado
final.
4. La respuesta correcta es la (a). La (b) es incorrecta porque la instruccin GASE
tambin es una instruccin selectiva. La (d) porque el resultado de la llamada se
multiplica por 2. La (d) porque no tiene errores sintcticos.
5.14 Problemas
5.14.1 Camino entre dos puntos
Dadas dos funciones m (x) :2x y r(r) : x I (que no deben ser implementadas).
- Di_
sear un subprograma recursivo que dados dos nmeroS, o ) o y b > 0, encuentre
una
fbrma de llegar desde a hasta b mediante aplicaciones sucesivas de m(x) y r(r). El sub-
programa mostrar por pantalla la secuencia que se produce al pasar desde
a hasta .
Adems, se quiere que:
ELSE
Farec:=n*Farec(n-1)
END;
END;
5.14.5 Funcionesiterativas
Escriba versiones no recursivas de las funciones del ejercicio anterior.
o Hs(x) : I
o H1(x) :2v
o H"(x) : 2x * Hn r (r) - 2(n - l) * Hn-2(x) para n >l
Se supone que en el programa principal se piden los valores de n (entero no negativo) y
x (real).
o Ack(O,n) : nll
o Ack(m,O): Ack(m- 1,1) si m > 0
o Ack(m,n) : Ack(m - I,Ack(m,n- 1)) si m,n ) 0
Dada la frmula recursiva F(N) : -f (N-2) con el caso base F(0) : 1, cules son
Ios valores de f (a) y r' (6)? Cul es el valor de f (5)?
J
INTRODUCCIN A LA RECURSIN
EN PASCAL
160
o MCD(A,0) :A
o MCD(A, B) : MCD(B' A mod B)
5.14.15 Callejero
se desea ir de un punto inicial
(A) a un punto r -'
Supngase un barrio con sus calles. Si
(B).Escribaunsubprogramaquecuenteelnmerodecaminosposiblesquehayer..
y en direcc
se puede aYanzar en direccin norte
los dos puntos *uponi"ndo que slo
este. EjemPlo:
l_.
Posibles caminos:
ffiffiffiffiffi
h-nplemente un programa que pida el punto
inicial y el punto final y use el
pare clecidir cuntos caminos posibles hay'
-qrama
Pnonr,nnrls 161
PROGRAM secuencia;
VAR
origen, destino, contm, contr: integer;
FUNCTION m(n: integer): integer;
J pu. I
)
{eOsr:m=2*n}
eEGIN {m}
m: =2*n;
END; {*}
{eosr:r=n-1}
nraru
u!u!r! f.J
t- J
f := n - 1;
END; {r}
ELSE
BEGIN
'.,-i rol -.
writeln(,El nmero de veces aplj-cado m ha sido: ,, cm);
writeln('El nmero de veces aplicado r ha sido: ,, cr);
write('Camino de funciones aplicadas desde eI,,
' desLino a1 origen: ,)
END
EINJJ; t reCurslva -|
Quin encuentra una solucin iterativa a este problema? Sin embargo la solucin recur-
siva es ms abordable: pinsese que el mover n discos entre Ia aguja 1 y la 3 es posible
de la forma siguiente:
1. Mover n - 1 discos desde la origen ala auxiliar utilizando como aguja auxiliar la
agtja destino.
2. Escribir'Se pasa el disco', n,'de', origen,'a', destino.
164 INTRoDUCCIN A LA RECURSIN EN PASCAL
ELSE
Espar : = Eslmpar (n - 1) {caso no trivial}
END,- {esear}
IFn=0THEN
Eslmpar := false {Caso trivial}
ELSE
Eslmpar := Espar(n - 1) {Caso no triviati
1..-; tEslmpar|
1. PROGRAM FuncionA;
VAR
num: integer;
ELSE
FaRec:=n*FaRec(n-1)
END;
sN PASCAL
t66 IN'rnoouccrN 't r'' RncunsrN
END;
r'^TrPr := PafCial
END;
Parcial := 3;
WHILEN>ODO
BEGIN * n;
Parcial := Parcial
n := n - 1
END;
FaIter ; = parcial
END;
a'cr\l { PrinciPa}}
Proqrama
wriietn('Valor de n: ') i
readln(num);
.."-.i rl n ( 'Recursivo =
FaRec (num) )
r EleTtr (num)
::.:";; " simPliricar
t' rterativo sin
)
EaIter (num) ) ;
. ,: lGRAM FUNCiONB;
---D
num: integer;
_-^^1 -
Xf: LCdL t
ll'
ELSE
rb(ec := x - fbReC(x, n-I)
END;
BEG]N
^--^.1 -1
yqrtrar ._
.- n.
v,
i := n
WHILEi>ODO
BEGIN
t - l
Pqrufqr -
".--^] ;- ^--^-
uarurar - ^,
i := i - 1
END;
Fblter; = parcial
END;
3. PROGRAM FuncionC;
VAR
num: integer;
ELSE
FcRec := 1 + FcRec(n DIV 2)
END;
BEGIN
exPonenLe : = 0;
.t ._
I .-
*.
If ,
WHILEi>=2DO
BEG]N
exponente := exPonente + 1
i := i DIV 2
END;
FcIter := exponente
END;
-^..t 1 r .
t_ - l
LND. tPrograma prlnclparJ
4. PROGRAM FuncionD;
VAR
num: integer;
: r: . 'i nl-oaar.
SoLUCI0NES A LoS PRoBLEMAS 169
i i -ro^o-.
BEGIN
crrml .- n '
i := n
WHILEi>=2DO
BEGIN
suma := sur + i MOD 10
i := i DIV 10
END;
Fdlter : = suma
END;
5. PROGRAM FuncionE;
VAR
num: integer;
END;
END;
readln (num) ;
ELSE
IF (N = 1) THEN
HermiceRec := 2*x
ELSE
HermiteRec :- 2*x*HermiteRec(x, n-1)
2* (rr-1 )*HermiteRec (x, n-2)
END;
PROGRAM Ackerman;
VAR
m, n: integer;
END;
n: integer;
\
'ISCEDURE Imprimirlnverso (n: integer) ;
]]-TIT
_ JII\
-
write (n MOD 10 ) ;
IF (n DIV 10 > 0) THEN
Imprimirlnverso(n DIV 10)
'ICGRAM NumDigitos;
--- D
r. i nfaaar.
14. tllUuYU! ,
BEGIN
IF (n DIV 10 = 0) THEN
NumDigitosRec : = 1
ELSE
DIV 10) + 1
NumDigitosRec := NumDigitosRec(n
END;
readln (n) ;
numero de digitos de n' ' es: ''
writeln('Er "
NumDigitosRec (n) ) ;
END. iPrograma PrinciPaI]
Calculando F(4):
t*l-)\ = R
F/r\ - -L*tr()\
- -)*1 -, -).
F(2) = -2*F(0)
F(o) = 1
Calculando F(6):
c+o - -LQ
-J
nt.\ r * P/\
r \o/ - -t* (-)\ = B
n//\ - -*F'f ?\
.*T -)
tr(?) = -2*F(0)
L \ I
-
El0\ = 1
Calculando F(5):
/\
ts l5l -)
r * U/1\
I \J/
=
F(3) - -3*p(1)
F'{rt - -1*1-1)
F(-1) - 1*P(-3)
el caso base'
En este caso nunca se alcanza
n, b: integer;
readln (n) ;
writeln ('Dame la base: , ) ;
readln (b) ;
writeln('Ef numera ,, fr, , en base ,, b, , es: ,);
CambioBaseRec (n, b)
:llD. {Programa principal}
ELSE
CalclnteresRec := n * i / 100 +
CalclnteresRec (c , fl-L, i)
END;
readln (n) ;
writeln ('Dame un interes: ' ) ;
readln (i) ;
5.15.15 Callejero
PROGRAM Barrio;
VAR
xlnicial, ylnicial, xFinal, yFinal : integer;
readln (x) ;
el Punto inicial Y el
{Cuenta eI numero de caminos entre
Punto
final avanzando nicamente en direccin norte Y estei
BEGIN
rF (xrni > xFin) OR (y]ni > yFin) THEN {Caso base}
__________
NCaminos : = 0
bidones: integer;
dist.ancia: real ;
IF (brd = 1) Then
DistMax : = dis
ELSE
rF (bid = 2) THEN
Di stMax := 2 * dis
ELSE
DistMax := DistMax(bid - 1, dis)
dis/ (z * bid - 3) ;
:1,);
readln (distancia) ;
TINTIL (distancia > 0) ;
writeln ('La distancia recorrida con ', bidones,
' bidones es ', DistMax(bidones, distancia) :6:2);
END. {Programa PrinciPali
VAR
aux: TCDigicos;
i : integer;
BEGIN {Mayor-Mutti}
I._ I,
REPEAT
aux:= []; {uay que inicializar el conjunto dentro
del bucle, para eliminar Ios digitos
de} numero de la iteracion anterior]
f .- r T l, {Se comienza a probar con 2 Porque 1
siempre es multiPlo cabalistico)
Descomponer (n*i,aux) ;
LrllTIL (Aux <> C) ; {ttasta que los digitos de aux sean
dstintos de los de n)
.,.a1,o::_Mr.r1ti:= i - 1; {eorque i contiene el numero en
eI que se deja de cumPlir la
condicion de multiplo cabalistico)
SorucroNES A Los PRoBLEMAS r77
END; {Mayor_MuIti }
o Tipo simple: sus valores son atmicos e indivisibles. Dentro de esta clase, se
distinguen dos subclases: ordinal y no ordinal.
o Tipo compuesto: sus valores no son atmicos y se pueclen descomponer en otros
ms simples.
179
180 Trpos SIMPLES Y coNJUNTos
As por ejemplo, el tipo integer es un tipo simple (sus valores son atmicos), es pre-
deflnido (ya viene prefljado en el lenguaje Pascal) y en particular es un ordinal (todc.
tienen predecesor y sucesor excepto el primero y el ltimo). La figura 6.1 nos muestr-
un resumen de los tipos de datos en Pascal.
EWy,
Puntero
I
Ordinal I Array
I Registro
l pr.a.ni.to IL Conprrrto
Ir r...q." Fichero
It
I l Char l- e,"aetinioo
I L- eoor...
L Defi. Proora* u.lo, IL f'"*.
Defi. Programador
I
lL Enunr erado
Subrango
La sintaxis en Pascal que debe emplear e1 programador para deflnir un tipo de datc,,
es la siguiente:
TYPE
TldentificadorTipo 1 = ExpresionDeTipo 1;
.: : ,:;j': I- emploDeTipos;
TY!E
TFniero = integer;
Trpo pNutrERADo 181
ipo, i, j: TEnt.ero;
:' .':""u'
Jre-
dos Se vern a continuacin tres expresiones de tipos para describir nuevos
dominios: enu-
stra lnerado. subrango y conjunto.
Entre parntesis se escribe la lista de valores que def,ne el dominio de los datos
sepa-
rados por comas, es decir, los posibles valores que pueden recibir las variables
de tipo
lldentificadorTipo. El tipo enumerado es un tipo ordinal ya que la posicin de un
(idevalor-i) en la lista de la declaracin establece un orden entre
identificador de valor
ellos: el primer identificador est en la posicin 0, el segundo en la 1, etc. Las opera,
'-iones que se pueden realizar sobre ejemplares de tipo enumerado son las propias de
los operadores relacionales y las funciones succ, pred y ord. Los valores
e tipo
numerado se pueden pasar como parmetros reales en las llamadas a funciones y
ItOS pro-
--edimientos.
Pascal no permite realizar operaciones de lectura y escritura sobre variables
de tipo
:numerado. Por tanto, para poder leer y mostrar datos al usuario, el programador
dete
:lacer corresponder los valores de tipo enumerado con los valores que aceptan
los proce-
Jrmientos predeflnidos de lectura y escritura . El siguiente fragmento de cdigo
muestra
:n ejemplo del tipo enumerado que modela das de la semana y cmo la funcin leerDia
:evuelve el da de Ia semana solicitado al usuario. Para ello, en la instruccin
CASE se
lna :stablece una corespondencia entre el tipo de datos TDiasSemana (tipo enumerado)
rse e
-::eger (tipo de datos que utiliza la funcin readln).
p1o
res ; IGRAM LosDiasDelaSemana,.
-:?E
TDiasSemana = (Lun, Mar, Mie, Jue, Vie, Sab, Dom) ;
:jl
dia, hoy: TDiasSemana;
t82 TIPoS SIMPLES Y CONJUNTOS
:/: -reelU].d
--.^ := Sb
hJNJJ; t deI case l 1
END; {t eeroiai
Errores comunes
Un error comn en los programadores noveles es confundir los valores de un tipo en-'
merado con cadena de caracteres. Los valores de tipo enumerado son identificadort
completamente diferentes de las cadenas de caracteres y con restricciones y caracteri''
ticas particulares. No se debe repetir un mismo valor en distintas deflniciones de tip
enumerados y no se deben redefinir palabras reservadas. El siguiente ejemplo mues!:-
declaraciones de tipos de datos errneas.
TYPE
TBoleano = ('verdad', 'falso')
{error: no son identificadores, son cadena de caracteres}
TAmigos=(pepe, juan, pedro, miguel)
TEnemigos= (antonio, pedro, enrique)
{error: se repite el valor pedroi
TNotas = (do, re, mi, fa, so1, Ia, si)
{error: pa}abra reservada do}
en el ejemplo anterior ste sera el tipo de los nmeros enteros. Este "supertipo" se de-
nomina tipo base o tipo anfitrin y debe ser de tipo ordinal. La sintaxis de Pascal para
declarar un tipo subrango es la siguiente:
-- ---r
_ __-
TNumMes = 1..L2;
:
--ICTION LeerNumMes TNumMes;
:
::,
entMes : int.eger;
]: ATIT
_ _ JII!
REPEAT
write ('Introduzca ef mes (formato tt4ytt
) : ') ;
readln (entMes) ;
LIITTIL (entMes >= 1) AND (entMes <= 72) ;
LeerNumMes := entMes;
L
184 TTPOS SIMPLBS Y CONJUNTOS
sobre el que se define la coleccin de elementos que tendr el conjunto y debe ser u:
ordinal. Los valores que describen al conjunto se expresan con la sintaxis:
[] i st.a- elementos l
Donde lista-elementos es una lista (puede ser vaca) de constantes, variables o e'-
presiones del mismo tipo de dato separadas por comas y enceradas entre corchete'
Ejemplos de conjuntos:
TYPE
TColores= (rojo, azu1, verde, amarillo);
TConjuntoColores = SET 0F TColores;
VAR
conjA, conjB, conjC: TConjuntoColores;
BEGIN
conjA:=frojo, azul, verde]; {conjunto de tres coloresi
conjB.= [rojo. .verde, amarillo] ; {conjunto de cuatro colores}
conjC:= [1 ; {conjunto vaco}
En la asignacin a una variable de tipo conjunto los elementos del conjunto deben "
compatibles con el tipo base. La tabla 6.1 muestra las operaciones que se pueden
con valores de este tipo de datos. El nuevo operador IN tiene la mnima prece(
respecto al resto de los operadores estudiados hasta el momento. I-a tabla 6'2 mue'
la precedencia entre operadores incluyendo los de conjuntos. El siguiente fragmentt-
cdigo muestra un ejemplo en el que se construyen los conjuntos de nmeros pafes
impares desde 0 hasta 9.
CONST
ITiIAXNUM=9;
TYPE
TDigitos= 0 . .9;
TConjunto= sET 0F TDigitos;
TRango= 1..}4AXNIIM + 1;
VAR
pares, impares: TConjunto;
i: TRango;
BEGIN
pares := [];
impares := [];
FOR i := 1 to MAXNUM do
IFimod2=0THEN
pares := Pares + [il
ELSE
TIPo CoNJUNTO 185
Observar que la variable i de tipo subrango ha sido declarada con el lmite superior
-:-'-NUM + 1 para evitar desbordamiento de valores al finalizar el bucle FOR. Los ele-
3ntos de un conjunto no son accesibles directamente. Es decir, no se pueden leer
-r:ictamente del teclado (con read o readln) ni se pueden escribir directamente (con
---:e o writeln). Para visualizar los elementos de un conjunto:
1. Se toma una variable del mismo tipo base del conjunto.
l. Se asigna a dicha variable el primer valor del tipo base.
. compiladores suelen restringir el uso del tipo conjunto por cuestiones de implemen-
,rn, obligando al programador a reducir la amplitud del domino del tipo base. por
: :rrplo, en TurtloPascal, el elemento mayor de un conjunto no podr superar a1 ele-
rtto con valor ordinal255, el menor no podr ser inferior al que tenga el valor ordinal
. no podr tener ms de 255 elementos.
186 TTpOS SIMPLES Y CONJUNTOS
+, -r 0R 2
<, <=, =, ), )=, <>, IN 1
precedente es el 4)'
Tabla 6.2: Precedencia entre los operadores (el nivel ms
VAR
x:1..10;
y: (A, B, C) ;
z: (A,B,C) ;
en el moment -
ejemplaies de diferentes tipos. Estas reglas se utilizan por ejemplo
es correcta desde el pu
urignu. una variable u otru y poder determinar si la asignacin
de vista de la compatibilidad de los datos.
Untiposedefineexplcitamentecomodeotrotipo.PorejemploTlesidnti.
T3. ya que el identificador T1 es usado explcitamente para definir T3 (lnea -1
,t) rYPE
.rl m1 Ta - lr..100;
LLt-
-l
]
') T? = T.l .
-- t
..+) T4 = L..1oo;
T1no es idntico con los dems ya que no es declarado explcitamente con Tl, T2 ni T3.
Dos tipos son compatibles si al menos una de las siguientes declaraciones es verdadera:
o son idnticos,
. uno es subrango de otro o
o ambos son subrangos del mismo tipo base.
t1 y t2 son idnticos.
o t1 es real y t2 es entero o un subrango de entero (realmente el compilador hace
conversin automtica y pasa L2 a real).
rer-
de o t1 ) t2 son tipos ordinales compatibles (y para que no haya desbordamiento e es
un valor permitido de1 tipo t1).
dos
6.7 Cuestiones de tipo test
loa 6.7.1 Enunciados
).
Las siguientes cuestiones pueden tener una o ms respuestas correctas:
ima
nla 1. Dada la siguiente definicin de tipos y constantes:
188 TIPOS SIMPLES Y CONJUNTOS
CONST
N = 10;
TYPE
TColor = (amarillo, azul, rojo);
TDigito = 0.'9;
TMinusculas = a..zi
TConiNumeros = SET 0F TDigit.o;
TConjLetras = SET oF TMinusculas;
VAR
n: 1..N + 1;
es correcta:
Decir cul o cuales de las siguientes afirmaciones
se puede declarar --
(a) La declaracin de TMinusculas es correcta porque
subrango del tiPo char'
(b)LadeclaracindeTColoresincorrectaporqueenlugardeparntesisdebe:-
haber corchetes.
(c)Ladeclaracindelavariablenesincorrectayaquenosepuededeclarar--
subrangoconoperacionesaritmticasenlapartededeclaracindevariabl..
de TConj Numeros es correcta ya que
el tipo base es adecua-
(d) La declaracin
y la sintaxis tambin'
ocurrira que:
2. Si el siguiente fragmento de cdigo se compilase
PROGRAM Coche;
TYPE
TCoches= (BMW, Mercedes, Ford, i"lat ) ;
TCamiones = (Ford, Man, Pegaso, Renault, Mercedes) ;
VAR
tuCoche: TCoches;
tuCamion: TCamiones;
BEGIN
writeln ('escribe el nombre de tu coche Y camion') ;
readln(tuCoche, tuCamion) ;
r \Tn
sintcticos'
(a) El bloque de declaracin de variables tiene errores
(b) El bloque de instrucciones presenta effores de compilacin'
(c) El bloque de cleclaracin de tipos es incorrecto'
( d) La cabecera pRocRAM presenta un identif,cador de programa incorrecto'
Cuosrrolos DE TIPO rEST 189
PROGRAM ProbO4;
VAR
x2, y2: integer;
--^^t
xJ: lcdr,'
PROCEDURE Procesa(veR x:integer; VAR y:real) ;
BEGIN
END;
BEGIN
Procesa (x2, y2) ;
r,l -_ r,a.
.- ILt
^J
END.
PROGRAM Ta]]a;
VAR
tallas: SET OF 1. .80;
etiquetas : (' s"' M"' L"' xL"'xxl' ) ;
BEGIN
tallas: = [60] ;
writeln (' int.roduce las tallas' ) ;
readln (tallas) ;
wrir,eln ( ' introduce Ias etiqueLas' );
readln (etiquetas) ;
END.
TYPE
T1 = 0..33;
ra
LZ
_ 1n
_ IV.,JJI
2?.
VAR
,,1
VI.
. TT
I, .
tr). f),
de compilacin.
(d) La asignacin v2;= ,,rl puede ser incorrecta dependiendo del valor de v1.
TYPE
TRango = 1..500;
con NumeroHabi tac ion?
Es la siguiente expresin asignacin-compatible
(a) S, pues el resultado de la expresin es un valor que est dentro del domr:
NumeroHabitacion.
de
(b) No, pues el resultado de la expresin es un valor que est fuera del
de NumeroHabitacion.
(c) 1o, pues el resultado de la expresin es un valor real, y TRango es
6.7.2 Soluciones
Las respuestas correctas son:
I d La declaracin de TMinusculas es incorrecta porque faltan comillas simples a
6.8 Problemas
6.8.1 Conversin de formato de fecha
>: desea realizar un programa que pida al usuario una fecha en formato DD MM AA,
-,,11o por ejemplo 12 01 01 (dos dgitos para el da, dos para el mes y dos para el ao) y
,: muestre por pantalla con el nombre del mes y con cuatro dgitos del ao. Por ejemplo,
., salida de la fecha anterior debe ser " 12 de enero de 2001 ".
6.8.3 El semforo
f,:alice un programa que simule el comportamiento de un semforo. Cada vez que se
:ulse la tecla intro cambiar de color. El programa terminar cuando cambie de color n
:ces (por ejemplo n=10). Para realizarlo utilice un tipo enumerado.
oNmerodeletras(sincontarlosespaciosenblancoysignosdepuntuacin)'
o Nmero de vocales.
o Nmero de dgitos.
o Nmero de smbolos de puntuacin (:;,'i!?)'
6,9 Soluciones
;l IGRAM ConversionFecha ;
lcnvertir eI formato de una fecha)
INTRADA: Ia fecha en formato dd mm aa]
SALIDA: la fecha en formato dd nombre mes y aaaa)
-:PE
TMes= (ene, feb, mar, abr, may, jun,
juI, 9o, sep, oct nov, dic);
TNumDi-a= 1..31;
TNumAnyo= 0. .99;
TNumMes= L. .L2 ,
- -- f
dia: TNumDia;
MCS: TNumMeS;
anyo : TNurnAnyo;
nombreDelMes: TMes;
mes : = entMes;
REPEAT
write ('Introduzca el ao (formato rrAAtr. /
)
readln ( entAnyo ) ;
UI\ITIL (entAnyo >= 0) AND (entAnyo <= 99);
anyo : = entAnyo
:-JJJ; t Leerl,'echa i
VAR
i: TNumMes;
mesActual: TMes;
BEGIN
mesActual := eflei
FOR i: = 2 TO NoMes DO
mesAcLual :=
SCC(mesActual) ;
NombreDeMes : = mesActuaf
END; {nombreDeMes}
(NOMMCS : TMES) ;
PROCEDURE ESCTibCMCS
BEGIN
CASE nomMes OF
ene: write (' enero' ) ;
feb: write (' febrero' ) ;
mar: write ('marzo' ) ;
abr: wrice i' abril' ) ;
may: write ('maYo') ;
jun: write 1'junio') ;
jul: write ('julio') ;
ago: wriLe (' agosto' ) ;
sep: $rrite(' sePtiembre' ) ;
oct: NriLe(' ocLubre' ) ;
nov: write ('noviembre' ) ;
drc: write (' d'iciembre' ) ;
nNo {Case)
END; {escribeMes)
IIPE
TMedio= (bicicleta, autobus, coche, avion);
---R
cpcion: char;
prisa, barato: boolean;
IF barato THEN
IF prisa THEN
Mej orTransporte : = auLobus
ELSE
Mej orTransporte : = bicicleta
ELSE
IF prisa THEN
MejorTransporte := avion
ELSE
MejorTransporte := coche;
r'-f .
CASE T OF
bicicleta: writeln ('bicicleta' )
6.9.3 El semforo
El estado del semforo es simulado por una variable de tipo enumerado de tres valor-'
(\os tres posrbles co\ores). La tuncrn Darvalor petmite a\ usuario rrrediante 1.I 111er:-
indicar el estado inicial. La funcin Siguiente deduce el siguiente color al que tier.:
que cambiar el semforo mediante operaciones succ (ntese que para el ltimo va1'-
enumerado no se aplica la operacin succ).
PROGRAM Semaforo;
{simulacin de un semforo}
{uutnAoe' estado inicial deI semforo}
isalfoa, cada vez que se pulsa tecla intro
eI semforo cambia de estado)
CONST
N= 10;
TYPE
Tsemaforo= (verde, amarillo, rojo) ;
VAR
s: TSemaforo;
.l i raaav.
I. rtluuYu!,
IFn=rojoTHEN
Siguiente: = verde
ELSE
Siguiente: = succ (n) ;
END;
, -*1-6^ar.
_---!Y!! /
--l:
: --: - ll- :.=:lu : Integer;
Sor,ucroNBs
t9l
VAR
j : integer;
BEG]N {uenu}
REPEAT
writeln(,Escoja una de las tres opciones,)
writ,eln (, 1 . Semaforo en rojo,
);
writeln(,2. Semaforo en amarillo,) ;
writeln (,3. Semaforo en rar^^
vurvu / \
/, -
readtn (j ) ;
Ut\TTrL (j , o) s (j < 4);
Menu:= j;
END; {tvlenu}
:EGIN {tarValor}
i:= Menu;
CASE OF i
L: DarVal_or := rojo;
2: DarVa1or := amarillo;
3: DarVa1or := verde;
END;
lD; {DarValori
rI amenfos
.mentos del conjunto
nnni',-r^ realizando
*^-r:-^,-, .
;;;,#;iffiril:
,vvurrrIvtrLU
$T'
{-.
.:.IGRAM Mayusculas
; :
--star letras maysculas de una frase
)
:NTRADA: una frase t.erminada en un punto)
198 TIPoS SIMPLES Y CONJUNToS
BEGIN{Programa principal i
cnniR .=
. l-l
t_)
.
I
PROGRAMRepartirCartas ;
iRepartir cuatro naipes de una baraja a cuatro jugadores
sin repetir naipe)
SolucroNps 199
:lrnonnl
lEU. . 1
-_!f J
CASE (Random(4) + 1) 0F
1 : dameUnPalo: =oro;
2 : dameUnPalo: =basto;
3 : dameUnPalo: =espada;
4 : dameUnPafo: =copa;
END i
dameUnNaipe : =Random ( 10 ) +1 ;
I'in .
CASE palo OF
oro: estaRepetido := naipe IN oros;
copa: estaRepetido := naipe IN copas;
espada: est.aRepetido := naipe IN espadas;
basto: estaRepetido := naipe IN bastos;
END;
I'Tn .
naipe: =dameUnNaipe;
L'IiTIL (NOT estaRepetido(oros, copas, bastos, espadas,
palo, naipe) )
END;
espadas := [];
FOR jugador := 1 T0 4 D0
D DN TIT
DEgf t!
writeln ('Cartas del jugador ' , jugador) ;
FOR reparLos := 1 T0 4 D0
reparteCarta(oros, copas, bastos, espadas) ;
END;
ra:,n I r .
Palabras;
?ROGRAIvI
compara dos palabras)
,ENTRADA: dos palabras terminadas en punto)
SALIDA: Ietras en comn, letras que slo
-iene la primera patabra y letras que s1o tiene la segunda)
:ONST
LETRAS= l'a'..'z'f + ['A'..'Z');
IYPE
TConjunLoletras= set 0F 'a' ..'z' ;
..iAR
^]^--.,
L qr . u110!
IEGIN {LeerPaIabra}
ni ta .= ['l
writeln('escriba una palabra acabada en punto y puise INTRO')
read (car);
WHILE (car <> ' .') D0
BEG]N
IF car IN LETRAS THEN
202 Trpos srMpLEs y coNJUNTos
END; {leerealabra}
VAR
I arr: . nL-.
ELSE
WHILE (cjLo <> [1 D0
BEGIN
IF (Ietra IN cjto) THEN
BEG]N
write (letra) ;
cjto := cjto - [etra]
END;
Iecra := Succ(letra);
END;
END ; { MuescraConj unto }
?ROGRAM Frase;
,Hacer estadsticas sobre una frase Lerminada en puntoi
'ENTMDA: la frase a estudiar acabada con un
'.')
.SALIDA, Numero de letras, vocales, dgitos
y signos de puntuacin)
]ONST
TEI-DAq- ltt tzt tLt tVt1.
L s .r 4 )t
VOCALES= l, a, , ,
,
e , , i, ,
, o, ,
,t), , , A, , ,8, , , I, , , O, , ,U, ) ;
DIGITOS= l' A' . .'9') ;
ESPECIALES=I' :',' ;',',',' .',t"t tt?',",' !'7;
-.rAR
:ND;
EsDigito := c IN DIGITOS;
:\Tn.
nEspe: integer) ;
ENI
BEGIN Mos
rTolr:o .- A. ]ND.
nvccales : = 0;
-ILr!rLVD .- V/
6.9.8
i:na ..- A.
- u/
tr\Tl .
-f,s val
,ncir
PROCEDURE Increment.ar (VAR a:integer) ; :.rn&dO
:_?..
BEGIN
a := a + 1;
END; . ?,OGI
Leal
PROCEDURE MostrarEstadistica(a, b, ct d:inLeger) ;
:NTT
BEGIN :ALl
writeln ('ESTADISTICAS' ) ;
-:PE
writeln('Numero de letras = ' ,a\; T'
-'f
writeln('Numero de vocales = ',b);
-1
writeln('Numero de digitos = ' ,c);
writeln('Numero de signos de puntuacion = ',d);
EINJJ ; tmoStrarestadrstrCa.|
-:=-i
BEGIN {Programa principal} --a
writeln ('Introduzca una frase terminada en punto ' ' .' ' ') ;
:a
END
ELSE
IF EsDigico(car) THEN
Incrementar (numDigitos)
ELSE
IF EsPuntuacion(car) THEN
Incrementar (numEspe) ;
:rn IF Esletra)
--^^l ^^--\
:=fU edll;
Sor-ucroNns 205
rND; {wHrlu}
It{ost rarEstadi s t ca numletras,
( numVocale s, numDigi tos, numEspe ) ;
:-.) . t Programa prlnC lpaI
f ^ r l
.f
.?OGRAM PiedraPapel;
Realizar todas tas posibles jugadas)
INTRADA: )
-:ALIDA:para cada jugada decir el ganador)
ITPE
TJugada = (piedra, papel, tijera);
--tD
)l , j2: T.Tugada;
ELSE
END; {rOn z}
END. {Programa principal}
.,1
.i
: tlli
- .;
--J\
J.
,efO
:asilli
lifere
a
a
I
cl
I
Captulo 7
207
208 LOS TIPOSDEDATO ARRAY Y STRING
t c a d r a C t
p p p p p p p p
P P P P P P P P
T C A D R A C T
(b)
(o)
(o)
Figura7.1:Ejemplosdeobjetosquesepuedenmodelarconarays:(a)tablerode:.
drez, (b) vector en el esPacio
arrays
1.L,1 Definicin de tipos y declaracin de variables
Untipoallaysedef,neentrminosdeuntipondice(qued{serdetipoordinal)r:'
utiliza la siguiente sintaxr'
array" norir" rarray se
tipo base. para definir .rn tipo
TIndiceNl OF TElemento
TArray = array lTIndicel
Losarayspuedentenerdiferentenmerodedimensioio::'Lt""indelnmer'-'
es un tipo ordinal
que exp:'
uru'""";";i" def,nicin' Cada rrndicei de acc'-'
Trndicei 0," ;;;y en esa dimelir y el modo
ro'Inu"
e1nmero . to''pol]""i"t lo" "1
aellas.TElemento"'"ftipobasedelarruyyd"fl'"eltipodeloselementosquec':- que mocl'.:"
datos y declarar variables
aelr1r tipo'it
tituyen la estructura' r"0* forma:
los datos ."pr"ttnt"d*'' en la f,gura 7' 1' de la siguiente
SVDE
T\/etr3D = arra! t1"31 OF real;
d' e' f' g' h);
I VL9UVJ-
TColumnas = (a, t, c,
OF char;
rrFal.r or = array [1 ' ' I , TColumnas]
I Iq!re!v
VAR
vectorl : TVector3D;
vector2 i arra tl-"31 OE real;
tablero: TTablero; iables de ttP
tipo arrav se declaran
L:is i arlables de *i,T]tH-H:: ffit::r.Xi;;
Ii"l:1,*f :Jll'"n'Ii'"i;;;*,."'T"I::,':::]tTili,Tl:
*:il:TT#?:Ti:T:"#J;n:;l*:t'::xi:;'JiJlXlf ;:ffrazono
'
por las
p'"tr", no es recomendable'
TJ#J*T*Hi::irffffi
enlaseccin7 '2'2'
"'
expondrrn
Oprna.croNEs CoN ARRAYS 209
(o) tb)
, i_gura 7.2: Acceso a los elementos de un array: (a) bidimensional de dirnensiones MxN,
r r unidimensional
-. acceso a los elementos individuales de un array se lleva a cabo a travs del nombre
-.' la coleccin seguido de uno o varios ndices entre corchetes que indican la posicin
,:1 dato dentro del array (ver figura 1 .2). El nmero de ndices necesarios para el acceso
, un elemento es funcin de las dimensiones del array. Por ejemplo, un programa que
,,lcule el mdulo de un vector facilitado por teclado podra escribirse de este modo:
.: IGRAM CalculaModulo
--:_i
vector: TVector3D;
modulo: real;
]]^T\T
, _,-aL\
writeln('Escriba 1as componentes x, y, z del vector');
readln(vector[1], vector[2], vector[3] ) ;
modulo : = sert (sqr (vector [1] ) + sqr (vector [2] )
r^r \ \
- T(.ra
qr \vtruLOI LS) ) I i
writeln('Ef modulo es: ',modulo);
:l:l .
TYPE
TDiasSemana (Iun, mar, mie, jue, vie, sab, dom)
=
TArrayDeDias = array ITDrasSemana] OF integer;
VAR
visitasMuseo : TArrayDeDias ;
ora: llJlassemana;
Para recorrer toda 1a coleccin pasando por cada uno de los datos, se puede utilizar ui-
estluctura de repeticin. Por ejemplo, para pedir por teclado las visitas recibidas ca- t12
da de la semana:
_os
FOR dia : = lun T0 dom DO
readln (visitasMuseo [dia] ) ; :d
rbl
El acceso a cada elemento de un amay de 1 dimensiones se realiza a travs d -
:'1
ndices. Supngase, por ejemplo, que se necesita guardar las temperaturas mxir.- -r t
diarias registradas en un conjunto de ciudades durante un mes. Para ello se define -' ,la
tipo de dato como el siguiente:
TYPE
:n
TCiudades = (Soria, Madrid, AviIa, Zamora);
l - -
- t..JLt
.. el
TTabla = array [TDias, TCiudades] OF real;
. -1
VAR
tabla, tablaBackup:
ir
TTabla;
Clu : 'l LluoadeS ;
dia: TDias;
Para leer las temperaturas de todas las ciudades cada uno de los das:
FOR dia := 1 TO 31 D0
FOR ciu : = Soria TO Zamora DO
Readln (tabla Idia, ciu] ) ;
elt
Para leer las temperaturas de todos los das para cada una de las ciudades basta
modificar el orden de anidamiento de los bucles.
\,
]la
-{signacin de arrays completos
Como ocurre con todos los tipos de dato compuestos, no se pueden rcalizar
de entrada/salida con rrays completos. sin embargo, s est permitido asignar
ctnrpletos cuando stos son de tipos idnticos. Por ejemplo, la instruccin:
:a:-a!ackup := tabla;
asigna a --ab-aBackup los datos almacenados en tabla.
OprucroNEs coN ARRAYS 2tt
Porie lleno Poe voco
tope maxamo
1ar una
ts cada
7,2.2 Arrays como parmetros de subprogramas
Los arrays pueden ser pasados como parmetrs a funciones y procedimientos. Para ello,
:e declaran como parmetro empleando un tipo delinido (no annimo) en la cabecera del
.ubprograma. En el paso de anays por valor y por referencia los parmetros formales y
sdel/ :eales deben ser de tipos idnticos. En Pascal, las funciones no pueden devolver valores
ximas :e tipo arrayi de modo que cuando sea necesario que un subprograma devuelva un
line un rrray, ste debe ser pasado como parmetro por referencia de un procedimiento.
El paso por valor de cualquier variable conlleva la generacin de una copia del valor
:n el parmetro formal. Si pasamos un affay, se copiarn sus elementos en el parmetro
-onnal, lo que supone un gasto sustancial de memoria. respecto al paso por referencia,
:n el que no se genera copia. Por esta razn, los arrays son usualmente pasados por
:et-erencia aunque no se pretenda cambiar el valor de sus componentes. Cuando se lleva
r cabo esta prctica, es necesario prestar especial atencin al uso de los parmetros con
:1 fin de evitar efectos indeseados.
ULTIMO
:YPE
rlaEca
2t2 Los trpos DE DATO ARRAy y srRrNc
Donde las constantes pRTMERO y uLTTMO y el tipo TBase han sido previamente
Es posible construir un procedimiento sencillo para pedir por teclado un nuevo da:
END;
END; {anadiri
CONST
MAxIMO
el pa
TYPE
S
Tstring = string tUaXflOl ; ios
OpnucroNrs coN srRrNGS 213
]3NST
LONGMATRICULA = 7;
. YPE
matricula : TMatricula;
frase: string;
Se puede acceder a los componentes individuales (caracteres) ile una cadena a travs de
'u nombre seguido de un ndice entre corchetes (de un modo similar a como se procede
.'on las variables de tipo array). Por ejemplo, si se necesita extraer la inicial
de un
rombre. guardado en un st.ring:
.-ROGRAM Iniciales .
Sintaxis
Descripcton . .- -
Funcin
orrcatena dos exPresiones
strlng
concat concat (cadena1,
cadena2 )
-.-_.--- (cadenar
length L length )
strinq
pos
1
\.,
]l^.pos (cadenar,
i .in la que comienza 1a cadenal
dentrt'
:
para el nr'
funciones y procedimientos predefinidos
7.4.2 Operaciones,
nejo de strings
EnestaseccinSepresentanlasoperaciones,procedimientosyfuncionespredefr
c1e dato string'
para el tratamiento del tipo
en Pascal
Operaciones
strins admite o"
Er tipo de rrato "1": 111T'f::'::,:i::Ttl1":"":,;fl: l,ll"if}'
puede ser una constante' una
::i;i::Jj":="'J;'e';t"", i*u. expresionI ^ +:^^ ^1r. r
cualquiera de1 tipo string o de tipo char'
o rnu
"^pr"rin
VAR
cadenal: string;
cadena2: string [3] ;
BEGlN
,HOLA';
cadenal-
cadenal cadenal [3] ;
cadena2 'Maria';
Eristelaposibilidaddequelalongituddelacadenaresultantedelaevaluaci-
e r presi n s e a mav or ;; ""; t;l;;i"? *'i111 ,1T*:iJ[ll;l
i: :: l"T:f,*nicamente los datos] i .
::1fi:::J::,"J:il;"";;'"""+ "' ejempio'
""" "u'o''" 9"u,'9""
cdigo anterior' la variable
que se ha reservado*"*o'iu' Por "" "l
'
I
l
Procedimientr Sintaxis Descripcin
delete delete ( cadena, Borra tamao caracteres de cadena a par-
posicion, tamao) tir de posicion, de modo que la cadena re-
,I-] duce su longitud en el nmero de caracteres
eliminados
tosi- insert insert (cadena1, Insefta cadenal en cadena2 a parlir de
ntro
I
posicion. Como resultado de la insercin,
I
iin- |
posicion) cadena2 aumenta su longitud un nmero de
ool crracteres igual a la longitud de cadenal
str sLr (exprNum, Convierte el valor de exprNum en su repre-
I
l*- l
val
cadena)
VaI (cadena,
valorNumerico,
codigoError )
sentacin como cadena de catacteres y 1o
devuelve en cadena
Conviefte el string guardado en cadena en
su valor real o entero valorNumeri co. Ade-
ms, devuelve en codigoError un valor en-
tero que ser 0 si se puede hacer la conver-
sin, o la posicin del primer carcter que
:l ma- produjo el error en caso contrario
A1 contrario que con los arrays, est permitida la lectura y escritura de variables de
tipo string completas, utilizando los procedimientos predeflnidos read, readln, write
y writeln.
rna ge-
ariable Adems, se pueden utilizar los operadores rglacionales para comparar dos strings.
La comparacin se lleva a cabo carcter a carcter. Si una cadena es ms corta que la
otra, se compara como si la ms corta se rellenara con espacios.
Por ltimo, es posible concatenar dos expresiones cualesquiera de tipo string me-
diante e1 operador "+"" En el siguiente ejemplo se muestra por pantalla la cadena ".luan
Garcia":
rombre := 'Juan';
apellJ-do := ' Garcia' ;
actor := nombre + apellido;
n de 1a writeln (actor) ;
a ltima
para los
:adena2 Se debe observar que el espacio en blanco es aadido explcitamente en la variable
ape I 1 ido.
216 LOS TIPOS DE DATO ARRAY Y STRI,NG
Funciones predefinidas
7.5.1 Enunciados
l. Cul de los siguientes tipos de dato NO puede ser ndice de un aruay?
(a) Enumerado.
(b) Subrango.
(c) Conjunto.
(d) Boolean.
2. Cul de las siguientes frases es ciefta?
(b) Los arrays son tipos de datos estructurados que permiten guardar cualquier
tipo de dato simple excepto los de tipo char, que se guardan en strings.
(c) Un array es una coleccin estructurada de componentes'del mismo tipo.
(d) Los arrays parcialmente llenos son aquellos que permiten modilicar su ta-
mao.
!.,:
5. Si un real necesita 4 bytes. un carcter I byte y un entero 2 bytes, cunta memoria
necesitar una variable del siguiente tipo de dato?
(a) 10 bytes.
r (b) 48 bytes.
(c) 40 bytes.
(d) 24 bytes.
(a) Es incorec'.a.
J4U Oectara un tipo de datos para contener 30 elementos booleanos.
(c) Declara un atray bidimensional de l0 elementos enteros y 3 elementos de
tipo char.
i-^-
Ir Jl . (d) Para acceder a sus elementos tendremos que usar dos ndices.
ren-
1 . Cllde las siguientes afirmaciones es (son) conecta(s)'/
7.5.2 Soluciones
1. La respuesta correcta es la (c). El tipo ndice de un amay debe ser obligatorian-.. -
de tipo ordinal.
7.6 Problemas
7.6.1 Acceso a los elementos de un array unidimensional
Implemente un programa que lea un vector de 10 enteros desde el teclado y muestre por
latos
pantalla estos elementos pero en el orden inverso al que fueron introducidos.
Disee un programa que pida al usuario un vectorX compuesto porN (N: 10) nmeros
reales {-r1 ,. .. ,xu}. Calcule a continuacin el valor medio (r) y la desviacin estndar
nente (o) de los elementos del vector.
rados
ro de
7.6.3 Encontrar elementos en una coleccin unidimensional
dinal.
os no 7.6.4 Desplazar elementos en un vector
empo
Construya un subprograma que despiace todas las componentes de un vector de N ente-
ros un lugar a la derecha, teniendo en cuenta que la ltima componente se debe desplazar
.o que al primer lugar. Generalice el subprograma anterior para desplazar las componentes k
S. lugares. Utilice los subprogramas construidos para escribir un programa que pida at
puede usuario un vector y un nmero de desplazamientos y que imprima el vector resultante.
recifi- Construya los procedimientos necesarios para permitir el desplazamiento de k luga-
res a la izquierda.
e slo
1 COn- 7.6.5 Separar elementos de un vector siguiendo un criterio
rda.
Dada una lista de elementos enteros, construya un subprograma que devuelva el vector
de los elementos pares y el de los elementos impares contenidos en la lista.
arrays
que la 7.6.6 Acceso y recorrido de un array bidimensional
lificar
Construya procedimientos que permitan:
le tipo
1. Leer una matriz por filas.
220 LOS TTPOS DE DATo ARRAY Y STRING
1.
7.6.10 Dibujar un histograma
2.
E:-'rba un programa que pida al usuario una lista de 30 temperaturas. A continuacin.
.!.r.1 dltidir ei intervalo entre la mayor y la menor temperatura en 10 subintervalos r
.Llnstruir un histograma con el nmero de temperaturas que se encuentran en cada uno
J.
de e 11os. Finalmente. se pide imprimir el histograma.
Pnonr,nnrls 22r
Cree un programa que sustituya todas las vocales que encuentre en un texto por el carc-
rer
tt*".
7.6.13 Palndromos
Disee una funcin que dada una lnea de texto nos diga si es palndroma. lJna palabra
o liase palndroma es aqulla que se lee igual de izquierda a derecha que de derecha a
rzquierda. Son ejemplos de palndromos "anilina" o "dbale arroz alazorra el abad".
Debe contemplarse adems la necesidad de eliminar los blancos de la frase para que el
nlisis de la misma sea el correcto.
IYPE
tSimbolos = string[4];
]ONST
MORSEt arrayl',a',..',z',f = (',.-" ',-..."
OF Tsimbolos
, , ,
'-.-.' , '-..' , ., , ..-., , --., , ...,, , , ,,, , , .--- , ,
,
Realice un programa traductor a cdigo Morse de tal manera que le introduzcamos una
palabra (en lenguaje natural) y la codilique en cdigo Morse.
3. Un subprograma que concatene dos cadenas de caracteres que se pasan como pa-
rmetro y que devuelva el resultado en otra cadena.
222 LOS TTPOS DE DATO ARRAY Y STRING
(
jr
n
d*!- jggadsr 3 (r
qu* quiarr:e rtrsu*ir t* f cla {l-1}:
"n'fi ul
or
C(
7.
Se
-'o
:iz
.ol
Figura 7 .4: El jtego de "las cuatro ertraya"
1.
-'Ui
4. Un subprograma que extraiga una subcadena de una cadena dada, de una longit -
-s
determinada a partir de la posicin de un carcter inicial.
,. 'c
I.,lo se permite el uso de variables de tipo string en ninguno de los apartados anterior."
'C', 'H', 'O', 'N' como los elementos bsicos de la qumica del carbono.
. '2','3','4','5' y '6' como ndices posibles de estos elementos.
Se pide analizar esta frmula para:
7.7 Soluciones
7.7.1 Acceso a los elementos de un'array unidimensional
PROGRAM Arrays0l;
CONST
N=10;
TYPE
Tvector = array t1..Nl OF integer;
VAR
i: integer;
vect,or: TVector;
END;
224 LOS TIPOS DE DATO ARRAY Y STRTNG
,.,-i r^t -.
writeln ('El vector introducido en orden inverso es: ') ;
FOR i := N DOWNTO 1 D0
write (vector [i] , ' ') ;
writeln
ENIJ . t Programa prlnclpal ]
PROGRAM Arrays02;
CONST
N = 10;
TYPE
TVector = array t1..Nl OF real;
VAR
vector: TVector;
I
PROCEDURE LeerVector(VAR v: TVector) ; )l
VAR
'i 'i nr anav
l11t!YU!,
.
BEGIN
FOR i: =1 T0 N D0 BEGIN t:
writeln('deme el elemento ', i, ' del vecLor');
readln (v lil )
E\TN .
ENIJ; t LeerVector ]
SUma: real;
BEGIN
SUma : = 0;
FOR i := 1 TO N DO
Suma := SUfll + v[i] ;
Media : = suma/N
:l.l ; it''reaia i
|
_-- -
_=:cr
- nnnu
i
. i
l.:f :l-:.: feal;
SolucroNRs 225
:]GIN
f,^rrm
quuLLr , -
.- n.
v,
?R.OGRAM Arrays03;
:CNST
N = 10;
IYPE
Tvector = array [1. .N] oF real;
.,'AR
vector: TVector.
IUNCTION Maxlmo(v: TVector) : real;
]/AR
i. irran--.
rrugYUr /
maximoParc: real;
3EGIN
maximoParc := v[1];
FOR i := 2 TO N DO
IF v[i] > maximoparc THEN
maximoparc := v[i] ;
Maximo : = maximoParc
END; {Uaximo}
-t
END. tPrograma prlnclpal-|
PROGRAM ArraysO4;
CONST
N = 10; l
TYPE -:,'
TVector = array [1..N] OF integer;
VAR
vector: TVector;
nDespl: integer;
BEGIN
FOR i := 1 TO k DO
DesplazarlD (v) ;
IND; {DesptazarKD}
writ.eln
END; {ImprimirVector}
BEGIN
FOR i := 1 TO k DO
Desplazarll (v) ;
END; {DesplazarKI}
7
'7 '5 separar erementos de un vector siguiendo
un criterio
En este problema se debe asignar valores
a los vectores de nmeros pares e
nmero de elementos que contendrn impares. El
estos vectores en tiempo de ejecucin
los valores que introduzca el usuario. por depencle de
lo tanto, no ," pr"d" ;;;;;;#;;;"
compilacin cul va a ser er nmero
de elemento, .n .u, uJ.r". ,r,
que, como mximo, stos van embargo. s se sabe
a contener er mismo nmero de erementos
el usuario (N). como se vio en la parte que introduzca
de teora der capturo, este tipo de problemas
puede modelar con ayuda de arrays se
parcialmente llenos. por otro lado,
el procedimiento de escritura rmprimrrvector se ha adaptado
para construir rmprimirvectorTope,
228 LOS TIPOS DE DATO ARRAY Y STRING
que permite imprimir por pantalla arrays parcialmente llenos y vuelve a utilizarse el
procedimiento de lectura Leervector.
PROGRAM Arrays05;
CONST
ENI
N = 10;
TYPE
BEG
Tvector = array [1..N] 0F integer;
VAR
vector, IistaPar, Iistalmpar: TVector;
nDespl, LopePar, toPeImPar: integer;
BEGIN
FOR i := 1 TO N D0 BEGIN
writeln('deme el elemento ', i, ' def vector');
readln (v til )
END; ,l
ENL; j LeervectorJ
,]
:
BEGiN
FOR i : = l- iO tope DO
write(v[r] ,'')
writeln
END; {ImprimrrVeccorTope}
::lIN
:3R i:= 1 TO N D0
-F odd(vtil ) THEN
:EGIN
rnncT
--fur
.=
.- lnneT
uvyul + ',]
!, .
-:roarItopeIJ := vIi]
:::l
Sor,ucroNns 229
ELSE
BEG]N
1-^)
LVIJU! .-
.- 1-^l
uvyEr T 'la/
a
parIcopeP] := vIi]
END
l^ )
-..) ; tUOnStrulrLIStaSJ
, _r,sT
\TFTI, = .
\T'AT
_r!v!
_ J,T.
-
.'- li
lMatriz = array [1..NFIL, 1..NCOL] OF integer;
.::CEDURE LeerMat.rizFilas (VAR m: TMatriz) ;
! . i nlaaa-.
: - ^ rnT
_ i:l\
iOR f := 1 TO NFIL D0
FOR C := 1 TO NCOL DO BEGIN
writeln('Deme eI elemento de la fila ,
, f,
'ycolumnd',c);
readln (m If , c] )
END
:-.- {LeerMatrizFi}as}
.. -:EDURE LeerMatrizColumnas (VAR m: TMatriz) ;
--:.
i . inFaar.
rUUYU!,
[
230 I,OS TIPOS DE DATO ARRAY Y STRING
I
BEGIN
t
FOR C := 1 TO NCOL DO
IYPI
FOR f := 1 TO NFIL D0 BEGIN
f' I
writeln('Deme el elemento de Ia fila
y columna ' , c) ; " AR
I
readln (m If, c] )
END
S
END; {LeerMatrizColumnas }
.ROC
PROCEDURE ImprimirMatrizFilas (m: TMatriz) ; ...,D
VAR
f
f, c: integer; :lT
- Jgf
BEGIN
F
FOR f := 1 TO NFIL D0 BEGIN
FOR C := 1 TO NCOL DO BEGIN
,)
wrice 1m [f , c] , '
END;
writeln
END l\Tn .
END; {ImprimirMaLrizFilas}
-JNC:
:
PROCEDURE ImprimirMatrizColumnas (m: TMatriz) ; -- D
VAR
f, c: integer;
i,
:l^Tn
_ JuaI'
BEGIN
SL
FOR C := 1 TO NCOL DO BEGIN
FC
FOR f := 1 T0 NFIL D0 BEGIN
write(m[f,c] ,'')
Tr
END;
r\Tn .
wriLeln
END
. JI\L 1
END; { ImprimirltatrizColumnas} --, D
i,
7.7.7 Un cuadrado mgico :EGIN
PROGRAM ArraYsOT;
CONST
Sor,ucroNrs 23r
]\]F'TT. = ? .
ITAT
t!Lv! _ J?.
- ,
:YPE
TMatriz = array [1..NFIL, 1..NCOL] 0F integer;
-,AR
matriz : TMatriz;
magico: boolean;
sumaref, i : integer;
END
iND; {LeerMatrizritas}
i, suma: integer;
3EGIN
SUma : = 0;
FOR i: = 1 T0 NFIL DO
SUma := SUma + m[i,i] ;
rv---
LLALA . - -UtttA
i, suma: integer;
3EG]N
qrrm: .- 0.
FOR i: = 1 TO NFIL D0
suma := suma + m[i, NCOL + 1 - i];
TrazaSec : = suma
IND; {trazaSec}
VAR
i, suma: integer;
BEGIN
.- n.
FOR i: = 1 T0 NCOL D0
Suma := SUIIIa + m[f ,i] ;
SumaFiI : = suma
END; {SumaFiI}
PROGRAM Arrays0S;
:ONST
\TtrTT, = 7.
NCOL = 6;
fYPE
TMatriz = array [1. .NFIL, 1. .NCOL] OF integer;
TVector = array [1. .NFIL*NCOL] 0F inreger;
:/AR
matriz: TMatriz;
maximo, nmax, i: integer;
maximofil, maximocol: TVector;
END;
IND; {leerruatriz}
tsEGlN
maximo := m[1,1];
1-
lIttta^ .- f ,
LOS TIPOS DE DATO ARRAY Y STRING
fil[nmax] := 1;
col[nmax] := 1;
FOR i := 1 TO NFIL D0
FoR i := 1 TO NCOL D0
IF (mIi, j] > maximo) THEN
BEGIN
nmax : = 1;
maximo := m[i,j];
fiIlnmax] := i;
collnmax] := j
END
ELSE IF (m[i,j]=maximo) AND NOT
( (i=1) AND (j=1) ) rHEN
BEGIN
nmax := nmax + 1;
maximo := m[i,j];
fiIlnmax] := i;
collnmax] := i
END
END; {EncontrarMaximo}
PROGRAM ArraysO9;
e
CONST
NFIL = 3;
\TAT
L!UV! - 2.
J, :- Jl
-
: il]
TMatriz = array [1..NF]t, 1..NCOL] OF real; l
VAR
matrizl, maLriz2, matriz3 : TMatriz; --. 1
'l raaav. fn
opcion: tlrruYu!,
SolucroNBs 235
:IGIN
REPEAT
writeln ('Elija una opcion: ' ) ;
writeln ('1-sumar' ) ;
writeln ('2-restar') ;
writeln ('3-multiplicar' ) ;
writeln ('4-traza'\ ;
writeln ('5-traspuesLa' ) ;
readln (op)
IJ\ITIL (opr=1) AND (op<=5
:l,D; {MostrarMenu}
; .i. i-raaar.
!t ). rrruuYu!/
]:1TIT
_JII\
-
FOR i := 1 T0 NFIL D0
FoR i := I T0 NCOL D0 BEGIN
writeln ('deme eI elemento fila' ,
END;
:1.); {LeerMatrizi
EOR k := 1 T0 NFIL D0
mRes[i,j] := mRes[1,j] + ml[i,k]*m2[k,j];
END
END; {Uuttipticar}
FUIICTION Traza (m1 : TMatriz): real;
VAR
.i .i
-r^^^-.
rrruuYur /
d.ux: IedI,'
BEGIN
i := 1 TO NFIL DO
FOR
aux := aux + ml[i,i];
Traza : = aux
END; {fraza}
FOR i := 1 TO NFIL D0
:aD r .= 1 T0 NCOL D0
ntAux[i,j] := m[j,i] ;
tr := TAUX;
!\l r. I U--^drt^l^\
LL\U I
'j7.lt
BEG]N lo, a
^
f uR r := I -tO NFIL D0 BEGIN
l
n
(
-^rk -'r
l
, TO NCOL DO histr
write(m[i,j] : 5: 2,,,) ; Pal
r.'r.l ral -.
END mi
:-.-; tlmprlmlrJ
l- l
,gri
:lv
::l-ll lPrograma principal)
I _=--:1:Menu ropcion) ;
-: -!CIoI-]<=3,) THEN BEGN
'-'-:=Ir 'matriz 1:');
231
Sor.ucroNss
LeerMatriz (ma[riz1) ;
writeln('matriz 2:');
LeerMatriz (matriz2) ;
CASE (opcion) 0F
1:Sumar(matriz1, maLriz2, 7, matriz3) ;
2:Sumar(matriz1, maLriz2, -1, matriz3) ;
END;
writeln ('El resultado es: ') ;
Imprimir (matriz3 )
END
ELSE BEGIN
writeln('matriz:');
LeerMatriz (matrizl) ;
CASE (oPcion) OF
4:wrlteln ('El resultado es: ' , Lraza (matrizl) ) ;
5: BEGIN
Trasponer (matrizl) ;
.ROGRAM arraYsl0;
-,I\ I
NTEMP = 30;
238 Los trpos DE DATo ARRAy y srRrNe
::J.
TTemp = array [1..NTEMP] OF real;
T
BEGIN
-
:
FOR i:= 1 TO NTEMP DO BEGIN
writeln(,Dame 1a temperatura ,, i
readln (t til )
END
END; {tediroatos}
"':,R
naximo, minimo, anchura: reali
I I *!^^^--
r; a.1LtrgcI /.
DTT\T
DLUAL\
maximo := t[1];
minimo := t[1];
FOR i:= 2 Ta NTEMP DO BEGTN
IF (t Ii] > maximo) THEN
maximo := t [i] ;
IF (t til < minimo) THEN
minimo:= t[i]
END;
anchura := abs(maximo - mi-nimo)/10;
m
FOR i := 1 T0 NSUBIN + 1 DO
inLer[i] := minimo + anchura*(i {v
- 1)
FO
END; { Construirlnt,erva}os }
cr
PROCEDURE ContarTemperaturas (t: TTEmp; inter: TlnLervalos; -
VAR n: TNum);
Sor,ucrocss 239
i, intervalo: integer;
llT^T
_tgaL!
FORi:=1T010D0
nlil .- n.
FOR i := 1 TO NTEMP DO BEGIN
int.ervalo : = 2;
WHILE (intervalo<NSUBIN+1) alO (t Ii] rinterIintervalo] ) DO
intervalo := inLervalo + 1-;
nIinterva]o-11 := nIinterva]o-11 + 1
END
:)lD; {ConLarTemperaturas}
END
:l,lD ; { ConstruirHistograma i
{v ef ee de intervalos}
FOR col := 1 TO NSUBIN + 1 D0
write ( interv [col] : 6: 2) ;
writeln
IND; {nlnui arHistograma}
240 LOS TIPOS DE DATO ARRAY Y STRING
EsVocal := x IN VOCALES
PROGRA]VI Arraysll;
CONST
VQCALES = 1,A,, ,8,, ,I,, ,O,, ,IJ,l;
VAR
frase: string;
i : int.eger;
En este caso no basta con saber si un carcter es vocal o no, sino que es necesario saber
.1u vocal es. Ya no es suficiente un conjunto constante para almacenar las vocales, y
.e debe por tanto utilizar un tipo con estructura interna. El tipo de dato con estructura
.nterna que se conoce es el array. Se puede definir un array de elementos constantes
Je esta forma:
]]NST
NOMBREARRAY: TTipoArray = (valor1 valorN);
Para definir pues, el vector de vocales (VOCALES), bastara con el siguiente cdigo:
- 1PE
TVocales = ARRAY tl..51 OF char;
, -r-L\1
VOCALES: TVOCA1CS = ('A' , 'E' , 'I' , 'O' , 'U') ;
.!.OGRAM Arrays12;
- IPE
TContador = ARRAY [1..5] OF integer;
TVocales = ARMY tl. .51 0F char;
',';R
frase: string;
'i . i rranav.
flluUYU!,
contador: TContador;
_ -r\t
VOCALES: TVOCAICS = ('A' , 'E' , 'I' , 'A' , 'U');
;iOCEDURE Annadir(x: char; VAR numvocales: TContador);
--- D
'l . finr-^^-.
t. lluUYur,
:__gII\
: TIT
VAR
ri r' uuYu!
i n]-aaav.
/
BEGIN
FOR i := 1 T0 length(frase) DO
Annadir (frase Ii] , numVocales)
END;
7,7.13 Palndromos
PROGRAM Arraysl3;
VAR
frase : string;
FOR i := 1 TO length(cadena) DO
'i l aaar
rrrreYu! .
/
:a: - l;
SolucroNns 243
i .-.= lanarhffrrcai.
aLlrYUlr\!rq-s/
-.1 i
WHILE (i < j ) aNn (f rase Ii] = f rase t-il ) oo BEGIN
i := i + 1;
J .- ) - r
END;
EsPalindromo := (fraseIi] = fraseIi] )
END;
VAR
palabra: Tpalabra;
Codtgo : '.1 CodIgo;
VAR
cadenal, cadena2, cadena3, cadena4: TCadena;
tope1, tope2, tope3 , tope4 : TTope;
inicio, longit.ud: integer;
PROCEDURE Leer(VAR cadena: TCadena; VAR tope: TTope);
BEGIN
l^ .-
.- n.
I t
writeln (,dame una cadena de caracteres: ,
) ;
WHILE NOT eoln DO BEGIN
tope := tope +1;
read (cadena Itope] ) ;
END;
readln
END; {leer}
i: integer;
,:iteln
:l{D; {fUostrar}
i i nianar.
IIruLYu! /
:aGIN
t.ope3 := topel + toPe2;
FOR i : =1 TO topel DO
cad3 [i] : = cadl [i] ;
FOR i := 1 TO tope2 DO
cad3 [i + Lopel] := cad2 [i] ;
:i,); {Concatenari
rormula: TFormula;
nALomos : TNAI.omos;
i. f'i n1-ona-.
rusYUr,
CONST
NOMBREAT: ARMy [1..4] OF char = ('C' , 'H' , 'O' , 'N');
CARACTERESVALIDOS = [,C,, ,H, , 'O' , 'N', '2' , '3' , '4'
'5" ,6'l ;
valAux : = TRUE.
, l/\n
WHILE (i <= lengrh(formuta)) eln valAux DO BEGIN
IO[
varAux
..^l
n.---
:= rormula[i] IN CARACTERESVALIDOS;
t
:'.- PESOAT
-.'=__da
:= vafAux
!r- --- - r !^ I De SoArr-
,1_ .)d
IT
SorucroNrs 247
pesoAux := 0;
FOR i := 1 TO 4 DO
pesoAux := pesoAux + PESOATIi]*atomIi];
PesoMolecul-ar : = pesoAux
END; {PesoMolecutar}
VAR
palabraA, palabraB: string;
I ^r--
rELIa. ^t^-
tllAli -
'i .
fllno.iger; irl-c
.._-
terminado: boolean;
:ncontrada: boolean;
n1-aor.
f'i ruuYUr /
3:3-1,
::-:::::ada : = false;
rOF. : : = 1 TO length (palA) D0 BEGIN
Sor,ucroxrs 249
i. inr-aa-.
auuYrr /
3EGIN
i := 1 TO nlineas
FOR DO
writeln
-ND; {limpiarnantallai
^*^-.- r-
3EGIN iPrograma Principal)
fal1os : = 0;
terminado := false;
wriLe('.Iugador (B) , deme 1a palabra que debe
adivinar eI jugador (A) : ,) ;
readln (palabraa) ;
LimpiarPantal la (NLIN) ;
InicializarPalabra (palabraB, length (palabraa) ) ;
Imprimir (palabraB, fa11os) ;
WHILE ((fa]los <= LIMITE) AND NOT(rerminado)) DO BEGIN
write (',Jugador (B) , introduzca una letra: , ) ;
readln (letra) ;
Comprobar(palabraA, palabraB, letra, fallos, terminado) ;
250 Los rrpos DE DATo ARRAY Y srRrNe
Imprimir(palabraB, fallos) ;
END
ELSE BEGIN
writeln('E1 jugador (B) ha excedido eI numero
maximo de fallos permitidos. ') ; I
writeln ( 'Ganador: .Tugador (A) ' ) V
END; {fnicializarTalero}
readln(jugada);
END; {Uenu}
BEGIN
LimpiarPantal-1a ( 10) ;
FOR X : = ALTO DOWNTO ]- DO BEGIN
wrire(, I ,),
FOR v := T TO ANCHO D0
write(tablero[x,y] ,, | ,);
'.,?.ir^l-,
rlralt
wrruu \ l,t t
| t
trAD r' - - T0
. ANCHO D0
--__tL^/, / /\.
w.I.-tLet'--- t t
rrri tal n.
END;
,uriralt
wlrLu\ l\ t
| t
FOR v := 1 TO ANCHO DO
,"-.i+-olt_t\ \t t t ,lr\.
tlt r I Jt
r.',ir^l.
END; {nintartablero}
&
Sor,ucroNns 253
:i,J; t lnSertarl,'lcha ]
fiI, col:int.eger;
buscado: char;
nVeces: integer;
parar: boolean;
]:ATIT
_ _ JII!
fif := posFBuscado;
col := posCBuscado;
parar := FALSE;
I\]HILE (f iI + direcFil <= ALTO) AND (col + direcCol <= ANCHO)
AND (fil + direcFil >= 1) AND (col + direcCol >= 1)
AND (NOT parar) DO
BEGIN
fiI := fiI * direcFil;
col := col + direcCol;
IF (tableroIfi],co]] = buscado) THEN
nVeces := nVeces + 1
ELSE
parar := true;
END;
NumeroFichas : = nveces
:l,D; {ttumerof ichas }
t HorI zontal l
cuentas [1] := NumeroFichas (Lablero,
posf, posc, 0, 1)
+ NumeroFichas(tablero, posf, posc, 0/ -1) - 7;
{vertical }
cuentas[2] := NumeroFichas(tabIero, posf, posc, 1, 0)
+ NumeroFichas(tablero, posf, posc, -1, 0) - 1;
254 Los rrpos DE DATo ARRAy y srRrNG
{oiagonat r} 3j
cuent.as[3] := NumeroFichas (tablero, posf, posc, 7, 1)
+ NumeroFichas(tablero, posfr posC, -1, -1) 1.
{niagonal z }
cuentas [4] := NumeroFichas (tablero, posf, posc, 1 1\
acabo := FALSE;
WHILE (upcase(continuar) = 'C') AND (NOT acabo) D0 BEGIN
EstablecerTurno ( i, caracter) ;
InsertarFicha (tablero, posf , posc, caracter);
PintarTablero (tablero) ;
acabo := FinDeJuego(tablero, posf, posc);
IF acabo THEN
write (' ENHOMBUENA, JUGADOR (, , caracter,
, I,
) , HAS GANADO EL .JUEGO )
ELSE
Menu (continuar) ;
END;
readln
LNIJ. t Programa prrnctpa_l J
:al::aEdad: string[31 ;
ci:i -niian.
,vur:v. ini-aar.
rrtusYsr r
Sor,ucroNns
BEGIN
REPEAT
wri-teln (,Teclea la edad: ,) ;
readln (cadenaEdad) ;
Val (cadenaEdad, edad, codigo)
;
IF (codigo <> 0) THEN
write (chr (z , {ns para que pite}
UNTIL codigo = O;
PedirEdad : = edad;
END;
-!
?l
Captulo 8
\lgoritmos de bsqueda y
ordenacin
,1 Algoritmos de bsqueda
:'roblema de la bsqueda consiste en la inspeccin de una coleccin de datos para
: ::Illinar si sta contiene un elemento concreto y, en caso afirmativo, indicar el lugar
. : ,rcupa dentro de la coleccin. En esta seccin se presentan los algoritmos de bs-
.J.r ms usuales: bsqueda secuencial (o lineal) y bsqueda binaria (o dicotmica).
: -, ello. se supondr que se busca un elemento al que se denominar elemBuscado
' ..:l array unidimensional de n elementos, cuyo ndice est definido por el intervalo
: .UtTIMOl . El objetivo es construir una funcin que encuentre y clevuelva el
. -l'::R.O.
-3r valor del ndice posicion para el que se cumple que vector [posicrcnl =e jem-
: . : I ic' Si se llega al final de 1a coleccin sin encontrar e l emBus cado. se devolver un
: rdentificativo que est fuera del rango. Sern de utilidad las siguientes definiciones:
-:
-
:: TMF'PO .,.1
--- TTM
a:
-l^m -
251
258 Ar-conrrrtos or nsqurDA Y oRDE,ucrN
PASO 1 elemBuscado
ffi
t
PASO 2
elemBuscado lTl
PASO 3 elemBuscado
PASO 4 elemBuscado
Una bsqueda lineal en una coleccin no ordenada (figura 8.1) consiste er ur recr .
;{B
en e1 que se compara elemBuscado con cada valor de la coleccin. Se comienza .
primera componente y se avanza secuencialmente hasta que se encuentra elemBu=: -
o se llega al final de la coleccin sin encontrarlo. A continuacin se presenta unt Il - .
construida para implementar el algoritmo descrito. En la seccin de problemas del
se presentan otras implementaciones de este algoritmo.
PASO 1 etemBuscad"
E
ffi
t
PASO 2
PASO
ry
3
elemBuscad"
elemBuscad"
E
E
ffi t
PASO 4 elemBuscad"
E
ffi t
Figura 8.2: Bsqueda en coleccin ordenacla de un elemento que
no pertenece a la colec-
cin
poslcron := succ(posicion) ;
IF (v[posicion] <> efemBuscado) THEN
BusqSecNoOrd := pred(pRIMERO)
ELSE
BusqSecNoOrd := posicion
END; {BusqSecNoOrd}
BEGIN
posicion := PRTMERO;
WHILE (posicion < ULTIMO) AND (v [posicion] < efemBuscado) D0
posicion := succ(posicion) ;
IF (v [posicion] = elemBuscado) THEN
BusqSecOrd ;= posicion
ELSE
BusqSecOrd ;= pred(PRIMERO)
END; {BusqSecOrd}
PASO 1 elemBuscado
ffi
PASO elemBuscad,
E
%
PASO 3 etemBuscado
E
1 2 3 4 5 7 B c
ordenacin en:
i, j, posMenor: Tlntervalo;
valMenor: TElem;
: ] -,-II\T\T
flt
264 Ar,conrrivros DE nsqurnl y ononNEcrN
9 3 1 2 7 B
t_J
I
tt
1 2 31415 7 B 9
j Se elige el elemento j
de la coleccin y se coloca en el lugal que le iorresponde den:
del conjunto de elementos 1 alj-1.
i := pred(i);
'/iliILE (j >= PRIMERO) AND (vtjl > aux) D0 BEGIN
Ar-conrrrros DE onBNlcrN 265
4 5 9 3 1 B 7 2
4 5 9 3 1 B 2 7 4 3 5 1 B 2 7
tl t+
4 5 3 9 1 B 2 7
tt
tl
4 3 1 5 2 B tl
tl
4 5 3 1 B 2 9 7
tl
v[succ(j)] := v[j];
i := pred(j)
END; iwHILr)
v[succ(j)] := aux
END {FoR}
:ND; {lnserciorDirecta}
y la j en la posicin j.
aux: TEIem;
BEGIN
FOR i := ULTIMO DOWNTO succ(pRIMERO) DO
FOR j := PRIMERO TO pred(i) DO
IF (vtjl > v[succ(j)]) THEN BEGIN
aux := vljl ;
vtjl := v[succ(j)];
v[succ(j)] := aux
END {rF}
END; {IntercambioDirectoi
8.2.4 Mergesort
Los algoritmos de ordenacin considerados hasta ahora, ordenan la coleccin entera
de elementos. En algunas ocasiones, el tamao de la coleccin es demasiado grande
y estos mtodos dejan de ser adecuados. La estrategia ms conveniente en estos casos
consiste en ordenar la coleccin a trozos, para luego fusionar adecuadamente estos trozos
obteniendo toda ia coleccin ordenada. Se hace necesaria, entonces, la implementacin
de un algoritmo que permita unir dos colecciones ordenadas de forma que la unin est
tambin ordenada.
supongamos un array v en el que dos subarrays contiguos vliz..cel y v[ce +
l-..del estn ordenados ascendentemente. El objetivo es fusionar estos dos subarrays
para conseguir una regin ordenada en el aray w ltz . . de I . para ello, comenzamos com-
parando los elementos v [iz] y v fce + 1], colocamos el menor en w [iz] y avanzamos
en el ndice del sub-array que contena ese valor menor. Volvemos a comparar dos ele-
mentos y colocamos el menor en w fiz + 1] , avanzando slo en el ndice apropiado. La
solucin en forma de procedimiento en Pascal se muestra a continuacin:
rym@m
mro=esoq.
_merOeso\
rodsort I
,/\ f
,"r*",, l*ffi)
*8".
E'" / / I
/ /
ErE
''r'/ / \r/
''ffiH T
ffiH
ErE
"/
@m \r,,i0,y'
mE
\sin
Iolil,ElqElilsFl8l
crr
uqve /^o\ .
\uu/ ,
ND
JLSE BEGIN
w[k] ,= v[j];
j := succ(j)
268 Ar,conrrnros DE nseupl v onorNlcrN
END;
k := succ (k)
END; {wurln}
trOD k := i T de D0
w[k] := v[k] ;
FOR k := i TO ce D0
wlk, de - ce] := v[k] ;
END; {nusion}
El algoritmo mergesort hace uso del algoritmo de fusin para ordenar un affay de forma
recursiva (ver ligura 8.7). La estrategia consiste en dividir recursivamente el array en
mitades, hasta que se llega a un determinado tamao umbral. En los ejemplos mostrado'
en este tema. se considera como tamao umbral el valor 1. Sin embargo, se pued.
utilizar otro tamao umbral, en cuyo caso es necesario ordenar cada subamay utilizanc
algn algoritmo de ordenacin. A partir de ah. se f'usionan las soluciones generando .
array inicial ordenado. El coste de este algoritmo es nlog(n), por 1o que es ms efrcier'- .
que los algoritmos de ordenacin por intercambio, que tienen una complejidad Oi:-
Esta diferencia es importante para un nmero grande de datos (r). El siguiente cd--.
muestra un procedimiento que ordena un array con el mtodo mergesort.
8.3.1 Enunciados
-
1. uCual de los siguientes algoritmos es ms indicado para ordenar colecc: "
(rl Seleccin.
CUnSTToNTS DE TIPo TEST 269
(b) Burbuja.
(c) Mergesort.
(d) Todas las anteriores son falsas.
El algoritmo de la burbuja:
(a) nueuar..uNTrL.
(b) FoR.
(c) WHILE.
(d) 2 estructuras de repeticin cualesquiera anidadas.
(a) Es O(nlog(n)).
(b) Es o(n).
(c) Es O(n').
(d) Es o(tog(n)).
(a) o(ntog(n)).
(b) o(n* (n - 1)).
(c) o(n).
(d) o(n - t).
(a) 1.
(b) los(.n').
(.c) n.
(d) 2.
8.3.2 Soluciones 8.
l. Las respuestas cor:rectas son la (a) y la (d). El orden de complejidad del algoritmo
de bsqueda binaria es log(n), que es menor que la correspondiente a la bsqueda $.2
lineal (ri).
Im
-1. Las respuestas correctas son la (c) y Ia (cl). Es un algoritmo de ordenacin por
10
intercarnbio cuya complejidad es n2.
RE]
tii
PRosr.nnr,s 271
-
:!
respuestas correctas son la (a) y la (c). La condicin de parada en la bsqueda
--neal en un array ordenado es "o bien se ha llegado al f,nal de la coleccin o bien
:1 elemento buscado es menor que el elemento actual'. Una estructura FOR no es
:decuada, ya que no permite la interrupcin de la bsqueda cuando el elemento
buscado es menor que el elemento actual.
*{ Problema
n .,!,1 Bsqueda secuencial en un array ordenado
:.:mente un procedimiento que perrnita buscar un elemento en un affay ordenado
nmeros enteros, siguiendo una estrategia de bsqueda secuencial. Utilice una
--, rura REPEAT . . UNTIL. Incluya la definicin de constantes y tipos de datos.
Implemente un programa que represente grficamente los pasos dados por una bsqueda
binaria, como en el siguiente ejemplo:
Numero buscado:12
23 5 810 1.22L2429334L s4557889
t .l
t ,]
t=l
EL 72 esta en la posicion numero: 6
Implemente un programa que represente grflcamente los pasos dados por un algoritmo
de ordenacin por intercambio directo. Imprima el vector en cada paso intercalando los
smbolos:
"==" debajo de los elementos que se estn comparando cuando estn ordenado:
entre s
"><" debajo de los elementos que se estn comparando cuando estn desordenado.
entre s
Una versin mejorada del algoritmo de ordenacin por intercambio directo consiste e:
realizar pasadas ordenando pares hasta que en un recorrido no haga falta ordenar nir..
guno. Se pide modificar el algoritmo de ordenacin por intercambio directo para >:
detenga en esta situacin.
Implemente un programa que represente grflcamente los pasos dados por un algoritn,
de ordenacin por seleccin directa. Imprima el vector en cada paso, indicando los d' .
In-rplemente un programa que represente grflcamente los pasos dados por un algontr
de ordenacin por insercin directa. Imprima el vector en cada paso, indicando e1 e ."
mento elegido para insertar, y los dos eiementos entre lo que se insertar.
SqLsq\qs \\
B.{.8 Listinte\etnico
\-srs\r.uautr\>rsB\b\tr'd q\'rrr-getre etrutram'a\sst'stsres'tt\'tsrgrs,s\e\t\g\srrs\s,
',lna\rs\a e personas B\ progtama ebe pemrirr'rr'.
.
S.5 Soluciones
\,5.1 Bsqueda secuencial en un array ordenado
--,nicin de constantes y tipos de datos:
--tr -
.llMERO = 1;
,-TTMO = 10;
- _l
. -=-:ion: Trndice;
..: _ :_n .= pred(PRIMERO)
l:r:--:
::sicion := succ(posicion) ;
- - -- (posicion = ULTIMO) oR (v [posicion] >= elemBuscado) ;
ELSE
extSup = pred(central)
IJIITIL (encontrado) OR (extSup < extlnf ) ;
IF encont.rado THEN EN
BusqBin2 : = cenLral-
ELSE PR(
BusqBin2 = pred(PRIMERO) c0
END; {BusqBin2 }
= 1;
PRIMERO
ULTIMO = 15; END;
N = ULTIMO - PRIMERO +1;
TYPE FIINC!
TINTCrVAIO = PRIMERO. .ULTIMO; VAR
Tlndice = Pred (PRIMERO) . . succ (ULTIMO) ; ex
I::em = integer; en
lTector = array [T1ntervalo] OF TElem; cu;
-I -;
BEG]N
e-=r.:*scado: TElem; ext
Sor,ucroNBs 275
vector: Tvector;
res : Tlndice;
i: integer;
. :.ICEDURE PedirVector (VAR vector: TVector);
-li-
r: Tlntervalo;
I I -TtT
- - --rr!
iOR i := PRIMERO T0 ULTIMO DO BEGIN
writeln(,Deme la componente/ /
i, ' de un vector ordenado:');
readln (vector Ii] )
]ND
-.-:
.: -lDURE ImprimirVector (VAR vector: TVector) ;
-i.
i: Tlntervalo;
!=GIN
FOR i := PRIMERO T0 ULTIMO DO
write(vect.orIi] : 3);
rrriteln
am,-
_]F I lt.
_ Lt
t1t.
-: -:P )t
'.:
- -:s::central: char;
extSup := ULTIMO;
encontrado : = FALSE;
WHILE (NOT encontrado) AND (extsup >= extlnf) D0 BEGTN
central := (extlnf + extsup) div 2;
n-qr-':= eXtinf;
PoSSup := extsup;
IF v Icentral] = elemBuscado THEN BEGIN
enconcrado = : TRUE;
CurSolcentra] i= '='
END
ELSE
' IF v [central] < efemBuscado THEN
BEGIN
extlnf := succ(central) ;
cursorcentral t= '>'
END
ELSE
BEGIN
extSuP = Pred(central) ;
CursorcenLTdl := '<'
END;
DibujarBusquBin (Posinf , Possup, central/ cursorcentral) ;
END; {WUrlr}
IF encontrado THEN
BusqBin : = central
ELSE
BusqBin = Pred(PRIMERO)
END; {eusqein}
:-S l
',i::rteln('el ', elembuscado, ' esta en Ia posicion: ', res
:l; . .-:: ::ama PrinCiPal )
Sor,ucroNns 211
.::3RAM Alg04;
. ];ST
f)TMtrDA - T
ILTIMO = 10;
l'i = 10;
-': ?1
IINTCTVA1O = PRIMERO. .ULTTMO;
llndice = Pred (PRIMERO) . . succ (ULTIMO) ;
lElem = integer;
-vector = drrdv [Trntervalo] 0F TElem;
.-:-
-,-ector: TVect.or;
-GIN
i : = PRIMERO TO ULTIMO D0
FOR
write (vector Ii] : 3) ;
writeln
3B;
ELSE
CaT i= t><t ;
writeln(car: ind*3 + 2\
END;
V
BEGIN {Programa principa}}
PedirVector (vector) ;
IntercambioDirecto (vector) ;
PR
Imprimi rVect.or (vector )
VA
END. {Programa principal}
BEt
8.5.5 Versin mejorada del algoritmo de la burbuja
;:aCEDURE IntercambioDirecto(VAR v: TVector) ;
.t_:
_ r. .
) fl'ind1.
rgrvu,
: -'
'Ftrlam.
-=*:-cs: boolean;
::r-1,
PRC
- : = IITIMO; VAR
la:i-CS := TRUE;
i;__: : >= succ(PRIMERO)) aNO (cambios) DO BEGIN
SolucroNBs
279
cambios := FALSE;
FOR j := pRIMERO TO pred(i) oO
rr (vljl > vlsucc(j)]) THEN BEGIN
aux := v[j];
vljl := vlsucc(j)l;
v[succ(j)] := uXi
cambios := TRUE;
END; {rei
i ,= pred(i)
END
:liD; {IntercambioDirecto}
PRIMERO = 1;
ULT]MO = 1 N.
= 10;
- :';E
TINtCTVAlO = PRIMERO. .ULTIMO;
Ilndice = pred (PRIMERO) . . succ (ULTIMO)
;
TElem = integer;
r vecror
T\7^^! ^--
= array ITInterval0] oF ?EIem;
-
vector: TVect.or;
=3GIN
FOR i := pRIMERO TO
ULTIMO DO BEGIN
writeln(,Deme la componente ,,
i,'deun vect.or desorde:rado:, );
readln (vector Ii] )
E}D
4D,-
_: TfnLervalo;
280 Ar,conrrvros DE rsquroa y onorNlcrN
i : = PRIMERO T0 ULTIMO D0
FOR
write(vectorIi]: 3);
wrlteln
END;
PosMenor | = j
END; {Ir}
IF (posMenor <> i) THEN
BEGIN
vfposMenor] := v[i];
v[i] := va1Menor;
END; {tr}
Dibuj arSeleccion ( j- , posmenor) ;
:eadln
.1,:t iFOR i)
,1
i=_E --rwLl;_L-LtsULd)
Sor,ucroNns 281
- .-digo del ejercicio anterior se puede utilizar para este ejercicio sustituyendo el pro-
--:rlla principal y los procedimientos OibujarSeleccion y SeleccionDirecta por
-: rj arlnsercion e InsercionDirecta, listados a continuacin.
: , ]fDURE Dibujarlnsercion(lugar, menor: Tlndice) ;
--:l
-- D1
^-:a _ ,<_,;
__ I ) ,_, ;
InsercionDirecta(VAR v: TVector) ;
Tlndice;
-Ftrl am.
END; {wutln}
v[succ(j)] := Xi E
Dibujarlnsercion (j, i)
readln P
END {FOR} B.
END ; { InsercionDirecta}
BEGIN {Programa principali
PedirVector (vector) ;
InsercionDirecta (vector) ;
ImprimirVector (vector )
t- l
ENIJ. t Programa prlnclpar J
PR(
8.5.8 Listn telefnico
En este programa se debe llevar a cabo una bsqueda cadavez que inseftamos un nue\ - VA
elemento, puesto que hay que insertarlo en el lugar correspondiente segn el orden a--
fabtico. Adems hay que "hacer hueco" al nuevo elemento. Esto implica que, par-
no perder informacin, es necesario desplazar los elementos de la lista posteriores a .- BEG
ltima incorporacin. Para la realizacin de estas operaciones se ha implementado
procedimiento NuevoCont act o.
PRLGH*AIV] IlST1N;
TI]T
ar\r _ f1 .
- /
trT\T = ?0.
TYPE
TRango = INI..FIN;
TContacto = array [1..2] 0F string;
TAgenda = array [TRango] OF TContacto;
TTope = pred(INI) . .succ(FIN) ;
\71D
tope: TTope;
agenda: Tagenda;
contacto: TContacto;
!y. 'iraaar.
frluuYu! ,
I/ l:'I'Ranqo;
cerminar: boolean;
:]-TNT
--grlr
tope := tope + 1;
rF (rope = INr) THEN
agendaItopeJ := contacto
{primer contacLoJ
:-SE
::GIN
terminar := FALSE;
; := rNI; iprimera posicion de la
I ----
agenda)
REPEAT
rF (agenda [j,1] > contacto t1l ) THEN {es eI sitio}
BEGIN
FOR i:= tope DOI^INTO (j + 1) OO
{se desplazan 1os elementos para hacer hueco]
agendalij := agendati _ 1l;
t.erminar := TFUE;
END
:LSE
J := J + 1;
I,
BEGIIi
_a -_:F= <> pred(INI)) THEN
_- _-- 1 := INI co tope D0
writeln(agendali, ll,,,, agenda li,Zl
:LSE
writeln(,El listin esta vacio,) ;
END;
Leercontact.o ( contacto ) ;
NuevoContacto(agenda, tope, contacto)
END;
2 : Mostrarlistin(Agenda, Tope)
END
-.ll\TTIL op = 3
:1--
-
8.5.9 Representacin grfica del algoritmo mergesort
--
En este ejercicio, tambin hemos aprovechado el cdigo ya implementado en los e.-- -_l
CONST
r(
= ' [';
CAR1
II
CAR2 = 'l';
BEGIN
IF
writeln(CAR1: izq*3 - 1, CAR2: (centro - izq) *3 + 2,
CAR1, CAR2: (der - on+-rn\*?
vearerv/ J --l\ Ll
rmj
END,- {Oibuj arl,imites }
Dil
re
PROCEDURE Fusion(v: TVector; iz, ce, de: Tlntervalo;
Flrc
Sot ucrol.Bs 285
VAR w: TVector);
VAR
i, j, k: pred(PRIMERO) . .succ (ULTIMO) ;
BEGIN
i :=
). ruvv
l orr i\uu/
o\ .
,
v .- :-.
WHILE (i <= ce) AND (j .= de) DO BEGIN
TEl (v[i] < v[j]) THEN BEGIN
--rt-l Tt l
WLJII := VLI,] ;
r.l .- ^,,^^/.1\
.- Duuu\al
END
ELSE BEGIN
w[k] := v[j];
j := succ(j)
END;
k := succ(k)
END; {WHILE i
k .:= Ji ro de D0
.FOR
-.. ,.
wlkl := v[k] ;
FOR k := i TO ce DO
w[k + de - ce] := v[k] ;
:. -; tuSIOn-|
END; {llergesort i
r reglst
Ja uno
Para c
tendr
o
r lVombr
no
nor
LS
'refdentit
fdent i fi
c
qror eI pro
I&porantr
idenfcac
rdenri.ficad
Captulo 9
Registros
--=:
fNombreRegistro = RECORD
nombref dentif icadorl : Tipoldent i f i cadorl ;
nombre Ident i f i cado12 : Tipoldenti f icad.or2;
istro es el nombre del tipo de dato registro que se desea definir. Los
-::ntificador, corresponden a los identificadores cle carlpo del e_cistro. Los
:ficador, son los tipos de datos, predefinidos de pascar. definiJos previa-
: : el programador o annimos, asociados a ios
canlpos del re-eistro.
n mismo .-oir,.o nol;;;., utilizar el
: - --:-
::ntificador de campo, aunque dos campos de regists
clistintos pueden tener el
-- rriticador.
281
Rocrsrnos
288
CONST
N = 30;
D - 1.
Lv t
TYPE
TNombre = string [N] ;
TDNr = string [D] ;
TAsignatur5 = 1' '8;
OF real;
fNots = ar:ay lTAsignaturasl
TEmpleado = RECORD
9.2 OPeraciones
englobar .
que se pueden realizar sobre los registros se pueden
Las operaciones
y operaciones de asignacin'
;;;, .,o"ruciones de acceso
g,Z.l Acceso a los campos de un
registro
se utiliza el oPeradot
Para acceder a un campo
de una varilbil de tipo registro
y el identiflcador de
"." entre el no*f'" de 1a variable' de tipo registro'
punto
que se desea tener accestl'
Lasoperacionesdelecturayescrituraestndardeunavariabledetiporesl.-
sobre un:i*p"
utr !.'rvv u"
realizan campo a campo' )oDttr Ll1-'ff:l':::iTl:"i;:H:,;-
'smo tipo. Ejen-:
que se utilizan con variables
de su mrt
aplicar todos los op"tuio'"'
PRoGRAlvl EjemPlo01;
!:!L
rri emoloReq= REi'uKU
entero : integer;
^^r-^-or.Chaf;
LdIqUUU!.
-1.
VAR
Oprn,lcroNns 289
:jemplo: TEjemploReg;
I . inlano-.
+rugY!!,
:: char;
.,1.2 Asignacin
: :uede da valor a un registro de dos fbrrr
: , inicializado, o
asignado varores
orro regisrro com-
regl := reg2;
END.
PROGRAM Ejemp1o02;
CONST
N = 1n.
INI = ,
FIN = q.
TVDtr
TDigitos = INI..FIN;
TCadena= string [N] ;
TDNI = array [succ(INI)..FIN]
OF TDigiLos;
TDatospersonales = RECORD
nombre: TCadena;
dni : TDNI;
END;
',/AR
290 REGrsrRos
persona: TDatosPersonales;
i, j: inceger;
DET\]
DLU T I\
readln (persona . nombre ) ;
FOR i := succ(INI) T0 FIN D0
BEGIN
read (j ) ;
persona.dniIi] j
END;
'=
END.
Para dar valor al campo dni del registro persona es necesario hacerlo componen..
a componente ya que se trata de un tipo de dato array.
PROGRAM EjemploO3;
CONST
N = 30;
M = 7'
TYPE
TCadena = string [N] ;
TMatricula = srring [M] ;
TCoche = RECORD
marca, modelo : TCadena;
END; {tCoche}
TAutomovil = RECORD
matricula : TMatricula;
nombre : TCoche; {Reg. Anidados}
^-^^.i ^ : ral_
END; {rautomovil}
...:
:oche1: TAutomovil;
:'Tn.
:iGIN
t1-
TYPE
TNombreRegistroVariante = RECORD
nombreldentif icadorl : Tipoldentif icadorl ;
nombreldentif icador2 : Tipoldentif icador2 ;
CASE nombreDiscriminante: TipoDiscriminante 0F
<val-or-simp1e1> : (Identl-variantel : Tipoldentl-variantel;
IdentM-variantel, tipofdentM-variantel ) ;
<valor-simpleN>:(Identl-varianteN:TipoIdentl-varianteN;);
EI'ID;
p-'-
Ha' que tener especial cuidado a la hora de acceder o asignar informacin a la
variante. Cuancio se -Quarda informacin no se debe olvidar asignar el valor adecuad
campo discriminante. Antes de acceder a la informacin siempre se debe consultar
d:"'
campo. De 1o contrario pueden producirse efectos no deseados durante la eject''
dei programa, es necesario tener en cuenta que se tratar de interpretar la informr-
aunque el tipo de dato no sea el adecuado.
CONST
N = 40;
TYPE
TNombre = strng [N] ;
TForma = (Libro, Articulo) ;
TDia = 1..31;
l}les = 7..L2;
lAnio = 1900..2240;
_FEChA = RECORD
-Ia: I'lJla;
l,les : TMes;
ARRays PARCIALMENTE LLENoS 293
lsr\o'. \Nrr\o;
E\tn -
.. \!u\\\catlorl = \Lq\\
, li- \i'' \rsr'. Nssre., ant-e. Lr\a\1
..ampO Titulo: TNombre;
iracin Paginas: integer;
ello, se CASE Tipo: TForma OF iParte variante)
uido por Libro: (Editorial : TNombre;
lLie tome Anio : TAnio);
:,raiquier Articulo: (Periodico: TNombre;
,rtndiente Dia: TFecha);
END; {fnubticacion}
INI
trTT\T
.-ta
TRango = INI..FIN;
TArraY = array [TRango] OF rea];
lArrayParcial = RECORD
vector: TArray;
tope: pred(INI) ..FIN; {Debe existir un val-or que indique}
iND; {que eI array est. vaco}
La siguiente deflnicin:
:'JPE
rFD a
r r\uY -- RECORD
CASE tipo: TForma OF
REGISTROS
2g4
libro: (editorial: stringll5i ;
fecha: TFechal);
articulo: (Periodico: string[25i ;
fecha: TFecha2) ;
END;
vadante'
(a) Es incorrecta porque solo tiene pafte
(b)Esinconectaporquenopuedehabernombresigualesendospafiesvaflan:-' e ! -:
de las dos pafles variantes flo
(c) Es incorrecta porque e1 campo fecha
mismo tiPo'
tener parte fija'
(d) Es correcta porque no es obligatorio
3.,CulesdelassiguientesafirmacionesreferentesaunregistroenPascalson.l:.
tas?
ser de distinto tipo de datos'
(a) Todos los campos de un registro deben
compatibles la instruccin r-
(b) Si 11, y 12 son variables registro de tipos
r2 es correcta'
una variable selectora'
(c) Todos los registros variantes han de incluir
de almacenamiento que '
(d) Los registros variantes requieren un espacio
'
TYPE
rAro = RECORD
campol : integer;
CASE camPo2: boolean OF
TRUE: (camPo3: integer) ;
]i E
!g TlT
rr\
,."r*pof := 3;
u.camPo2 := TRUE;
:ND.
TMiRegi stro;
(a) Es incorecto ya que una variable de tipo RECORD no se puede definir como
un argumento.
(b) Es incorrecto porque una funcin no puede devolver un valor de tipo RECORD.
(c) Es correcto siempre que el tipo de datos TMiRegistro est def,nido.
(d) Es correcto ya que una funcin puede tener parmetros de tipo de dato
RECORD e integer.
(a) Con varias variables de tipo registro con los mismos identif,cadores de campo.
(b) Con variables de tipo array, permitiendo el acceso a sus componentes utili-
zando nicamente el tipo ndice.
(c) Con varias variables de tipo registro si no tienen parte variante.
(d) Con varias variables de tipo registro con identificadores de campo diferentes.
-'.2 Soluciones
1
--) - La respuesta correcta es la (c). La nica restriccin que existe sobre los campo:
de un tipo registro, es que no pueden declararse de tipo fichero (captulo 10). I-r,
memoria que se reserva para una variable de tipo registro es constante. para que
la asignacin de la opcin (b) fuese correcta, las variables deberan ser de tipo:
idnticos.
4. La respuesta correcta es la opcin (c). El campo del registro campo3 es de tipi
entero, cualquier asignacin de otro tipo no esta permitida, adems la asignacir
y comprobacin de tipos se realiza en tiempo de compilacin.
5. La opcin correcta es la (b). Los registros, al igual que otros tipos de datos, puecle r
9.8 Problemas
9.8.1 Declaracin de un tipo registro simple
Escriba una declaracin de tipo registro que almacene la siguiente informacin sobre u.
disco de audio: ttulo, autor, ao de publicacin y duracin en segundos.
3. Nmero de Telfono.
4. D|T.
\rta: Cada re-uistro delinido por el usuario debe tener una defrnicin separada.
Pnosr,nN{,{s 297
PROGRAM Informe;
TYPE
TCadenal5 = string tfS1,
'.t"1ar1ta = RECORD
nombre: TCadena*15;
fecha : TCadena*15;
horas : real
END;
VAR
operador: TTarifa;
BEGrN i1:,_:..
\
lrtITH TTarifa DO
BEGIN
nombre:=,Hotef Villarosa, ;
f echa : = ,,Junio 5, 19g9,,T ;
horas := 30.5
END;
writeln (operador) x
END" {Informe}
o Agenda:
o Mensajes:
It l! l)
,,
r..
I
rrr .J
aa
aa
aa
*a
*aa
aaa
1...
Jo l: : aa
*a
aa
aa
a*a
**a
- Recibir un mensaje: Para poder recibir mensajes, tambin se tendr que tener
hueco en la memoria destinada a tal fin. Pero en este caso cuando la memoria
est llena se avisar al usuario cada vez que este realice cualquier operacin
en el telfono.
9.9 Soluciones
CONST
N = 30;
A.
TYPE
TTitulo = string [N] ;
TAutor = TTitulo;
TAnio = string [C] ;
TTiemPo = real;
TDiSCO = RECORD
titulo: TTitulo;
autor: TAutor;
anio: TAnio;
duracion: TTiemPo;
CONST
N = 30; {Para }a longitud del nombre}
v --
q.
't
INI = 1;
FIN = 27;
FIN-N = 2000; {mximo numero de casa)
FIN-C = 9999; imximo numero de cdigo
postali
ul,t = o; {mximo nmero de convocatorias}
TYPE
TNumeTO = INI. 'FIN-N;
TCodigo = INl..FIN-C;
TNombre = string [Nl ;
TTeIefono = string [Cl ;
TDni = TTelefono; {Para que el dni incluYa }a
letra)
TRango = INI. .FIN;
TRango2 = INI. .ULT;
LInfO = KI.\-UK!
tombre: 'I'NomDre;
Sor,ucroNrs 301
nota: char;
END;
TRepe = RECORD
nombre: TNombre;
Conv: TRango2;
END;
TAsignaturas = array [TRango] OF Tlnfo;
Tconvocatoria = array lTRangoJ OF TRepe;
TDireccion = RECoRD
calle, ciudad: TNombre;
numero: TNumero;
codigo: TCodigo;
END;
TEstudiante = RECORD
nombre: TNombre;
direccion : TDireccion;
telefono: TTelefono;
dni : TDni;
asignaturas : TAsignaturas;
CASE repecidor: boolean OF
TRUE: (convocatoria: TConvocatoria) ;
END;
3EGIN
REPEAT
wrrte (,Inrroduzca e1 nombre: ,);
readln (nom) ;
writ.e ( ,El nombre es : si es correcto pulse s') ;
readln (c) ; "/nom''
LTIT]L c IN [,S,,,S,]
302 RBGISTRoS
END; ilntroduceNombre)
InLroduceNumero : = i
END; {IntroduceNumero}
code: integer;
BEGIN
REPEAT
write ('Introduzca eI codigo postal:
readln (s) ;
val (s,i,code);
IF code <> 0 THEN {Se na producido error}
i ;= pred(INI);
UNTIL (i > pred(INI)) AND (i < succ (FIN C));
IntroduceCodigo : = i
END; {IntroduceCodigo}
h,
Sor,ucroNns 303
IND; {IntroduceDireccion}
^.
U. ^t^--. ,
UIIAI
:EGIN
REPEAT
write ('lntroduzca eI numero de telefono: ');
readln (t1f) ;
write ('E1 telefono es : ' ,LLf,' si es correcto pulse s');
readln (c) ;
IN [,S,,,S,]
UNTIL C
:){D; {Introducerlf}
. ]n=v.
:JGIN
REPEAT
write ('rntroduzca el numero del D.N.I. : ') ;
readln (dni) ;
write('El D.N.r. es: ',dni,' si es correcto pulse s');
readln (c) ;
UNTIL c IN ['s','S']
:)JD; {IntroduceDNI }
-J'IJCTI0N
r Nota : char;
_'tD
^ D-. .
U, ^t--.
UIIAI ,
]fTTT
- -gII\
REPEAT
write ('Introduzca la nota: ') ;
readln (c) ;
write ('La nota es: ' , c,' si es correcto pulse s' ) ;
readln (s) ;
UNTIL s IN l's' ,'S') ;
IT^l
IIULA - . - L
:)'TD; {Xota}
info.nota := Nota
END; {tntroducetnfo}
VAR
i: TRango;
BEGIN
FOR i- : = INI T0 FIN D0
Introducelnfo (asig lil )
END; {IntroduceAsignaturas}
VAR
i : integer;
s: string[4J ;
code: integer;
BEGIN
REPEAT
write('Introduzcaelnumerodeconvocatoria:');
readln (s) ;
VaI ( s, i, code) ;
IF COdC <> O THEN {se tra producido error}
i = pred(INI) ;
LINTIL (i > pred (INI ) AND (i < succ (ULT) ) ;
)
NumeroConvo : = i
END; {Numeroconvo}
repe.conv := NumeroConvo
END; {IntroduceRePe}
VAR
i: TRango;
BEGIN
FOR i : = INI T0 FIN D0
rntroduceRePe (convo Ii1 )
ElD ; { In[roduceConvocatorias ]
--- D
l'r:r.
: IGIN
writeln ('Introduzca los datos del estudiante') ;
InLroduceNombre ( estudiante. nombre) ;
Int roduceDi recc ion ( estudiante . direcc ion ) ;
IntroduceTlf (estudiante. telefono) ;
IntroduceDni (estudiante . dni ) ;
writeln('Introduzca los datos de las asignaturas');
IntroduceAsignaLuras (estudiante. asignaLuras) ;
REPEAT
write (' Es repetidor (sln) 7 ' '
readln (c) ;
IINTIL c IN l's' ,'S' ,'r,' , 'N'] ;
estudiante. repetidor : = (c IN l' s' , 'S' I ) ;
IF estudiante.repetidor THEN
BEGIN
writeln ('Introduzca datos sobre l-as convocatorias:' )
- : t-Lntroduce!;studlanteI
l_ )
writeln (nombre)
:-l; {MuestraNombre}
writeln (num)
:- -; {MuestraNumeroi
de la ciudad: ')
u^/rite ( 'Nombre ;
l,1ue (dir.ciudad);
straNombre
write ( 'Nombre de la cal-le: ' ) ;
lluestraNombre (dir. calle) ;
rvrite ( 'Nmero: ,);
l'luestraNumero (dir.numero);
306 Rpcrsrnos
END; {MuestraTelefonoi
END; iMuestraAsignaturas )
END; {MuestraConvocatorias}
Sor,ucroNrs 307
IND; {MostrarEsrudiante}
...4R
e1 : TEstudiante;
:EGIN {Programa Principal}
IntroduceEstudiante (e1) ;
MostrarEsrudiante (e1 ) ;
:-\l_). t Programa Prlnclpa_L )
TTarifa = RECORD
nombre: TCadena 15;
fecha : TCadena 15;
horas : real
END;
TTarifa = RECORD
308 Rncrs:rnos
nombre: TCadenal5;
fecha : TCadenal5;
horas : rel
END;
WITH TTarifa D0
WITH operador DO
En el primer END del programa no aparece el ";", y sin embargo hay una instrue -
cin a continuacin. Para que el cdigo compile debemos introducirlo.
La itima instruccin del cdigo writeln (operador) es una operacin errnea
El tipo de dato de operador, es un tipo registro sobre el que no se pueden aplicar
directamente las operaciones de entrada-salida. Para que el cdigo funcione ade-
cuadamente y muestre la informacin almacenada en esta variable, se tendr quc
hacer 1o siguiente:
CONST
N = 9;
INI = 1;
FIN = 30;
TYPE
TRango = INI..FIN;
TTeI = string INJ ;
TNombre = string IFIN] ;
TA}UMNO = RECORD
nombre: TNombre;
t1f, dni : TTel;
END;
TPlazas = array [TRango] OF TAIumno;
TAgenda = RECORD
plazas: TPlazas;
num: pred(INI)..FIN; ifuf -:- no hay alumnos
matricul-ados, FIN eI cupo esta completo)
END;
o Segundo aparlado:
BEGIN
FOR i := agenda.num DOWNTO (j + 1) Do
ELSE
i := med +1
UNT]L (i , j) 0R (plazas [med] .dni = alumno.dni) ;
Sor,ucroNos 311
FALSE: (numero:TTlf);
END;
TAlmacen = array[TRango] OF TMensaje;
TMemoria = RECORD
todos: TAlmacen;
tope: pred (INI) . . FIN. {Necesitamos un valor que indique}
END; {que no hay datos}
Tlnfo = RECORD
nombre: TCadena;
LII: TIII;
i
I
END;
I
TContactos = array [TRango21 0F Tlnfo;
TAgenda
= RECORD
cont.actos: TContactos;
max: pred(INI) ..N; {Necesitamos un va}or que indique que}
END; {no hay datos}
BEGTN
REPEAT
write ('Int.roducir nombre: ,
) ;
readln (nom) ;
writeln ('EI nombre introducido es: , nom,
,
es correcto pulse s');
readln,",,tt
UNTIL c IN ['s','S']
END; { IntroducirNombrei
dev: char;
: ] 1T\T
_ _ J11\
REPEAT
writeln ( 'Escoj a una de las siguientes opciones : , ) ;
writeln('1. Int.roducir eI nombre de1 contacto,,
' que se desea eliminar') ;
writ.eln (,2. MosLrar la lista de cont.actos, ) ;
readln(dev);
IJ}'TTIL dev IN l'7', ,2,f; {Se podra aadir una opcin ms para
permit.ir salir sin act.uar)
Muest.raOpcionesBorrar : = dev
:.,1 ; {MuestraOpcionesBorrar}
: : - :EDURE AvisoMemoriallena;
::-r1T
__,-11\
r,riteln('La memoria de mensajes entrantes esta llena,)
. - ; {Avisol,lemoriaLlena}
: . 1rr.
91f q! ,
- - -rrnro,
writeln('1. Enviar mensaje a un numero de la agenda,);
wriLeln('2. Enviar mensaje a un numero introducido,,
' por el usuario') ;
readln(a);
-']NTIL a IN l'l.' ,'2,f ;
3t4 RncrsrRos
ModoEnvio : = a
END; {l',1odoEnvio}
BEGIN
writeln ('1. Opciones Agenda' ) ;
writeln('2. Opciones mensajes' ) ;
writeln ('3. salir' ) ;
readln (a) ;
MenuPPal : = a
END; {tutenulpat }
BEGIN
REPEAT
writeln (' 1 Aniadir un nuevo conLacto')
. ;
writeln ('2 Eliminar un contacto ') ;
.
readln (a) ;
UNTIL a IN [' ]-' , tat
L t
t)t1.
J Jt
MenuAgenda : = a
END; ilufenuagenda)
IntroducirNombre ( c . nombre) ;
IntroducirTlf (c. tlf)
:).); {CrearContacto}
':,ICEDURE MostrarContacto
(contac: TInfo) ;
--a -.prrnl
.:st = *r"a.u por pantalla el nombre det contacto]
::. T\T
___-rr\
writeln('Nombre:', contac.nombre)
:l-; {MostrarContactoi
agenda.max := pred(INI)
:--; {Crearagenda}
HaySitio := (agenda.max<>N)
ll; {ttaysitio}
-:,CEDURE InsertarContacto (VAR agenda:TAgenda;contacto :TInfo)
.:e = la agenda no esta }lena)
316 RBcrsrnos
VAR
i, j : TRango2;
final: boolean;
BEGIN
IF Esvacia (agenda) THEN
BEG]N
agenda.max := succ (agenda.max) ;
agenda. contactos Iagenda. max] : = contacto
END
ELSE
BEGIN
final := FALSE;
i := INI;
WITH agenda DO
BEGIN
max : = succ (max) ;
I^IHILE NOT f inal AND (i < max) D0
IF contacLos Ii] .nombre > contacto.nombre THEN
BEGIN
final := TRUE;
FOR 'i := nldX DOWNTO i + 1 DO
contactos Ij ] : = contactos Ij -1]
END
ELSE
i := i + 1;
conLactos Ii] : = contacto
END
END
END; {InsertarContacto}
- .:^
=y
.
;= nran /-^--
- prt:urtttdx/ t
;
:--]
: - rminarContacto )
. _ ,1,
Escogercontacto (agenda: TAgenda) : TRango2 ;
_
-: pred(INI)..N;
. laar;
-, --
- ,= pred(INI);
i = agenda.max;
I ,l-l: _-_- r1
--
-r j_= j THEN
i := INI
:-SE
i := succ(i);
,,;::-tefn ('Si desea elimi-nar eI sgte. contacto, pulse s: , ) ;
:,:cstrarcontacto (agenda . contactos Ii ] ) ;
:eadln (c) ;
'-],:lL c IN ['s' , 'S'] ;
:.:cgerCont.acto : = i
:scogercontacco )
= = TPITtr l
:..- = Busca el nombre introducido por eI usuario en la agenda,
, -, encuentra devuelve la posicin en la que esta. Si no
--=-ve pred(INI) )
-j
REPEAT
med := (i+j) DIV 2;
final = (contactos [med] . nombre = nombre) ;
IF contactos [med] .nombre < nombre THEN
i := med + 1
ELSE
j := med - 1
UNTIL final 0R (i , j)-
IF final THEN
EncontrarConLacto : = med
ELSE
EncontrarConLacto := pred(INI)
END
END
ELSE
EncontrarContacto := pred(INI)
END; {EncontrarContacto}
{ere = TRUE}
{post = Si hay sitio se aade el nuevo contacto. Si no 1o hay se
el:-ge un contacto para ser borrado o se abandona e1 proceso. Si se
e-rge borrar un antiguo contacto se aade el nuevo. La agenda debe
Dernanecer ordenada)
1r: D
c : TInfo;
abandonar: BOOLEAN;
'i .nD:nn, .
r l\qlIYV ,
eleccion: char;
BEGIN
abandonar := FALSE;
IF NOT HaySitio (a) {o se borra un contactoi
THEN
BEG]N {o se abandona el proceso}
writeln('No queda sitio en fa agenda, para aadir un nuevo,
' contacto tendr que eliminar un contacto antiguo.,);
REPEAT
writ.e ( 'Si desea elimi_nar un registro pulse s, si desea'
' abandonar pulse n
readln (eleccion) ;
--ITIL efeccion IN ['s' ,'S' ,'trr, ,N'];
,
abandonar := (eleccion IN [,n,, 'N',] ) ;
Sor,ucroNns 3t9
END
:i.D; {aniadirContacto}
-. 1r.
-: TRango2;
I: pred (INI) . .N;
lomb: TCadena;
:: -T\T
_ _ if r!
ELSE
writeln ('Ese nombre no se encuentra' ,
' en la agenda') ;
END;
,2, : BEGIN
i : = EscogerContact.o (a) ;
EliminarContacto (a, i )
END
END
END
ELSE
320 Rncrsrnos
BEGIN
REPEAT
c := MenuAgenda;
CASE C OF
,1, :AniadirContacto (agen) ;
END; {Opcionesagenda}
{ere = TRUE}
BEGIN
REPEAT
writeln('Introduzca eI texLo de1 mensaje:');
readln (mensa. texco) ;
writeln('Si desea modificar eI mensaje pulse s');
readln (c) ;
UNTIL NOT (c IN ['s' , 'S'] )
END; {Crearl,tensaje}
ll(UrlJI
_"re = --,f
.?:st pantalla el
= Muestra por mensaje)
::: -li
l;-lF- mensae DO
-,--r ! ^ a' ,- ^,
/,r--ar-\Lcxto)
EN); ilosirarMensaje)
Sor,ucroNns 32t
i,j: pred(rNr)..rrN;
. n1^,=r .
tlaTrr
_fgfr\
i = pred(INI);
REPEAT
IFi=FINTHEN
i := INI
ELSE
i := succ(i);
writeln('Si desea eliminar e1 sgte. mensaje, p'rlse s:');
MostrarMensaje (mem. todos Ii] ) ;
readln (c) ;
LIJTIL c IN ['s','S'];
WITH mem DO
FOR j := i TO pred(FIN) Do .,{"
rS
todos Ij ] : = todos j +11 ; ,qL
&;-.
-
d.
'\r
r,.",u:."ri,.:,.
of
322 REGISTRoS
mem.trope .= predtmem.cope)
; ,)
- _.f t Ll rmlnarlvlensal e ]
op : char;
tsEGIN
REPEAT
writeln ('Escoj a una de la opciones : ' ) ;
writeln ('1. Borrar Ia memoria' ) ;
writeln ('2 . Seleccionar un mensaje para borrarlo' ) ;
readln (op) ;
TINTIL op IN l'1' ,'2') ;
CASE op 0F
' 1' :VaciarMemoria (memoria) ;
' 2' : EliminarMensaj e (memoria) ;
::'l
END
-
END ; i l,impiarltemoria )
l
todosItopeJ := Illeilsi
END E
::r-l: TL
Sor,ucroNBs 323
.-
-ll mensa DO
: I _ -tT
_ _ ,--L!
-_*^^r^^
_ ___Jsrqv -. +-
- I i
:: ^ TNT
- _ -_rr\
identificacion : = agenda. contactos Ii] .nombre;
writeln ( ' Ef usuario de nombre , , agenda. cont.actos
Ii] . nombre,
' tiene e} numero ,, agenda.cont.actosIi] .t1f);
:l.l
:.SE
numero := tlf'
,,ITH f echa DO
GetDate (anio,mes, dia, semana) ;
}IITH hora DO
GetTime (hora, minutos, seg, mseg) ;
:ND;
: -: {TerminarMensaje}
,-TH mensa D0
:: 1
__JAI\T\T
conocido .- E^TCEr.
numerO : = r'l t -
WITH fecha DO
GetDate (anio,mes/dia, semana) ;
WITH hora D0
GetTime (hora,minutos, seg,mseg) ;
,.
TerminarMensa j eEnt rante ]
= rRUEi
= Se enva un mensaje, creado por eI usuario y s:
en la memoria de mensajes enviados)
rensaje: Tlvlensaje;
EP: char;
:om: TCadena;
Eif: TTlf;
REGISTROS
_: pred(INI)..N;
:rnal terror: boolean;
::-:-N
I
lrearMensaj e (mensaj e) ;
(
cp := ModoEnvio;
irnal := FALSE;
error := FALSE;
(
CASE op 0F
,1, :REPEAT
IntroducirNombre (nom) ;
a: - aT
j : = Encontrarcontacto ( a, nom) ;
IF j ., pred(INI) THEN
final : = TRUE t1e
_^^+
_-_>t
ELSE
BEGIN
---:,
writeln ('El nombre introducido no se"
' encuentra en la agenda') ; - I r rt
(
wriLeln('Vuelva a inLentarlo' ) ; I
END;
final 0R error;
UNTIL
'2':IntroducirTlf (tIf)
END;
IF NOT error THEN
BEGIN I
r'--l .
IF Memoriallena (mem) THEN
LimpiarMemoria (mem) ;
-l
TerminarMensaje (mensaj e, , ),tlf , final) ;
AvisoMensaj eEnviado;
(
END
,]e :_ :_ -JII T\
- -\lJ; t EnvlarMensal J
(
(
;-ICCEDURE RecibirMensaje (VAR mem: TMemoria) ;
\ (
--'-s - 'Prrr
:-rst = Ilega un mensaje desde otro telfono y se almacena en la I
-=-.:::ia de mensajes recibidos)
*::saje: TMensaje;
AAII,
::l-l:
-: MemoriaLlena(mem) THEN
Sor,ucroNns 325
BEGIN
Avi soMemoriaLlena ;
LimpiarMemoria (mem)
:: char;
ti
].EPEAT
t .- MenuMensaj es;
CASE c0F
'1' :EnviarMensaje (salientes, agen) ;
'2' : RecibirMensaj e (entrantes) ;
END
-ITTIL NOT (c IN l'L' ,'2'))
, OpcionesMensaj es
)
=:enda: TAgenda;
::tra, sale : TMemoria;
lp : char;
T*
Programa Pr:_ncipal i
-:earAgenda (agenda) ;
l:earMemoria (entra) ;
--:earMemoria (sale ) ;
::ftrA.f
:p := MenuPpal;
lF Memoriallena(entra) THEN
Avi soMemori aLl ena;
IASE op OF
' 1' : OpcionesAgenda (agenda) ;
'2' : OpcionesMensajes (agenda, entra, sale)
326 Rncrsrnos
END
UNTIL NOT (op
fm l'L' ,'2'))
END. {Programa Principal}
INI = 1;
-l tvt . pR(
-
ia tt. tsE(
- 1t
TYPE
TCadena = string [N] ;
TRango = INI..FIN;
TDATOS = RECORD
x,y: TRango; E}JD
END;
TAlmacen = array [TRango] 0F TDatos; FUtv(
todas: TAlmacen;
t-pe: pred(INI) ..EIN;{Tiene que existir una posicin
que i-ndique que no haY datos)
lt,.t ;
PROC
BEG]]
F-LINCTICIi ii::rccuceCoordenada : TRango;
VAR EIVD;
c: chari
code tz: integer; Ft]-NCT
REPEAT
write ('lntroduzca Ia coordenada: ' ) ; FL']VCT]
-:::loduceCoordenada = : z PROCEDI
r^
:-.- -:-:lloduceeoor0enaOal
-al
t Post =
Sor,ucrorvps
iIITH d DO
3EGIN
write (, (, ,x,, , ,
,y,,) ,) ;
:ND
:l: {MostrarDatos}
::GIN
WITH a DO
BEG]N
tope := succ(tope)
todaslcope] := o
END
:l'Jf ; {GuardaAlmacen}
WITH a DO
BEGIN
o := todas [t.ope] ;
rope ; = pred (t.ope )
END
END; {ExcraeAlmacen}
o.x := pred(o.xl
:_._: T
-
tlleCrementaX.l
-- l
:: a-1,
._ nrorl /n .r\
I,lUu\v.}/
-ramo-r.v)
- = --c,,.crr-or I
l'rarda: TLlamadas;
a;x: TDatos;
- -1- . 'i nlaaar.
tlrusyu!,
::ror: boolean;
: : r-]'t
lont : = 0;
:ilror : = FALSE;
-nicial izaAlmacen ( guarda ) ;
luardaAlmacen(guarda,orig) ; {No comprobamos que eI almacn
est lleno porque fo acabamos de crear)
;';:{ILE (NOT AlmacenVaco (guarda) ) ANO (NOT error) DO
:EG]N
ExtraeAlmacen (guarda, orig) ;
IF Iguales(orig,dest) THEN
cont := Cont + 1
ELSE
BEGIN
IF NOT lgualCoordenada(orig,dest,Cl) THEN
BEGIN
IncrementaX (orig) ;
error : = Almacenlleno (guarda) ;
IF NOT error THEN
GuardaAlmacen (guarda, orig ) ;
DecrementaX (orig)
END;
IF NOT IgualCoordenada (orig, dest, C2 ) fHE:,1
BEGIN
IncrementaY (orig) ;
error : = Almacenlleno (guarda) ;
IF NOT error THEN
GuardaAlmacen ( guarda, orig) ;
DecrementaY (oriq)
END
:., D
330
RBcrsrnos
IF error THEN
writeln ('Se ha Producido un error de
d'esbordamiento' )
ELSE
NumeroCaminos ; = cont
END; {NumeroCaminos}
TodoCorrecto(o, d: TDatos) :
boolean;
FT]NCTION
BEGIN
AND (o.y <= d.Y))
TodoCorrecto := ((o'x <= d'x)
END; {lodoCorrecto}
VAR
origen, destino: TDatos;
caminos: integer;
P,r'cTlJ {Proqrama PrinciPal i
,,ri re'l n ( 'Introduzca coordenadas de origen:') ;
IntroduceDatos ( origen) ;
.,ri rol n ('Introduzca coordenadas d,e destino:') ;
IntroduceDatos (destino) ;
lF TodoCorrecto(origen' destino)
THEN
BEGIN
destino) ;
caminos := NumeroCaminos(origen'
write ('El numero de caminos desde
') ;
McstrarDatos (origen) ;
'rite (' hasta ') ;
EI,SE
uirilelnr'E- crigen es menor que eI destino,',
' no haY caminos');
1
END. {Programa PrrncrParl
rl- aptulo l0
Ficheros
. _ principal
,1oria es una memoria
rvrrrurra vol
.:io volatll por lo qu(
':io de ajmacenamie
aimacenamienro
'nto pemanenre
permanente de ilf:]: :'e
.rF inf,ormacijn.
no se puede urilizar como
.: tene que proces
un gran volumen
-
_ -'pacio suficiente a,tt
-.pacio de
principat ,rlit"::]:|.ofifle cue no se disponga
enr memoria p.lr";porlrf::L::ffi:,T:
Fichero o archivo?
e r
il Hffi T:il,"j fl:,|jl,LH:,:::,,,"
mi smo p-po,*o
'. '1ff'*l#:'::,;T,^l;;;,:;;r""1"ii ;,if *:
uesrgnar a una coreccin
ur, archivo "zip,, o..,ur,,. Si coleccin de ,.files,,,
,.rires,,
._- irrlJr'r. ir^,u,*
."1TS,:ffi
' un ejemplarl-;T:ffi * Ia paiabra
aotr. f ,i 'rtlltzar
que contien" "fichero"
-*;'hy,"xi,^[!:;T,,1i;#1#i:::l"',"#T
vo,, cuando lo haga
.._ coleccin de
ficheros. o "rrrdo
";"rnplm
qr"
331
FICHEROS
10.2 Definiciones
es una secuencia de componentes almacenados
en un soporte externo' S'
un fichero
sino que se asigna de fornl''
tamao no est fijado de antemano ni hay que concretarlo,
propio soporte de almacenamientt
dinmica; la limitacin de tamao viene dada por el
que permiten un almacenamient
una de ias principales caractersticas rle los licheros es
programas'
permanente que facilita el uso de los datos por diversos
Se denomin a registrut lgico a una componente
individual del fichero' se denomir'"'
(infbrmacin que se transf,ere) ent:'
bloque rt reg,istro.fsico alauniilad de transferencia
principal' Se denomina bttli'
el dispositivo de almacenamiento externo y la memoria
doncle se almacena el bloque ledc
de entrada/salida al rea de la memoria principal
bien clonde se construye un bloque antes de escribirlo'
con el tipo de dato punte:
Asociado a cada fichero hay un puntero (no confundir
que contiene la direccirl
que se ver en el captulo l1') o ctrrsor que es una variable
posicin del registro lgico que va a ser ledo o escrito'
lgicos:
Los ficheros pueden contener varios tipos de registros
frchero tienen la misma longitud'
Registros de longitud fija: todos los registros clel
Registros de longitud variable: la longitud de
los registros del mismo fichero pue-'
variar, pero oscila entre un mnimo y un mximo'
es totalmente variable' Normaim:.
Registros delimitados: la longitud de 1os registros
un registro de otro'
se utilizan caracteres delimitaclores para separar
identificado por
,:::)it"":-1. dal., . Si en et no1lre fsico no se especifica la unidad y el
. camino
' -':iorios, se sobreentender que el fichero est ubicado en la unidatl y
directorio de
I.
'rn programa esta operacin se realizar una sola vez con cada
fichero y es previa
- '.ier otra. A continuacin se muestra un ejempro de su
uso dentro de un programa:
!j emploAssign;
::-_qn(fichero,'c:\Datos\agenda.txt, ) ;
:- . :=sarFichero (fichero)
;
Por ejemplo, el entero 27195 podra almacenarse como tal entero en un f,chero bin'-
rio de la misma manera que se representa en memoria principal (representacin intem",
en 16 bits, quedando: 0110101000111011. Sin embargo, si ese mismo valor entero ..
quisiera almacenar en un fichero de texto, se almacenara con sus correspondientes -'
racteresASCII: "2"'7" "1""9""5",esdecir:00110010001101110011000100111(r
001 10101.
Las ventajas de los f,cheros binarios respecto a los de texto son las siguientes:
Pero no todo son ventajas para los flcheros binarios. Tambin presentan un tn'
veniente: su falta de portabilidad. La representacin interna puede variar de uros r'r- -
nadores a otros y de unos lenguajes de programacin a otros, por 1o que no puede: '
utilizados por cualquier programa en cualquier ordenador.
-
A continuacin se describe en detalle cada uno de estos tipos de fichero. En ade -.
cuando se hable de una componente de un fichero se referir a un registro lgico.
-'- D
ficheroTexto: text;
La entrada y salida estndar en Pascal, Input y Output, son ficheros de tir
que \ a estn definidos. En un fichero de texto:
I
Trpos DE FICHERoS EN PnscIr. 335
-,',do fichero antes de ser procesado tiene que ser "abierto" y una vez procesado debe
'jr ''cerrado". La forma en que un f,chero se abre depende de1 tipo de operaciones
.ictura, escritura) que se realizarn con el fichero. Sin embargo, la forma de cerrarlo es
.Jependiente de las operaciones que se hayan realizado.
Apertura de un fichero de texto. Hay tres formas de abrir un fichero de texto. La
:r--era de ellas slo es vlida en Turbo Pascal.
El procedimiento reset. abre un flchero de texto para leerlo, por 1o que presupone
- -: ei fichero existe. En caso de que no exista se producir un effor de ejecucin. Este
- --edimiento coloca el puntero del fichero especificado al principio del mismo. Su
-.ris es la siguiente:
:eset. ( f icheroTexto) ;
r: : end ( f icheroTexto) ;
Donde car es una variable de tipo char y num una de tipo real.
Hay dos funciones booleanas asociadas a la deteccin de la marca de fin de lnea
de fin de fichero: eoln y eof respectivilteflte: Srr sintaxis es:
.-.:
.'. -'-r: - -:?:--a: LeXt;
.-
Trpos DE FrcHERos EN Prsclr, J-1 /
=r. h=r.
num: real;
: ] 1T\T
--JII\
tu="t (ficheroTextol ;
WHILE NOT eof (ficheroTexto) D0 BEGIN
readln(ficheroTexto, car, num) ;
Procesarlinea (car, num) ;
END;
close ( ficheroTexto) ;
: Irl&rler&
ms adecuada de implementar una lectura secuencial (de principio a fin) de
--. fichero es mediante el esquema de recorido; en este caso, un bucle WHILE cuya
. rdicin de terminacin se refrere a la terminacin del flchero. As, cuando el puntero
-.. hchero detecte la marca de fin significar que se ha procesado todo su contenido. Si
: -ntenta realizar una lectura una vez que la marca de fin ha sido detectada se producir
.ror de ejecucin.
Escritura de un fichero de texto. La escritura se realiza con los procedimientos
- -:e y writeln utilizando el siguiente formato explcito:
write (ficheroTexto, listaParametros) ;
writeln (f icheroTexto, listaparametros) ;
: -:heroText.o : cext;
'=--
--y . 1r'
.racn. -,,4r;
:- rr : real ;
- :r,irite (f icheroTexto ) ;
::1tr^rll
readln(car, num);
wriLeln(ficheroTexto' car:2'
num:10:2) ;
(s/n) :') ;
write('Qureres continuar
readln (resp) ;
UNTIL (resp = 's') oR
(resp = 's');
close (ficheroTexto) ;
END;
TYPE
OF TComponente;
TFicheroBinario = FILE
y t'
tipo excepto un tipo frchero "*:titly::11'i:
lComponente puede ser cualquier se presentan algunos eJ emF.
re d.l fr;;;r; qr. .. ".loru. A conlinuacin
sisrro 1gico
TYPE
= (Lun, Mar, Mie' Jue, Vie,
Sab, Dom);
TDiasSenana
r'r-:1^,r: = ARFAY [i..100] OF integer;
TRegistroEmPleado = RECORD
nombre: string[401 ;
numefo: feal
END;
TFicheroNumeros FILE OF integer;
TFicheroDias FILE OF TDiasSemana;
TFicheroTablas FILE OF TTabla;
0F TRegi stroEmPleado;
TFicheroEmPleados = FILE
EltipoTFicheroNumeroscomespondeaunficherobinariocuyascomponentes)
del tipo enumer'-
del tipo TFicheroDias son
de tipo integer; fu' tornpo'entls
I'
I
TDiasSemana;cadaComponentedeltipoTFicheroTablasesunaffaydetipoTTa:..
un flchero binario culos coffipol';-
tli;r"roe*pleados describe
y, por ltimo. el tipo
I
I
l,-rmo se ha visto con los ficheros de texto (apartado 10.4.1), un flchero binario antes
-:r procesado tiene que ser "abiefto" y una vez procesado debe ser "cerrado". La for
:r Que un flchero binario se abre depende del tipo de operaciones (lectura, escritura) r
.r \ ayan arealizar. Sin embargo, y al igual que con los de texto, slo hay una manera
-:rrarlo.
Apertura de un fichero binario. Hay dos formas de abrir un fichero binario.
rcedimiento reset abre un fichero binario para realizar tanto operaciones de lect
- lno de escritura. Presupone que el fi.chero existe. En caso de que no exista se produ,
- . enor de ejecucin. Este procedimiento coloca el puntero del fichero especificad
ncipio del mismo. Su sintaxis es la siguiente:
:,rin inr;.
reset. ( f icheroBinario) ;
1: la menl,
-
r:ntes soll El procedimiento rewrite tiene un comportamiento similar al visto con fichero
:'tto. Abre un fichero binario para escribir en 1, destruyendo su contenido en el
-I. La sint', ,: que se realice con un fichero que existe. Este procedimiento coloca el puntero
-hero al principio. Su sintaxis es la siguiente:
rewrite ( f icheroBinario) ;
::rdo varTComponente una variable del mismo tipo que las componentes del ficl
, -::eroBinario. Este procedimiento lee una componente de f icle:cBinario ,
:-ero contenido en varTComponente.
SU
.omponentes : La funcin eof ya descrita en el apartado 10.4.1 tambrn se utiliza para detectr
r tipo enumer.-
- - de un fichero binario. Sin embargo, la funcin eoln no se puede utilizar con fich
r de tipo TTa: - , - .arios.
Juyas COmPor:' El siguiente fragmento de cdigo muestra cmo se escribe en pantalla todo el cc
- ,de un fichero binario:
340 Frcnnnos
TRegistroEmpleado = RECORD
nombre: string [401 ;
numero: real
END;
TFj-cheroEmpleados = FILE OF TRegistroEmpleado;
VAR
f ichero : TFicheroEmpleados ;
registro : TRegistroEmpleado;
BEGIN
reset (trchero) ;
WHILE NOT eof (fichero) DO BEGIN
read (f ichero, registro) ;
writeln ( 'E1 nombre es : ' registro. nombre) ;
writeln ( 'EI nmero es : ' registro. numero) ;
END; {wurlr}
close (fichero) ;
END;
donde varTComponente es una r.ariable del mismo tipo qrre las componentes del flche :
ficheroBinario. Este procedimrento escribe el contenido de la variable varTCon: -
nente en f icheroBinario.
El siguiente fragmento de cdigo muestra cmo se crea un fichero binario a prtir -:
informacin leda del teclado:
TRegistroEmpleado = RECORD
nombre: string [40J ;
numero: redl
f ichero : TFicheroEmpleados ;
Tlpos DE FICHERoS EN PASCAL 34
registro : TRegist.roEmpleado ;
:]-T\T
_ _ _-_r!
re\irLLe (f ichero) ;
t.!,}tt
vrrile('Escribe un nombre y un nmero: ,) ;
-rea,\n\-reg\sUco .nombre reg\s\-ro .rru\ero
, ) ,i
wrl-Le(tichero, regisLro) ;
-'rs flcheros de acceso directo son aquellos en los que se puede acceder a una
: rnente cualquiera indicando la posicin que ocupa en el flchero. Pascal estnc
rport& los flcheros de acceso directo, pero otras versiones, como Turbo Pascal,
-,poftan.
imilar al que se En Turbo Pascal un fichero binario puede ser procesado indistintamente cor
n se refiere a la - -hero de acceso secuencial o de acceso directo. La nica condicin necesaria par
do. ,:. hchero pueda ser tratado con acceso directo es que est almacenado en un sr
te de un flcheo , :e ccionabie (disco magntico, disquete, ... ).
D: El acceso directo a una componente se realiza situando el puntero del fichero
'icin en la que se quiere hacer la operacin de lectura o escritura. El posicionan
, r. puntero se realiza con el procedimiento seek. Su sintaxis es:
END;
TFicheroEmpleados = FILE OF TRegistroEmpleado;
VAR
f ichero : TFicheroEmPleados ;
registro : TRegisLroEmPleado ;
BEGIN
reset (fichero);
=""0 t
fichero,
); 23
read (f ichero, registro) ;
END;
Tngase en cuenta que cada operacin de lectura y escritura hace avanzar el puntero u: *
posicin. En el ejemplo anterior, el puntero estara apuntando a la posicin 74 tras -
ejecucin de la instruccin read (fichero, registro).
Adems del procedimiento seek hay dos funciones predefrnidas que facilitan prtrc;'
sar flcheros con acceso directo: filepos y filesize. Su sintaxis es:
TYPE
1(
, TRegistroEmPleado = RECORD
lA nombre: string [4ol ; _u
numero: real :,tl
END;
TFicheroEmpleados = FILE OF TRegistroEmpleado; . :.:
--j
VAR
f ichero : TFicheroEmPleados ;
registro : TRegistroEmPleado ;
3EGIN
PedirDatos (registro) ;
END;
FrcnBnos coMo pnnnrnrnos -1+-1
:r el siguiente ejemplo se muestra cmo hacer una lectura secuencial a partir de una
.: :-rinada posicin del flchero.
_ .:
---.egistroEmpleado = RECORD
nombre: stri-ng[40i ;
numero: real
:rchero : TFrcheroEmpleados ;
:egistro : TRegistroEmpleado;
:csicion: longint;
E j emploFicheroParametro ;
: - cheroText.o : text ;
ProcesarFichero (VAR fichTexto: text) ;
l-
t ProcesarF'lchero)
ProcesarFichero )
344 FTCHEROS
I
BEGIN
assign(ficheroTexto,'c: \Datos\agenda.txt' ) ;
reset (ficheroTexto) ;
ProcesarFichero (f icheroTexLo) ;
close (ficheroTexto)
END,
La funcin Exi ste devolver el valor TRUE si la operacin reset ( f i chero ) se i-.
;:bo con xito (el fichero asociado a la variable fichero existe) y devolver el r, '-
lr-:: encasocontrario. Ntesequeenelcasodequelafuncindevuelvaelvalor -.
c. i;he ro quedar abierlo. IJna vez hecha la comprobacin de la existencia del fic: -
er .&!rr cle que no se haya realizado la operacin de E/S correctamente, se podr d: ' -
si se muestra un mensaje al usuario, Se crea el fichero o 1o que pueda convenir .- -
correcta elecucin de1 programa.
Cursrroxps DE TrPo rEST 3115
I Seale cul de las afirmaciones siguientes sobre los ficheros binarios es cierta:
(a) L funcin eoln (varFichero) utilizada con flcheros binarios devuelve va-
lor TRUE si el apuntador o puntero de varFichero est sobre la marca de fin
de lnea y FALSE en caso contrario.
(b) Su paso como parmetro sigue las mismas normas que con otros tipos de
datos: se pasa por valor cuando es un parmetro de entrada y por referencia
cuando es un parmetro de entrada-salida o slo de salida.
(c) Permiten realizar tanto un acceso secuencial como directo independiente-
mente del tipo de soporte.
I Seale cul de las afirmaciones siguientes sobre los ficheros de texto es cierta:
(a) Cuando se abren con append permiten operaciones de escritura una vez se
ha colocado el puntero con el procedimiento predefinido seek.
{b) Se utilizan mediante variables de un tipo predefinido.
-{c) Estn organizados igual que los archivos estndar Input y Output.
(d) Cuando se abren con reset permiten tanto operaciones de lectura como de
escritura.
. Seale cul de las aflrmaciones sobre eI siguiente cdigo es cierta:
-,rAR
4. Seale cul cle las afirmaciones siguientes sobre los flcheros binarios es cierta:
6. Seale cul de las aflrmaciones siguientes sobre los ficheros binarios es cierta:
(a) El modo de acceso utilizado en los ficheros de texto y en los binarios pue-.
ser distinto.
(b) Para sobreescribir cualquier tipo de flcherc se emplea el procedimiento :=
write.
-="(c) El procedimiento append funciona de la misma forma en ficheros de tert'
binarios.
td) En Pascal hay dos tipos de ficheros: binarios y de texto.
8. Seriale cul cle las aflrmaciones siguientes sobre los ficheros binarios con acc;.
secuencial es cierta:
l
CussrroNns DE TIPo rEST
'.*.(a)AlescribirComponentesenelficherosiempreseaadenalhnaldeltlrt.n,:
(b) No se puede acceder a la primera componente del fichero'
(c)ParaleerunaComponentedelficheroesnecesarioConocerlaposrcinque
ocupa.
haber ledo todas las pre-
**.(d) Para leer una componente del fichero es necesario
cedentes'
10.7.2 Soluciones
l.Laafirmacincomectaesla(d).Lafuncineo}nnosepuedeutilizarconficheros
pasarlos como parmetros por re-
binarios; los ficheros binarios siempre hay que
se puede realizat si el soporte
ferencia; y eI acceso directo a un fichero binario slo
es direccionable.
mentelaprimeraComponentealaqueseaccedeenprimerlugarlnoesnecesario
leerla'
conocer la posicin que ocupa una componente para
348 Frcnnnos
10.8 Problemas
10.8.1 Copia de flcheros de texto
Escriba un programa que permita copiar un fichero de texto. Para ello, el programa
preguntar al usuario el nombre que tendr la rplica.
:: este tipo de particin el valor de los campos de los registros no se tiene en cuenta.
,nsiste en almacerrar Iy' registros contiguos del fichero origen alternativamente en los
, . o ms ficheros destino. Este tipo de particin se utiliza en el mtodo de ordenacin
-. ncheros de mezcla directa (ver apartado 10.8.7).
Sea el fichero de alumnos descrito anteriormente. Se quiere partirlo en dos ficheros,
-; lnanera que N registros contiguos del fichero origen se almacenen altemativamente
: -. .tro y otro. El valor de N se pedir por teclado. Ntese que en este caso el contenido
!1 -l ( )i t_
!2: 2, 3, 7, 10, 1
La fusin de dos f,cheros consiste en agrupar en un nico nuevo fichero los registros de
ambos. Los f,cheros que se quieren fusionar estn ordenados por uno de sus campos y el
f,chero resultante de la fusin se espera que tambin est ordenado por el mismo campo-
Obviamente, los ficheros que se quieren fusionar deben tener el mismo tipo de registro
lgico. Por ejemplo, se tienen dos flcheros F1 y F2 y los valores del campo por el que
estn ordenados son:
F7 2, 3, 6, 8, 9, 72, 15
F2.. L,3, 5,'7,10t
FL: ]-5, 2, 7, 12
12: 2a, 3, 10, 1
Fusin en secuencias de tamao N : 1:
::: 2, 3, 15, 20
:2:1,'7,10, L2
' . ..,rn en secuencias de tamao Iy' : 1:
F2:2,3,7,10, 12
Obsn'ese que la fusin se realiza con una secuencia ordenada de cada fichero.
Particin en secuencias ordenadas:
' "-.::f =rthttp : I lwww .urj c . es " >Universidad Rey Juan Carlos</a>
#;"1''*-*'":T:""',."fi
]':":t:;"n,T:X[i": :,.'
o,o,i"",lJlff Hil:"X,:::.:ff
i::il:::#;:H1: [',::?i:ilffi;,r ;"i
:::i:::ff::ti;li;lliil],'
e:
J"J:J:,:::J:::"""0:'"
#ffiil:*:l*::11;;"1'";1[:'
i::lli:,"$:1,"J;ii1xl;til?"il1;':il:*trl,:^T:::tH"J::':X?i#:Tl;
','J:'J,1?.:r;:X1""$?#"'ilX"'*f utilizando bs' 1a -'
o"nas consultas
T i?:il:ll:?:H#::T[::,T:Ttl'*"
binario'
i.trtc,*i.u sobre el propio f,chero
zona.
Sor,ucroNrs 355
2. Suponiendo que el fichero est ordenado por cdigo de zona y, dentro de cada
zona, por cdigo de producto, escriba un programa que obtenga un informe por
pantalla de las unidades vendidas. El informe deber tener una lnea por cada
zonay producto dentro de esa zona. Cuando se acabe una zona se indicar, en
otra lnea, el total de unidades vendidas enla zona.
10.9 Soluciones
10.9.1 Copia de ficheros de texto
,
Se van a plantear dos soluciones pafa tealttzr la copia de un flchero de texto.
VAR
r. hzr.
BEGIN { CopiaCaracterACaracter }
reset (FOrg) ;
rewrite (FDes) ;
WHILE NOT eof (FOrg) D0 BEGIN
read (hOrg, car) ;
wrrte (f'ljes, car ) ;
,y
close (FOrg) ;
cfose (FDes) ;
END; {CopiaCaracterACaracter}
VAR
car: char;
BEGIN i CopiaCaracterYLinea)
reset (FOrg) ;
rewrlte (t'Des) ;
WHILE NOT eof (FOrg) DO BEGIN
IIIHILE not eoln(FOrg) D0 BEGIN -
read(FOrg, car);
write (FDes, car)
356 Frcnnnos
END;
writeln (FDes) ;
readTn(rorg);
END;
l['r)rl
\l v!f / ,
.
- l^a lL'llaq
\L Dee l
I .
I
END ; lCopiaCaracterYLrnea)
El programa completo:
VAR
FOrigen, FDestno: text;
correcto: boolean;
nombre: string;
END;
UNTIL correcto OR (upcase(car) = 'S,);
END;
REPEAt'
correcto := TRUE;
write('Escribe el nombre del fichero copia: ,);
readln (nombre) ;
:oo.i (FDes, nOmbre) ;
IF Existe(FDes) THEN BEGIN
writeln ('El fichero copia existe (pu1se R , ,
'para reescribirlo, S para salir)');
read (car) ;
lF Upcase(car) <> 'R' THEIV
correcto := FALSE;
END;
UNTIL correcto OR (Upcase(car) = 'S');
ItrIn .
car: char;
SfGIN {CopiaCaracter}
reset (FOrg) ;
rewrlte (lDes) ;
WHILE NOT eof (FOrg D0 BEGIN
read(FOrg, car);
wrl_te (hljes, car) ;
END;
close (FOrg);
:lose (FDes) ;
r.-- , iCopiaCaracter)
BEGIN { CoPiaCaracterYLinea }
(t"Org)
reset ;
rewrite(bDes);
hIHILE NOT eof (Forg) D0 BEGIN
P
v,
WHILE not eofn(FOrg) D0 BEGIN
read(FOrg, car);
write (FDes, car)
!L
END;
writeln 1fes) ;
readln (FOrg) ;
END;
close tFOrg) /
c,Lose ('Des ) ;
END; iCoPiaCaracterYLinea)
IF correcto THEN
CopiaCaracterACaracter ( F0rigen' FDestino);
(FOrigen' FDestino) )
{o CopiaCaracterYLinea
END;
END. {lrograma PrinciPalJ
VAR
l^vi-^. iovl :
:.: ?IAT
read (car) ;
E
-: car <> chr(13) THEN END;
tfTexto, car) ;
"',:-:e
:a: chr(13); wri t:
,1,--- --
SorucloNns 359
close (fTexto);
:i.); {almacenar}
contE := contE + 1;
write (, ,) ;
END;
,I, ,,i, : BEGIN
contl := ConLf +
write (, _,) ;
END;
'a' ,'o' : BEGIN
contO := conto +
writ.e (, _,) ;
END;
,U,
,,U,: BEGIN
contU := conLU + 1;
write (, ,) ;
END;
ELSE
write (car) ;
trI\Tn.
!a!u/ f^-^^i
luqDEJ
IND; {whilei
,,;riteln;
360 Frcnnnos
I
C
=:-:: ; jl : l;.=---stro;
f,
SolucroNns
nj ovenes : TEstruct.uraArray;
EIJI\TCTION Existe (VAR f ichero: TFichero) :
BEGIN {existe}
{$r-}
reset (fichero) ;
{$r+}
Exrste := (IOResuIr = 0);
close (fichero) ;
END; iexiste)
esMenor: boolean;
encrada: TRegistro;
BEGIN { CalcularNMasJovenes }
reset (agenda) ;
nMenores.tope := 0;
WHILE NOT eof (agenda) DO BEGI}J
read (agenda, entrada) ;
IF nMenores.tope < N THEN BEGIN
nMenores. t.ope : = nMenores. tope + 1;
nMenores. datos lnMenores . tope] . anioNacimienLo : = MAXINT
END;
.-
)'
r ll .
esMenor := FALSE;
REPEAT
j := j + 1;
IF entrada. anioNacimient.o <
.:_:
PI
A I\I .
U ' ' !r ,
::l:N {MostrarNMasJovenes }
FOR nJovenes'tope DO BEGIN
i:= 1 TO
VA
write (nJovenes'datos Iil 'apel]idos:35) ;
writeln;
END;
END; {MostrarNMasJovenes}
MostrarNMaSJovene s (nJovenes ) ;
E}\D
ELSE
,,,riielnt'EI fichero agenda.dat no existe')
;
CONST
vm-lr=rtl,
[Af |
-
TYPE
TFicherolma$en = FILE ob DYte;
TNombreFichero = string [501 ;
'.-iR
ancho, alto: integer;
correcto: boolean;
:,cherolmagen : TFicherolmagen ;
:--j
1:s.: fichero) ;
:--l
Sor,ucroNns 363
n:v. hr.
nombre : TNombreFichero ;
:EGIN { nediroatostmagen}
REPEAT
COTTECTO : = TRUE;
write('Ruta y nombre de Ia imagen sin extension',
(.raw):');
readln (nombre) ;
nombre := nombre + EXT;
assign (fichero, nombre) ;
IF Existe (fichero) THEN BEGIN
write('Anchura: ') ;
readln(ancho);
write('Altura:');
readln (alto) ;
END
ELSE BEGIN
writeln('El fichero no se encuentra (Pulse ',
'una tecla para seguir o S:Salir)');
read (car) ;
correcto : = FALSE;
END;
l,'}JTIL correcto 0R (Upcase (car) ='g' '
:. 1; {ledirnatoslmagen}
.:ICEDURE PintarPixel (pix: byte) ;
: r,IN i eintarlixel )
write(pix:3);
-
-; ilintareixel)
::ICEDURE ErrorlecLura(comp_x, comp_y: integer) ;
.. IIN { ErrorLectura }
'.'-.i ral.
writeln('Error de lectura en efemento: ', comp x, ',',
364
FrcnBnos
comp_y) ;
fallo: boolean;
BEGIN {lectura}
reset (fRaw) ;
fallo := FALSE;
., .-
.- 1.
r,
^
,, ._ 1.
| '- -t
WHILE (x <= alto) AND NOT fallo DO BEGIN
writeln;
WHILE (y <= ancho) AND (not eof (fRaw) ) D0 BEGIN
read (fRaw, Pixel) ;
pintarPixel (Pixel) ;
y := y+1;
END;
rF eof (fRaw) AND (y <= ancho) THEN BEGrN
errorlectura (x, y) ;
fallo := TRUE;
END;
y:= 1_;
x+1;
END;
LecturaCorrecta := NOT falIo;
close (fRaw) ;
end; {rrN }ectura}
PROCEDURE FinalExito;
BEG]N {rinalExito}
','-.iraln.
writeln ('Fin de programa con exito' ) ;
writeln('Alejate para ver el resultado') ;
Il.iD ; irinalrxito )
PRCCEDURE FinalFalIo;
BEGIN { rinalrallo}
Sor,ucroNBs 365
r-
:.,U. t Programa prrncrpal J
r=j: TRegistro;
,' Part i c ionContenido )
:eset (f0rg) ;
:ewrite (fMan) ;
366 Frcnnnos
rewrite (fTar) ;
WHILE NOT eof (forg) DO BEGIN
read (fOrg, reg) ;
IF reg.turno = 'M' THEN
write (fMan, reg)
ELSE
write (fTar, reg) ;
END; {wttrlri
close ( fOrg) ;
close (fMan) ;
close (t'Iar) ;
END ; {ParticionContenido}
BEGIN IPrograma principa])
assign (fMagnana,' turnoMagnana.bin' ) ;
assign (fTarde, 'turnoTarde.bin' ) ;
assign (fOrigen, 'TodosTurnos.bin' ) ;
ParticionContenido (fOrigen, fMagnana, fTarde) ;
-1
EjNlJ. t Programa prlncrpal.f
reg: TRegistro;
conr: inCeger;
cambio: boolean;
BEGIN { Particl-onSecuenciasN}
reseL (fOrg) ;
rewrite (fPar1) ;
rewrite (fPar2) ;
Camb1o := TRUE;
nnl .-
. n.
vt
dni: string[9J ;
direccion: string[35J ;
codigoPostal : string [51
ciudad: string[20J;
turno: char;
END;
TFichero = FILE OF TRegistro;
VAR
fOrigen, fPar[l, fParL2: TFichero;
VAR
regAnt, regAct: TRegistro;
cambio: boolean;
BEGIN { rarticionSecOrdenadas }
reseL (forg) ; t
rewrite (fPar1) ;
rewriLe (fPar2) ;
:ambio := TRUE;
::c.lrt. aPellidos i= ' ' i
,';:---: NCT eof (fOrg) DO BEGIN
-..-^i j--- zoaAcj-).
-=:- ---y/!tYreu/ /
END; {wttri,r}
close (fOrg) ;
cfose (fPar1) ;
close 1fPar2) ;
E\D; {ParticionSecOrdenadas}
PROGRAM FusionDosFicherosBinarios ;
TYPE
TDATOS = RECORD
nombre: string[20J ;
apellidos: string[35J ;
END;
I
TReqistro = RECORD
clave: rnteger;
datos: TDatos;
END;
TFi-chero = FILE 0F TRegistro;
-,.AR
rewrite (fFus) ;
reset (f1) ;
reset (f2) ;
]
!r11r -1
,-
. -
f:lao.
Lqre,
f:.n2 := false;
LeerFichero(f1, 17, finl) ;
END
ELSE BEGIN
wrice (fFus, 12) ;
LeerFichero(f2, 12, ftn2) ;
END;
}
END; {wHrf,r}
WHILE NOT finl DO BEGIN
write (fFus, r1) ;
LeerFichero ( f1, T7, finl ) ;
E\TN.
END; {Fusron;-c:r=::s
?LCGLAM 0rdenacionMezclaDirecta ;
TYPE
TRegisrrc = RECORD
Sor,ucroNns 311
codigo: string[10] ;
denominacion: strinq [3 0] ;
END;
TFichero = FILE OF TRegistro;
rewrite (fpar1) ;
rewrit.e (fpar2\ ;
cambio := TRUE;
anl . = n.
WHILE NOT eof (fOrg) D0 BEGIN
read (fOrg, reg) ;
IF cambio THEN
write (fpar1, reg)
ELSE
write (fpar2, reg) ;
cont := cont + 1;
IF cont = n THEN BEGIN
cambio := NOT cambio;
Cont : = 0;
END;
END; {wHrlo}
close (f0rg) ;
close (fparf) ;
close (fPar2) ;
:, -, {ParticionSecuenciasN}
ELSE
fin := TRUE;
END;
rewrite (fOrg) ;
reset (fPar1) ;
reset lfPar2)
finl : = false;
fin2:= false;
Leer(fParr1, regF1, lint) ;
Leer ( fParL2, regF2, fin2\ ;
conlF'T .- n.
.^nlF', .=
. n.
vl
contF2 := contF2 + 1;
END; {wurlr}
ContFl := 0;
ContF2 : = 0;
END; iwiirln i
close (f0rg) ;
close (fPartf) ;
close(fParL2);
:. --t .
assign(fPart1,' fPartSl.bin' ) ;
assign(fPart2,' fPartS2.bin' ) ;
assign (fOrigen, 'afumnos,bin') ;
MezclaDirecta (fOrigen, fParLl , fParL2) ;
l_ -
:. tPrograma prlnclpar
1
-. ]
VAR VAR
fOrigen, fPartl, fParL2: TFichero;
reglogico: TRegistro;
DE
PROCEDURE ParticionSecOrdenadas (VAR fOrg, fParl ,fPar2: TFichero) ; DEU
VAR
regAnt, regAct: TRegistro;
cambio: boolean;
BEGIN { ParticionSecOrdenadas }
reset (fOrg ;
rewrite (fPar1) ;
rewrite (fPar2) ;
cambio := TRUE;
regAnt.codigo i= ";
WHILE NOT eof(fOrg D0 BEGIN
read (fOrg, regAct) ;
IF NOT (regAnt.codigo <= regAcL.codigo) THEN
cambio := NOT cambio;
IF cambio THEN
write (fPart, regAct)
ELSE
write (fPar2, regAct) ;
regAnt := regAct;
END; {wurlu}
close (f0rg) ;
close (fPar1) ;
close (fPar2) ;
END; {ParticionSecOrdenadas}
END
ELSE BEGIN
write (fOrg, regE2) ;
write (regF2. codigo:3 ) ;
codAnLF2 := regF2.codigo;
Leer(fPart2, regF2, fin2\ ;
END;
END; {wHrlu}
WHILE NOT finl AND (codAntFl <= regFl.codigc :- ::l-l:
write (fOrg, regFl) ;
write (regF1 . codigo:3 ) ;
codAntFl := regFl.codigo;
Leer(fPart1, regF1, finl) ;
END; t wHrLE l
WHILE NOT fin2AND (codAntF2 <= re9F2.cci:gc1 D0 BEGIN
write (forg, regE2) ;
wriLe (regF2. codigo:3 ) ;
codAntF2 := regF2.codigo;
Leer ( fParL2, regE2, ftn2\ ;
316 FICHEROS
END; {wurrn}
END; {Wtttt u}
close (fOrg) ;
JIose (IPartr) ;
close (fPart2) ;
I),); {FusionSecOrdenadas}
reg: TRegistro;
ordenado: boolean;
::GIN {MezclaNatural}
ordenado := FALSE;
REPEAT
ParticionSecOrdenadas (fOrg, fParl , fPar2) ;
reset (fPar2) ;
ordenado := (filesize(fPar2 = 0);
cl-ose (fPar2) ;
IF NOT ordenado THEN
FusionSecOrdenadas (fOrg, fParl , fPar2) ;
LTJTIL ordenado;
:1,-r; {MezclaNaturali
::l:N {Programa princiPali
assign(fPart1,' fPartSl.bin' ) ;
PROGRAM As i sLenteWebPersonal ;
CONST PR(
NIIMIDIOMAS = 1; Vzu
NIIMEROESTUDIOS = 1;
;f-PE BEC
TFicheroTexto = text;
THes = string [10J ;
TDia = 1..31;
Sor,ucroNns 371
TAnio = 1900..2100;
TNombre = string[15];
TApellidos = string[30] ;
TFecha = RECORD
dia: TDia;
mes: TMes,.
anio: TAnio;
END;
TDi reccion=RECORD
calle: string[20] ;
numero: integer;
codigo: string[5] ;
localidad: string[15] ;
provincia: string[15J ;
END;
TEstudio = string [15] ;
TEstudios = array Il..NumeroEstudios] OF TEstudio;
Tldioma = string[15];
Tldiomas = arrayIl..NumIdiomas] OF Tldioma;
TCurriculum = RECORD
nombre: TNombre;
apellidos : TApellidos ;
fechaNacimient.o : TFecha;
direccion : TDireccion;
Lelefono: string[9] ;
mail: string[40];
estudiosprevios : TEstudios ;
roromas : Idlomas;
'.1
foto: string[50] ;
END;
pagWeb : TFicheroTexto;
curriculum: TCurriculum;
writeln ('ApelIidos' ) ;
readln(Apellidos);
writeln ('Fecha de Nacimiento' ) ;
writeln ('Direccion' ) ;
write('Telefono:');
readln (Telefono) ;
readln (Mait) ;
FOR i := 1 TO NumeroEstudios DO
BEGIN
write ('Estudios Previos ' ,
END;
FOR i := 1 TO Numldiomas DO
BEGIN
write ('rdioma ' , i,
readln(rdiomas Ii] );
END;
write ('Ruta nombre de la foto: ');
readln (F',oto )
i . i nt-aaa-,
reuYur,
BEGIN {MostrarEstudios}
FOR i := 1 TO NumeroEst.udios-1 DO
write(pag,,,, curr.Estudiosprevios [i],,,, ) ;
f n-,.i r ^
tEvrra mostrar 1a ",', al final del ultimo)
write (pag, " , curr.Estudiosprevios [NumeroEstudios] ) ;
END; iMost.rarEstudios)
',',ct)TT.Direccion'Numero"
curr.Direccion'Codigo"' ) ; "'
writeln (pag, curr.Direccion' Localidad"
curr. Direc cion. Provinca, "'
,<fp>,);
writeln(pag,' <p><b>Telefono: </b>', curr'Tefefono'
, .lpr,) ;
END ; { CreacionCuerPoPagina}
rewrite (Paglleb) ;
close (PagWeb) ;
END. {Programa PrinciPal}
PROGRAM ASiStCNTCWCb;
TYPE
TTrtulo = string [25] ;
T?arrafo = string;
TFi:neroTexto = text;
Sor,ucroNns 381
pagWeb : TFicherotexto;
fin: boolean;
buf f er: word,.
ELSE
writeln (pag, ' .p>' , parrafo+parrafo2, , </p>,) ;
:).1; {narrafo}
lil Frcnnnos
END; irmagen)
VAR
texto, link: string;
cenLrar: char;
BEGIN {untace}
write ('Introd'uzca el destino del enlace: ' ) ;
readln (link) ;
readln (texto) ;
(S/N) ');
writeln('La quiere centrar en Ia pantalla?
readln ( centrar ) ;
IF uPcase(centrar) = 'S' THEN
*ria"tr, (p,g, '<div align="center" ><a href="' '
Iink, "'>', texto , '<fa><fdiv>')
ELSE
I rrI <f a>')
writeln(pag,'<a href="',link' 't'eXLo
i 10.9
"
END; {enl-ace}
?R0(
-.-:
rnal,oPcion: char;
:::-); {fuienui (I)magen"
i;rrteln('EIrge insertar entre (P)arrafo'
'o (E)n1ace');
:eaCln(opcion);
Sor,ucroNBs 383
lFechaReduc = RECORD
mes: 7..L2;
anio: ir.teger;
:ITN.
_LtD I
-Registro = RECORD
referencia: string[15] ;
titulo: string[30J ;
FICHEROS
END;
autor: string[501;
fechaEdicion : TFechaReduc ;
IIrtJCl
paisEdicion: string [25] ;
3EGI}
numPaginas: integer;
numPrestamos: integer;
estado: char;
END;
TFichero = FILE OF TRegistro; l1-- .
'--t_:,
:--.JLE
:iblioteca: TFichero; :l^Ttf
_
- -bro : 'I'Reglstro;
--41!
encontrado := FALSE;
|^IHILE (NOT encontrado) AND (extsup>=extlnf ) D0 BEGIN II
cenLral := (extSuP + extlnf) div 2;
seek (bib1io, central) ;
read (biblio, reglog) ;
IF reglog.referencia = ref THEN
encontrado : = TRUE
ELSE
IF reglog.referencia < ref THEN
extlnf := centraf + 1
ELSE
extSuP := central - 1;
.'- illlILEJ
-, -..-::-:radO THEN
.-=;-:iaBinariaF := central
:,::
: .-'l*=:==inariaF z= -L;
,l
Sor,ucroNns 385
:ND; {BusquedaBina:iaF}
j-lrlJCTION Existe (VAR f ichero: TFichero) : boolean;
IIGIN {existe}
{sr-}
reseL (fichero) ;
{$r*}
Existe := (IOResult = 0);
- l. /^vr.lt
END
ELSE
writeln ('EI fichero bibio.dat no existe');
T-
ENIJ. t Programa prlnclpai lJ
1. Para obtener un nuevo f,chero en el que haya un registro lgico por cada zona, se
deben procesar todas las componentes con el mismo cdigo de zona y realizat el
sumatorio por cada una.
En este caso slo debemos controlar el cambio de zona, por lo que tenemos una
alto nivel para realizar un programa con
--lruptwa de control. Una descripcin de
una ruptura de control sera el siguiente:
LeerRegistro ( ) ;
I4HILE NOT f inFichero 0 D0 BEGIN
IniciacionCodigo ( ) ;
\,^IHILE coincideVatorCodigo 0 AND NOT f inFichero 0 D0 BEGIN
TratamientoCoincidevalorCodigo ( ) ;
LeerRegistro ( ) ;
E-'iD ; {wHIlr }
. -:-a. -zacionCodigo ( ) ;
ErT.
DI\U, ,'l-:r-:"
Ntese que no se han detallado los parmetros de los subprogramas, ya que van--
rn segn el probiema particular.
Una particularizacin de la descnpcin anterior al problema que nos ocupa se..-
1a siguiente:
PROGRAM RupturasControl 1;
TYPE
TRegistroVentas = RECORD
codigoProducto: string [151 ;
TRegistroVentasZona = RECORD
Sor,ucroNns 387
VAR
fVentas: TFicherovent.as;
fVentasZona : TFicheroVentasZona ;
cfose (fVentasZona) ;
END ; { CalculototalesporZona}
2. Para obtener un informe con una lnea por cada producto dentro de cada _
y una lnea con los totales por zona, se deben procesar todas las compol.:-
con el mismo cdigo de zona y con el mismo cdigo de producto dentro dt ,, .
zona. llevando dos sumatorios: producto por zona y zona. En este caso deb;'
controlar el cambio de zona y el cambio de producto, por 1o que tenem, . _
LeerRegistro ( ) ;
WHILE NOT finFichero 0 D0 BEGIN
IniciacionCodigol ( ) ;
WHILE coincideValorCodigol 0 ANO
NOT finFichero O D0 BEGIN
IniciacionCodigo2 0 ;
I^IHILE coincideValorCodigol ( )
AND coincideValorCodigo2 ( )
AND NOT finFichero 0 D0 BEGIN
TratamientoCoincideValorCodigo ( ) ;
E
Sor,uctoNss 389
LeerRegistro ( ) ;
END; {wHrlu}
FinalizacionCodigo2 ( );
END; {wntLn}
FinalizacionCodigol ( ) ;
END; {wurln}
Ntese, que al igual que en el caso anterior, no se han detallado los parmetros
de
los subprogramas, ya que variarn segn el problema pafticular.
lJna particularizacin de la descripcin anterior al problema sera la siguiente:
PROGRAM Rupturascontrol 2;
TYPE
TRegistroVentas = RECORD
codigoproducto: string [15] ;
codigoZona: string [10] ;
unidadesVendidaS ; j nroaor.
END;
TFicheroVentas = FILE OF TRegistroVentas;
,7AR
r ventas :'.]-'I,'rcheroventas ;
.-1
reg: TRegiscroVentas;
fin: boolean;
codigoZonaAnt : string [10] ;
codigoProductoAnt: string [15J ;
sumaZona, sumaProducto: real;
: ::IN { Ca}culoTotalesPorZonayporproducto }
390 Frcunnos
reset (fVenLas);
r:
lIl-t-- := IrA.lrtr;
Leer(fVenuas, reg, fin) ;
WHILE NOT fin DO BEGIN
codigoZonaAnt := reg.codigoZona;
sumazona := 0.0;
writeln(codigoZonaAnt : 11) ;
WHILE (codigoZonaAnt = reg.codigoZona) AND NOT fin
DO BEG]N
codigoProductoAnt : = re9 . codigoProducLo ;
sumaProducto : = 0.0;
WHILE (codigoZonaAnt = reg.codigoZona) AND
(codigoProductoAnt = reg.codigoProducto)
AND NOT fin DO BEG]N
sumaProducto := sumaProducto +
reg. unidadesVendidas ;
Leer ( fVencas , reg, fin) ;
END; {wHrlr}
,
sumaZona := Sumazona + sumaProducto;
writeln (' ' :l!, codigoProductoAnt:16,
sumaProducto:6:0) ;
END; {wurln}
writeln(" i12, 'Tota1 zona ttt sumaZona:6:0);
END; {wHrlu}
cfose (fVentas) ;
END; { Cal culotota} e s PorZonaYPorProducto }
1P-L-l
reset (fichero) ;
{$r*}
Existe := (IOResulc = 0l;
close (fichero) ;
END; {existe}
assign(fVentas,' fVentas.bin' ) ;
-: Existe(fVentas) THEN BEGIN
writeln('Informe Ventas por Zona y Producto':40);
',.- l r o l - .
CalculoTotalesporZonayporproducto ( fVentas ) ;
END
ELSE
writeln(,El fichero de ventas no existe,);
END. {Programa principa}}
W
Captulo 11
- 1.1 Punteros
un valor entero en un prograrna se declara
H:::::111
r:*" : ""cesita
co.nle-ner_un dato de esre ripo, f".-n"r, ;il;";;;
una varia-
:::
deciaraunavariabre-0"i,r"""ir.";;"t.*;'j;,:'B:',;",-',fj:'f,J*:fflT:
' !rv vraq! J 4)r )uLs51\arllenle. ue ra m1(mir manera algu_
393
PUNTEROS Y ESTRUCTURAS DE DATOS
DINMICAS
)g4
pEntero, ^integer;
pEntero que es de tlpo-p*[[!!fo 9r'
En la lnea anterior se declara una variable llamada
s1o ser capaz de referenciar' o corn:--
cias al smbolo circunflejo "A" l Este puntero
tipo base at que se refiere .
ffi; ;;;;;ra;;ores de tipo enrero, puesro que el necesita un tipo base al que "
;;;;Jf ;;;.;" general la declaracin de un puntero el puntero o el tipo punl':
para definir
pueda referir y utiliza un smbolo de circunflejo
i"no. En el ejemplo anterior el tipo base es integer y para apunt;:
propiamente
valoresdeestetiposernecesarioreservarmemoriaparaguardarunvalorentero.E...
a travs de la declaracin de una 3Il*-
\
reserva ha podido ser realizada estticamente
de tipo entero:
Puntero; ()'
- 'l
PROGRAM
g,-{
VAR
pEntero: ^ integer ;
.l-laar.
entero : IltuLYe! / ., " .i:
t '.
BEGIN - (. - -" q-$- .' ".t
Eloperaclot.,@,,,tambjnllamadooperadordedireccin,aplicadoauna
r/er.c-Ir.e tit poscit, cle ntentot'it en la que se en.:uentra. La a.signacin de )a
cie mernoria del entero al puntero le da control total al puntero sobre el valor dcl enter'
.\s. el puntero estar en disposicin de actuar sobre el valor del entero una yez que e,\l;
enlazado. En Pascal. la forma de ret-erenciar al valor al que est apuntando es a trar-.
dei operador posthjo circunflejo "A" aplicado a la variable puntero, tambin llamadi'
operador de cle s re.feretlL'iLt o indireccin.
L'lr^ L
IJ!]lLurv .- J t
Mediante el puntero se puede actuar sobre la variable de tipo entero que est decla-
rada, de hecho, en este ejemplo se ha conseguido alterar su valor, de manera que en:
s
a
VAR
pEnterc' ^inLeger; pi
entero : integer; 11r
BEGIN pr
.- 4.
^lv^ se
a
pEntero : = @entero; ut
Lhf^v^ l.
.- r t
Plluurv ac
write (entero) ;
END; V
'l
PuNrpnos 395
entero
pEntero
'-gura 11.1: Puntero que contiene la direccin de memoria flcticia 215 correspondiente
- ,ina variable entera con valor 2 r'
- ravs del puntero se ha modificado el valor de la variable ent.ero y en pantalla se
-.u.stra 3 en lugar de 2.
t
= Para indicar que un puntero no apunta a una direccin especfica de memoria se le
-':qna un valor especial, tlrllEs especialmente til, como se ver ms adelante, y puede
:- asignado
|j!1eluiT.t]po 9-e puntero. Ntese que esto no conlleva que el valor del
-ntero sea indefinido, pues est my bien deflnido con el valor de NrL.
Hasta ahora se ha introducido el concepto de puntero haciendo uso de variables de
- s annimos pero, al igual que con cualquier otro tipo de datos, se puede
- pio. Nuevamente se utiliza un tipo base para la creacin del tipo puntero: definir uno
,: , IRAM TipoPuntero;
-,
-:-
-l
T-! ^.^^
_lIlLErU i rro_o-.
= f,I-LEyCr;
lPuntEntero = ^in1-eoer.
-:
DEntero: TpuntEnLero;
entero : TEntero;
.:
396 PUNTERoS Y ESTRUCTURAS DE DAToS DINMICAS
tipo entero. Una vez reservado dicho espacio se le asigna el valor 3 y se escn'n- .'
pantalla. Tras utilizarlo debemos liberar la memoria previamente reservada, utiliz*- -
el procedimiento dispose.
memoria que no ocupa el propio puntero, cabe la posibilidad de simular una transf'er: ,
de infbrmacin de una porcin de cdigo a otra mediante la asignacin de puntero:
Por otra parte, el paso por referencia de parmetros a un subprograma no im: . -
una copia del contenido de la variable pasada, sino que el parmetro real y el ft
identifican fsicamente al mismo bloque de memoria.
=-
Por tanto, si un bloque de memoria est apuntado porun puntero y ste es pa.-_
por valor a un subprograma, el parmetro formal toma como valor una copia del - _
que apuntaba el parmetro real. En esencia, este paso de puntero por valor es url :.
f
por referencia del dato que era apuntado por el puntero. En otros lenguajes, como er .
el paso por referencia no existe de manera explcita mediante alguna palabra reser\:-,
como VAR en Pascal. En estos lenguajes el paso por ref'erencia se hace especficamc .
mediante punteros.
.: - l:-LU Referencia; 11
_:--:
:. -:.:Sntero = ^integer;
: :.==^-- : -:unCEnterO;
' ----'''-
---A1AY.
|
------a
:
_ larrf
Jlt\
-
a+-v^
srlLurv .-
._ 1-
i
pReal : = @entero;
writeln (pReat) , {se imprime 2}
PasoValor (entero) ;
writeln (entero) ; {se imprime 2}
PasoValor (pReal^) ;
writeln (pReal^) ; { se imprime z }
?asoRef erencia (pRea1 ) ;
'riteln (pReal^ ) ;
{se imprime 4}
entero + 2;
r-'-r hasta este punto, adems de no parecer muy tiles. e1 uso los punteros
va
-; todos los principios de abstraccin tan deseables en un lenguaje de progra-
-: :ito nivel. sin embargo, gracias a la facultad de reservar y liberar memoria
los punteros son esenciales para la creacin de estructuras dinmicas
que
en funcin de las necesidaries de la ejecLrcin.
398 PUNTEROS Y ESTRUCTURAS DE DATOS DINMICAS
entero
pEntero
ptrntero_
r --
Figura 11.2: Laasignacin de un puntero a otro no duplica la informacin, ambos
teros quedan apuntados al mismo dato
L:s--:
Figura 11.3: Lista de nodos, implementada como registro con campo infornt.-
enlace al nodo siguiente
trpo de registro que lo contiene, por lo que se tiene una delinicin recursiva exceF -
en Pascal.
-_'-a
- -a)
lEiemento = ...;
l- rsra = ^TNodo;
TNodo = RECORD
:-nf o : TEIemento;
EsrnucruRAs DE DATos orNvrrcas 399
s19: TL]-sta;
END;
1.lJ_L S Ld,'
ey(aux);
a:r^.info := info;
a;x^.sig := Iista;
lista := uxi
Para borrar el elemento cabecera de una lista y liberar la memoria que lo contiene
previamente se debe comprobar que la lista es no nula. Seguidamente y utilizando
un
puntero auxiliar para tomar la cabecera de la li.sta, se hace avanzar el puntero original
que apuntaba a la propia cabecera y se libera memoria con el puntero auxiliar.
VAR
aux : Tlista;
D D TTT
D!U f L\
IF NOT EsVacia(Iist.a) THEN
BEGIN
aux := lisra^.sig;
dispose (1isca) ;
lista := uxi l
(
END;
e
END;
Como puede observarse en el procedimiento anterior, para ayanzar en una Iista enlazad. SI
lista := list.a^.sig;
o bien mediante una funcin, y teniendo cuidado de no salirse del espacio reservado ;.
la estructura:
Por extensin, para recorrer una lista desde su cabecera y procesar cada uno de :-
rlementos de informacin se utilizara un bucle a modo de esquema de recorrido:
frritese que la lista se pasa por valor al procedimiento y se ayanza directamente con el
:-rrmetro fbrmal, que es una copia del real. Avanzar con el real, sin ayuda de punteros
-:riliares, implicara la prdida de los elementos que se dejan atrs, sin posibilidad cle
::uperarlos y desperdiciando la memoria.
\1.2.2 Pitas
pila
illra i 1.4: Ejemplo de pila, el nico elemento accesible es el que hace de cima
Colasr!'
- .s son enlazadas con Ia particularidad de que los elementos
k
As. e1 primer elemento en entrar a
.s el prlme que equivale a una estructura FIFO (First-In First-Out).
es fcil ver ejemplos de colas en Ia vida cotidiana, desde
-- las personas
402 PuNrnnos y ESTRUCTURAS DE DATos orNrrrcls
Extraccin
Cola
Figura 11.5: Cola como particularizacin de una lista enlazada simple donde la insercir
es por el final de la estructura y la extraccin por cabecera
BEGIN
Pruru .- r\r!/
pAct := col&;
I^IHILE (pAct <> NiLl D0
BEG]N
pAnt ; = pAct;
nr
yuu .-
.- -Ar^ oi-.
.Drg;
IJ6UL
END;
IF (pAnt = NIL) THEN
InsertarElemenLo (coIa, info)
ELSE
InsertarElement.o (pAnt, inf o) ;
tr\Tn .
Co 1a
Fi_sura 11.6: Cola como registro con punteros cabecera y final para facilitar la insercin
. la extraccin de elementos
-tilrzar 2 punteros para realizar el acceso a los elementos cabecera y linal de manera
-.re actuando sobre el elemento flnal se pueda insertar un nuevo nodo como indica la
:ura 11.6. Completando la definicin de tipos, las tareas de insercin y eliminacin
- ,nsiguen terier una complejidad constante O(1).
" ';E
TEIemento
TEnlace = ^TNodo;
TNOdO = RECORD
info: TElemento;
s j-g: TEnlace;
TCola = RECORD
cabecera, final: TEnlace;
:.1\ l,_/ ,'
- :4. 1a cola es un registro con 2 punteros que apuntarn a la cabecera y al frnal res-
te de manera que la creacin de cola vaca se ve modificada.
Extraccin
Cofa
I
Figura 11.7: Cola doblemente enlazada como registro con punteros cabecera y final par.
facilitar la insercin y la extraccin de elementos
O(1), pues las operaciones individuales necesarias son simples y todas ellas tienei -"
orden de complejidad constante.
Un caso especial es la cola doblemente enlazada con punteros cabecera y finai d,. - - ,
;ada uno de los nodos contiene campos de enlace con el nodo anterior y siguiente :
n sura 1 1.7). Esta implementacin ofrece sutiles mejoras y la posibilidad de retro, : - :
er los recorridos sin el uso de punteros adicionales.
--,_ - l
lI -::ent o
l::-_.ce = -lNooo;
TN-cdc = RECORD
CunsrtoNBS DE TIpo rEST 405
I
lnlo : I'Ejlemento;
ant, sig: TEnlace;
END;
TCola = RECORD
caDecera/ Irna-L:'ltjnlace;
END;
11.3.1 Enunciados
1. cul de las siguientes afirmaciones sobre 1as estructuras FIFo es falsa?
* ila) Es una lista particularizada al caso en el
cual slo se insertan y eliminan
elementos por uno de los extremos.
(b) Se puede implementar como una estructura dinmica.
(c) Es una cola.
(d) Es una lista particularizada ai caso en el cual se insertan los elementos por
un extremo y se eliminan por el otro.
PROGRAM TesT3;
'AR .,\ b
lt
b: integer; L-l t-; r
r
c, d: ^ inLeger ; --: {-t
"*L
I - - Ttf
_,-rL\
'l .- .
6t" J (
I
^ .= ):.
t- A t
3s39
1
406 PuNrBnos y ESTRUCTURAS DE DATOS DTNMTCAS
d= t , , ./ \
Nl ^ ,1-,-/ t n^-t t d^-t d^
wtILctttt
',,r'iJ-ol-lr^ dt 9- t Ut U - , u/u-ru,itt .
^
e .= d.
a^ ,- ).:
.1,
nr1
writeln l'a=" at ,k-,
D- t
1^
D I
I
^A -
U
I
r c^ , 'd^=' , d^) ;
dispose (d) ; 2- 'z
END.
6. El procedimiento NEW:
(a) Debe ser llamado cuando queramos utilizar una variable de tipo pur' :-
registro.
9.(b) Reserva de manera dinmica tanta memoria como necesite el tipo b.,.-
puntero pasado como argumento.
(c) Se utiliza en los subprogramas para dar sentido a los punteros locale:
(d) S1o se llama cuando el puntero que se le pasa como parmetro debe
a memoria comparlida.
PROGRAM Test7;
TYPE
'I'Plnteger = .lnteger ;
VAR
i ,i
plnt: TPlnteger; '- \. L: L
t*r
._,r
t \
_1-
d, D, c, d: integer; \-i t-.t
-.\ -r
pAux :=
pAux :=
END;
BEGIN c
b := a;
MisLeriol (plnt, a) ;
a .- nlnl-
:ND.
?ROGRAM TesTS;
5PE
TPEnt.ero = ^integer;
ER
i: integer;
408 PUNTEROS Y ESTRUCTURAS DE DATOS DINMICAS
P, g: TPEntero;
END;
BEGIN
.^',,
Iluw /\
\Y/ ,
I .- r/
A^
1 '- zt
n .-
.- i
t, "-,
Misterio (p", q) ;
write("i - ", i);
writeln ( ", q^ = ", q );
dispose (q) ;
END.
VAR
p : A_-'lijato;
(a) Tras la declaracin tenemos una lista preparada para ser utilizada'
(b) Para poder utilizar p necesitamos hacer la llamada new (p) '
(c ) p permite apuntar a cualquier tipo de dato definido por el usuario.
---c,(d) Podemos utilizar p sin necesidad de hacer new (p) .
PROGRAM TesT11;
TYPE
'IPEntero = rntegeri
VAR
p,e : TPEntero;
IA^'
h .- t*h .
END;
BEGIN
-^,., \y/
]]uw /-\ .
|
new (q) ;
_
P '- r t
d .-
.- l.
Y J,
Misterio (p^, q) ;
writeln (p^ ) ;
writeTn(q^);
dispose (p) ;
dispose (q) ;
END.
PROGRAM TesT13;
VAR
d, b, c: ^integer;
4lO PuNrnnos Y ESTRUCTURAS DE DATos orNlrrcls
BEGIN
-^,.,
1luw I/. \
\q/ /
p l' at
new(c); &
dispose (c) ;
.- h.
dispose (c) ;
dispose (a) ;
END.
11.:
t 14. Seale las af,rmaciones correctas:
1
(a) Es muy conveniente liberar el espacio de memoria mediante di spose cuan -
no se vaya a utilizar ms un puntero'
(b) No conviene liberar el espacio de memoria mediante dispose cuando n! ':
r,a a volver a utilizar ms el puntero ya que corremos el peligro de desaju.,-"
la memoria de la mquina.
-
(c ) Siempre ocurre que por cada declaracin de variable puntero que escrib;, .
una seccin VAR debo escribir en la seccin de instrucciones una llamec- -
new. J.
-Hd) Despus de llamar a new, el valor al que apunta el puntero es indefinido
g15. Teniendo en cuenta que pTres y pUno son punteros a inLeger, eS correc--
siguiente secuencia de instrucciones para triplicar el valor numrico apuntadc
pUno?
(c) )io. porque la instruccin (II) slo triplica el valor numrico ilpulltu- a
p - :e s. no el de pUno. a
CuB,srroNBS DE TIPo TEST 411
vPun: ^integer
y ejecutar 1a instruccin
-^ : = 3,
vPun
la operacin @vpun:
-X.3.2 Soluciones
l' La afirmacin farsa es ra (a). En una
esactua donde er priner eremento en
entrar es el primero en sarir (First-In First-out
o FiFo) no ," r", pueden insertar y
eliminarpor el mismo extremo.
I La afirmacin correcta es la (d). un nodo
de una rista dobremente enrazada
tiene dos punteros que apuntan con_
a los nodos predecesor y sucesor
respectivamente.
caso de nodos cabecera o final
uno de los punreros quedar
i::#:r;11'J-',eI
-: ' La afirmacin correcta es la (cl). Haciend
o wa trazase observa que se
dos variables de tipo entero (a inicializan
y b) a los valores 3 y 5 respectivamente.
puntero c se reserva memoria A trar s cier
pata almacenar un entero y
para que apunte a ra misma se iniciariza er puntero d
regin de memoria reservada
vuelca el contenido de la anteriormente. Luego se
varire a (3) u i"rru regin
contiene el puntero c para que
apunte a la variable a. En
, ,. .r,nilr';ilJaTil:
c^ y d^ contienen el mismo este punto _ie rlene que a,
varr: 3- ,.uuu, de c se modica
asignando er varor de b (5). por er conenido de a,
tanto tu prir"r, instruccin
tre'cre nrura mostrar:
a=5 b=5 c^= d^=3,
a-)
^-tr 1^-tr
D-J n^-'
V A^-a
V -L
--
Puesto que tanto c como d quedan apuntados a una regin de memoria que fue
reservada en tiempo de ejecucin, la instruccin dispose (d) es legtima para li-
berar clicha memoria antes de finalizar el programa, y por tanto no produce ningn
error de ejecucin.
,1. Las respuestas correctas son la (a) y la (c). Idealmente, el tamao de una lista
dinmica no viene limitada por el tipo de dato con el que se implementa, sin em-
bargo, en la prctica, la cantidad de memoria disponible en una computadora no
es ilimitaclo. Lo que es seguro es que por el hecho de ser una estructura dinmica
el tamao no viene prefijado en tiempo de compilacin como en el caso de las
estticas, descartndose la respuesta (b). En cuanto a las implementaciones bastil
decir que se pueden encontrar implementaciones simplemente enlazadas, doble-
mente enlazadas, con puntero cabecera y final,... Por otra pafte, una lista vaca nt
contiene ningn nodo, incoherente es el hecho de que adems dicho nodo apuntc
a NIL, pues un nodo en s no es un puntero.
5. Las afirmaciones correctas son la (a) y la (d). Cuando se trata de forma abstract-
el concepto cle una estructura se debe ignorar la implementacin que se utiliz,
En este caso, y por hablarse de una pila, 1o nico que se debe tener en cuenta a l*
hora de categorizar la estructura es que el ltimo elemento que entra en ella es
primero que sale (Lasfln First-Out, LIFO) y que por tanto el primer elemento qLi.
entra es elltimo que sale (First-In Last-Out, FILO).
6 La rnica respuesta coffecta es la (b). Tal y como fue descrito el procedimien:
:-r.'en 1a seccin 11.1.1, se necesita pasar un puntero como parmetro al ptoir-
dirniento. Este puntero queda apuntando a la regin que se reserva en tiempo c.-
ejecucin. El resto de respuestas son totalmente incoherentes.
7. La afirmacin correcta es la (d). Se deben observar los pasos por valor y p
referencia que se hacen en los procedimientos Misteriol y Misterio2. En l*'
primeras lneas de cdigo se inicializan las variables a y b a 2. Seguidamente ,.
llama a Misteriol pasando por referencia un puntero y la variable a. Por tanto. :
parmetro formal ent referencia a la misma regin de memoria que el parne .:
real a. A travs del puntero se le asigna a esa regin de memoria el valor de 5. -
la salida se tiene que el valor de a es 5, y puesto que plnt se pas por referen-. -
contina apuntando a la variable a. A la variable c se le asigna el valor .-5. --
llamada a Misterio2 se hace con el puntero y la variable b, ambos pasados :
vaior. Dentro de1 procedimiento se modifica el valor de la copia de b, pero nl .
parmetro real, por tanto no afecta a dicha variable b. A la saiida, y puesto qu; .
parmetro real plnt fue pasado por valor, se asigna el valor de 5 a la variable ''
- ' : afirmacin correcta es la (d). A primera vista puede parecer correcta la (a), sin
-::bargo no se especilica si el puntero apunta a una regin reservada o no. Si la
4t4 PuNrpnos y ESTRUCTURAS DE DATos nrNurcas
II.4 Problemas r
.:
TPaciente = RECORD
numHistCli : TNumHistClinica ;
hora: THora;
END;
TCola = ^TNodo;
TNOdO = RECORD
rnlO: 1'Pacl-ence;
sig: TCola;
END;
Se pide:
mediante una pila. El tren entra en el tnel por las vas de un andn y sale por las
del otro. cambiando as el sentido de su marcha. Suponga que cada vagn es un res-'
que contiene ia siguiente infbrmacin:
lI
Pnonr,Buls 411
Si es mquina propulsora:
Si es vagn de pasajeros:
Para simular el cambio de sentido del tren considere la siguiente situacin: El tren
. -.tiene un nmero indeterminado de vagones. Los vagones van entrando en el tnel uno
-ro. y una vez que el tren entra completamente, ste estar listo para salir, habiendo
-:rbiado el sentido de su marcha. El primer y ltimo vagn del tren son mquinas
:ulsoras (la cabecera del tren ser el primer vagn).
Se pide:
Definir los tipos de datos necesarios para simular un tren de vagones como los
cspeci fi cados anteriormente.
- Dado el subprograma:
. .. si es una entrada.
418 PUNTNNOS Y ESTRUCTURAS DE DATOS NTNUTCAS
o 2, si es una salida.
o 3. si es un alta.
o 1, si es una baja.
Se pide:
Los nombres de los tipos debern ser acordes a la informacin que se tiene en :
siguiente apartado.
2. Disee un subprograma, cuyo nombre ser ActualizaAlmacen que actualic;
lista de los artculos del almacn con una lista de las incidencias. en funcin -.
tipo de incidencia:
artculos:
dencias.
- 2. restar a la cantidad de la lista de artculos la cantidad de la de r -
dencias.
- -1. eliminar la informacin del artculo de la lista de artculos.
o 1.2 J. si no hay correspondencia:
lista: TLista.
c: char,.
f,:iTION EsVacia Gista: Tlista) : boolean;
&G]N
EsVacia := (lista
=NIL);
-:--Tn
__ J CrearlistaVacia (VAR lista :
.-1. TList.a)
-:l^
:= NIL;
,_
(cadena: rlisra)
= *^r,r::::ii:i0"",
rrvr .ESVCla (cadena) THEN ; BEGrN
read (c) ;
InsertarFinal (lista, c) ;
END;
readln;
MosrrarCadena ( lista)
;
{se tibera la memoria reservadai
Eliminarlista ( lisca) ;
readln;
-. {programa principal}
]:T
l{ = 10;
-.:
IInfo = string[10];
_L1sta = "TNodo;
, A___
INOdO = RECORD
rnIO : I'-LntO;
cr^. lrl l
)f,9: rLrSL,.
-lSta: '.t'LlSta;
_, numElementos: integer;
,:IURE CrearlistaVacia(VAR I: TListar ;
- := NIL;
_--.rx: t!1sta/.
-= (pAux) ;
Aaa PUNTEROS Y ESTRUCTURAS DE DATOS DINMICAS
pAux^.rnfo := info;
pAux^.sig := Primer;
primer '= PAux;
END;
1
BEG]N
contador := contador+1;
pAux := pAux^'sig;
END;
ContarElemlter := contador;
END;
P-r'ux: TLista;
:: l -1,
:-_.--,: ; = primer;
-'l o'i a.
- - -...= - --
! rtlLur
-o-^ ' J!: /
_-_t-.*X
ll_:!::= ;
END;
BEGIN
IdHILE (lista <> l,-Lr )O
EliminarNodo ilisa) ;
END;
fIrLqo 'lrrp!rs
'i her: l.a
r memoria reservada)
Sor,ucroNrs +13
-T
Eliminarlista ( lisca) ;
r-
:ND. iPrograma principal)
|RAM ContaRecur;
tlSta: '1'Lrsta;
i, numElement.os: integer;
:-]:CTION ContarElemRecur(primer:
TLista) : integer;
:::II\
IF (primer = NIL) THEN {caso base}
ContarElemRecur : = 0
ELSE
contarElemRecur := 1 + ContarEremRecur(primer^.sig) ;
::
) ;
.Se libera la memoria reservada]
._iminarlista (1isca) ;
.|
, Programa principal
PROGRAM Ordenacion;
CONST
N = 6;
TYPE
TInfo = integer;
Tlist.a = ^TNodo;
TNodo = RECORD
info: integer;
sig: TLista;
END;
VAR
lista: TList.a;
i, entero: integer;
PROCEDURE CrearlistaVacia(VAR Iista: TLista) ;
BEGIN
II
_Lr5Ld.
-L -
:= 1\1L,.
END;
;:-terlOr := lrSLa;
_; ,Iista <> NIL) THEN
tsGJN
--sta := lista^.sig;
SolucroNns 1l<
a-J
EsOrdenada := orden;
WHIl,E (lista<>NIL) DO
BEGIN
writeln ( lsta^ . info) ;
lista := lista '"'3tAi^.
lND;
;riteln
.:cgrama principal]
--: PuNrnnos Y ESTRUCTURAS DE DATos DINAMIcAS
:eadln; I
{se libera la memoria reservada} t
Eliminarlista ( lista) ; l
:::1. {Programa princiPat} END;
PROCE
11.5.5 Interseccin de listas
innol
;l -GRAM Interlistas; rAR
tr
rlxunes a ambas) R
. IPE
{Se detine e1 campo de informacin de las lista}
TDATO = RECORD
cod: integer;
A^^^- - >uI1fJ$i
ucsur: l
]ID;
--sta = ^TNodo; : _-.
U
-],:Co = RECORD
producto: TDato;
- -g : TLista; .: _ lE.
t---
_:
:GIN
llof. .- Nl ll.
pAux: TLista;
: ] TIT
- _UII\
new (pAux) ;
pAux^.producto := elem;
pAux^.sig := lista;
Iista .= pAux;
r.-n.
elem: TDato;
parar: char;
l
,I I_ itr\TtT
REPEAT
write ('Dame cdigo de1 producto: , )
VAR
auxl2: Tlista;
BEG]N
auxl2 : = lista2;
{Se recorre la listal una sola vez}
WHILE (listat <> NIL) DO
BEGIN
{Se recorre lista2 tantas veces como elementos
tenga 1ista1 )
WHILE (auxl2 <> NIL) D0
BEGIN
{Buscamos coincidencias en cdigo}
IF (Iist.a1^.producto.cod = auxl2^.product.o.cod)
THEN
Insertar ( listaOut, listal^ . producto) ;
auxl2 : = auxl2^.=ig,
END;
la
tAI salrr
-^r r -- de este bucle se tiene auxl2 aI final
de lista2. Se debe volver a apuntar al primer
nodo de la lista)
auxl2 : = lista2;
{Sin embargo se avanza e1 puntero cabecera de
listal porque se t.rabaja sobre una copia (la
Iista fue pasada por valor) )
listal := listal".sig;
END;
END;
:--::
WHILE (lista <> NIL) D0
BEG]N
writ.eln ( 'Cdigo: , , list.a^ . producto. cod) ;
writeln('Detal_l_e:,, lista^.producto.descr)
lista:=li-sta^.sig;
Sor,ucroNrs 129
END;
IND;
CrearlistaVacia ( lista2 )
l_
t lntersecclon de ambas.f
Interseccion (1ista1, lista2, list.alntelrsE.:_t:-
:rriteln('Los elementos comunes a ambas s3::' I
I'iostrarlista ( Iistalnterseccion) ;
.Se
libera Ia memoria reservadar
430 PunrBnos Y ESTRUCTURAS DE DATos orNn,rrcIs
Eliminarlrsta r lisral ) ;
Eliminarlrsra, lista2 ) ;
E1 iminarlista ( Iistalnterseccion) ;
END. {P:ograma principat}
El cdigo y la forma de proceder son anlogos a los del ejercicio anterior. E1 subpro-
-qrama lnterseccin modilica para realizar la operacin de unin, que incluye todos
se
los elementos de ambas listas en la lista resultante, aunque sin repeticiones en caso cle
haberlas.
VAR
aux, auxOuc: TLista;
ENCONTRADO: Boolean;
BEGIN
{se recorre la listal una sor-a vez y se copia cada nodo en
I ^r-a- l
r-L!jLdUUL- I
WHILE (listal <> NIL) DO
BEGTN
Insertar ( IistaOut, 1ista1^ . producto) ;
liscal := lisral^.sig;
EI\TN.
BEGIN
END;
iSi no hubo coincidencias t.ras recorrer
listaOut
i nsorl-. se
"o o.l_ producto de 1ista2)
IF (NOT ENCONTRADO)
TUM
fnsertar (listaOut, 1ista2^.producto)
;
{Se continua con el siguiente nodo}
'I i eJ-o
ruua ,= 1ista2^.sig;
END;
]\T .
':.CGRAM AlmMadCiud;
. IPE
TArticulo = RECORD
precio: integer;
descripcion: string;
codigo: integer;
END;
Tlist.a = "TNodoArt.iculo;
TNodoArIicu]o = RECORD
info: TArticulo;
sig: TLista;
END;
-:
lMadrid, lCiudadReal, list.a: TI,i sr: .
;: int.eger ;
opcion: char;
salir: boolean;
rr L : tArtl_cuIo;
:odigo: integer;
eleccion: string;
r:: _ IfDURE
VisualizacionRecursiva (l
l=:a visualizar la lista del fin : TLrsta) ;
a1 principio)
lil PuNrnnos y ESTRUCTURAS DE DATos rNvrrcls
:: i_-i
inversa: char;
P
BEGIN
v
writeln ('Quiere visualizar de forma inversa? (S/N) ') ;
readln (inversa) ;
B
IF (upcase(inversa)='S') AND (Iista <> NIL) THEN
Visual i zacionRecurs iva ( I i sta)
ELSE
BEGIN
WHILE (lista <> NIL) D0
E]
BEGIN
wriLe ( IisLa^ . info. codigo) ;
PI
write (Iista^ . info. descripcion) ;
B]
wri-te ( lista^ . info. precio) ;
wri te In;
Iista := Iisca^.sig;
END;
END;
END;
END;
IF (act <> NIL) THEN
BEGIN
SolucroxBs 433
aux: TLista;
::3IN
new (aux) ;
aux^ . info ..-
- .7+-
q!U, .
aux^ . sig ._ t.
1 := uxi
-1sta := NIL;
pAux: TList.a;
: _
_ ] JII!
-TIf
pAux = primer;
primer ;= primer".sig;
dispose (pAux) ;
-,-- PuNrsnos Y ESTRUCTURAS DE DATos DINAMICAS
':,:IDURE Insertar(VAR
primer: TLista; info: Tlnfo);
-.--t-:l
pAux: TLista;
::^T\T
__irr\
new (pAux) ;
-^
nArrY rnfa .- info.
nArlv^
r_.,*-. .__9
ci := prlmer;
primer '= PAux;
:]\tn .
pAux: TLista;
t:-f\T
__JTI\
cAux .-:-
^^.,.. IJrrmer;
^-ir
Drimer ;= primer^.sig;
i-spose (pAux) ;
:.-
--: - -::-T.E Invertir (VAR primer: T],ista) ;
r,-."-::--e fsicamente la lista)
SolucroNrs 431
pAuxprimer: TLista;
BEGIN
IF (primer <> NIL) THEN
BEGIN
{Sl tray elementos se necesita una lista auxiliar.|
)
Crearli s t aV ac i a ( pAuxpr imer ) ;
IHILE (primer <> NIL) DA
BEGIN
Insertar (pAuxprimer, primer^. info) ;
{Se eliminan elementos de Ia original
segn se copian)
EIi_minarNodo (primer) ;
END;
primer ;= pAuxprimer;
END;
END;
VAR
lista: tlista;
j . i nlaaa-.
Mostrarlista (lista)
TYPE
'I'lnto = ].nteger;
TLISTa = ^TNodo;
TNOdO = RECORD
info: Trnfo;
ant: TLista;
.
>.9; 'l'l
r!It)Ld,'
END;
pAux^.info := info;
pAux^.ant := NIL;
nArrv^ .!_Y
ai ._ prlmer;
I,s,! ^
primer ;= pAux;
END;
VAR
I I ^L^ !r I
^-^
J-.L5Ld.: LLlSLd.;
i . rlauLYU!,
. i ntaaa-.
writeln('Lista:,);
Most.rarlista ( lista) ;
--^^lf-
r rid uIl.t,.
!rarrll
uqurr-. /
writeln(' Invertimos :, ) ;
Invertir (lista) ;
writeln(,Lista:,);
Mostrarlista (lista) ;
ra,.1 1-.
--:
11, lZ, f: 'I'LISta; --
:-L-
l,_: PRO(
{ nnr
.: - I:IURE InsertarElemenLoPorElFinat (VAR I : Tlista; b : Tlnfo) ; VAR
"-::.
-:'*x/ nuevo: TLisCa;
::i--\ tsEGI
IF EsVacia(l) THEN
3EGIN
new (aux) ;
aux^.info := b;
^
aux^.sig := l;
'I .- lrrv.
END
ELSE
BEG]N
aUX := I;
I{HILE (aux^.sig .> NIL) D0
aux:= aux^.sig;
new(nuevo);
nuevo^.info := b;
nuevo^. sig : = aux^. sigi
aux^.Sig := riUeVoi
END
:\Tn .
mono: Tlnfo;
orden, coef,i: integer;
::GIN
writeln ('Indica eI orden del polinomio' ) ;
:eadln (orden) ;
liR i := orden DOi^INTO 0 D0
- TIT
: ] ,.II\
ENI
SolucroNBs 413
3]G1N
InsertarElementoPorEIFinaI (R, aux2^. info) ;
aux2 := aux2^.si9i
END
:.SE
WHILE NOT EsVacia(aux1) D0
BEG]N
InsertarElementoPorElFinal (r, auxl^. info) ;
auxl := auxl^.si9;
END;
END;
writeln;
END;
1l
END;
VAR
pAux: Tlista;
BEGIN
r--*._
nArrv pr].mer;
primer := Primer^.sig;
dispose (pAux) ;
:1.- I
:l r--
': <> NTL)
-: -lsta D0
CrearPolinomio(I2);
Mostrarlista(I2);
writeln;
Mostrarlista (r) ;
ral l n .
END;
VAR
pAux: TCola;
DEN
D!U IT\T
I!
pAux := cola;
IF NOT EsVacia(cola) THEN
BEGIN
446 PuNtBnos y EsTRUCTURAS DE DATos nrNnrrcls
cola := col-a^.si9;
dispose (pAux) ;
tr\T .
END;
pAnt ;= pAct;
PAUL ;=
n71l- pACt
^^*^ .Stg; '
END;
IF (pAct^ . info. numHistCli = num) THEN
BEGIN
IF (pAnt <> NIL) THEN {si no es el primero)
BEGIN
pAnt". sig : = pAct^. sig;
dispose (pAct) ;
END
ELSE
BEGIN
cola := pAct^.sig; icabecera al 2oelem.
dispose(pAct); {se libera Ia cabecera}
END;
END;
END;
END;
pAuxl := colal;
pAux2 := cola2;
{tvlientras haya elementos en ambas col-as se
comparan y se aaden pacientes a la auxiliar)
11
WHILE (pAuxl <> NIL) AND (pAuxZ <> NIL) D0
BEGIN
IF NOT Mayorlgual (pAuxl^. info.hora,
pAux2^. info.hora) THEN
DETI]
DUTI\
END;
I{HILE (paux2 <> NIL) DO
BEGIN
InsertarFinal (colaAux, pAux2^. info) ;
nnrrw? . - nArrv)^ '"-Y
ci a.
END;
END;
END;
TVagon = RECORD
peso: integer;
CASE maquina: boolean OF
TRUE: (potencia: integer;
maquinista: string [10] ) ;
FALSE: (pasaj eros : integer) ;
END;
TTren = ^TNodo;
TNodo = RECORD
vagon: TVagon;
dr_t rtrtrr^.
olY. f I!uff,
END;
r.ft#"
H1 ,.-
a
END;
#s'"
:.'
PROCEDURE CrearTren(VAR tren: TTren, ;
*'
r+l
-
450 PUNTERoS Y ESTRUCTURAS DE DATOS DINMICAS
BEGIN
CrearTrenvacio (tren) ;
{Se inserta una mquina en un extremoi
Inicializarvagon (vagon, IRUE) ;
Insert.arVagon(tren, vagon) ;
{Se insertan los vagones de pasajeros}
writeln('Numero de vagones de pasajeros?');
readln (numVagones) ;
FOR i := 1 T0 numVagones D0
BEGIN
InicializarVagon (vagon, FALSE) ;
InsertarVagon (Lren, vagon) ;
END;
zado para e1 crrnte\to del tren pero son operaciones comunes altipo PiIa (C--.
Ll^d. i
pActual : = tren,. -F
pAnt.erior := NIL;
WHILE (pActual^.sig <> NIL) DO
BEGIN
pAnterior = pAct.ual;
pActual ;= pActual^."ig,
END;
IF (pAnterior = NIL) THEN
tren := pAct.ual^.sig
ELSE
pAnterior^. sig : = pActual^. sig;
vagon = pActual^.vagon;
dispose (pActual) ;
END;
END;
REPEAT
ExtraerUltimoVagon (tren, vagon/ ;
J
PUNTEROS Y ESTRUCTURAS DE DATOS
DINMICAS
TYPE
Tlncidencia = 7..4;
TArticulo = RECORD
codigo: integer;
descriPcion: string [30J ;
cantidad: integer
END;
TListaAlmaceri = ^TNodoAlmacen;
TNOdCAIMACEN = RECORD
articulo: TArticulo;
sig: TListaAl-macen
tr\Tn '
TListalncidencias = ^TNodolncidencia;
TNodolncidencia = RECoRD
articufo: TArticulo;
incidencia : Tlncidencia ;
sig : TListalncidencias
l. --t .
dispose (aux)
END;
VAR
act.ual , anterior, aux: TlistaAlmacen,.
DINMICAS
PUNTBROS Y ESTRUCTURAS DE DATOS
:: llN
^rl := listaAlmacen;
anterior := NIL;
haya nodos
{ut siguiente bucle se realizar mientras
en ambas listas)
wHrLE (actual <> NrL) AND (listarnc <>
NlL) D0
BEGIN
IF (actual^ . articulo ' codigo = listalnc^ '
articulo ' codigo) THEN
fu:r r'oincidencia de cdigo de artculo de
i 11qJ
uvtrvt
ambas listas)
BEGIN
(listaInc^'incidencia) 0F
CASE
1: actual-^ ' articulo ' cantitiad : = actual^ '
articulo. cantidad + listalnc^ ' articulo ' cantidad;
2: actuaf^ ' articulo ' cantidad : = actual^ '
articulo. cantidad - listalnc^ ' articulo ' cantidad;
4 : EliminarNodo(anterior' actual'
listaAlmacen) ;
listarnc) ;
ELSE
writeln('Artculo no existe en el almacn"
SorucroNns 455
listalnc := listalnc^.sig
END;
END; {WHILE}
{rin aet bucle para nodos en ambas listas}
ir1 siguient.e bucle procesa incidencias restantes, si
l
Ias nllb1era i
WHILE (listrnc <> NIL) Do
BEGIN
CASE (listalnc^. incidencia) OE
3: InsertarNodo(anterior, actual, IistaAlmacen,
listalnc);
ELSE
writeln('Artculo no existe en eI almacn.',
'No corresponde una incidencia de baja.');
END;
listalnc := Iistalnc^.sig
uuo; {wurlu}
END;
TYPE
TElemento = char;
TPila = ^TNodo;
TNodo = RECORD
e: TElemento;
c i n. TDi
-,a. I
-. --a;
END;
BEGIN
prla = NtL;
END;
END;
BEGIN
new (aux)
qq^
"ra*^ t o.
u. -o
-u,
.
aux^.si-g;= pila;
pila: =aux;
END;
nilr.'FD'iI:.
t L L Ls t
posicion: integer;
: _] - TIT
- --11\
ISe recorre Ia expresin, se apilan 1os ,(, y
s: desapilan cuando se encuentran los cierres ,) , .
S- la pila termina vaca, Ios parntesis estn
SolucroNBs 457
balanceados en la expresin)
CrearPilaVacia (pila) ;
posicion := 1;
WHILE (posicion <= length(expr)) DO
BEGIN
IF [posicion] = ' (') THEN
(expr
Apilar (pila, expr [posicion] )
Como el lector sabr, a travs de las funciones y de los procedimientos se puede descom-
poner un problema complicado en varios ms sencillos de resolver. Adems se simplifica
:1 cdigo ya que se evita duplicarlo, es decir, se reutiliza un mismo cdigo. or-eanizado
:n subprogramas, en varias partes del programa. El nico incon\.eniente es que este
.'digo debe estar definido en el programa que 1o utiliza. Esta limitacin desaparece
1 hacer uso de las unidades de Turbo Pascal. Las unidades. pueden contener subpro-
lramas, constantes, tipos de datos, y variables. Para que un pro-srama pueda utilizar el
-ontenido de una unidad, nicamente debe incluir el nombre de Ia unidad, precedido de
-r palabra reservada Uses, a continuacin de 1a ,:abecera del programa.
Las unidades pueden compilarse de forma separada al programa que las utiliza. Esto
:ioporciona grandes ventajas, especialmente para el mantenimiento del cdigo, porque
-: pueden modiflcar y probar independientemente de los programas que las utilicen.
12.1 Estructura
-l estructura de las unidades permite separar qu hace un procedimiento o una funcitin
,: cmo lo hace. A esta separacin de conceptos se le llama abstraccitr .fiutt r,,i. L:
-:rdades encapsulan Ia implementacin de los procedimientos y las fun.i\rn->. permi-
:rdo al usuario emplearlos sin que se tenga acceso al cdigo de 10: nrirr-t,>.
Las unidades estn formadas por cuatro paftes: la cabecera de 1a un:i:l1. una pafie
-[ca, una parte privada, y una zona de inicializacin de variables.
.l <idencificador> {cabecera}
INTERFACE
IUSES<]ista de unidades> {opcionaL}-
{Declaraciones pblicas de consra:-r:-: , -: : : ' -rariables }
{Cabeceras pblicas de procedrmie:-cc- '.' : ^:-::-ones}
IMPLEMENTAT]ON
IUSES <]ista de unidades> {opcional-i,
459
460 UNrolons EN TURBo Plsclr
{Declaraciones privadas }
Implementacin de procedimientos y funciones)
IBEGIN
-i;-- i .-icializacin) {opcional}J
- '-o
En cabecera de la unidad se 1e da el nombre que la identifica. Este nombre es
1a e.
De las cuatro partes que componen una unidad la nica opcional es la de inicializacr
Sin embargo, no tiene sentido crear una unidad con el INTERFACE vaco, porque rf .:
:clra utilizar ningn procedimiento o funcin deflnido en la zona de IMPLEMENTA:- -.'
-:' .r
se crea con las definiciones de los subprogramas en el INTERFACE no se estara li., -
l. -- ':'
Cnn.lcrN DE uNA uNTDAD 161
-NIT Mates;
TNTERFACE {parce pbIica}
FUNCTION potencia(base: real; exponente:
integer) : real;
{nre = rnuui
lrwDL -= ocl resultado es base^exponente)
fDncr
FLI-NCTI0N Logaritmo (numero, base: real ) . re:t
nrrmr^ >
{ Pro = rlumero 0 .,y base
- n *-^^--- > O)
{eost = eI resultado es e1 logaritmo de nmero en base)
IMPLEMENTATION {parte privada}
FIINCTION potencia(base: real; exponente:
integer) :
VAR
acum: real;
i . trLuYUr
i rra^o-.
/
BEGIN
aCUm = 1;
:
f'UR 1 := 1 T0 abs (exponenLe) DO
acum := acum * baSe.
IFexponente>0THEN
Potencia : = ct_t.
ELSE
potenci-a := _,,a:.^:
END;
BEGIN
Logaritmo : = Ln (numero) ,,'T i,.bas:
END;
462 UNrrrnrs nN Tunso Plsclr,
PROGRAM Ejemplo0l;
USES Mates;
VAR
u,v: Iedl,'
'i tlltUYu!,
'i nraaav.
BEGIN
write ('Introduzca un numero real: ')
readln (u) ;
write (' Introduzca un numero entero:
--::1- 1i \
/,
--rurrr\f
':-.--eln(u:2:2, ' elevado a', i, t
C.
, Logaritmo(v,u) t2t2) ;
--_
(a) La estructura de una unidad se compone de dos partes, una parte pblica y
una parte privada.
-{b) La estructura de una unidad se compone de cuatro partes, siendo una de ellas
opcional.
(c) Todas las partes que forman parte de la estructura de una unidad son opcio-
nales.
(d) La estructura de una unidad no contiene partes opcionales.
UNIT EjemploOl;
]NTERFACE
PROCEDURE Inr,ercambio (VAR a, integer) ;
IMPLEMEN?ATION
PROCEDURE Inr:::a:i_: -.';i :, integer) ;
VAR
aux: intege:;
BEGIN
,rv
qu^ .
.- l-'.
- !/
b := a;
:= Uxi
END;
END.
461 UNrlns nN Tunso PASCAL
12.4.2 Soluciones
1
o Implemente una unidad que conten-qa el tipo cie dart r-,r.::r : :. :.;ma 9.g.1
y las operaciones necesarias que perrnitan: rnicielizer:1 ::,..:,: :,--,n datos intro-
ducidos por el usuario: del'olr'er cacla uno de est Lj.i,..: :r.,-)::r;lor pantalla la
informacin acumulada en el registro.
e Implemente una unidad que contenga un tipo de ditr. c.. ur o tipo elemento sea
el tipo de dato definido en el apartado anenor.
c Implemente una unidad para un tipo de dato fichero binario, siendo el elemento
base del fichero el definido en el primer aparrado.
466 UNroIrs rN Tun.no PASCAL
o Disee un programa que cree una cola vaca, le inserte varios nodos, y antes de
terminar la ejecucin del programa cree un flchero con la informacin contenida
en la cola.
12.6 Soluciones
INI = 1;
= q.
E'T\T
N = 20;
M -- tO.I
LL
TYPE
TCadena = string [N] ;
TTlf = st.ring[Ml ;
TRango = IN] .FIN;
TRango2 = INI..N;
IFecha = RECORD
Cia: word;
:.: S : V,'Ord;
::- I : i:c::C:
l.t:
-:---;':-::1:'.,:
= --.:----.-
:::'
m-f-*--:-:: ,..-Ii;
END;
TMensaje = RECCRD
texto: strlng;
I eCna : '.t'l'Cha ;
hora: THora;
CASE conocido: boolean OF
TRUE: (identificacion: TCadena) ;
FALSE: (numero:TTlf); IM
IND; usl
--r,lmacen = array[TRango] OF TMensaje; PR(
].:::.oria = RECORD VAJ
:cdos: TAlmacen;
-3ce: pred(INI)..Flll; {Necesitamos un valor que :E(
Sor,ucrouns 467
_:.iPLEMENTATION
-SES Dos;
;iOCEDURE IntroducirNombre (VAR ncn: tlaj:::_ ;
".iR
. lnn.
:farrf
!g aI!
-
468 UNronops nl Tunno Plsclr,
REPEAT
wrrLe ('Introducir nombre: ') ;
readln (nom) ;
'riLeIn ('El nombre introducido es: ' , nom, '
si es correcto pulse s');
readln (c) ;
-NTIL C IN [,S,,,S,]
:-,- ; t IntroduclrNombreJ
.: r--,1 : ---isoMemoriaLlena;
:1. ,
VAR
a: char;
BEGIN
REPEAT
writeln(,1. Enviar mensaje a un numero de Ia agenda,);
writeln(,2. Enviar mensaje a un numero introducido,,
' por eI usuario,) ;
readln (a) ;
IINTIL a IN l, l, ,,2,) ;
ModoEnvio : = a
END; {uoaonnvio}
ENI
.: -:- ',:: -:.=:..arContacto (VAR agenda: TAgenda; ConLacto: TInf o)
'-i ;
Fti
-'"--:" VAT
Sor,ucroNrs
4lt
final: boolean;
BEGIN
IF Esvacia (agenda) THEN
BEGIN
agenda.max := succ (agenda.max)
;
agenda.conLact,os lagenda.max] :=
contacto
END
ELSE
BEGIN
final := FALSE;
i := INI;
WITH agenda DO
BEGIN
max : = succ (max) ;
WHILE NOT final AND (i < max) DO
IF contactos Ii] .nombre > contacto.nombre THEN
BEGIN
final := TRUE;
E'aD ._ i+1DO
-.i
.,rq^ DOWNTO
contacrosIj] := contactos Ij -1]
END
ELSE
r .- a + _L;
contactosIi] := contacto
END
END
END; {InsertarContacto}
BEG]N
I r--i frrr \
_ ;= _I\-Lj /'
--_=J
- := ao3nda.max;
:.: : a-:.f
_ii=jTHEN
i := INI
ELSE
i := succ(i);
writ.eln('Si desea eliminar el sgte. contacto, pulse s:,);
MostrarContacto (agenda. cont.actos Ii] ) ;
readln (c) ;
UNTIL c IN ['s','S'];
EscogerContacto : = i
END; {EscogerContacroi
END
END
ELSE
EncontrarContacto := pred(INI)
END; {EncontrarContacto}
VAR
u^ : uIl.d.r
-L^-^
,'
Urnons nN Tunro PASCAL
. ----raa). VAR
--.)!lYv- t
- --:,4
!--u\a!\r/
T\lT\ !.r!, NT.
- --, , tr'.U^-- . lJ-(r -L 1
:: r-1, RI
c := MuesLraOpcionesBorrar;
CASE C OF
, 1, : BEGIN U}
IntroducirNombre (nomb) ; END;
(a'nomb) ;
i,', ::";:HffilHto PROCE
i = EscogerContacto (a)
: ; BEGIN
EliminarContacto (a, i ) mr
END END;
END
END FUNCT.
ELSE BEG]N
writeln('No se puede eliminar ningun contacto. Mer
, LA AGENDA ESTA VACIA') END; 1
:\D; {BorrarContacto}
PROCEI
:F.OCEDURE OpcionesAgenda (VAR agen: TAgenda) ; BEGIN
----t
meI
! . ^L--.
!1rq! , B.ID; {
::l-l'l
:.:PEAT PROCED
c := MenuAgenda; orlR
CASE c OF li
r, J
'1' :AniadirContacto (agen) ;
,2, :BoTTaTContacto (agen) ; 3EG]N
rl.- t.
- .-- -- - ,c IN l'7','2'l); REP.
: - . ...=-.-:-genda)
VAR
^. ^].--.
U. Ullql ,
BEGIN
REPEAT
writeln('Introduzca eI texto del mensaje:');
readln(mensa.texto);
writeln('Si desea modificar eI mensaje pulse s');
readln (c) ;
tllVTIL NOT (c f N [' s' , ' S' ] )
END; {Crearlzlensaj e}
END; {VaciarMemoria}
VAR
i,j: pred(INI) ..FIN;
^.
U. ^t--.
UIIAI ,
BEGIN
i = pred (rNr) ;
REPEAT
]Fi=FINTHEN
i := INI
ELSE
476 UNrlors nN Tunso Plscll-
I /t \
.L := SUCU\Il;
-----
BEG]N
WITH memoria D0
BEG]N
tope : = succ (tope) ;
todosItopeJ := mensa
END
END; {GuardarMensaje}
BEGIN
conocido := f;
T E' f! TUE^I
ffEt!
BEGIN
identificacion : = agenda. contacLos .nombre;
Ir]
writeln(;r:-, de nombre,, agenda.conracros
:::r:io Ii] .nombre,
' tiene eI numero ,, agenda.contactos ti] .t]f);
END
ELSE
nUmero :- llf.
WITH fecha DO
GetDate (anio, mes, dia, semana)
;
WITH hora DO
GetTime (hora, minut.os, seg, mseg)
;
END
:\D; {TerminarMensajei
op : = ModoEnvio;
frn- .-;LTetr.
'- "'-"Lt
------: - L Jl
'-' , nPEaf
IntroducirNombre (nom) ;
j : = Encontrarcontacto (a, nom) ;
IF j ., pred(INI) THEN
final : = TRUE
ELSE
BEGIN
writeln (,El nombre introducido no se ,
'encuentra en la agenda,);
error : = Esvacia (a) ;
writeln(,Vuelva a intentarlo, ) ;
END;
final OR error;
UNTIL
'2' i Introducj_rTlf (tlf )
END;
IF NOT error THEN
BEGTN
IF Memoriallena (mem) THEN
LimpiarMemoria (mem) ;
TerminarMensaj e (mensaj e, , j , tlf, final ) ;
GuardarMensaje (mem, mensaje) ;
Avi soMensaj eEnviado ;
END
END; {EnviarMensaje}
PROCEDURE
salientes:
VAR
SorucroNBs
l
u. ^L--
ullar -
i
f FN TIT
JUat!
REPEAT
c := MenuMensajes;
CASE c 0F
'1' :EnviarMensaje (salientes, agen) ;
:ND.
IROGRAM Mensajes;
-ses Ej emplo;
.,'AR
agenda: TAgenda;
trl]LId bd_Le : -'.iomnr i :
, -- -E...! _ ta /
op: char;
:IGIN {Programa Principaii
CrearAgenda (agenda ;
CrearMemoria (entra) ;
CrearMemoria (sale ;
REPEAT
op := MenuPpal;
IF MemoriaLlena (entra) THEN
Avi soMemori aLlena ;
CASE op 0F
180 Uxrnlons rN Tunso Plsclt-
END
-LINTIL NOT (oP fU l'L' ,'2'))
:),Tl . {Programa PrinciPal }
Todos los subprogramas que utiliza este programa estn en el INTRFACE de la unidad
por lo tanto, una vez compilada (y almacenada en el directorio correspondiente) el pro-
grama Mensaj es podr ejecutarse coffectamente.
UNIT Orden;
INTERFACE
CONST
pRIMERO = 1; {Constantes necesarias para la descripcin
ULTIMO = 30; de los tiPos de datos)
TYPE
Tlntervalo = pR1MERO..ULTIMO; {fipos de datos pblicos}
TEIem = lntegeri
TVector = array [Tlnterva]ol OF TElem;
{subprogramas pblicos }
PROCEDURE SeleccionDirecta(VAR v: TVector) ;
PROCEDURE InsercionDirecta(VAR v: TVector) ;
PROCEDURE IntercambioDirecto(VAR v: TVector) ;
PROCEDURE Mergesort(VAR v: TVector; izq, der: Tlntervalo);
IMPLEMENTATION
IYPE {Tipo de dat.o Privado}
Tlndice = pred (PRIMERO) . . succ (ULTIMO) ;
valMenor := v[i];
posMenor : = i;
FOR j := succ(i) rO ULTIMO DO
IF vIj]<valMenor THEN BEGIN
valMenor := v[j];
posMenor : = j
END; {rr}
IF posMenor<>i THEN BEGIN
v[posMenor] := v[i] ;
v[1] := vafMenor;
Et\u tr_-r
1')
END {FoR i}
END; {SeleccionDirecta}
aux: TElem;
BEGIN
FOR i := succ(pRIMERO) TO ULTIMO DO BEGTN
arlv .-.rf il
j := pred(i);
WHILE (j>=pRTMERO) AND (vIj]>aux) DO BEGIN
vlsucc(j)] := v[j];
j := pred(j)
END; iwt+ilu)
v[succ(j)] := aux
END {FOR}
END; { InsercionDirecta}
f E.T]T\T
.IJN]T
SI
.l .- iry.
L ,_ L4I INTERF
-.1 :=
.- errf ne)'
Duuv\vv/ I TYPE
J
Y ;= iz; TI
I{HILE (i<=ce) AND 1i<=de) D0 BEGIN
FORk:=j TOdeDO P:
wtkl := vlkl ; P
FOR k := i TO ce DO P
w[k+de-ce] := v[k] ; P
END; {fusion} P
iSubprogramas publicos )
I
UNrpaps EN TURBo Plsclr,
VAR
mono: TInfo;
l. irfanor.
UILlc]I,
^rlan LvE!
^aaf / l. tlruuYu!,
BEG]N
writeln ('Indica el orden del polinomio' ) ;
readln (orden) ;
readln (coef) ;
mOnO.exP:= i;
mono.COef := cOef;
InsertarElementoPorElFinal (1, mono) ;
END
-. lrearPolinomio)
BEGIN
ar:'l .= .]1.
aux2 := L2; {Si ambas list.as no son vacas se comparan
y suman los coeficientes)
IF (NOT EsVacia(aux1)) ANO (NOT EsVacia(aux2)) THEN
BEG]N
WHILE (NOT EsVacia(auxl)) AlO (NOT EsVacia(aux2)) DO
BEGIN {Sr 1os exponentes son iguales se suman fos
coeficentes )
IF (auxl^.info.exp = aux2^.info.exp) THEN
BEG]N
mono:= ux1^.info;
mono.coef := 1o[o.coef + aux2^.info.coef;
auxl := auxl^.si9;
aux2 := aux2^.si9;
END
ELSE
BEGIN {Si un exponente es mayor que otror su
monomio se aade a la resultante.|
IF (aux1^.info.exp > aux2^.info.exp) THEN
BEGIN
mono:= ux1^.info;
auxl := auxl^.si9;
END
ELSE
BEGIN
mono := uX2^.info;
aux2 := aux2^.Si9;
END
END;
IF (mono.coef <> 0) THEN
InsertarElementoporElFina- :, l::_-
END; {WHILE }
END; {tri {Si una lisra es vaca
la otra se aade :a_ :-=_
IF EsVacia (auxt ) TI:EN
WHILE NOT EsVacra i;rl t:
BEGIN
Insert.arElementoporElFinal (R, ar:x2^. info)
aux2 := aux2^.sig;
END
ELSE
/
:- UNIDADES EN TURBO P'SCAI
=i.CCEDURE
Mostrarlista(I: Tlista) ;
3]GIN
IF NOT AsVacia(1) THEN
BEGIN
WHILE(1^.sig <> NIL) DO
BEGIN
write (1" ' info. coef, 'x ^,, I^.info.exp, '+');
I := l^'sig;
END;
write (l^. info. coef, 'xn' , l^ ' info ' exp) ;
writeln
END
EN
END; {Mostrarlista}
PAux: Tlista; iN
BEGIN
:0
PAux := Primer;
primer = Primer^'sig;
disPose (PAux)
END; inliminarllodo)
BEGIN
WHILE (lista<> NIL) D0
TY
EliminarNodo ( lista)
:lll ; {U1imi-narl,ista}
l
-.Jelossubprogramas,deestauni<lad,hasidoextradodelcaptuloL1
'- - ' .: ::rn.ipal del problema 11'4'9 quedara:
. . -
-.
.--:!l
i -':--
.-t
Sor,ucroNBs 481
:-:la: char; i
D
:1,-;
a-=-=
nEaADD
r\!Lv\
C
-
:lombre : TNombre; BEGI
conv: TRango2;
:'-:.
--isignaturas = arraY [TRango] 0F Tlnfo;
-:onvocatoria = array [TRango] OF TRepe;
-f,ireccion = RECORD
calle, ciudad: TNombre;
numero: TNumero;
codigo: TCodigo;
END;
END;
TEstudiante = RECORD
FUNC
nombre: TNombre;
VAR
direccion: TDireccion;
telefono: TTelefono; i
dni: TDni; S
asignaturas : TAsignaturas; C
^atr
!J! raeLidOf:
lu|\/ bOOIean OF BEG]
END;
{ subprogramas Pblicos }
(VAR estudiante : TEst'udiante)
PROCEDURE IntroduceEstudiante
PROCEDUREMostrarEstudiante(estudiante:TEstudiante);
IMPLEMENTATION
:: char; PROC
:
----'l -__\ tsEGI
: ].DEAT
rite ('Introduzca eI nombre: ' ) ;
::adln (nom) ;
pulse s' ) ;
'::
-ie ('El nombre es : ' , nom, ' si es correcto
..:lr l\ I
-:.r-ra\e/
' - ,- , -l'tr ['s','S']
: - - ,:-:eNombre) B,ID;
VAR
-l .i-r^^^-^
rllLCgeI ,.
s: string[4];
code: integer;
BEGIN
REPEAT
write ('Introduzca el ]-]ufie ro: /) ,.
readln (s) ;
val (s, i, code) ;
IF code <> O THEN iSe tra producido error)
i := pred(INI);
UNTIL (i > pred (rmr ) ) arm (i < succ (FIN_N)
IntroduceNumero : = i
);
END; {IntroduceNumero}
-':
PRO(
- ---i-- I
:-r-1, VAR
- 1:1''-f
- ---_ :
-^^a"-^' ol
',';'rite (' Introduzca nrrP.,^o de celef ono: ' ) ;
el numero BEG:
readln (t]f) ;
write 'tt
' 't:""t"1'1"?i""t;tfl"=" =' '
'
]ND
read'Ln (c) ;
"')
c: Char; BEG
:
"rlT\T
REPEAT
,.,riror'Tntroduzca
w!ttu \ rr e} numero del D'N'I': ');
readln (dni) ;
,.,rirol'tr1.
w!ruu \ !f D.N.I. es: ',dni,
' si es correcto Pulse s');
readln (c) ;
UNTIL C IN [,S,,,S']
END; {IntroduceDut} ENI
:a" PR
. '- - -----=l'::'ire (info'nombre) ;
VA
'- -- ': ---. : = NOta
Sor,uctovrs
491
END; {Introducelnfo}
rnrroduceRepe(vAR repe:
::::^:rr*r
D!gAI\
rRepe) ;
fntroduceNombre (repe.nombre)
;
repe.conv := NumeroConvo
END; ilntroduceRepeJ
IncroduceRepe co:-..- _
END; {IntroduceConvocator_as
I: a':-aT ;
END;
::a-1,
.:-eln ('Introduzca los datos deI estudiante') ;
Dpn/r
- :: roduceNombre estudiante . nombre ) ;
(
BEGI
- ion ( estudiante . di recc ion ) ;
:-: roduceDi recc
- :-, roduceTlf estudiante . telef ono ) ;
l
(
END
i:
3EGIN
:lJ); {IntroduceEstudiante}
W
F
Subprogramas para mostrar informacin)
iND;
:.'- I MuestraNumero)
i:
- --,= 'lTombre de la ciudad: ');
sEGIN
,1,:mbre (dir.ciudad) ;
w1
l -rbre de la calle: ');
- .-::e (dir.calle); FC
. - :-]: '\;
:: ..'--=t: (dir.numero) IND; i
;
: , :-:: POStal: ') ;
SotuctoNns
193
r: IRango;
BEGIN
writeln (,Listado de asignaturas: ,)
;
FOR i : = INI TO FIN DO
MuestraAsig (asig ti; ;
END; {MuestraAsignaturas
}
PROCEDURE MuestraConvoca:c:_as as _r :
VAR
i: TRango;
BEGIN
writeln (, List.ado de convocatorias
consumidas: , ) ;
FOR i := fNf TO FIN DO
MuestraConvo (asig tjl
END; {Muest.raConvocatorias}
Urrrtuns BN Tunso Pasc'r'
=\D ; {MostrarEstudiance}
;\ln
PROGRAM EjemPlo3;
USES Registro;
VAR
e1 : TEstudiante;
BEGIN iPrograma PrinciPal)
IntroduceEstudiante (e1) ; p
MostrarEsrudiante t e1) ;
B
END. {Programa PrinciPal}
a:
,,-:plelo = RECORD
rreal, Pimag: real;
IMPLEMENTATION
PROCEDURE IntroduceNumero(VAR c: TComplejo) ;
BEGIN
write('Introduzca la parte real del numero complejo: ,);
readln (c.prea]) ;
write('rntroduzca Ia parte imaginaria del numero complejo: ,);
readln(c.pimag)
END; ilntroduceNumero)
-1) * (a.pimag*b.Pimag) ;
c.Preal := a.Preal*b'Preal + (
a . preal *b . Pimag
c.Pimag := a.Pimag*b'Preal +
anD; {r"rurtipri-ca}
END. Rr
UnprogramaquepruebesilaunidadComplejofuncionaCorrectamente,podraserel U]
que se detalla a continuacin' I]
PROGRAMCalculadora;
T
USES Complejo;
VAR
n7, n2, n3: TComPIejo;
BEGIN {Programa PrinciPal}
IntroduceNumero (n1) ;
IntroduceNumero (n2) ;
write ('Resultados de 1as operaciones sobre: ') ;
MuestraNumero (n1) ;
write('y');
MuesLraNumero (n2) ;
' ::-teln;
' : -:e ('Suma: ') ;
.---: 11 , n2, n3)
--.::aNumero(n3) ;
-^---. ,\.
- - '--- !
'==-q. 1t
- =- -
__-:ta : = 1,,_-
:1.-: l:=a:LrscaVacia)
I-1.-l- -f EsVacia (lista: TLista) : boolean;
:::_:; I
_JVAUIA .- \aIDLa - t\aL/
:'-- fE'ol/".i".| I
VAR s
aux: TLista; l
BEGIN lr
new(aux); c
aux^.info := info; d
A.
aux^.sig := Iista; d
Iista : = aux d
END; {InsertarElemento} e
c
PROCEDURE EliminarElemento(VAR Iista: TLista) ;
VAR
aux: TLista;
I
BEGIN u
IF NOT EsVacia(lista) rHnU I]
BEGIN T'
aux := lista^.sig;
dispose(liscal ;
lista := aux;
END
END; {eliminarflementoi
n4
-:- :: j--:LUIler vllif
\rf a.
Duq. lrl 1di-\
r!aDuq/ PR
::.--' BE
:--: --S:a <> NIL) D0
:: r--_ EN
Sor,ucrouBs
199
IMPLEMENTATION
PROCEDURE CrearpiLaVacia(VAR pila: TFria ;
BEGIN
pila : _- NIL
END; {Crearpilavacia}
500 UNToInps EN TURBo PASCAL
IINIT Disco;
INTERFACE
L,tlt\ 5 I
N = 30;
TYPE
TTitulo = stri_ng [N] ;
TAutor = TTitulo;
TAnio = string [C] ;
TTiempo = reaf;
TDisco = RECORD
titulo: TTitulo;
autor: TAutor;
anro: 'I'Anro;
ouracl0n: '1"I'rempo;
END;
IMPLEMENTAT]ON
PROCEDURE IntroduceTitulo (VAR nom: TT::*_:
VAR
c: char;
BEGIN
REPEAT
writ.e (, Introduzca el nombre: , ) ;
UNrn.oBS BN Tunno PASCAL
:eadln (nom) ; l
i;rite ('E} nombre inLroducido es : ' , nom, v
' si es correcto pulse s'); L
-^.t-/-\
!uqutI] \u/ / IND;
-liTIL c IN ['s','S']
?ROC
]DAT
J!Ut
UNTIL c IN ['s','S']
IND; {IntroduceAnio} :ITN.
3EGIN
REPEAT PROC:
wriLe ('Introduzca la duracion: ' ) ; 3EGI]
readln (tiempo) ; II
L]NIT Cola;
INTERFACE
USES Disco;
TYPE
504 UNT.nBs BN TuRso PASCAL
lE,enenro = lDlsco;
lE:-_ece = "INodo;
Iiicco = RECORD
Lnlo : TElemento,.
sig: TEnIace;
EINT .
TCO]A = RECORD
cabecera, final: TEnlace;
END;
IMPLEMENTATION
PROCEDURE CrearColaVacia(VAR Cola: TCola) ;
BEGIN
cola.cabecera := NIL;
cola.final := NIL
END; {CrearColaVacia}
new (aux) ; P]
1*x .l-nlo := info;
^..--a l --r^
VJ
=-::^.sig := lista;
- =:- := aUX B]
::'-- rFl
^-^-f ^l
PR..EDURE ExtraerNodo(vAR
cora: TCola; vAR info: TElemento);
aux: TEnIace;
BEGIN
IF NOT EsColaVacia(cola) THEN
i
t
BEGIN
I
info := cola.cabecera^.infc;
IF cola.cabecera = cola.firal THEN {Es el ltimo nodo}
BEGIN
dispose (cola. cabecera r;
cola.cabecera := NIL;
cola.final := NIL;
END
ELSE
BEGIN
dux : = CO_La. Ca.beCe:i .
cola.final := NIL;
WHILE NOT EsColaVacia(cola) DO
BEGIN
aux:= cola.cabecera;
cola . cabecera : = cola . cabecera^ .s iq ;
dispose (aux) ;
506 UNroIoBs EN TURBo PIscIr,
END;
END; {DestrurrCola}
END.
Solucin del tercer apartado. En este caso hemos supuesto que cuando se abre un ficher
para escritura se sobreescribe todo su contenido anterior. Esta ltima unidad se pue .r
ver como un recubrimiento de las funciones y procedimientos de Turbo Pascal.
;1i-IT Binario;
INTERFACE
USES Disco;
TYPE
TElem = TDisco;
TFichero = FILE OF TEIem;
IMPLEMENTATION
FUNCTI0N ExisteFichero (VAR f: TFichero) : boolean;
{ere = el nombre fisico del fichero ha sido asignado a fi
{lost = TRUE si el fichero ya existe, FALSE en caso contrario}
VAR
aux: boolean;
D E TIT
J!glr!
{$r-}
:e:jeL \Il ;
-. _+ )
-a iOResult = 0) THEN P
:: a-l; {
-- --^ !\
{
: -. -=: -chero : = TRUE B
:
:-:: E]
EI
:.-- t - . .-.-
--
Sor,ucroNns -507
END; {abrirficheroEscritura}
.: , l:_rfi Programa;
-::: -rsco, CoIa, Binafio;
,,t,s:
llOM = 'fichero.dat';
_-_1
: : TCola;
E
=-:m: TDisco;
E
^L---
^h^t^.
END.
:::IN {Programa Principati
CrearColaVacia (c) ;
REPEAT
writeln ('InLroduzca l-a informacion por favor: ' ) ;
Introducelnfo (elem) ;
InsertarNodo (c, elem) ;
writeln (' Para parar pulse s' ) ;
readln (p) ;
LINTIL p IN ['s' ,'S'f ;
AbrirFicheroEscritura (NOM, fich) ;
I{HILE NOT EsColaVacia(c) D0
BEGIN
ExtraerNodo (c, elem) ;
EscribirFichero (fich, elem) ;
END;
CerrarFichero ( fich)
END. {Programa Principal}
.:llFAM Comprobar;
.--::j Disco, Binario;
.,-: -
= ' fichero. dat' ;
- --: l)isco;
- ' -: ichero;
., :::iean;
::.- . -r:a:a PrinCipal)
,r ., =__,t IHEN
Sor,ucroNBs 509
BEGIN
I{HILE NOT eof (f ich) D0
BEGIN
LeerFichero (fich, elem) ;
Muescralnfo (e1em) ;
END;
CerrarFichero ( fich)
END
ELSE
writeln('Se ha produci-do un error,)
END. {Programa Principal}
Anexo I
Normas de estilo
597
-
598 ANnxo I
PROGRAM NombrePrograma ;
Propsito:
Entrada:
Salida:
variablel : tipol;
END ; {Nombrelrocedimiento}
FI.IITCTION NombreFuncion ( tistaParametros) : tipoFuncion;
BEGIN iuombreFuncion)
END; {NombreFuncion}
InstruccinN
END. {Programa principa}}
Instruccin IF. Se elegir entre este formato, que escribe BEGIN en la siguiente
:.: -11 -F y a su misma altura,
]F Condicon THEN
"=GIN
fnstruccin1;
...i
I-=:mccinN
Axrxo I s99
END
ELSE
BEGIN
InstruccinA;
InstruccinZ
END; {elsu}
InstruccinN
END
ELSE IF Condicin2 THEN BEGIN
fnstruccinA;
...;
InstruccinZ
END
ELSE BEG]N
Instruccina;
:'
lnscrucclonz,.
END; {rlsr}
CASE expresin OF
valor1: BEGIN
Instruccin1;
...;
TnstruccinN
END; {Valort_ }
valor2: InsLruccioni;
valorN: BEGIN
InstruccinA;
..,;
InstruccinZ
END; {Valorn}
600 Annxo I
ELSE
InstruccionElse;
END; {casn}
Instruccin wHrLE. Es similar al tp. Se elegir una de las dos formas de escri-
birlo, poniendo BEGIN en la lnea siguiente,
WHILE Condicion DO
BEGIN
Instruccin1;
..,;
InstruccinN
END; {wutrr}
o en la misma lnea:
InstruccinN
END; {wHrlu}
Istmccin REPEAT.
REPEAT
Instruccin1 ,'
...;
Inst.ruccinN
UNTIL Condicin;
BEGIN
InsLruccin1;
-rstruccinN
.-^- I
=. - -'Jf .l
['=,.-.
ANrxo I 6ul
o en la misma lnea:
Normas tipogrficas: se trata de seguir unas normas para que todos los progra-
madores las sigan y se facilite la lectura )' comprensin del cdigo. Algunas reglas
son:
- Losidentiflcadores(losnombresI.ll-..ficlreros.fuente.segr.. l.,:-,i;'r-.,'tll3s
normas que los identificadores en P.ca1 l debern te n.: . :-- il-.:\illltr ocho
Caracteres, SegUidOS de Un pUntt \ rJne e\tenlirln i.- :l.i-> .:,r,1> P.\S)para
sercompatibles con el sistema operri-\''- '\1S-DOS -' :l-'':'-' -----:i'pas' o
como ejemplo.Pas.