sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. este...

161
1 Pascal 7.0 Sacado de - www.auladigital.com . 1.1 Pasos para la solución de problemas El proceso de resolución de un problema con una computadora conduce a la escritura de un programa y a su ejecución en la misma. Aunque el proceso de diseñar programas es esencialmente un proceso creativo, se pueden considerar una serie de fases o pasos comunes, que generalmente deben seguir todos los programadores. Las siguientes son las etapas que se deben cumplir para resolver con éxito un problema de programación: 1. Definición del problema 2. Análisis del problema 3. Selección de la mejor alternativa 4. Diagramación 5. Prueba de escritorio 6. Codificación 7. Transcripción 8. Compilación 9. Pruebas de computador 10. Documentación externa 1.- DEFINICIÓN DEL PROBLEMA Está dada por el enunciado del problema, el cúal debe ser claro y completo. Es importante que conozcamos exactamente que se desea del computador; mientras qué esto no se comprenda, no tiene caso pasar a la siguiente etapa. 2.- ANÁLISIS DEL PROBLEMA Entendido el problema (que se desea obtener del computador), para resolverlo es preciso analizar: Los datos o resultados que se esperan. Los datos de entrada que nos suministran. El proceso al que se requiere someter esos datos a fin de obtener los resultados esperados. Areas de trabajo, fórmulas y otros recursos necesarios. Una recomendación muy práctica es el que nos pongamos en el lugar del computador, y analizar que es necesario que me ordenen y en que secuencia, para poder producir los resultados esperados. También da buenos resultados hacer similitudes con la labor de un empleado que hace el mismo trabajo que deseamos programarle al computador. 3.- SELECCIÓN DE LA MEJOR ALTERNATIVA Analizado el problema, posiblemente tengamos varias formas de resolverlo; lo importante es determinar cúal es la mejor alternativa: la que produce los resultados esperados en el menor

Upload: duongque

Post on 27-Sep-2018

214 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

1

Pascal 7.0

Sacado de - www.auladigital.com .

1.1 Pasos para la solución de problemas

El proceso de resolución de un problema con una computadora conduce a la escritura de unprograma y a su ejecución en la misma. Aunque el proceso de diseñar programas esesencialmente un proceso creativo, se pueden considerar una serie de fases o pasos comunes, quegeneralmente deben seguir todos los programadores.

Las siguientes son las etapas que se deben cumplir para resolver con éxito un problema deprogramación:

1. Definición del problema2. Análisis del problema3. Selección de la mejor alternativa4. Diagramación5. Prueba de escritorio6. Codificación7. Transcripción8. Compilación9. Pruebas de computador10. Documentación externa

1.- DEFINICIÓN DEL PROBLEMAEstá dada por el enunciado del problema, el cúal debe ser claro y completo. Es importante queconozcamos exactamente que se desea del computador; mientras qué esto no se comprenda, notiene caso pasar a la siguiente etapa.

2.- ANÁLISIS DEL PROBLEMAEntendido el problema (que se desea obtener del computador), para resolverlo es precisoanalizar:

• Los datos o resultados que se esperan.• Los datos de entrada que nos suministran.• El proceso al que se requiere someter esos datos a fin de obtener los resultados esperados.• Areas de trabajo, fórmulas y otros recursos necesarios.

Una recomendación muy práctica es el que nos pongamos en el lugar del computador, y analizarque es necesario que me ordenen y en que secuencia, para poder producir los resultadosesperados. También da buenos resultados hacer similitudes con la labor de un empleado que haceel mismo trabajo que deseamos programarle al computador.

3.- SELECCIÓN DE LA MEJOR ALTERNATIVAAnalizado el problema, posiblemente tengamos varias formas de resolverlo; lo importante esdeterminar cúal es la mejor alternativa: la que produce los resultados esperados en el menor

Page 2: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

2

tiempo y al menor costo. Claro que aquí también es muy válido el principio de que las cosassiempre se podrán hacer de una mejor forma.

4.- DIAGRAMACIÓNUna vez que sabemos cómo resolver el problema, pasamos a dibujar gráficamente la lógica de laalternativa seleccionada. Eso es precisamente un Diagrama de Flujo: la representación gráfica deuna secuencia lógica de pasos a cumplir por el computador para producir un resultado esperado.La experiencia nos ha demostrado que resulta muy útil trasladar esos pasos lógicos planteados enel diagrama a frases que indiquen lo mismo; es decir, hacer una codificación del programa peroutilizando instrucciones en Español. Como si le estuviéramos hablando al computador. Esto es loque denominaremos Algoritmo o Pseudocódigo.Cuando logremos habilidad para desarrollar programas, es posible que no elaboremos eldiagrama de flujo; en su lugar podremos hacer directamente el pseudocódigo del programa.

5.- PRUEBA DE ESCRITORIOPara cerciorarnos de que el diagrama (y/o el pseudocódigo) esta bien, y, para garantizar que elprograma que codifiquemos luego también funcione correctamente, es conveniente someterlo auna Prueba de Escritorio . Esta prueba consiste en que damos diferentes datos de entrada alprograma y seguimos la secuencia indicada en el diagrama, hasta obtener los resultados. Elanálisis de estos nos indicará si el diagrama esta correcto o si hay necesidad de hacer ajustes(volver al paso 4). Se recomienda dar diferentes datos de entrada y considerar todos los posiblescasos, aun los de excepción o no esperados, para asegurarnos de que el programa no produciráerrores en ejecución cuando se presenten estos casos.

6.- CODIFICACIÓNUna vez que hayamos verificado el diagrama mediante las pruebas de escritorio, codificamos elprograma en el lenguaje de computador seleccionado. Esto es, colocamos cada paso deldiagrama en una instrucción o sentencia, utilizando un lenguaje que el computador reconoce.Todos los lenguajes de programación proveen facilidades para incluir líneas de comentarios enlos programas. Estos comentarios aclaran lo que se ordena al computador y facilitan entender elprograma. Puesto que estos comentarios no son tenidos en cuenta como instrucciones, y aparecenen los listados del programa, resulta muy conveniente agregar abundantes comentarios a todoprograma que codifiquemos. Esto es lo que se denomina Documentación Interna.

7.- TRANSCRIPCIÓNEl programa codificado es necesario que lo llevemos a un medio que sea aceptado como entradapor el computador: lo perforamos en tarjetas, lo grabamos en un disco flexíble o lo grabamos enun disco duro. Este programa es el que se conoce como Programa Fuente (Source).

8.- COMPILACIÓNUtilizamos ahora un programa de computador llamado Compilador o Traductor, el cúal analizatodo el programa fuente y detecta errores de sintaxis ocasionados por fallas en la codificación oen la transcripción. Las fallas de lógica que pueda tener nuestro programa fuente no sondetectadas por el compilador. Cuando no hay errores graves en la compilación, el compilador

Page 3: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

3

traduce cada instrucción del programa fuente a instrucciones propias de la máquina (Lenguaje deMaquina), creando el Programa Objeto.Algunos computadores utilizan Interpretadores, (Generalmente para el Lenguaje Basic), enreemplazo de programas compiladores. La diferencia consiste en que el interpretador recibe,desde una terminal, sólo una instrucción a la vez, la analiza y, si esta bien, la convierte al formatopropio de la maquina. Si la instrucción tiene algún error, el interpretador llama la atención de lapersona para que corrija dicha instrucción.Como resultado de la corrida del compilador, podemos obtener varios listados:

• Listado del programa fuente• Listado de los errores detectados• Listado de campos utilizados, etc.

Los errores los debemos corregir sobre el mismo programa fuente, ya sea reemplazando lastarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de lacompilación lo repetimos hasta eliminar todos los errores y obtener el programa ejecutable.

9.- PRUEBAS DE COMPUTADORCuando tenemos el programa ejecutable (en lenguaje de maquina), ordenamos al computadorque lo ejecute, para lo cúal suministramos datos de prueba, como lo hicimos en la prueba deescritorio (paso 5). Los resultados obtenidos los analizamos, luego de lo cúal puede ocurrircualquiera de estas situaciones:a.- La lógica del programa esta bien, pero hay errores sencillos, los cuales los corregimosmodificando algunas instrucciones o incluyendo unas nuevas; el proceso debemos repetirlodesde el paso 6 .b.- Hay errores ocasionados por fallas en la lógica, lo que nos obliga a regresar a los pasos 4 y 5para revisión y modificación del diagrama.c.- Hay errores muy graves y lo más aconsejable es que regresemos al paso 2 para analizarnuevamente el problema, y repetir todo el proceso.d.- No hay errores y los resultados son los esperados. En este caso, el programa lo podemosguardar permanentemente en una librería o biblioteca del computador, para sacarlo de allícuando necesitemos ejecutarlo nuevamente.

10.- DOCUMENTACIÓN EXTERNACuando el programa ya se tiene listo para ejecutar, es conveniente que hagamos sudocumentación externa siguiendo las normas de la instalación o las recomendaciones indicadaspor el profesor. Una buena documentación incluye siempre:

a. Enunciado del problemab. Diagrama de pasadac. Narrativo con la descripción de la soluciónd. Relación de las variables o campos utilizados en el programa, cada uno con su respectiva

funcióne. Diagrama del programaf. Listado de la última compilacióng. Resultados de la ejecución del programa.

Page 4: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

4

1.2 Objetivos de la programación

En la preparación de un programa, el programador puede tener que escoger entre solucionesalternativas en muchos puntos. Cada elección debe hacerse para satisfacer los objetivos yrestricciones de la tarea de programación particular. Aquí asumiremos como apropiados paratoda tarea de programación los siguientes objetivos:

• Exactitud

• Claridad

• Eficiencia

EXACTITUDUn objetivo obvio en la escritura de cualquier programa de computador es que tiene quesatisfacer su especificación exactamente. A menudo, sin embargo, a causa de la complejidad dela labor del programa, y de un entendimiento o cuidado inadecuados de parte del programador,un programa falla en satisfacer alguna parte de su especificación. Un programador tiene que seren todo tiempo cuidadoso de la exactitud o pertinencia del programa para su propósitoespecificado.Un factor clave en el logro de exactitud es la simplicidad. Escogiendo el algoritmo o técnica mássimple disponible, es más probable que un programador vea si satisface o no los requerimientosde la especificación del programa, y es menos probable que la describa incorrectamente en suprograma. La innecesaria complejidad no cumple propósito alguno en la programación decomputadores.Algunos programas son, por supuesto, inherentemente complejos. Para tales programas, elprogramador debe adoptar un tratamiento sistemático que controle y limite la complejidad de laque tiene que ocuparse en cada etapa.

CLARIDADUn programa es necesariamente tan complejo como el algoritmo que describe. Sin embargo, esimportante que la forma en que el algoritmo esté descrito, por el texto del programa, no sea mascomplicada de lo que es necesario. La claridad del programa es una ayuda importante para elprogramador mismo en el diseño y limpieza del programa; y para otros que puedan tener que leery alterar el programa en alguna etapa posterior.La claridad del programa es lograda casi en la misma forma que para cualquier texto escrito, talcomo un ensayo o un libro en los cuales se requiere:a).- Una separación lógica del texto en partes comprensibles (capítulos, secciones, etc.) quereflejen la distinción entre los temas que describen, y su presentación en una secuencia lógicaque refleje las relaciones entre ellas;b).- Una selección cuidadosa de las características del lenguaje, usadas en cada parte paraexpresar su sentido propuesto tan precisamente como sea posible;c).- Otra selección cuidadosa de las palabras usadas para denotar los objetos y conceptosinvolucrados;d).- La inclusión de comentarios y preámbulos para clarificar el texto principal cuando seanecesario;e).- Un aprovechamiento de los dispositivos para presentación de textos, tales como las líneas enblanco y la sangría, para enfatizar la relación entre partes componentes de textos.

Page 5: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

5

Un programador podría ser tan diligente en el uso de éstas técnicas para lograr claridad como elautor de cualquier texto. En muchos casos, la utilidad de un programa es determinada tanto por laclaridad de su texto como por las cualidades del algoritmo que describe.

EFICIENCIAEl costo de ejecutar un programa de computador, es medido normalmente en términos de :a).- El tiempo tomado por el computador para llevar a cabo la secuencia de operacionesinvolucradas;b).- La cantidad de memoria de computador usada en hacerlo.En muchos ambientes (de máquina), el programa competirá con otros programas por el uso deesos recursos del computador, y es, por tanto, lógico minimizar los requerimientos del programapara cada uno.El tiempo tomado para ejecutar el programa, es directamente proporcional al número deoperaciones que el procesador tiene que realizar al hacerlo. El programador debe, por tanto,escoger un algoritmo que minimice las operaciones implicadas, y tener cuidado de evitarcualquier operación redundante al expresar el algoritmo como un programa de computador.La memoria usada por el programa durante su ejecución, es determinada por la cantidad de datosque tienen que ser guardados, y por el número de instrucciones del procesador requeridas paradefinir el programa, ya que éstas también tienen que ser guardadas en la memoria. Paraminimizar el almacenamiento usado por su programa, el programador debe, por tanto, considerarlos datos manipulados y el número de operaciones especificadas por el programa.Para algunos programas, o partes de programas, el uso eficiente del tiempo o del almacenamientopuede ser crítico; para otros puede serlo menos. El programador debe estar enterado decualquiera de tales requerimientos de eficiencia cuando escriba su programa.

1.3 Herramientas de programación

Las dos herramientas más utilizadas comúnmente para diseñar algoritmos son : diagramas deflujo y pseudocódigos.

DIAGRAMAS DE FLUJOUn diagrama de flujo (flowchar) es una representación gráfica de un algoritmo. Los símbolosutilizados han sido normalizados por el Instituto Norteamericano de Normalización (ANSI), ylos más frecuentemente empleados se muestran acontinuación:

Page 6: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

6

PSEUDOCÓDIGOCon la PE, el pseudocódigo sigue siendo un excelente medio para expresar la lógica de unprograma. A continuación se muestran algunos ejemplos de palabras para construir algoritmos enpseudocódigo.

PALABRA UTILIZACIÓNABRE Abre un archivoCASO Selección entre múltiples alternativasCIERRA Cierra un archivo

ENTONCES Complemento de la selecciónSI - ENTONCES

ESCRIBE Visualiza un dato en pantallaFIN Finaliza un bloque de instruccionesHASTA Cierra la iteración HAZ - HASTAHAZ Inicia la iteración HAZ - HASTAINICIO Inicia un bloque de instruccionesLEER Leer un dato del tecladoMIENTRAS Inicia la iteración mientrasNO Niega la condición que le sigueO Disyunción lógica

O - BIEN Complemento opcional de la selecciónSI - ENTONCES

PARA Inicia un número fijo de iteracionesSI Inicia la selección SI-ENTONCESUSUAL Opcional en la instrucción CASOY Conjunción lógica{ Inicio de comentario} Fin de comentario<= Asignación

1.4 Programación estructurada

El creciente empleo de los computadores ha conducido a buscar un abaratamiento del desarrollode software, paralelo a la reducción del costo del hardware obtenido gracias a los avancestecnológicos. Los altos costos del mantenimiento de las aplicaciones en producción normaltambién han urgido la necesidad de mejorar la productividad del personal de programación.

Page 7: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

7

DEFINICIONESLa programación estructurada (en adelante simplemente PE ), es un estilo de programación conel cual el programador elabora programas, cuya estructura es la más clara posible, mediante eluso de tres estructuras básicas de control lógico, a saber :

a. SECUENCIA.b. SELECCIÓN.c. ITERACIÓN.

Un programa estructurado se compone de funciones,segmentos, módulos y/o subrutinas, cadauna con una sola entrada y una sola salida. Cada uno de estos módulos (aún en el mismoprograma completo), se denomina programa apropiado cuando, además de estar compuestosólamente por las tres estructuras básicas, tiene sólo una entrada y una salida y en ejecución notiene partes por las cuales nunca pasa ni tiene ciclos infinitos.La PE tiene un teorema estructural o teorema fundamental, el cual afirma que cualquierprograma, no importa el tipo de trabajo que ejecute, puede ser elaborado utilizando únicamentelas tres estructuras básicas ( secuencia, selección, iteración ).

DEFINICIÓN DE LAS ESTRUCTURAS BÁSICAS DE CONTROL LÓGICO1.- SECUENCIAIndica que las instrucciones de un programa se ejecutan una después de la otra, en el mismoorden en el cual aparecen en el programa. Se representa gráficamente como una caja después deotra, ambas con una sola entrada y una única salida.

Las cajas A y B pueden ser definidas para ejecutar desde una simple instrucción hasta un móduloo programa completo, siempre y cuando que estos también sean programas apropiados.

2.- SELECCIÓNTambién conocida como la estructura SI-CIERTO-FALSO, plantea la selección entre dosalternativas con base en el resultado de la evaluación de una condición o predicado; equivale a lainstrucción IF de todos los lenguajes de programación y se representa gráficamente de lasiguiente manera :

Page 8: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

8

En el diagrama de flujo anterior, C es una condición que se evalúa; A es la acción que se ejecutacuando la evaluación de este predicado resulta verdadera y B es la acción ejecutada cuandoindica falso. La estructura también tiene una sola entrada y una sola salida; y las funciones A y Btambién pueden ser cualquier estructura básica o conjunto de estructuras.

3.- ITERACIÓNTambién llamada la estructura HACER-MIENTRAS-QUE o REPETIR - HASTA- QUE ,corresponde a la ejecución repetida de una instrucción mientras que se cumple una determinadacondición. El diagrama de flujo para esta estructura es el siguiente :

Aquí el bloque A se ejecuta repetidamente mientras que la condición C se cumpla o sea cierta.También tiene una sola entrada y una sola salida; igualmente A puede ser cualquier estructurabásica o conjunto de estructuras.

VENTAJAS DE LA PROGRAMACIÓN ESTRUCTURADACon la PE, elaborar programas de computador sigue siendo una labor que demanda esfuerzo,creatividad, habilidad y cuidado. Sin embargo, con este nuevo estilo podemos obtener lassiguientes ventajas :

1. Los programas son más fáciles de entender. Un programa estructurado puede ser leído ensecuencia, de arriba hacia abajo, sin necesidad de estar saltando de un sitio a otro en lalógica, lo cual es típico de otros estilos de programación. La estructura del programa esmás clara puesto que las instrucciones están más ligadas o relacionadas entre si, por loque es más fácil comprender lo que hace cada función.

2. Reducción del esfuerzo en las pruebas. El programa se puede tener listo para producciónnormal en un tiempo menor del tradicional; por otro lado, el seguimiento de las fallas odepuración (debugging) se facilita debido a la lógica más visible, de tal forma que loserrores se pueden detectar y corregir más fácilmente.

3. Reducción de los costos de mantenimiento.4. Programas más sencillos y más rápidos.5. Aumento en la productividad del programador.

Page 9: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

9

6. Se facilita la utilización de las otras técnicas para el mejoramiento de la productividad enprogramación.

7. Los programas quedan mejor documentados internamente.

1.5 Otras técnicasAdemás de la PE, existen las siguientes técnicas o métodos de trabajo para mejorar laproductividad del personal que trabaja en programación de computadores :

1.- DESARROLLO DESCENDENTE DE PROGRAMASEl concepto de Desarrollo Descendente (también conocido como Desarrollo Ariba-Abajo,Desarrollo Estructurado o Desarrollo Top-Down), se aplica tanto a la fase de diseño del sistemao aplicación como a la fase de programación y codificación de los programas.El desarrollo descendente de programas consiste en construir un programa tratando dedescomponerlo en módulos (funciones o segmentos), cada uno encargado de realizar un trabajoespecífico. Esta organización se va logrando de arriba hacia abajo en forma de árbol y podemosrepresentarla gráficamente como un DIAGRAMA DE ESTRUCTURA.

2.- DOCUMENTACION JEPSConocida originalmente como la técnica HIPO (Hierarchy plus Input-Process-Output), permiteproducir las especificaciones funcionales de un programa y al mismo tiempo su documentación.Consiste en una tabla visual de contenido que apunta a los diagramas HIPO del paquete ymuestra las funciones y subfunciones que efectúa el programa y las inter-relaciones de lasmismas. En cada diagrama HIPO se relaciona la entrada con el proceso y la salida respectiva.HIPO es una herramienta muy útil en la fase de diseño y se complementa muy bien con la PE .

3.- INSPECCIONES DE TRABAJOSon sesiones de revisión en las cuales el creador de los programas los explica a sus compañeros;de ésta forma asegura la detección y corrección de errores en un momento en el cual no resultantan costosos.La legibilidad de los programas estructurados facilita estas inspecciones de trabajo.

4.- BIBLIOTECAS DE DESARROLLOEs la recopilación organizada del material que contiene la última versión de toda la informaciónde un proyecto (diseños, especificaciones, diagramas, listados de computador, etc.).Aunque este tipo de organización es muy práctico con cualquier estilo de programación, encajamuy bien con la PE .

5.- GRUPOS CON PROGRAMADOR EN JEFEIncluye grupos de trabajo con mínimo tres integrantes organizados de la siguiente manera :a).- Programador jefeb).- Programador de respaldoc).- Encargado de la biblioteca de desarrollo.El grupo puede incluir otros programadores, analístas y usuarios finales. El Programador en Jefees responsable del diseño y codificación de los programas producidos por su grupo.

Page 10: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

10

La PE es adecuada con estos grupos de trabajo puesto que facilita al Programador Jefe la revisióndel material producido por los demás miembros.

La combinación de las técnicas de Desarrollo Descendente de programas y la ProgramaciónEstructurada ofrece las siguientes ventajas, adicionales a las ya enumeradas antes :a.- El programa puede ser distribuido entre varias personas, y la posterior integración de losdiferentes módulos no debe presentar mayores inconvenientes.b.- Durante la etapa de pruebas del programa, los módulos superiores (que generalmente son losmás críticos) reciben más atención.c.- El mantenimiento de los programas resulta menos costoso debido a que la atención seconcentra en un determinado modulo, reduciendo así la posibilidad de error.

LA TRANSFERENCIA INCONDICIONALAlgunas veces se asocia la PE con la eliminación total de las instrucciones GO TO ("vaya a") enun programa, lo cual no es absolutamente cierto. Un programa construido con las tres estructurasbásicas de control no requiere el uso de instrucciones GO TO para transferir el control de un sitioa otro; esto es una consecuencia del desarrollo descendente de los programas estructurados y dela limitante misma que tiene el programador para transferir el control, cuando sólo utiliza las tresestructuras básicas.El empleo exagerado de la instrucción GO TO puede hacer incomprensible un programa noestructurado; sin embargo, el empleo moderado de ésta instrucción aporta más claridad a losprogramas no estructurados. Es posible que se presenten casos en PE en los cuales el empleo deuna instrucción GO TO le de más claridad y efectividad a un programa estructurado.También utilizamos GO TO en los casos en que el lenguaje utilizado no tiene una instrucciónequivalente a la estructura de iteración empleada, de tal suerte que ésta sólo la podemos simularcon un GO TO, tal como sucede con algunas versiones de BASIC y FORTRAN ( AUNQUE ENREALIDAD HOY YA NO EXISTEN MÁS )

2.1 Estructuras general de programas en Pascal

Pascal es un lenguaje de programación de alto nivel, que facilita la práctica de la programaciónestructurada. Utiliza un traductor que produce código ejecutable, lo cual disminuye los tiemposde ejecución de los programas.El lenguaje Pascal fue desarrollado por Niklaus Wirth, con el propósito de ayudar a losestudiantes en el manejo de las técnicas de la programación estructurada, pero en la actualidad suaplicación es de propósitos generales.La construcción de programas en Pascal se basa en módulos que guardan las siguientes reglas deconstrucción :

Program identificador ; {cabecera opcional en Turbo Pascal}Uses identificadoresLabel lista de etiquetas ; {sección de etiquetas}Const

definiciones de constantes

Type

Page 11: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

11

declaración de tipos de datos definidos por el usuario

Var

declaración de variables

Procedure

definiciones de procedimientos

Function

definiciones de funciones

begin {cuerpo del programa}

sentencias

end.

Las cinco secciones de declaración -Label, Const, Type y Procedure y/o Function , así comolacláusula Uses y Program, no tiene que estar presentes en todos los programas. Turbo Pascalesmuy flexible al momento de escribir las secciones de declaración, ya que se pueden hacer encualquier orden (en Pascal estándar ISO si se require este orden). Sin embargo es convenienteseguir el orden establecido, le evitará futuros problemas.Ejemplo:Program MiPrimerPrograma; {cabecera}Uses Crt; {declaraciones}Const iva =0.10;Type cadena =string[35]; meses =1..12;Var sueldo :real; numero :integer; nombre :cadena; Nmes :meses;begin ClrScr; {Limpia la pantalla} Write ('Escribe tu nombre : '); {Visualiza información en pantalla} ReadLn(nombre);{Leer un dato del teclado} WriteLn ('Bienvenido ', nombre); {Visualiza información en pantalla} Readkey; {Espera la pulsación de una tecla} ClrScrend.

Page 12: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

12

Nota: Las declaraciones de constantes, tipos y variables también se pueden poner en losprocedimientos y/o funciones.Todo objeto referenciado en un programa debe haber sido previamente definido.Ejemplo:Program Incorrecto; {cabecera}Const pi=3.141592;Var Meses:array [1..Max] of string[15];begin ...................................end.El programa anterior es incorrecto ya que hacemos referencia a la constante Max en ladeclaración de variables sin haberla definido en la declaración de constantes.

2.2 IdentificadoresEn la mayoría de los programas de computador, es necesario manejar datos de entrada o desalida, los cuales necesitan almacenarse en la memoria principal del computador en el tiempo deejecución. Para poder manipular dichos datos, necesitamos tener acceso a las localidades dememoria donde se encuentran almacenados; esto se logra por medio de los nombres de los datoso IDENTIFICADORES.Los identificadores también se utilizan para los nombres de los programas, los nombres de losprocedimientos y los nombres de las funciones, así como para las etiquetas, constantes yvariables.Las reglas para formar los identificadores en Pascal son las siguientes :

1. Pueden estar compuestos de caracteres alfabéticos, numéricos y el carácter de subrayado(_ ).

2. Deben comenzar con un carácter alfabético o el carácter de subrayado.3. Puede ser de cualquier longitud (sólo los 63 primeros caracteres son significativos).4. No se hace distinción entre mayúsculas y minúsculas.5. No se permite el uso de los IDENTIFICADORES RESERVADOS en los nombres de

variables, constantes, programas o sub-programas.

Identificadores válidosNombreCadenaEdad_MaximaX_Y_ZEtiqueta2

Identificadores no válidosNum&Dias : carácter & no válidoX nombre : Contiene un blancobegin : es una palabra reservadaeje@s : carácter @ no válido

Page 13: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

13

Elección de identificadores

La elección de identificadores permite una mejor lectura y comprensión de un programa. No esaconsejable utilizar identificadores que no sugieran ningún significado.La siguiente tabla muestra los IDENTIFICADORES RESERVADOS en Turbo-Pascal. Losmarcados con un asterisco no están definidos en Pascal estándar . Los marcados con ? no seutilizan en Turbo-Pascal

*ABSOLUTE IN VAR RECORD*AND *OVERLAY GOTO ELSEARRAY *STRING ?PACKED WHILE*EXTERNAL BEGIN TO LABELFILE FOR DIV REPEATFORWARD OF *INLINE WITHNIL THEN PROCEDURE END*SHL CASE UNTIL MODAND FUNCTION DO SETFILE OR IF *XORNOT TYPE PROGRAM*SHR CONST DOWNTO

Turbo-Pascal define los siguientes IDENTIFICADORES ESTANDAR de tipos predefinidos,constantes, variables, procedimientos y funciones. Cualquiera de ellos puede ser redefinido,

perdiéndose así la facilidad de utilizar su definición original.ADDR DELAY LENGTH RELEASEARCTAN DELETE LN RENAMEASSIGN EOF LO RESETAUX EOLN LOWVIDEO REWRITEAUXINPTR ERASE LST ROUNDAUXOUTPTR EXECUTE LSTOUTPTR SEEKBLOCKREAD EXIT MARK SINBLOCKWRITE EXP MAXINT SIZEOFBOOLEAN FALSE MEM SEEKEOFBUFLEN FILEPOS MEMAVAIL SEEKEOLNBYTE FILESIZE MOVE SQRCHAIN FILLCHAR NEW SQRTCHAR FLUSH NORMVIDEO STRCHR FRAC ODD SUCCCLOSE GETMEM ORD SWAPCLREOL GOTOXY OUTPUT TEXTCLRSCR HALT PI TRMCON HEAPPTR PORT TRUECONINPTR HI POS TRUNC

Page 14: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

14

CONOUTPTR IORESULT PRED UPCASECONCAT INPUT PTR USRCONSTPTR INSLINE RANDOM USRINPTRCOPY INSERT RANDOMIZE USROUTPTRCOS INT READ VALCRTEXIT INTEGER READLN WRITECRTINIT KBD REAL WRITELNDELLINE KEYPRESSED

2.3 Declaración de etiquetasEn el remoto caso de que sea necesaria la utilización de la instrucción Goto, deberá marcarse conuna etiqueta la línea a donde desea enviarse el control de flujo del programa.La declaración deberá encabezarse con el identificador reservado Label, seguido por la lista deetiquetas separadas por comas y terminada por un punto y coma.Pascal estándar sólo permite etiquetas formadas por números de 1 a 4 dígitos.Turbo-Pascal permite la utilización de números y/o cualquier identificador, excepto losidentificadores reservados.Su uso no está recomendado y en este tutorial no se empleará nunca.

2.4 Definición de constantesEn la definición de constantes se introducen identificadores que sirven como sinónimos devalores fijos.El identificador reservado Const debe encabezar la instrucción, seguido por una lista deasignaciones de constantes. Cada asignación de constante debe consistir de un identificadorseguido por un signo de igual y un valor constante, como se muestra a continuación:Const valor_maximo =255; precision =0.0001; palabra_clave='Tutankamen'; encabezado =' NOMBRE DIRECCION TELEFONO ';Un valor constante puede consistir de un número ( entero o real ), o de una constante decaracteres.La constante de caracteres consiste de una secuencia de caracteres encerrada entre apóstrofes ( '), y, en Turbo-Pascal, también puede formarse concatenándola con caracteres de control ( sinseparadores ), por ejemplo :'Teclee su opción ==>'^G^G^G ;Esta constante sirve para desplegar el mensaje :Teclee su opción ==>y a continuación suena el timbre tres veces.Las constantes de caracteres pueden estar formadas por un solo carácter de control, p.ej. :hoja_nueva = ^LExisten dos notaciones para los caracteres de control en Turbo Pascal, a saber :

Page 15: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

15

1. El símbolo # seguido de un número entero entre 0 y 255representa el carácter al que corresponde dicho valor decimal en el codigo ASCII.

2. El símbolo ^ seguido por una letra, representa el correspondiente carácter de control.Ejemplos :#12 representa el valor decimal 12 ( hoja_nueva o alimentación de forma ).#$1B representa el valor hexadecimal 1B ( escape ).^G representa el carácter del timbre o campana.^M representa el carácter de retorno de carro.Pascal proporciona las siguientes CONSTANTES PREDEFINIDAS :Nombre Tipo Valorpi real 3.1415926536 (Sólo en Turbo Pascal)false booleantrue booleanMaxInt integer 32767

Además de las constantes literales para los tipos integer y real con representación decimal yhexadecimal, y las constantes literales para el conjunto de caracteres ASCII, más los caracteresespeciales ( no incluidos en el conjunto estándar del ASCII ).

2.5 Definición de tiposAdemás de identificadores, los datos deben tener asignado algún tipo que indique el espacio dememoria en que se almacenarán y que al mismo tiempo evita el error de tratar de guardar un datoen un espacio insuficiente de memoria .Un tipo de dato en Pascal puede ser cualquiera de los tipos predefinidos ( integer, real, byte,boolean, char ), o algún otro definido por el programador en la parte de definición de tipos .Los tipos definidos por el programador deben basarse en los tipos estándar predefinidos, para locual, debe iniciar con el identificador reservado Type , seguido de una o más asignaciones detipo separadas por punto y coma. Cada asignación de tipo debe consistir de un identificador detipo, seguido por un signo de igual y un identificador de tipo previamente definido.La asignación de tipos a los datos tiene dos objetivos principales:

1. Detectar errores de operaciones en programas.

2. Determinar cómo ejecutar las operaciones.

Pascal se conoce como un lenguaje "fuertemente tipeado" (strongly-typed) o de tipos fuertes. Estosignifica que todos los datos utilizados deben tener sus tipos declarados explícitamente y ellenguaje limita la mezcla de tipos en las expresiones. Pascal detecta muchos errores deprogramación antes de que el programa se ejecute.Los tipos definidos por el programador pueden utilizarse para definir nuevos tipos, por ejemplo :Type entero = integer; otro_entero = entero;A continuación se hace una breve descripción de los tipos predefinidos .

Page 16: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

16

Tipos enteros

Tipos enteros predefinidos

Tipo Rango Formatobyte 0 .. 255 8 bits sin signointeger -32768 .. 32767 16 bits con signolongint -247483648 .. 2147483647 32 bits con signoshortint -128 .. 127 8 bits con signoword 0 .. 65535 16 bits sin signo

BYTEEl tipo byte es un subconjunto del tipo integer, en el rango de 0 a 255 . Donde quiera que seespere un valor byte, se puede colocar un valor integer; y viceversa ( EXCEPTO cuando cuandoson pasados como PARAMETROS ). Asimismo, se pueden mezclar identificadores de tipo bytey de tipo integer en las expresiones.Los valores de tipo byte se guardan en UN OCTETO de memoria.

INTEGEREl rango de los valores definidos por el tipo integer , en Turbo Pascal, se encuentra entre -32768y 32767 .Cada valor de este tipo se guarda en DOS OCTETOS de memoria.

LONGINT (enteros largos)A partir de la versión 4.0 se han incorporado números que amplían el rango de variación de losenteros a -2,147,483,648. Este tipo de datos se denomina longint (enteros largos). OcupanCUATRO OCTETOS de memoria. Existe una constante predefinida de tipo longint, denominadaMaxLongInt, cuyo valor es 2,147,483,647.

SHORTINT (enteros cortos)En ciertos casos, puede ser práctico disponer de valores enteros positivos y negativos cuyoalcance sea más restringido que el de los tipos enteros. Los tipos shortint pueden tomar valoresentre -128 y 127. Ocupan UN OCTETO de memoria.

WORDExisten casos en los que se desea representar únicamente valores positivos. Este es el caso. Porejemplo, cuando se desea acceder desde un programa hasta una dirección de memoria. En talsituación, no tiene sentido una dirección negativa. Turbo Pascal dispone del tipo word (o palabra,de palabra de memoria), cuyo intervalo posible de valores es de 0 a 65535. Ocupa DOSOCTETOS de memoria.

Tipos reales

REALEn el contexto de Pascal, un número real es aquel que está compuesto de una parte entera y unaparte decimal, separadas por un punto. El rango de estos números está dado entre los valores 1E-38 y 1E+38 . Cada valor de este tipo se guarda en SEIS OCTETOS de memoria.

Page 17: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

17

Durante una operación aritmética con números reales, un valor mayor que 1E+38 (sobreflujo)causará la detención del programa y desplegará un mensaje de error ; mientras que un valormenor que 1E-38 (bajoflujo), producirá un resultado igual a cero.Deben tomarse en cuenta las siguentes restricciones para los valores de tipo real :

1. No pueden utilizarse como subindices en las definiciones del tipo estructurado array.2. No pueden formar subrangos.3. No se pueden usar para definir el tipo base de un conjunto (tipo estructurado set)4. No deben utilizarse para el control de las instrucciones for y case.5. Las funciones pred y succ no pueden tomarlos como argumentos.

Los números reales están siempre disponibles en Turbo Pascal, pero si su sistema incluye uncoprocesador matemático como 8087, 80287 u 80387, se dispone además de otros tipos denúmeros reales:

• real (real)• single (real corto)• comp (entero ampliado)• double (real de doble precisión)• extended (real ampliado)

Computadoras sin coprocesador matemático (emulación por software)

datos disponibles : real, comp, double, extended y single.

Computadoras con coprocesador matemático

datos disponibles : real, comp, double, extended y single (reales IEEE)

Desde la versión 5.0 se permite utilizar los datos tipo coprocesador matemático aunque sucomputadora no lo tenga incorporado. La razón es que se emula dicho coprocesador. Losdiferentes tipos reales se diferencian por el dominio de definición, el número de cifrassignificativas (precisión) y el espacio ocupado en memoria.

• Turbo Pascal 4.0 requiere obligatoriamente un chip coprocesador matemático para haceruso de números reales de coma flotante IEEE.

• Turbo Pascal 5.0 a 7.0 emula el chip coprocesador matemático totalmente en software,permitiendo ejecutar tipos IEEE tanto si tiene como si no un chip 8087/287/387 instaladoen su máquina.

Tipo Rango Cifras Tamaño y bytesreal 2.910 E -39 .. 1.710 E 38 11 -12 6single 1.510 E -45 .. 3.410 E 38 7 - 8 4double 5.010 E -324 .. 1.710 E 308 15 - 16 8extended 1.910 E -4932 .. 1.110 E 4932 19 - 20 10comp -2 E 63 +1 .. 2 E 63 - 1 19 - 20 8

BOOLEANUn valor de tipo boolean puede asumir cualquiera de los valores de verdad denotados por losidentificadores true y false, los cuales están definidos de tal manera que false < true .Un valor de tipo boolean ocupa UN OCTETO en la memoria.

Page 18: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

18

CHARUn valor de tipo char es cualquier carácter que se encuentre dentro del conjunto ASCII ampliado,el cual está formado por los 128 caracteres del ASCII más los 128 caracteres especiales quepresenta, en este caso, IBM.Los valores ordinales del código ASCII ampliado se encuentran en el rango de 0 a 255. Dichosvalores pueden representarse escribiendo el carácter correspondiente encerrado entre apóstrofes.Así podemos escribir :'A' < 'a'Que significa : " El valor ordinal de A es menor que el de a " o " A está antes que a "Un valor de tipo char se guarda en UN OCTETO de memoria.

CADENA (STRING)Un tipo string (cadena) es una secuencia de caracteres de cero o más caracteres correspondientesal código ASCII, escrito en una línea sobre el programa y encerrado entre apóstrofos.El tratamiento de cadenas es una característica muy potente de Turbo Pascal que contiene ISOPascal estándar.Ejemplos:'Turbo Pascal','Tecnológico', #13#10Nota:

• Una cadena sin nada entre los apóstrofos se llama cadena nula o cadena vacía.• La longitud de una cadena es el número de carácteres encerrados entre los apóstrofos.

2.6 OperadoresLos operadores sirven para combinar los términos de las expresiones.En Pascal, se manejan tres grupos de operadores :

1. ARITMÉTICOS2. RELACIONALES3. LÓGICOS

2.6.1 Operadores aritméticosSon aquellos que sirven para operar términos numéricos. Estos operadores podemos clasificarlosa su vez como :

a. UNARIOSb. BINARIOS

Los operadores UNARIOS son aquellos que trabajan con UN OPERANDO.Pascal permite el manejo de un operador unario llamado :MENOS UNARIOEste operador denota la negación del operando, y se representa por medio del signo menos ( - )colocado antes del operando.

Por ejemplo :Si x tiene asignado el valor 100, -x dará como resultado -100 ; esto es que el resultado es elinverso aditivo del operando.Los operadores BINARIOS, son los que combinan DOS OPERANDOS , dando como resultadoun valor numérico cuyo tipo será igual al mayor de los tipos que tengan los operandos.

Page 19: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

19

La siguiente tabla muestra los símbolos de los operadores binarios de Pascal así como losnombres de las operaciones que realizan.

Operadores aritméticos básicosOperador Operación Operandos Ejempl

o Resultado

+ Suma real , integer a + b suma de a y b- Resta real , integer a - b Diferencia de a y b* Multiplicación real , integer a * b Producto de a por b/ División real , integer a / b Cociente de a por bdiv División entera integer a div b Cociente entero de a por b

mod Módulo integer a modb

Resto de a por b

shl Desplazamiento a la izquierda a shl b Desplazar a la izquierda b bitsshr Desplazamiento a la derecha a shr b Desplazar a la derecha b bits

Conviene observar lo siguiente :1. Cuando los dos operandos sean del tipo integer, el resultado será de tipo integer.2. Cuando cualquiera de los dos operandos, o ambos, sean del tipo real, el resultado será de

tipo real.3. Cuando, en la operación div, OPERANDO-1 y OPERANDO-2 tienen el mismo signo, se

obtiene un resultado con signo positivo; si los operandos difieren en signo, el resultado esnegativo y el truncamiento tiene lugar hacia el cero.

Ejemplos :7 div 3 = 2(-7) div (-3) = 2(-7) div 3 = -27 div (-3) = -215.0 div 3.0 = no válido15 div (4/2) = no válidoLa operación div almacena sólo la parte entera del resultado, perdiéndose la parte fraccionaria(truncamiento).

4. La operación MODULO está definida solamente para OPERANDO-2 positivo. Elresultado se dará como el entero no negativo más pequeño que puede ser restado deOPERANDO-1 para obtener un múltiplo de OPERANDO-2 ; por ejemplo :

6 mod 3 = 07 mod 3 = 1(-6) mod 3 = 0(-7) mod 3 = -1(-5) mod 3 = -2(-15) mod (-7) = -1En la operaciones aritméticas, debe asegurarse que el resultado de sumar, restar o multiplicar dosvalores, no produzca un resultado fuera de los rangos definidos por la implementación para losdiferentes tipos.

Page 20: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

20

2.6.2 Operadores relacionalesUna RELACIÓN consiste de dos operandos separados por un operador relacional. Si la relaciónes satisfecha, el resultado tendrá un valor booleano true ; si la relación no se satisface, elresultado tendrá un valor false. Los operadores deben ser del mismo tipo, aunque los valores detipo real, integer y byte pueden combinarse como operandos en las relaciones. A continuación sedescriben los operadores relacionales utilizados en Pascal:

Símbolo Significado= IGUAL que<> NO IGUAL que< MENOR que> MAYOR que<= MENOR o IGUAL que>= MAYOR o IGUAL que

Ejemplos:Relación Resultado20 = 11 false15 < 20 truePI > 3.14 true'A' < 20 false'A' = 65 true

2.6.3 Operadores lógicosAl igual que las relaciones, en las operaciones con operadores lógicos se tienen resultados cuyovalor de verdad toma uno de los valores booleanos true o false.Los operadores lógicos en Pascal son :NOTSintaxis : not operandoDescripción : Invierte el valor de verdad de operando.Ejemplo :Si bandera tiene un valor de verdad true, not bandera produce un resultado con valor de verdadfalse.ANDSintaxis : operando.1 and operando.2Descripción : Produce un resultado con valor de verdad true cuando ambos operandos tienenvalor de verdad true; en cualquier otro caso el resultado tendrá un valor de verdad false.ORSintaxis : operando.1 or operando.2Descripción : Produce un resultado con valor de verdad false cuando ambos operadores tienenvalores de verdad false; en cualquier otro caso el resultado tendrá un valor de verdad true.XORSintaxis : operando.1 xor operando.2Descripción : Un operando debe tener valor de verdad true y el otro false para que el resultado

Page 21: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

21

tenga valor de verdad true.

Turbo Pascal también permite las siguientes operaciones entre los bits de operandosexclusivamente de tipo entero :ANDSintaxis : operando.1 and operando.2Descripción: Pone a ceros los bits de operando.2cuyos correspondientes en operando.1 estén en ceros.Los valores se pasan a binario, y, sobre cada bit de operando.1 serealiza la operación and lógica con el correspondiente bit de operando.2.Ejemplo : 29 and 30 = 28Cuya forma en binario es : 0000000000011101 = 29 (operando.1)and 0000000000011110 = 30 (operando.2) _____________________ 0000000000011100 = 28 (resultado)OR ( o inclusiva )Sintaxis : operando.1 or operando.2Descripción : Pone a uno los bits de operando.1 cuyos correspondientes bits en operando.2 estána uno.Ejemplo : 17 or 30 = 31En binario: 0000000000010001 = 17 (operando.1)or 0000000000011110 = 30 (operando.2) _____________________ 0000000000011111 = 31 (resultado)XOR ( o exclusiva )Sintaxis : operando.1 xor operando.2Descripción : Invierte el estado de los bits de operando.1, cuyos correspondientes en operando.2están a uno.Ejemplo : 103 xor 25 = 126En binario: 0000000001100111 = 103 (operando.1)xor 0000000000011001 = 25 (operando.2) ______________________ 0000000001111110 = 126 (resultado)SHLSintaxis : operando.1 shl operando.2Descripción : Desplaza hacia la izquierda los bits de operando.1, el número de posicionesestablecidas por operando.2.Los bits que salen por el extremo izquierdo se pierden.Ejemplo : 10 shl 2 = 40En binario: 0000000000001010 = 10 (operando.1)

Page 22: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

22

shl 2 <= 0000000000101000 = 40 (resultado)(operando.2)SHRSintaxis : operando.1 shr operando.2Descripción : Desplaza hacia la derecha los bits de operando.1 el número de posicionesestablecidas por operando.2.Los bits que salen por el extremo derecho se pierdenEjemplo : 125 shr 3 = 15En binario : 0000000001111101 = 125 (operando.1)shr 3 => 0000000000001111 = 15 (resultado)(operando.2)

2.7 ExpresionesLas expresiones son secuencias de constantes y/o variables separadas por operadores válidos.Se puede construir una expresión válida por medio de :

1. Una sola constante o variable, la cual puede estar precedida por un signo + ó - .2. Una secuencia de términos (constantes, variables, funciones) separados por operadores.

Además debe considerarse que:Toda variable utilizada en una expresión debe tener un valor almacenado para que la expresión,al ser evaluada, dé como resultado un valor.Cualquier constante o variable puede ser reemplazada por una llamada a una función.Como en las expresiones matemáticas, una expresión en Pascal se evalúa de acuerdo a laprecedencia de operadores. La siguiente tabla muestra la precedencia de los operadores enTurbo Pascal:

Precedencia de operadores5 - (Menos unario)4 not3 * / div mod and shl shr2 + - or xor1 = <> > < >= <=

Las reglas de evaluación para las expresiones son :1. Si todos los operadores en una expresión tienen la misma precedencia, la evaluación de

las operaciones se realiza de izquierda a derecha.2. Cuando los operadores sean de diferentes precedencias, se evalúan primero las

operaciones de más alta precedencia (en una base de izquierda a derecha ), luego seevalúan las de precedencia siguiente, y así sucesivamente.

3. Las reglas 1) y 2) pueden ser anuladas por la inclusión de paréntesis en una expresión.Ejemplos :

1. 3 + 2*5 {*,+}4 + 10 =14

2. 20*4 div 5{Igual prioridad de izquierda a derecha : *,div}

Page 23: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

23

80 div 5 = 163. 3 - 5 * (20+(6/2))

3 - 5 * (20+(6/2)) = 3 - 5 * (20 + 3){paréntesis más interno}= 3 - 5 * 23 {segundo paréntesis}= 3 - 115 {Multiplicación}= -112 {resta}

2.8 Instrucciones

Aunque un programa en Pascal puede contar con una sola instrucción (también llamadaenunciado, sentencia o estatuto), normalmente incluye una cantidad considerable de ellas. Unode los tipos de instrucciones más importantes lo forman las instrucciones de asignación; lascuales asignan a una variable (por medio del símbolo := ) , el resultado de la evaluación de unaexpresión.La sintaxis para las instrucciones de asignación es :identificador := expresión ;Al símbolo := le llamaremos, en lo sucesivo : "simbolo de asignación"Los siguientes son ejemplos de instrucciones de asignacion :numero := 100 ;importe := precio * cantidad ;hipotenusa := sqrt(sqr(cateto_op)+sqr(cateto_ad ));Es posible construir una instrucción vacía escribiendo sólamente el punto y coma de unainstrucción.Así podemos escribir :valor := valor + 1;;Lo que incluye las dos instrucciones :valor := valor + 1;y la instrucción vacía : ;

Bloques de instrucciones

En todo lugar donde sea válido utilizar una instrucción simple, es posible utilizar una instruccióncompuesta o bloque de instrucciones, el cual se forma agrupando varias instrucciones simplespor medio de los identificadores begin y end.Por ejemplo:begin suma := 1000.0; incr := 20.0; total := suma + incr {Obsérvese la ausencia de punto y coma al final de la instrucción}end.No es necesario escribir el punto y coma antes de end ya que el punto y coma se usa para separarinstrucciones, no para terminarlas.begin y end son delimitadores de bloque.

Page 24: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

24

3.1 Procedimientos de entrada / salida

Desde el punto de vista del hardware, las instrucciones de entrada y salida le ayudan alprograma a comunicarse con un periférico de la computadora tal como una terminal, unaimpresora o un disco.Las instrucciones de entrada estándar, sirven para leer carácteres desde el teclado, y lasinstrucciones de salida estándar despliegan carácteres en la pantalla.En Pascal todas las operaciones de entrada/salida se realizan ejecutando unidades de programaespeciales denominados procedimientos de entrada/salida que forman parte del compilador y susnombres son identificadores estándar:Procedimientos de entrada Read ReadLnProcedimientos de salida Write WriteLn

3.2 Procedimientos Read y ReadlnLos procedimientos predefinidos Read y ReadLn (contracción de Read Line), constituyen la basepara las instrucciones de entrada estándar.Las instrucciones de entrada proporcionan datos durante la ejecución de un programa. Lasinstrucciones para llamar a los procedimientos Read y ReadLn son de la siguiente forma :

Read(lista_de_variables);ReadLn(lista_de_variables);

donde :lista_de_variables : es una lista de identificadores de variables separados por comas, los datosque se pueden leer son :reales, enteros, caracteres, o cadenas. No se puede leer un boolean o unelemento de tipo enumerado.Los datos estructurados , arrays, registros o conjuntos, no se pueden leer globalmente y se suelerecurrir a diseñar procedimientos específicos.La acción de la instrucción es obtener, del teclado, tantos valores de datos como elementos hayen lista_de_variables. Los datos deberán ser compatibles con los tipos de las variablescorrespondientes en la lista.Cada valor entero o real en el flujo de entrada puede ser representado como una secuencia decaracteres en alguna de las formas permitidas para tales números, y puede estar inmediatamenteprecedido por un signo más o un signo menos. Cada valor entero o real puede ser precedido porcualquier cantidad de caracteres blancos o fines de línea, pero no deberá haber blancos o fines delínea entre el signo y el número.La diferencia entre las instrucciones Read y ReadLn consiste en que Read permite que lasiguiente instrucción continúe leyendo valores en la misma línea; mientras que, con ReadLn lasiguiente lectura se hará después de que se haya tecleado el carácter de fin de línea.Cuando se tienen datos de tipo char en una instrucción Read, los caracteres blancos y los de finde línea son considerados en el conteo de los elementos de las cadenas de caracteres mientras nose complete el total especificado para cada una de ellas. Cada fin de línea es tratado como uncarácter, pero el valor asignado a la variable será un carácter blanco.Es aconsejable que cada cadena de caracteres se lea en una instrucción Read o ReadLn porseparado, para evitar el tener que ir contando hasta completar la cantidad exacta de caracteres

Page 25: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

25

que forman la cadena ( o de lo contrario se tendrán resultados sorpresivos y frustrantes alverificar los datos leídos ).Ejemplo:Var nombre :string[30] ; edad :integer; estatura :real; . . . ReadLn(nombre); ReadLn(edad); ReadLn(estatura);

3.3 Procedimientos Write Y Writeln

La salida estándar se realiza en base a estos procedimientos predefinidos, y las instrucciones parainvocarlos toman las siguientes formas :

Write(lista_de_salida);WriteLn(lista_de_salida);

donde :lista_de_salida es una lista de variables, expresiones y/o constantes, cuyos valores van a serdesplegados en la pantalla.El procedimiento Write permite que la siguiente instrucción se realice en la misma línea ,mientras que WriteLn alimenta una nueva línea, antes de finalizar.Por ejemplo, las instrucciones :Write ('! HOLA ');WriteLn('AMIGOS !');producirán la salida :

! HOLA AMIGOS ! cursor en la siguiente línea.Mientras que :Write('TECLEE <CTRL> F PARA FINALIZAR ==> ');desplegará :TECLEE <CTRL> F PARA FINALIZAR ==> CURSORPara producir un renglón en blanco, se debe escribir :WriteLn ;Un valor booleano desplegará cualquiera de las cadenas : TRUE o FALSE,así :Write('20 + 30 = ', 20 + 30 ,' ES ', 20 + 30 = 50);producirá :

20 + 30 = 50 ES TRUE dejando el cursor en la misma línea, al final de TRUE.

Page 26: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

26

Cuando un valor de salida se escribe sin una especificación de longitud de campo, se utilizará laespecificación de campo por omisión.La especificación de longitud de campo por omisión dependerá del tipo de valor de salida y de laimplementación de Pascal.Así tenemos que, para todas las implementaciones :

1. La especificación de longitud de campo por omisión para los valores de tipo char es 12. Si el valor a ser desplegado requiere menos del número de caracteres especificado, se

imprimirán tantos caracteres blancos como sean necesarios para completar dicho número.3. Si el valor a ser desplegado requiere un número de caracteres mayor que el especificado,

se usa la mínima especificación de longitud de campo que se requiera para representar unvalor de tipo real o entero, pero las cadenas serán truncadas ajustándolas al campoespecificado y desechará los caracteres en exceso que se encuentren más a la derecha.

4. En el caso de valores de tipo real, se puede utilizar una especificación de longitud defracción.

Por omisión en Turbo Pascal, los valores de tipo real se desplegarán en formato de punto flotante(también llamado exponencial), así :

a. Para el caso de valores positivos ( R >= 0.0 ), el formato es: bbn.nnnnnnnnnnEsnn

b. Para valores negativos ( R < 0.0 ), el formato es : b-n.nnnnnnnnnnEsnndonde :b = blancon = número ( 1-9 )s = signo ( + ó - )E = letra "E" para exponenteLa especificación de campo mínima aceptada es :

• para R >= 0.0 , SIETE caracteres.• para R < 0.0 , OCHO caracteres.

Ejemplos:Sentencias ResultadosWriteLn ('Hola Mundo'); Hola MundoWriteLn('22' + '20'); 2220WriteLn(pi); 3.1415926536E+00WriteLn(3.0); 3.0000000000E+00

Debido a que Pascal alinea (justifica) las impresiones hacia la derecha del campocorrespondiente, cuando es necesario acomodar tabularmente los caracteres de cadenas que noocupan la totalidad de columnas especificadas.Por ejemplo, suponiendo que nombre es un identificador de tipo string[20] (cadena con formatode 20 caracteres), para que la impresión de todos los valores de nombre empiece en la mismacolumna, podemos utilizar la instrucción :WriteLn(numero,'.- ',nombre,' ':20- length(nombre),calif:3);y, al ejecutar el programa se tendrá algo parecido a :

Page 27: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

27

1.- JUAN FLORES 90(Nótese la justificación de los nombres2.- EGRID L. CASTRO 100hacia la izquierda y los números hacia3.- RAMON RAMIREZ 99la derecha)

Formatos de salida

Formato 1 : WriteLn (ítem:anchura...);Anchura: Expresión entera (literal, constante, variable o llamada a función) queespecifíca la anchura total del campo en que se escribe ítem.

Formato 2 : WriteLn (ítem:anchura:dígitos ...);Dígitos: dígitos decimales de un número realAnchura: Total de dígitos del número real contando parte entera, punto decimal ydígitos decimales.

Ejemplos:Valor:= 25.0776;Sentencias Resultados ComentarioWriteLn (Valor); 2.5077600000E+01WriteLn(Valor:2); 2.5E+01WriteLn(Valor:2:1); 25.1 Notese el redondeoWriteLn(Valor:2:4); 25.0776WriteLn(Valor:2:8); 25.07760000WriteLn('Tec':1); TecWriteLn('Tec':3); TecWriteLn('Tec':5); _ _ Tec Espacios vacios _

4.1 SecuenciaEn este caso, las instrucciones se ejecutan una después de la otra sin omitir ninguna de ellas.La sintaxis para las instrucciones ejecutadas en secuencia es :

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

................<instrucción.1> ;<instrucción.2> ;................................<instrucción.N> ;................................

4.2 SelecciónLa selección de alternativas en Pascal se realiza con alguna de las dos siguientes formas :4.2.1 IF-THEN-ELSE

Page 28: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

28

Dado que una condición produce un valor verdadero o falso, se necesita una sentencia de controlque ejecute determinada sentencia si la condición es verdadera , y otra si es falsa. En Pascal estaalternativa se realiza con la sentencia IF-THEN-ELSE. A continuación se describe el diagramade flujo y el formato de la sentencia.

Formatos de la sentencia IF:

if <condición> then<instrucción_1> else<instrucción_2>

En este caso, primero se evalúa condición y si el resultado arroja un valor de verdad(verdadero),se ejecuta instrucción_1 ; en caso contrario se ejecuta instrucción_2.

La condición es una expresión Booleana que puede ser verdadera o falsa (true o false). Unaexpresión Booleana se forma comparando valores de las expresiones utilizando operadores derelación (relacionales) o comparación y los operadores lógicos vistos anteriormente.

Ejemplos :

Omisión de cláusula else :Program Edades;Uses Crt;Var edad : integer ;begin WriteLn('Escribe tu edad : ');

Page 29: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

29

ReadLn(edad); if edad >= 18 then WriteLn('!Eres Mayor de edad !'); WriteLn('Esta instrucción siempre se ejecuta'); ReadKeyend.Nota: Antes de la palabra end no se debe anteponer un punto y comacomo se muestra en este ejemplo. El hacerlo generaria una sentenciavacia (sentencia que no hace nada).

Utilización de cláusula else :Program Edades;Uses Crt;Var edad : integer ;begin WriteLn('Escribe tu edad : ') ; ReadLn(edad) ; if edad >= 18 then WriteLn('!Eres Mayor de edad !') else WriteLn('!Eres Menor de edad !'); WriteLn('Esta instrucción siempre se ejecuta'); ReadKeyend.Nota: Antes de la cláusula else no se antepone un punto y coma, si lo hubiese el compiladorproducirá un mensaje de error, puesto que no existe ninguna sentencia en Pascal que comiencecon else. La parte else es opcional, pero la ejecución siempre continuará en otra instrucción.

En lugar de utilizar instrucciones simples, se pueden usar bloques de instrucciones, comoacontinuación se muestra :

Program Edades;Uses Crt;Var edad : integer ;begin WriteLn('Escribe tu edad : ') ; ReadLn(edad) ; if edad >= 18 then begin WriteLn('!Eres Mayor de edad !');

Page 30: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

30

WriteLn('!Ya puedes Votar!') end else begin WriteLn('!Eres Menor de edad !'); WriteLn('!Aún no puedes votar!') end; WriteLn('Esta instrucción siempre se ejecuta'); ReadKeyend.

Sentencia IF anidadas :Program NumMayor;Uses Crt;Var n1,n2,n3,mayor : integer ;begin WriteLn('Escribe tres numeros enteros : '); ReadLn(n1,n2,n3); if n1>n2 then if n1>n3 then mayor:=n1 else mayor:=n3 else if n2>n3 then mayor:=n2 else mayor:=n3; WriteLn('El mayor es ',mayor); ReadKeyend

4.2.2 CASE-OF-ELSEEsta forma es muy útil cuando se tiene que elegir entre más de dos opciones, por lo que lellamaremos forma de selección múltiple.

Page 31: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

31

La siguiente figura representa la selección múltiple.

Su formato es :

case <selector> of constante.1 : begin <instrucciones>; end;

constante.2 : begin <instrucciones> ; end; ..................... .....................

constante.N : begin <instrucciones> ; end else begin <instrucciones> ;

Page 32: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

32

end;end; { FIN DE CASE }

Dependiendo del valor que tenga la expresión selector, se ejecutarán las instruccionesetiquetadas por constante .

Aquí también los bloques de instrucciones pueden ser reemplazados por instrucciones simples.

Conviene tener presente que no debe escribirse punto y coma antes de la palabra else.

Reglas:

La expresión <selector> se evalúa y se compara con las constantes;las constantes son listas deuno o más posibles valores de <selector> separados por comas. Ejecutadas la(s) <instrucciones>,el control se pasa a la primera instrucción a continuación de end (fin de case).

La cláusula else es opcional.

Si el valor de <selector> no está comprendido en ninguna lista de constantes y no existe lacláusula else, no sucede nada y sigue el flujo del programa; si existe la cláusula else se ejecutanla(s) <instrucciones> a continuación de la cláusula else.

El selector debe ser un tipo ordinal ( integer, char, boolean o enumerado). Los números reales nopueden ser utilizados ya que no son ordinales. Los valores ordinales de los límites inferiores ysuperiores deben de estar dentro del rango -32768 a 32767. Por consiguiente, los tipos string,longint y word no son válidos.

Todas las constantes case deben ser únicas y de un tipo ordinal compatible con el tipo delselector.

Cada sentencia, excepto la última, deben ir seguidas del punto y coma.Ejemplo:

Program Tecla;{El siguiente programa lee un carácter del teclado y despliega un mensaje en pantalla si es letra o número o carácter especial}Uses Crt;Var caracter : char;begin Write('Escribe un caracter : ');

Page 33: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

33

caracter:=ReadKey;WriteLn; case caracter of '0'..'9' : WriteLn('Es un número'); 'a'..'z','A'..'Z' : WriteLn('Es una letra') else WriteLn('Es un caracter especial') end; ReadKeyend.

4.3 IteraciónLas formas de iteración sirven para ejecutar ciclos repetidamente, dependiendo de que secumplan ciertas condiciones. Una estructura de control que permite la repetición de una seriedeterminada de sentencias se denomina bucle1 (lazo o ciclo).

El cuerpo del bucle contiene las sentencias que se repiten. Pascal proporciona tres estructuras osentencias de control para especificar la repetición:

4.3.1 WHILE-DOLa estructura repetitiva while(mientras) es aquella en la que el número de iteraciones no seconoce por anticipado y el cuerpo del bucle se ejecuta repetidamente mientras que una condiciónsea verdadera .

Su formato es :

while <condición> do begin <instrucciones>; end;

y su diagrama :

Page 34: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

34

Reglas de funcionamiento:

La condición se evalúa antes y después de cada ejecución del bucle. Si la condición es verdadera,se ejecuta el bucle, y si es falsa, el control pasa a la sentencia siguiente al bucle.

Si la condición se evalúa a falso cuando se ejecuta el bucle por primera vez, el cuerpo del bucleno se ejecutará nunca.

Mientras la condición sea verdadera el bucle se ejecutará. Esto significa que el bucle se ejecutaráindefinidamente a menos que "algo" en el interior del bucle modifique la condición haciendo quesu valor pase a falso. Si la expresión nunca cambia de valor, entonces el bucle no termina nuncay se denomina bucle infinito lo cual no es deseable.

ejemplos:

Program Ej_While;Uses Crt; {El siguiente programa captura una cadena, hasta que se presione la tecla Esc(escape), cuyo ordinal es el #27.}Const Esc = #27;Var nombre : string[30]; tecla : char; cont : word;begin ClrScr; cont:=1; While (tecla<>Esc) do begin Write(cont,' Nombre : '); ReadLn(nombre); inc(cont); tecla:=ReadKey endend

4.3.2 REPEAT-UNTILLa acción de repeat-until es repetir una serie de instrucciones hasta que se cumpla unadeterminada condición .

Page 35: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

35

Su formato es :

repeat <instrucción.1> ; <instrucción.2> ; .................. .................. <instrucción.N> ; until <condición>;

Aquí las palabras repeat y until sirven también como delimitadores de bloque.

Su diagrama de flujo es :

Reglas de funcionamiento:

La condición se evalúa al final del bucle, después de ejecutarse todas las sentencias.

Si la condición es falsa, se vuelve a repetir el bucle y se ejecutan todas sus instrucciones.

Si la condición es falsa, se sale del bucle y se ejecuta la siguiente instrucción a until.

La sintaxis no requiere begin y end.Analícense los diagramas de while-do y repeat-until, para comprender las diferencias entreambas formas.

Page 36: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

36

Ejemplo:

Program Ej_Repeat;Uses Crt; {El siguiente programa captura una cadena, hasta que se presione la tecla Esc(escape), cuyo ordinal es el #27.}Const Esc = #27;Var nombre: string[30]; tecla : char; cont : word;begin ClrScr; cont:=1; Repeat Write(cont,' Nombre : '); ReadLn(nombre); inc(cont); tecla:=ReadKey Until (tecla=Esc)end.

4.3.3 FOR-TO-DO

Cuando se sabe de antemano el número de veces que deberá ejecutarse un ciclo determinado,ésta es la forma más conveniente.

El formato para for-to-do es :

for <contador>:=<expresión.1> to <expresión.2> do begin <instrucciones> ; end;

Al ejecutarse la sentencia for la primera vez, a contador se le asigna un valor inicial(expresion.1),y a continuación se ejecutan las intrucciones del interior del bucle, enseguida se verifica si elvalor final (expresión.2) es mayor que el valor inicial (expresión.1); en caso de no ser así seincrementa contador en uno y se vuelven a ejecutar las instrucciones, hasta que el contador seamayor que el valor final, en cuyo momento se termina el bucle.

Page 37: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

37

Aquí, contador no puede ser de tipo real.

Ejemplo:

Program Ej_For;Uses Crt; {El siguiente programa despliega en pantalla el numero de veces que se ejecuta las instrucciones contenidas en el bucle for}Var Valor_final,contador : integer;Begin ClrScr; Write('Escribe el número de iteraciones : '); ReadLn(valor_final); for contador:=1 to valor_final do WriteLn('Iteración : ',contador); ReadKeyend.

El contador se puede decrementar sustituyendo la palabra to por la palabra downto.

Formato:

for <contador>:=<expresión.1> downto <expresión.2> do begin <instrucciones> ; end;

Ejemplo:

Program Ej_Downto;Uses Crt; {El siguiente programa despliega en pantalla el numero de veces que se ejecuta las instrucciones contenidas en el bucle for}Var Valor_final,contador : integer;Begin ClrScr; Write('Escribe el número de iteraciones : '); ReadLn(valor_final); for contador:=valor_final downto 1 do WriteLn('Iteración : ',contador);

Page 38: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

38

ReadKeyend.

5.1 Tipos de datosPascal requiere que todos los tipos de datos sean formalmente definidos antes de ser utilizados,ya que tal definición será usada por el compilador para determinar cuanto espacio de memoria sereservará para las variables de cada tipo, así como para establecer los límites de los valores quepueden asignarse a cada variable, por lo que estableceremos las siguientes reglas generales paralos diferentes tipos de datos que se utilizan en Pascal:Cada variable debe tener un solo tipo en el bloque donde fue declarada.El tipo de cada variable debe ser declarado antes de que la variable sea utilizada en unainstrucción ejecutable.A cada tipo de dato se le pueden aplicar ciertos operadores específicos.Para facilitar su estudio, hemos clasificado a los tipos de datos que pueden ser definidos por elprogramador en SIMPLES y ESTRUCTURADOS.

5.2 Tipos simplesHasta aquí, hemos considerado los tipos simples estándar integer, real, boolean, char y byteproporcionados por Turbo Pascal.

Estos tipos de datos pueden ser utilizados para declarar variables numéricas, de caracteres y/ológicas. Sin embargo, es posible que ninguno de ellos satisfaga los requerimientos de undeterminado problema, haciéndose necesaria la utilización de otros tipos como:

TIPO SUBRANGOEl tipo de dato más simple que se puede definir en un programa Pascal es el tipo subrango ointervalo. Estos tipos son útiles, sobre todo por la facilidad que ofrecen para verificarautomáticamente errores. Un tipo subrango se define de un tipo ordinal, especificando dosconstantes de ese tipo, que actúan como límite inferior y superior del conjunto de datos de esetipo. Un tipo subrango es un tipo ordinal y sus valores se ordenan de igual modo que en el tipopatrón de que se deducen.

Ejemplos:

1. 0..9 este tipo subrango consta de los elementos0,1,2,3,4,5,6,7,8,9

2. '0'..'9' este subrango consta de los caracteres'0' a '9'

3. 'A'..'F'

Page 39: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

39

este subrango consta de los caracteres'A' a 'F'

Se pueden crear variables cuyos valores se restrinjan a un subrango dado. Las declaraciones detipo subrango se sitúan entre las declaraciones de constantes y de variables.

Formato:

type Nombre = límite inferior .. límite superior

Ejemplos:

{$R+} {Directiva de compilador R}Program Positivos;Uses Crt; {El siguiente programa realiza una validación para que sólo se acepten valores positivos entre 0 y 32767 por medio de un tipo subrango}Type NumPositivo = 0..MaxInt;Var numero : NumPositivo;Begin ClrScr; {numero:=-1; (está instrucción provocaría un error} Write('Escribe un número entero positivo : '); ReadLn(numero); ReadKeyend.

Nota: Puesto que Turbo Pascal no siempre produce un error cuando el valor de un tipo subrangoestá fuera de su rango definido. Sin embargo se puede tener la posibilidad de visualizar dichoserrores mediante la directiva de compilador:

{$R+} activada{$R-} desactivadaPor default esta desactivada. Sólo se debe usar durante la fase de depuración.

TIPOS ENUMERADOSEn estos tipos de datos simples, se listan los identificadores que serán asociados con cada valor autilizar.

Page 40: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

40

Por ejemplo :

Type dias_semana =(lunes,martes,miercoles,jueves, viernes,sabado,domingo); colores_baraja =(espada,oro,basto,copa);De igual forma las variables pueden ser de tipo enumerado:

Var dias : dias_semana; baraja : colores_baraja;

Formato:

Type nombre = (constante1,constante2,...,constanteN)

Los datos de tipo colores_baraja sólo podrán tomar los valores denotados por : espada, oro,basto, copa . La posición de cada valor en la lista define su orden, por lo que para el tipodias_semana tenemos que :

domingo > viernes da como resultado truesabado < martes da como resultado falsejueves <> miercoles da como resultado true

Características:

Un tipo de dato enumerado es un tipo ordinal cuyo orden se indica por la disposición de losvalores en la definición.

El número de orden de cada elemento comienza en 0 para el primer elemento.

Las variables de tipo enumerado sólo pueden tomar valores de estos tipos.

Los únicos operadores que pueden acompañar a los tipos ordinales son los operadores derelación y asignación.

A los valores de los tipos enumerados se les pueden aplicar las funciones estándar succ (desucesor), pred (de predecesor) y ord (de ordinal).

Page 41: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

41

En el caso del valor máximo de un tipo enumerado, succ no está definido, y, para su valormínimo, no está definido pred.

La función estándar ord es aplicable a los argumentos que sean valores de tipo enumerado. Larelación biunívoca se da entre los valores del tipo y los enteros comprendidos entre 0 y N-1,donde N es la cardinalidad del tipo enumerado.

El tipo estándar boolean es equivalente a un tipo enumerado de la forma :

boolean = ( false, true);

Aplicación de las funciones Ord, Pred, Succ

Argumento(x) Tipos de datos Ord(x) Pred(x) Succ(x)lunes dias_semana 0 Indefinido martesoro colores_baraja 1 espada basto22 Integer 22 21 230 Integer 0 -1 1-20 Integer -20 -21 -19MaxInt Integer MaxInt MaxInt-1 IndefinidoFalse Lógico 0 Indefinido true

Ejemplo:

Program Dias_Semana;Uses Crt; {El siguiente programa muestra los dias de la semana por medio de tipos enumerados}Type Dia_Semana = (Lunes,Martes,Miercoles,Jueves, Viernes,Sabado,Domingo);Var dias :Dia_Semana; i :byte;Begin ClrScr; dias:=lunes; for i:=1 to 7 do begin case dias of Lunes :WriteLn('Lunes '); Martes :WriteLn('Martes '); Miercoles :WriteLn('Miercoles'); Jueves :WriteLn('Jueves '); Viernes :WriteLn('Viernes '); Sabado :WriteLn('Sabado ');

Page 42: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

42

Domingo :WriteLn('Domingo ') end; dias:=succ(dias) end; ReadKeyend.

5.3 Tipos estructuradosEn Pascal, se pueden definir , a partir de los datos simples, otros tipos más complejos conocidoscomo tipos estructurados.

Cuando se declara una variable como de un tipo estructurado, se puede manipular la estructuracompleta, o bien trabajar con los datos individuales que la forman.

A continuación, se describirán los diferentes tipos estructurados que pueden manejarse en Pascal.

5.3.1 Cadenas (strings)Turbo Pascal proporciona el tipo string para el procesamiento de cadenas (secuencias decaracteres ).

La definición de un tipo string debe especificar el número máximo de caracteres que puedecontener, esto es, la máxima longitud para las cadenas de ese tipo. La longitud se especifíca poruna constante entera en el rango de 1 a 255.

El formato para definir un tipo string es :

<identificador> = string [limite_superior];

Las variables de cadena se declaran en la sección Var o Type.

Declaración en Var:

Var nombre : string[30]; domicilio : string[30]; ciudad : string[40];Declaración en Type:

Type cad30 : string[30]; cad40 : string[40];Var nombre : cad30; domicilio : cad30;

Page 43: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

43

ciudad : cad40;Una Vez declaradas las variables se pueden realizar asignaciones u operaciones delectura/escritura.

nombre := 'Egrid Lorely Castro Gonzalez' ;domicilio := 'Altamirano #220';ciudad := 'La Paz B.C.S.';

El contenido de la cadena se debe encerrar entre apóstrofes. Si se desea que figure un apóstrofeen una cadena, es preciso doblarlo en la cadena. Los procedimientos de Entrada/Salida son de lasiguiente forma :

ReadLn (nombre);WriteLn('Hola ',nombre);

Longitud de una cadenaLas variables de tipo cadena pueden ocupar la máxima longitud definida, más un octeto quecontiene la longitud actual de la variable. Los caracteres que forman la cadena son numeradosdesde 1 hasta la longitud de la cadena.

Ejemplo:

Var nombre : string[10];begin nombre := 'Susana';end.

Obsérvese que el primer byte no es el carácter '6' si no el número 6 en binario (0000 0110) y losúltimos bytes de la cadena hasta 10 (7-10) contienen datos aleatorios.

Una cadena en Turbo Pascal tiene dos longitudes :

Page 44: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

44

Longitud física : Es la cantidad de memoria que ocupa realmente, está se establece en tiempo decompilación y nunca cambia

Longitud lógica : Es el número de caracteres almacenados actualmente en la varible cadena. Estedato puede cambiar durante la ejecución del programa.Es posible acceder a posiciones individuales dentro de una variable cadena, mediante lautilización de corchetes que dentro de ellos se especifíca el número indice dentro de la cadena autilizar así para el ejemplo anterior se tiene :

nombre[1] ==> 'S'nombre[2] ==> 'u'nombre[3] ==> 's'nombre[4] ==> 'a'nombre[5] ==> 'n'nombre[6] ==> 'a'

Operaciones entre cadenasLas operaciones básicas entre cadenas son : asignación, comparación y concatenación. Es posibleasignar una cadena a otra cadena, incluso aunque sea de longitud física más pequeña en cuyocaso ocurriría un truncamiento de la cadena.

Ejemplo:

Var nombre : String[21]; . . . nombre := 'Instituto Tecnológico de La Paz';El resultado de la asignación en la variable nombre será la cadena'Instituto Tecnológico'.

Las comparaciones de las cadenas de caracteres se hacen según el orden de los caracteres en elcódigo ASCII y con los operadores de relación.

'0' < '1' '2' > '1' 'A' < 'B' 'm' > 'l'Reglas de comparación de cadenasLas dos cadenas se comparan de izquierda a derecha hasta que se encuentran dos caracteresdiferentes. El orden de las dos cadenas es el que corresponde al orden de los dos caracteresdiferentes. Si las dos cadenas son iguales pero una de ella es más corta que la otra, entonces lamás corta es menor que la más larga.

Page 45: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

45

Ejemplo :

'Alex' > 'Alas'{puesto que 'e' > 'a'}'ADAN' < 'adan'{puesto que 'A' < 'a'}'Damian' < 'Damiana'{'Damian' tiene menos caracteres que 'Damiana'}'El gato' < 'Los gatos'{puesto que (blanco) < 's'}Otra operación básica es la concatenación. La concatenación es un proceso de combinar dos omás cadenas en una sola cadena. El signo + se puede usar para concatenar cadenas ( al igual quela función concat ), debiendo cuidarse que la longitud del resultado no sea mayor que 255.

Ejemplos :

'INSTITUTO '+'TECNOLOGICO'='INSTITUTO TECNOLOGICO''CONTAB'+'.'+'PAS'= 'CONTAB.PAS'

Se puede asignar el valor de una expresión de cadena a una variable cadena, por ejemplo :

fecha := 'lunes';y utilizar la variable fecha en :

frase:='El próximo '+fecha+' inician las clases';Si la longitud máxima de una cadena es excedida, se pierden los caracteres sobrantes a laderecha. Por ejemplo, si fecha hubiera sido declarada del tipo string[7], después de la asignacióncontendría los siete primeros caracteres de la izquierda (CENTENA).

PROCEDIMIENTOS Y FUNCIONES DE CADENA INTERNOSTurbo Pascal incorpora las siguientes funciones y procedimientos para el tratamiento de cadenas.

Procedimientos y funciones de cadenaProcedimiento FunciónDelete ConcatInsert CopyStr LengthVal Pos

Procedimiento DeleteDelete borra o elimina una subcadena de una cadena contenida en otra cadena de mayor longitud.

Page 46: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

46

Formato :

Delete (s, posición, número)

S Cadena original o fuentePosición Expresión entera que indica la posición del primer carácter a suprimir.Número Cantidad de caracteres a suprimir.

Si posición es mayor que la longitud de la cadena, no se borra ningún carácter. Si númeroespecifíca más caracteres que los existentes desde la posición inicial hasta el final de la cadena,sólo se borran tantos caracteres como estén en la cadena.

Ejemplo :

Cad := 'Tecnológico'Delete(cad,1,5)Resulta la cadena 'lógico'

Procedimiento Insert

Insert inserta una subcadena en una cadena.

Formato :

Insert (cad1, s, posición)

cad1 cadena a insertars cadena donde se insertaposición carácter a partir del cual se inserta

Ejemplo:

cad:= 'México 'Insert (' lindo y querido',cad,7)Resulta 'México lindo y querido'

Procedimiento Str

Este procedimiento efectúa la conversión de un valor númerico en una cadena.

Page 47: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

47

Formato :

Str (valor,s)

Valor expresión númericas cadena

Ejemplos :

Numero := 235.55; Str(Numero,cadena); Write(cadena); Resulta la cadena '2.355000000E+02' Numero := 12345; Str(Numero,cadena); Write(cadena); Resulta la cadena '12345' Numero := 12345; Str(Numero+1000:10,cadena); Write(cadena); Resulta la cadena ' 13345'

Procedimiento Val

Este procedimiento convierte una cadena en variable númerica. Para que esta conversión seaefectiva, el contenido de la cadena de caracteres debe corresponderse a las reglas de escritura denúmeros: no debe de existir ningún blanco en la primera o última posición.

Formato:

Val (S, variable, código)

S : cadenaVariable : variable de tipo entero o realcódigo : si la conversión ha podido ser efectuada toma el valor cero; en caso contrariocontiene la primera posición del primer carácter de la cadena S que impide la conversión y enese caso variable no queda definida

Ejemplo:

Var cad : string[10]; num1,codigo : integer;

Page 48: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

48

num2 : real;begin cad:='22.25'; Val(cad,num2,codigo); if codigo=0 then WriteLn(num2:2:2) {Produce 22.25} else WriteLn(codigo); cad:='12x45'; Val(cad,num1,codigo); if codigo=0 then WriteLn(num1) else WriteLn(codigo) {Produce 3}end.

Función Concat

Además del uso de '+' para la concatenación, Turbo Pascal tiene la función concat que permiteconcatenar una secuencia de caracteres.

Formato:

Concat (S1,S2,...,Sn)

S1,S2...cadenas o variables de caracteres (expresión tipo cadena)Ejemplo :

Var cad1,cad2 : string[20]; destino : string[50];begin cad1:='Hola como '; cad2:='Estas '; destino:=Concat(cad1,cad2,', estoy bien')end.

Esto produce una cadena destino igual a 'Hola como estas, estoy bien'

Page 49: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

49

Función CopyEsta función devuelve una cadena de caracteres (subcadena) extraída de una cadena.

Formato:

Copy(s,posición,número)

s : cadena (fuente)posición: primer carácter a extraer (tipo entero)número : total de caracteres a extraer (tipo entero)

Si posición es mayor que la longitud de S, se devuelve una cadena vacía; si número especifícamás caracteres que los indicados desde posición, sólo se devuelve el resto de la cadena.

Ejemplo:

cad := 'Instituto Tecnológico de La Paz';cad2 := Copy(cad,26,6);Write(cad2);

Lo que produce la cadena 'La Paz' contenida en cad2.

Función Lenght (longitud)

La función Lenght proporciona la longitud lógica de una cadena de caracteres y devuelve unvalor entero.

Formato :

Length (s)

s expresión tipo cadenaEjemplo :

Var cad : string[20];begin cad:='Hola'; WriteLn(Length ('Hola como estas')); {devuelve el valor 15} WriteLn(Length ('')); {devuelve cero (cadena vacía)} WriteLn(Length (cad)); {devuelve el valor 4}

Page 50: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

50

WriteLn(Ord(cad[0])) {devuelve el valor 4}end.

Función Pos

Esta función permite determinar si una cadena está contenida en otra. En este caso, la funcióndevuelve la posición donde comienza la cadena buscada en la cadena fuente, si la cadena noexiste, se devuelve el resultado 0.

Formato :

Pos (cadena buscada, cadena fuente)

Ejemplo:

cad:= 'uno dos tres cuatro cinco seis';WriteLn(Pos('dos',cad));{Resulta 5 que es la posición de 'd'}WriteLn(Pos('ocho',cad));{Resulta 0 no existe la cadena 'ocho'}

5.3.2 Arreglos (array)Un arreglo está formado por un número fijo de elementos contíguos de un mismo tipo. Al tipo sele llama tipo base del arreglo. Los datos individuales se llaman elementos del arreglo.

Para definir un tipo estructurado arreglo, se debe especificar el tipo base y el número deelementos.

Un array se caracteriza por :

Almacenar los elementos del array en posiciones de memoria contínua

Tener un único nombre de variable que representa a todos los elementos, y éstos a su vez sediferencían por un índice o subíndice.

Acceso directo o aleatorio a los elementos individuales del array.

Los arrays se clasifican en :

Unidimensionales (vectores o listas)

Multidimensionales ( tablas o matrices)

Page 51: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

51

El formato para definir un tipo array es :

nombre_array = array [tipo subíndice] of tipo

nombre_array : identificador válidotipo subíndice puede ser de tipo ordinal: boolean o char, un tipo enumerado o un tipo subrango. Existe un elemento por cada valor del tipo subíndicetipo describe el tipo de cada elemento del vector; todos los elementos de un vector son del mismo tipo

Las variables de tipo array se declaran en la sección Var o Type.

Declaración en Var:

Var nombres : array[1..30] of string[30]; calif : array[1..30] of real; numero : array[0..100] of 1..100;Declaración en Type:

Type nombres : array[1..30] of string[30]; calif : array[1..30] of real; numero : array[0..100] of 1..100;Var nom : nombres; califica : calif; num : numero;

Arrays unidimensionalesUn array de una dimensión (vector o lista) es un tipo de datos estructurado compuesto de unnúmero de elementos finitos, tamaño fijo y elementos homogéneos.

Supongamos que desea conservar las edades de 10 personas. Para almacenar estas edades senecesita reservar 10 posiciones de memoria, darle un nombre al array, y a cada persona asignarle

Page 52: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

52

su edad correspondiente.

Nombre del vector edadesSubíndice [1],[2],...Contenido edades[2]= 28

Ejemplo:

Program Vector_edades; {El siguiente programa captura 20 edades y las muestra en forma ascendente por medio de arrays}Uses Crt;Const MaxPersonas = 10;Var edades : array [1..MaxPersonas] of byte; i,j,paso : byte;begin ClrScr; {lectura de array} for i:=1 to MaxPersonas do begin gotoxy(10,5); ClrEol; Write('Edad de la ',i,' persona : '); ReadLn(edades[i]) end; {ordenación} for i:=1 to MaxPersonas-1 do begin for j:=i+1 to MaxPersonas do begin if edades[i]>edades[j] then begin paso :=edades[i]; edades[i]:=edades[j]; edades[j]:=paso end end; WriteLn(edades[i]) {escritura del array} end; Readkeyend.

Page 53: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

53

Arrays paralelosDos o más arrays que utilizan el mismo subíndice para referirse a términos homólogos se llamanarrays paralelos.

Basados en el programa anterior se tienen las edades de 'x' personas, para saber a que persona serefiere dicha edad se puede usar otro arreglo en forma paralela y asociarle los nombres demanera simultánea con las edades.

Ejemplo:

Program Paralelo_edades; {El siguiente programa captura 10 edades y nombres por medio de arrays paralelos y los muestra ordenados en forma ascendente}Uses Crt;Const MaxPersonas = 10;Var edades :array [1..MaxPersonas] of byte; nombres :array [1..MaxPersonas] of string [10]; aux_nom :string[10]; i,j,aux_edad :byte;begin ClrScr; {lectura de arrays paralelos de manera simultánea} for i:=1 to MaxPersonas do begin gotoxy(10,5); ClrEol; Write(i,'.- Nombre : ','Edad : '); gotoxy(23,5);ReadLn(nombres[i]) ; gotoxy(48,5);ReadLn(edades[i]) end; {ordenación}

Page 54: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

54

for i:=1 to MaxPersonas-1 do begin for j:=i+1 to MaxPersonas do begin if edades[i]>edades[j] then begin aux_edad :=edades[i]; edades[i] :=edades[j]; edades[j] :=aux_edad; aux_nom :=nombres[i]; nombres[i]:=nombres[j]; nombres[j]:=aux_nom end end; WriteLn(nombres[i]:10,' ',edades[i]:3) {escritura de los arrays paralelos} end; Readkeyend.

Arrays bidimensionales (tablas)Un array bidimensional (tabla o matríz) es un array con dos índices, al igual que los vectores quedeben ser ordinales o tipo subrango.

Para localizar o almacenar un valor en el array se deben especificar dos posiciones (dossubíndices), uno para la fila y otro para la columna.

Formato:

identificador = array [índice1, indice 2] of tipo de elemento

identificador = array [ índice 1 ] of array [ indice 2 ] of tipo de elemento

Page 55: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

55

Supongase que se desea almacenar las calificaciones de 5 alumnos obtenidas en 3 examenes ymostrar en orden ascendente sus promedios respectivamente. En este caso se usará un arraybidimensional (tabla o matríz) de 5 filas y 4 columnas en la cual se almacenará las calificacionesde 3 examenes en 3 columnas y la cuarta columna se utilizará para almacenar su promediorespectivo, además de un array unidimensional (vector) donde en forma paralela se almacenaránlos nombres de los alumnos de la siguiente forma :

Ejemplo:

Program Matriz_Vector; {El siguiente programa captura las calificaciones de 5 alumnos en 3 examenes, y despliega en pantalla los promedios ordenados en forma descendente }Uses Crt;Const MaxAlumno = 5; MaxExamen = 4;{Columna 4 almacena el promedio}Var Alumno :array[1..MaxAlumno] of string[10]; examen :array[1..MaxAlumno,1..MaxExamen] of real; aux_examen :array[1..MaxExamen] of real;{reserva 20 posiciones de memoria de datos reales :5 filas por 4 columnas} promedio :real; aux_alumno :string [10]; i,j,col,ren :byte;begin ClrScr; {lectura de arrays paralelos de manera simultánea} gotoxy(5,5);Write('Nombre'); gotoxy(20,5);Write('Examen1 Examen2 Examen3 Promedio'); col:=5;ren:=6; for i:=1 to MaxAlumno do begin

Page 56: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

56

gotoxy(col,ren); ReadLn(alumno[i]); {lectura de vector} col:=22;promedio:=0; for j:=1 to MaxExamen-1 do begin gotoxy(col,ren); ReadLn(examen[i,j]); {lectura de matríz} promedio:=promedio+examen[i,j]; col:=col+10 end; examen[i,j+1]:=promedio/3; gotoxy(col,ren);Write(promedio/3:3:2); inc(ren); col:=5 end; {ordenación} for i:=1 to MaxAlumno-1 do for j:=i+1 to MaxAlumno do begin if examen[i,MaxExamen]<examen[j,MaxExamen] then begin {intercambio de nombres en vector} aux_alumno:=alumno[i]; alumno[i] :=alumno[j]; alumno[j] :=aux_alumno; {intercambio de calificaciones en matríz} move(examen[i],aux_examen,SizeOf(aux_examen)); move(examen[j],examen[i],SizeOf(aux_examen)); move(aux_examen,examen[j],SizeOf(aux_examen)) end end; {recorrido de matríz y vector} gotoxy(25,14);Write('Datos ordenados'); gotoxy(5,16);Write('Nombre'); gotoxy(20,16);Write('Examen1 Examen2 Examen3 Promedio'); col:=5;ren:=17; for i:=1 to MaxAlumno do begin gotoxy(col,ren); Write(alumno[i]); col:=22; for j:=1 to MaxExamen do begin gotoxy(col,ren); Write(examen[i,j]:3:2); col:=col+10

Page 57: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

57

end; col:=5; inc(ren) end; readkeyend.

Arrays multidimensionalesTurbo Pascal no limita el número de dimensiones de un array, pero sí que debe estar declarado eltipo de cada subíndice.

Formato :

identificador = array [índice1] of array [índice 2]..of array [índice n] of tipo de elemento

identificador = array [índice 1, índice 2,...,índice n] of tipo de elemento

Ampliando el ejemplo anterior supongase que ahora deseamos capturar calificaciones para 3materias en cuyo caso aplicaremos un array tridimensional. De la siguiente forma :

(nombre,examen,materia)

Ejemplo:

Program Tridimensional;

Page 58: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

58

{El siguiente programa captura calificaciones de 5 alumnos en 3 examenes de 3 materias distintas, y despliega en pantalla los promedios ordenados en forma descendente }Uses Crt;Const MaxAlumno = 5; MaxExamen = 4; {Columna 4 almacena el promedio} MaxMateria = 3; materia : array[1..3]of string[8]=('Fisica','Ingles','Historia');Var Alumno : array [1..MaxAlumno] of string[10]; examen : array [1..MaxAlumno,1..MaxExamen,1..MaxMateria] of real; aux_examen : array [1..MaxExamen]of real; {reserva 60 posiciones de memoria de datos reales : 5 filas por 4 columnas y 3 dimensiones} promedio :real; aux_alumno :string [10]; i,j,k,col,ren : byte;begin ClrScr; {lectura de arrays paralelos de manera simultánea} for k:=1 to MaxMateria do begin ClrScr; gotoxy(34,3);Write(materia[k]); gotoxy(5,5);Write('Nombre'); gotoxy(20,5);Write('Examen1 Examen2 Examen3 Promedio'); col:=5;ren:=6; for i:=1 to MaxAlumno do begin gotoxy(col,ren); if k=1 then ReadLn(alumno[i]) {lectura de vector} else Write(alumno[i]); col:=22;promedio:=0; for j:=1 to MaxExamen-1 do begin gotoxy(col,ren); ReadLn(examen[i,j,k]); {lectura de matríz} promedio:=promedio+examen[i,j,k]; col:=col+10 end; examen[i,j+1,k]:=promedio/3; gotoxy(col,ren);Write(promedio/3:3:2);

Page 59: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

59

inc(ren); col:=5 end; gotoxy(15,22); Write('Presione una tecla para continuar....'); ReadKey end; {ordenación} for k:=1 to MaxMateria do for i:=1 to MaxAlumno-1 do for j:=i+1 to MaxAlumno do begin if examen[i,MaxExamen,k]<examen[j,MaxExamen,k] then begin {intercambio de nombres en vector} aux_alumno:=alumno[i]; alumno[i] :=alumno[j]; alumno[j] :=aux_alumno; {intercambio de calificaciones en matríz} move(examen[i,k],aux_examen,SizeOf(aux_examen)); move(examen[j,k],examen[i,k],SizeOf(aux_examen)); move(aux_examen,examen[j,k],SizeOf(aux_examen)) end end; {recorrido de matríz y vector} for k:=1 to MaxMateria do begin ClrScr; gotoxy(35,4);Write(materia[k]); gotoxy(25,5);Write('Datos ordenados'); gotoxy(5,6);Write('Nombre'); gotoxy(20,6);Write('Examen1 Examen2 Examen3 Promedio'); col:=5;ren:=7; for i:=1 to MaxAlumno do begin gotoxy(col,ren); Write(alumno[i]); col:=22; for j:=1 to MaxExamen do begin gotoxy(col,ren); Write(examen[i,j,k]:3:2); col:=col+10 end; col:=5; inc(ren)

Page 60: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

60

end; gotoxy(15,22); Write('Presione una tecla para continuar....'); readkey endend.

5.3.3 Registros (record)Un registro es una estructura que consiste de un número fijo de componentes llamados campos.Los campos pueden ser de diferentes tipos y deben tener un identificador de campo.

La definición de un tipo registro debe consistir de la palabra reservada record, seguida de unalista de campos y terminada por el identificador reservado end.

formato:

type tipo_reg = record lista id1:tipo 1; lista id2:tipo 2; . . . lista idn:tipo n end;

tipo_reg nombre de la estructura o dato registrolista id lista de uno o más nombres de campos separados por comastipo puede ser cualquier tipo de dato estándar o definido por el usuario

Ejemplo :

Type registro_empleado = Record nombre : string[30] ; profesion : string[20] ; puesto : string[20] ; sueldo : real end;Un registro puede representarse gráficamente en función de sus campos.

Page 61: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

61

El registro como un todo tiene el nombre registro_empleado. Este nuevo tipo que se acaba dedefinir puede utilizarse en la sección Var, para declarar variables como por ejemplo :

Var empleado : registro_empleado ;Para asignar valores a cada campo del registro empleado, puede procederse de la siguientemanera :

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

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

.......................empleado.nombre := 'MENDEZ ROMERO FEDERICÓ';empleado.profesion := 'INGENIERO CIVIL';empleado.puesto := 'DIRECTOR';empleado.sueldo := 5000.00 ;.....................................................................

Para simplificar la notación de los registros, se pueden utilizar instrucciones With Do.

Por ejemplo, la instrucción :

WriteLn(empleado.nombre:35, empleado.puesto:25, empleado.sueldo:15:0);puede escribirse :

Page 62: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

62

With empleado DoWriteLn(nombre:35,puesto:25,sueldo:15:0);

Asimismo, para leer datos usamos :

With empleado Dobegin Write('NOMBRE : '); ReadLn(nombre); Write('PROFESION : '); ReadLn(profesion); Write('PUESTO : '); ReadLn(puesto); Write('SUELDO MENSUAL : '); ReadLn(sueldo)end;

Obsérvese el siguiente segmento de programa :

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

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

..............................Type fecha = Record anio : 1900..1989 ; mes : 1..12 ; dia : 1..31 end; datos = Record nombre : string[30] ; sueldo : real ; fecha_ingreso : fecha end;Var personal : datos ; ............................... ............................... ...............................La asignación del valor 15 al campo dia del registro personal se hace de la siguiente manera :

personal.fecha_ingreso.dia := 15 ;donde :

personal.fecha_ingreso

Page 63: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

63

hace referencia al campo fecha_ingreso del registro personal, mientras que :

diase refiere al campo dia del campo fecha_ingreso, que a su vez es un registro de tipo fecha.

Usando la forma With Do quedaría :

With personal Do With fecha_ingreso Do dia := 15 ;que es equivalente a :

With personal, fecha_ingreso Do dia := 15 ;

o también a:

with personal Do with fecha_ingreso Do dia:=15;Ejemplo:

Program Registro; {EL siguiente programa captura 10 empleados y sus datos personales en un arreglo con la utilización de registros}Uses Crt;Const MaxEmpleados=10;Type registro_empleado = Record nombre : string[30]; profesion : string[20]; puesto : string[20]; sueldo : real end;Var registro : registro_empleado; empleado :array[1..MaxEmpleados] of registro_empleado; i,col,ren :byte;begin ClrScr; Write(' Nombre Profesión Puesto Sueldo'); col:=1;ren:=2; for i:=1 to MaxEmpleados do begin With registro do

Page 64: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

64

begin gotoxy(col,ren); ReadLn(empleado[i].nombre); gotoxy(col+21,ren); ReadLn(empleado[i].profesion); gotoxy(col+40,ren); ReadLn(empleado[i].puesto); gotoxy(col+59,ren); ReadLn(empleado[i].sueldo); inc(ren); col:=1; end end; ReadKeyend.

5.3.4 Conjuntos (sets)Un conjunto es una colección de objetos relacionados. Cada objeto en un conjunto es llamadomiembro o elemento del conjunto.

Aunque en matemáticas no hay restricciones para que los objetos puedan ser elementos de unconjunto, Pascal sólo ofrece una forma restringida de conjuntos, por lo que :

Los elementos de un conjunto deben ser del mismo tipo, llamado el tipo base.El tipo base debe ser un tipo simple, excepto el tipo real.

Representación de conjuntos:

Elementos Notación Matemática Pascal1,2,3,4,5 {1,2,3,4,5} [1,2,3,4,5]a,b,c {a,b,c} ['a','b','c']

Aunque se puede utilizar notación de tipo subrango para especificar secuencia de valores quepertenezcan a un conjunto, los elementos del conjunto no tienen una ordenación internaparticular. La única relación entre los miembros de un conjunto es: existe o no existe en elconjunto.

[5,5] y [5] son equivalentes (contienen un sólo elemento)

Ejemplos de conjuntos:

[1,3,5] conjunto de tres enteros[1..3,8..10] conjunto de seis enteros [1,2,3,8,9,10][ ] conjunto vacío (ningún elemento)['a','b','A'..'D'] conjunto de seis elementos ['a','b','A','B','C','D']

Page 65: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

65

Un conjunto especial, denominado conjunto vacío, es aquel que no contiene ningún elemento.

El formato para la definición de un tipo conjunto es :

type <identificador> = set of <tipo_base>

Ejemplos :

Type dias_mes = set of 0..31; mayusculas = set of 'A'..'Z'; caracteres = set of char; equipos = (Chivas,Santos,Pumas, Toluca,Tigres,America, Leon); futbol = set of equipos;Var GrupoA,GrupoB : futbol;En Turbo Pascal, el máximo número de elementos permitidos en un conjunto es 256, y losvalores ordinales del tipo base deben estar en el rango de 0 a 255 .

Asignación en conjuntosLos elementos se ponen en los conjuntos utilizando una sentencia de asignación.

GrupoA := [Chivas,Santos,Toluca]; GrupoB := [Tigres..Leon];Si dos tipos de conjuntos son compatibles (tienen los tipos de base compatibles: igual tipo dedato, o uno subrango de otro, o ambos del mismo tipo patrón), sus variables representativas sepueden utilizar en sentencias de asignación.

GrupoA := GrupoB; GrupoB := [];{asignación del conjunto vacío}

La relación InEl operador relacional In y una expresión relacional nos permite conocer si un elemento dadopertenece a un conjunto dado.

Formato:

elemento in [ lista de elementos ]

Page 66: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

66

El resultado de evaluar la expresión relacional puede ser true o false. El tipo de datos deelemento y la lista de elementos deben ser compatibles.

Ejemplo:

Program Hasta_Si; {El siguiente programa obtiene del teclado un nombre hasta que se presiona la tecla 's' o 'S' o Esc}Uses Crt;Const Esc =#27;Var nombre : string[30]; tecla : char;begin Repeat ClrScr; Write('Escribe tu nombre : '); ReadLn(nombre); Write('Desea Salir S/N ? : '); Tecla:=Readkey Until tecla in['s','S',Esc]; ClrScrend.

Operaciones con conjuntosUna vez creados los conjuntos y las variables tipo conjunto es posible realizar tres operacionesbinarias sobre ellos: unión, intersección y diferencia. La siguiente tabla resume elfuncionamiento de las operaciones con conjuntos A y B.

Operaciones sobre dos conjuntos A y B

Unión + A+B es el conjunto que contiene todos los elementos que están en A, en B o en ambos.

Intersección * A*B es el conjunto cuyos elementos pertenecen a A y B simultáneamente.

Diferencia - A-B es el conjunto cuyos elementos son de A pero no de B.

Page 67: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

67

Ejemplo:

Operación Resultado[1,3,4,5]+[1,2,4] [1,2,3,4,5][1,3,4,5]*[1,2,4] [1,4][1,3,4,5]-[1,2,4] [3,5][1,2,3]+[ ] [1,2,3][1,2,4]*[3,5,6] [ ][1,2,3]-[ ] [ ]

Reglas de prioridad

Cuando una expresión de conjuntos contiene dos o más operadores de conjunto, éstos se evalúande acuerdo a la siguiente prioridad:

* Prioridad más alta+,- Prioridad más baja

En caso de operaciones con igual prioridad se evalúan de izquierda a derecha.

Comparación de conjuntos (operadores de relación)Los conjuntos se pueden comparar entre sí mediante el uso de los operadores relacionales (==,<>,<=,>=). Los operandos deben ser del mismo tipo base. El resultado de la comparación es unvalor lógico: true o false.

Operadores de relación de conjuntos A y BOperador Nombre del operador Resultado< = Subconjunto El valor de A< = B es true. Si cada elemento de A

es también de B. En caso contrario es false.= Igualdad El valor de A = B es true si cada elemento de A está

en B y cada elemento de B está en A. En casocontrario A = B es falso, A=B equivale a (A<=B) and (B<=A).

< > Desigualdad El valor de A < > B es true si el valor de A = B esfalse y viceversa.

> = Superconjunto A < > B equivale a not (A = B), A >= B es true si B<=A es true.

Ejemplos :

Comparación Resultado[3,5] = [3,5] true

Page 68: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

68

[ ] = [1] false[ ] <= [1,5] true[1,2] >= [1,2,3,4] false[ ] >= [1,2] false[1,4,5] = [4,5,1] true

Prioridad de operadores :Operador Prioridadnot 1 (más alta)*,/,div,mod,and 2+,-,or 3=,<>,<,<=,>,>=,in 4 (más baja)

Lectura de conjuntosAlgunas operaciones no se pueden ejecutar sobre variables de conjunto. Por ejemplo, no sepuede leer cinco ciudades en un conjunto Mundo con la siguiente sentencia:

ReadLn(Mundo)La razón es que la computadora no puede saber cuantos elementos existen en el conjunto.

Si se desea leer y almacenar datos en un conjunto se debe utilizar un bucle.

for elemento:=1 to 5 do begin {leer un dato} {almacenar el valor en el siguiente elemento del conjunto} end;

Reglas :

Inicializar A al conjunto vacío.A := [ ];

Leer cada elemento x del conjunto y añadirlo al conjunto A con la operación unión (+)ReadLn(x);A := A + [x];

Page 69: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

69

Escritura de conjuntosLos valores de conjuntos no se pueden visualizar con la sentencia Write.

Para visualizar los elementos de un conjunto A se debe utilizar el siguiente algoritmo:

Copiar los elementos de A en un conjunto auxiliar Aux que tenga un tipo base compatible con elde A.

Declarar x una variable del tipo base de Aux e inicializar x al primer elemento de este tipo base.

Mientras x es diferente del último elemento de este tipo base y Aux no está vacía, hacer :

I. Si x pertenece a Aux, entonces visualizar x y eliminarlo de AuxII. Sustituir x con su sucesor.

Ejemplo:

Program Impares; {El siguiente programa encuentra y muestra todos los números impares menores o igual a un número dado n que esté entre el límite 1..255}Uses Crt;Type numeros = set of 1..255;Var impares,Aux :numeros; x,MaxNum,i :byte;begin ClrScr; Write('Escribe un número entero : '); ReadLn(MaxNum); impares:=[]; {inicializa a conjunto vacío} for i:=1 to MaxNum do begin if odd(i) then impares:=impares + [i] {añadir elementos al conjunto} end; {visualizar elementos del conjunto} Aux:=impares;

Page 70: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

70

x:=1; while (x<>MaxNum+1) and (Aux<>[]) do begin if x in Aux then begin WriteLn(x); Aux:=Aux-[x] end; x:=succ(x) end; ReadKey; ClrScrend.

5.3.5 Archivos (file)Un tipo archivo se define con los identificadores reservados FILE OF, seguidas por el tipo de loscomponentes del archivo.

Por ejemplo :

Type empleado = file of Record nombre:string[30]; sueldo:real; end;Var nomina : empleado ;

también puede escribirse así :

Type empleado = Record nombre:string [30]; sueldo:real; end;Var nomina : file of empleado;

En el capítulo 8 se verá con más detalle este tema.

6.1 SubprogamasUn programa en Pascal consiste de uno o más módulos, los cuales a su vez también pueden estarconstituídos por otros módulos, y así sucesivamente. Estos módulos serán llamados, en términosgenerales, SUBPROGRAMAS, y en particular PROCEDIMIENTOS y FUNCIONES.

Page 71: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

71

Un subprograma es un bloque de programa que realiza una tarea determinada, y que al llamárseleo invocársele puede necesitar que se le pasen PARAMETROS.

Los parámetros son identificadores que proveen un mecanismo para pasar información hacia lossubprogramas invocados.

Los parámetros que se utilizan en la declaración de subprogramas se llaman PARAMETROSFORMALES.

Un subprograma puede ser invocado desde cualquier punto del programa, por medio de unainstrucción INVOCADORA, la cual puede contener una lista de parámetros llamadosPARAMETROS ACTUALES.

6.2 ProcedimientosUn procedimiento es un subprograma que realiza alguna de las tareas del programa, y que nodevuelve ningún valor al subprograma que lo invocó.

Un procedimiento está compuesto de un grupo de sentencias a las que se asigna un nombre(identificador) y constituye una unidad del programa. La tarea asignada al procedimiento seejecuta siempre que Pascal encuentra el nombre del procedimiento.

En Turbo Pascal resulta obligatorio declarar los procedimientos antes de ser referenciados en elcuerpo del programa.

6.2.1 Declaración de un procedimientoLa sintaxis para declarar un procedimiento es :

Formato 1 :

procedure nombre_procedimiento; declaraciones locales begin cuerpo del procedimiento end;

Formato 2:

procedure nombre_procedimiento(parámetros formales); declaraciones locales begin cuerpo del procedimiento end;

Page 72: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

72

La existencia de parámetros_formales dependerá de la naturaleza del procedimiento, esto es, dela tarea que va a realizar y de la forma en que lo ha estructurado su creador.

6.2.2 Invocación al procedimientoPara invocar a un procedimiento, la sintaxis es :

<nombre_de_procedimiento> (parámetros_actuales) ;

donde la existencia de parámetros_actuales dependerá de que en la declaración delprocedimiento se hayan utilizado parámetros formales.

Para ejemplificar el uso de procedimientos, diseñaremos un programa que resuelva el problemade SUMAR Y MULTIPLICAR MATRICES.

PSEUDOCODIGO

{PROGRAMA PARA SUMAR Y MULTIPLICAR MATRICES}INICIO IMPRIME encabezado. LEE las dimensiones de las matrices A y B. SI las matrices no son compatibles para la suma, ENTONCES IMPRIME mensaje_1. SI las matrices no son compatibles para la mult., ENTONCES IMPRIME mensaje_2. SI son compatibles para la suma o para la mult. , ENTONCES INICIO LEE las matrices A y B. IMPRIME las matrices A y B. SI son compatibles para la suma, ENTONCES INICIO SUMA las matrices A y B. IMPRIME la matriz resultado C. FIN SI son compatibles para la multiplicacion, ENTONCES INICIO MULTIPLICA las matrices A y B. IMPRIME la matriz resultado D. FIN FINFIN.

Page 73: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

73

CODIFICACION :

Program Opera_matrices; {Programa para sumar y multiplicar matrices de orden hasta de dim_max por dim_max }Uses Crt;Const dim_max = 10;Type mat = array [1..dim_max , 1..dim_max] of real;Varmat_a,mat_b,mat_c : mat;bandera_suma,bandera_mult:boolean;ren_a,ren_b,col_a,col_b :integer;

procedure inicio;Var contador : integer;begin ClrScr; gotoxy(23,2); WriteLn('SUMA Y MULTIPLICACION DE MATRICES'); for contador := 1 to 80 do Write('='); WriteLnend;{Lee las dimensiones de las matrices}procedure dim ;begin WriteLn('DIMENSIONES DE LA MATRIZ A'); WriteLn; Write('Número de renglones ==> '); ReadLn(ren_a); Write('Numero de columnas ==> '); ReadLn(col_a); WriteLn; WriteLn; WriteLn('DIMENSIONES DE LA MATRIZ B'); WriteLn; Write('Número de renglones ==> '); ReadLn(ren_b); Write('Número de columnas ==> '); ReadLn(col_b)end;

{Verifica la compatibilidad para la suma}

Page 74: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

74

procedure compat_suma (ren_f_a,ren_f_b,col_f_a,col_f_b:integer; Var bandera_f:boolean);begin if ((ren_f_a <> ren_f_b) or (col_f_a <> col_f_b)) then begin WriteLn; WriteLn('Las matrices A y B son incompatibles para la suma'); bandera_f :=false end else bandera_f :=trueend;{Verifica la compatibilidad para la multiplicación}procedure compat_mult(ren_f_a,ren_f_b,col_f_a,col_f_b:integer; Var bandera_f:boolean);begin if col_f_a <> ren_f_b then begin WriteLn; WriteLn('Las matrices A y B son icompatibles para la multiplicación'); bandera_f := false end else bandera_f := trueend;{Lee una matriz}procedure lee(nmat:char;Var mat_f:mat;ren_max,col_max:integer);Var ren,col : integer;begin WriteLn; WriteLn('ELEMENTOS DE LA MATRIZ : ',nmat); WriteLn; for ren := 1 to ren_max do for col := 1 to col_max do begin Write('Elemento [ ',ren,',',col,'] = '); ReadLn(mat_f[ren,col]) endend;{Suma dos matrices}procedure suma( mat_f_a,mat_f_b:mat;Var mat_f_c:mat; ren_f, col_f :integer);Var ren,col : integer;begin

Page 75: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

75

WriteLn; WriteLn('La suma de A y B es :'); for ren := 1 to ren_f do for col := 1 to col_f do mat_f_c[ren,col] := mat_f_a[ren,col] + mat_f_b[ren,col]end;{Multiplica dos matrices}procedure multiplica( mat_f_a, mat_f_b: mat ;Var mat_f_c : mat ; ren_f_a, col_f_a, col_f_b :integer);Var ren, acol, bcol : integer ; acum : real ;begin WriteLn; WriteLn('El producto de A y B es :'); for ren := 1 to ren_f_a do for bcol := 1 to col_f_b do begin acum := 0.0 ; for acol := 1 to col_f_a do acum := acum + mat_f_a[ren,acol] * mat_f_b[acol,bcol]; mat_f_c[ren,bcol] := acum endend;{Imprime una matriz}procedure imprime(nmat : char ; mat_f : mat ; ren_f, col_f : integer) ;Var ren, col : integer;begin WriteLn; WriteLn('MATRIZ ',nmat); for ren := 1 to ren_f do for col := 1 to col_f do begin Write(mat_f[ren,col]:6:1,' '); WriteLn end; WriteLn; Write('Oprima una tecla para continuar..... '); ReadKey; WriteLnend;{Módulo Principal}begin inicio;

Page 76: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

76

dim; compat_suma(ren_a,ren_b,col_a,col_b,bandera_suma); compat_mult(ren_a,ren_b,col_a,col_b,bandera_mult); if bandera_suma or bandera_mult then begin lee('A',mat_a,ren_a,col_a); lee('B',mat_b,ren_b,col_b); imprime('A',mat_a,ren_a,col_a); imprime('B',mat_b,ren_b,col_b); if bandera_suma then begin suma(mat_a,mat_b,mat_c,ren_a,col_a); imprime('C',mat_c,ren_a,col_b) end; if bandera_mult then begin multiplica(mat_a,mat_b,mat_c,ren_a,col_a,col_b); imprime('D', mat_c, ren_a, col_b) end endend.

Observe que el MÓDULO PRINCIPAL está formado por un bloque de instrucciones queinvocan a procedimientos.

6.3 FuncionesLa diferencia principal entre un procedimiento y una función es que el identificador de la funciónasume un valor, y cuando la función termina su tarea, devuelve ese valor al módulo que lainvocó; mientras que el procedimiento no devuelve ningún valor.

Puesto que el nombre de la función toma un valor, dicho nombre debe tener asociado untipo de dato.

6.3.1 Declaración de funcionesLa declaración de una función tiene la siguiente forma :

function Nombre (p1,p2,...):tipo {declaraciones locales y subprogramas}begin <cuerpo de la función> Nombre := valor de la funciónend;

p1,p2,... lista de parámetros formales

Page 77: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

77

tipo tipo de dato del resultado que devuelve la función

Ejemplos :

function verifica : boolean ;{ Función sin parámetros formales}function cambia(Var valor_1, valor_2: real):real;function potencia( base, exponente : real ):real;

6.3.2 Invocación de funcionesLas funciones se invocan de la siguiente manera :

<nombre_función> (parámetros_locales) ;

donde :

parámetros_locales es una lista de variables y/o constantes separadas por comas. La existencia deparámetros_locales dependerá de que existan parámetros formales en la declaración de lafunción.

Por ejemplo, resolvamos el problema de cacular la raíz cuadrada de un número, utilizando elalgoritmo de Newton:

x(i+1) = x(i) + 0.5 ( a/x(i) -x(i) )

La codificación del programa sería :

Program Raiz_cuadrada;{El siguiente programa calcula la raíz cuadrada de un número}Uses Crt;Var raiz, numero : real;

{Declaración de la función raiz_cuad}function raiz_cuad( a : real ) : real ;Var c,x : real ;begin x := 1E-9 ; c := 1.0 ; while Abs (c-x)>1E-9 do begin

Page 78: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

78

c := x ; x := x + 0.5 * ( a/x -x ) end; raiz_cuad := x {El resultado se asigna a nombre_función}end;begin ClrScr; Write('La raíz cuadrada de : '); ReadLn(numero) ; raiz:=raiz_cuad(numero); {Invoca a la función raiz_cuad} WriteLn ; WriteLn('Es igual a : ',raiz:6:8); ReadKey; ClrScrend.

6.4 Ambito de variablesLas variables se clasifican en LOCALES y GLOBALES. Una variable LOCAL es una variabledeclarada dentro de un subprograma, y el significado de dicha variable se limita a esesubprograma y a los módulos que éste contiene. Cuando otro subprograma utiliza el mismonombre de variable, se crea una variable diferente en otra posición de la memoria. Por eso, si unsubprograma asigna un valor a una de las variables locales, tal valor no es accesible a los otrossubprogramas.

Cuando se desea que otros subprogramas tengan acceso al valor de una variable, ésta debedeclararse como GLOBAL, lo cual se logra declarándola en el módulo que abarca a dichossubprogramas.

Para tener la seguridad de que una variable va a tener un alcance GLOBAL, conviene declararlaen el MODULO PRINCIPAL.

Los conceptos anteriores se aclaran por medio de la siguiente figura :

Page 79: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

79

Program anidado;

Referencias de identificadores válidos :

Bloque Identificador Significado de cada identificadoranidado M constante global i,,j varibles globales A procedimiento declarado en anidadoA i parámetros de A r,s variables locales B función local j variable declarada en anidado B función declarado en anidado M constante globalB g parámetros de B m,n variables locales r,s variable declarada en A i parámetro de A y variable declarada en anidado A procedimiento declarado en anidado B función declarada en anidado M constante global

Page 80: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

80

6.5 Paso de parámetrosAl invocar a un subprograma se le pueden pasar parámetros, los cuales pueden consistir devalores de variables declaradas en el módulo invocador. El paso de tales parámetros puedehacerse de dos maneras :

6.5.1 Paso por valorEl paso de parámetros por valor consiste en enviar una COPIA del valor de la variable al móduloinvocado.

De esta manera se asegura que el valor de la variable sólo puede ser modificado por el móduloque la declaró.

Si la palabra Var no aparece delante del parámetro formal en un procedimiento, Turbo Pascalsupone que el parámetro formal es un parámetro por valor.

Ejemplo:

Program Suma_por_Valor; {El siguiente programa realiza la suma de dos numeros }Uses Crt;Var A,B,C:integer;

procedure suma(A,B,C :integer);begin C := A + Bend;

begin ClrScr; C:=10; A:=10; B:=10; suma(A,B,C); WriteLn(A,',',B,',',C); ReadKey; ClrScrend.El resultado de la ejecución del programa sería :

10,10,10

El valor de C no se modifica puesto que es un parámetro por valor.

Page 81: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

81

6.5.2 Paso por referenciaEn el caso de que se requiera que el valor de una variable sea modificado por el móduloinvocado, debe hacerse el paso de parámetro por referencia, por medio del cual el móduloinvocado tiene acceso a la dirección en que se guarda el valor a modificar.

Para aclarar los conceptos de paso por valor y paso por referencia, analicemos el programa desuma y multiplicación de matrices dado en la sección anterior.

Observamos que las invocaciones a subprogramas son similares en los casos de paso por valor ypaso por referencia.

Por ejemplo, las invocaciones a los procedimientos imprime y suma quedan de la siguientemanera :

imprime('C',mat_c,ren_a,col_b);suma(mat_a,mat_b,mat_c,ren_a,col_a);y sus respectivas declaraciones son :

procedure imprime(nmat:char;mat_f:mat;ren_f,col_f:integer);procedure suma(mat_f_a,mat_f_b:mat;Var mat_f_c:mat;ren_f,col_f:integer);Vemos que en la declaración del procedimiento suma existe la parte: Var mat_f_c : mat

la cual significa lo siguiente :

"La variable mat_f_c contiene la dirección de la variable correspondiente en la invocación (mat_c ) , y es de tipo mat "

Esto significa que el paso del parámetro mat_c se hizo por referencia, y que el procedimientoinvocado (suma) puede modificar el valor de mat_c .

Ejemplo:

Program Suma_por_Referencia; {El siguiente programa realiza la suma de dos números }Uses Crt;Var A,B,C:integer;

procedure suma(A,B:integer;Var C:integer);begin C := A + Bend;

Page 82: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

82

begin ClrScr; C:=10; A:=10; B:=10; suma(A,B,C); WriteLn(A,',',B,',',C); ReadKey; ClrScrend.El resultado de la ejecución del programa sería :

10,10,20

El valor de C se modifica puesto que es un parámetro por referencia.

Nota : En Turbo Pascal no se permite el paso de procedimientos y funciones como parámetros

6.6 RecursiónEn Pacal, a un procedimiento o función le es permitido no sólo invocar a otro procedimiento ofunción, sino también invocarse a sí mismo. Una invocación de éste tipo se dice que es recursiva.

La función recursiva más utilizada como ejemplo es la que calcula el factorial de un númeroentero no negativo, partiendo de las siguientes definiciones :

factorial (0) = 1factorial (n) = n*factorial(n-1), para n>0La función, escrita en Pascal, queda de la siguiente manera :

function factorial(numero:integer):integer;begin if numero = 0 then factorial := 1 else factorial := numero * factorial(numero-1)end;Si numero = 4, la función realiza los siguientes pasos :

Page 83: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

83

factorial(4) := 4 * factorial(3) Se invoca a si misma y crea una segunda variable cuyo nombre esnumero y su valor es igual a 3.

factorial(3) := 3 * factorial(2) Se invoca a si misma y crea una tercera variable cuyo nombre esnumero y su valor es igual a 2.

factorial(2) := 2 * factorial(1) Se invoca a si misma y crea una cuarta variable cuyo nombre esnumero y su valor es igual a 1.

factorial(1) := 1 * factorial(0) Se invoca a si misma y crea una quinta variable cuyo nombre esnumero y su valor es igual a 0.

Como factorial(0) := 1, con éste valor se regresa a completar la invocación: factorial(1) := 1 * 1 ,por lo que factorial(1) := 1

Con factorial(1) := 1, se regresa a completar: factorial(2) := 2 * 1, por lo que factorial(2) := 2

Con factorial(2) := 2, se regresa a completar : factorial(3) := 3 * 2, por lo que factorial(3) := 6

Con factorial(3) := 6, se regresa a completar : factorial(4) := 4 * 6, por lo que factorial(4) := 24 yéste será el valor que la función factorial devolverá al módulo que la haya invocado con un valorde parámetro local igual a 4 .

Page 84: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

84

Un ejemplo de procedimiento recursivo es el siguiente:

Supóngase que una persona se mete a una piscina cuya profundidad es de 5 metros. Su intenciónes tocar el fondo de la piscina y después salir a la superficie. Tanto en el descenso como en elascenso se le va indicando la distancia desde la superficie (a cada metro).

Program Piscina;Uses Crt;Const prof_max = 5;Var profundidad:integer;

procedure zambullida(Var profun :integer);begin WriteLn('BAJA 1 PROFUNDIDAD = ',profun); profun := profun + 1; if profun <= prof_max then zambullida(profun) else WriteLn; profun := profun - 1; WriteLn('SUBE 1 PROFUNDIDAD = ', profun-1)end;begin ClrScr; profundidad := 1; zambullida(profundidad)end.

7.1 ApuntadoresEn una computadora cada posición de memoria tiene una dirección y un valor específicoalmacenado en esa posición. Se han utilizado nombres de variables en lugar de direccionesporque los nombres son más fáciles de recordar. Para almacenar un nuevo valor en memoria seasigna a una variable, y la computadora envía una dirección a la memoria seguida por el valor aalmacenar en esa posición.

Pascal proporciona un tipo especial de variable denominado apuntador, que es una variable cuyovalor es una dirección de una posición de memoria.

Page 85: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

85

Al definir un tipo apuntador se debe indicar el tipo de valores que se almacenarán en lasposiciones designadas por los apuntadores. La razón es que los diferentes tipos de datosrequieren diferentes cantidades de memoria para almacenar sus constantes, una variableapuntador puede contener una dirección de una posición de memoria adecuada sólo para un tipodado. Por esta razón se dice que un apuntador apunta a una variable particular.

Una variable tipo apuntador contiene la dirección de la posición de otra variable

Para declarar una variable de tipo apuntador en Pascal se debe especificar el nombre de lavariable y el tipo del valor que se almacenará en la posición de memoria a la que el apuntador serefiere.

Formato:

Type tipo_apuntador = ^tipo dato

Una variable de tipo tipo_apuntador es un apuntador hacia un dato de tipo nombre del tipo. Elsigno '^' se lee "apunta hacia".

Ejemplos:

Type Apuntador = ^real;Var P : Apuntador;{define el tipo,cuyos valores apuntan a posiciones que contienen números reales P apunta a posiciones que contienen números reales}Var P : ^real;

Type registro = record nombre:string[10]; edad :integer; sexo :char end;Var P :integer; Q :^registro;

Page 86: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

86

P sólo puede contener direcciones de posiciones de memoria adecuada para almacenar enteros. Qse limita a datos de tipo registro.

7.2 Operaciones con apuntadoresLos apuntadores se crean con las declaraciones ya citadas:

Type ApuntadorEntero : ^integer;Var P:ApuntadorEntero;P es una variable tipo ApuntadorEntero que apunta a posiciones que contienen enteros.

La posición de memoria designada por el valor de la variable apuntador P se representa por P^.La siguiente figura representa la relación entre P y P^.

P^:=1000 el valor de P^ es 10003 * P^ + 500 = 3500

Como P^ designa una posición de memoria, se puede utilizar como cualquier otra variable. Sepueden asignar valores a P^ y utilizar valores P^ en expresiones como cualquier otra variable. SiP apunta a posiciones que contienen reales, P^ es una variable real.

Sin embargo, estas operaciones no se pueden realizar directamente tras la declaración, debido aque el objeto o dirección apuntada P^ no tiene existencia. Antes de que un programa utilice unpuntero, se requiere primero espacio para el tipo de datos objeto de la dirección del puntero. Enotras palabras, un programa debe inicializar sus punteros - su declaración no basta- ; parainicializar un puntero se debe utilizar el procedimiento New.

7.2.1 NewEl procedimiento New crea una variable dinámica y establece que una variable tipo apuntadorapunte a ella.

Formato:

New (P)

P variable puntero

Page 87: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

87

La nueva variable creada es la ya conocida con el símbolo P^. La llamada a New exige queexista suficiente espacio de memoria libre en el montículo -la pila de variables dinámicas- (heap)para asignar a la nueva variable. En caso contrario se producirá un error en tiempo de ejecución.

New(P)

Llamada al procedimiento New que asigna almacenamiento para un valor de tipo real y sitúa la

dirección de esta posición de memoria en la variable de tipo apuntador P.

La sentencia de asignación

P^ := 22

almacena el valor entero en la posición de memoria P.

Como P^ se considera una variable, podrá ser visualizado su valor

Write(P^); {Visualiza el valor 22}P:=25; {Asignación no válida}Write(P); {Sentencia no válida}

Ejemplo:

Var 1. P,Q : ^char;begin 2. New(P); 3. New(Q); 4. P^:='A'; 5. WriteLn(P^); 6. Q:=P; 7. Q^:='B'; 8. WriteLn('P^ = ',P^,' ; Q^ = ',Q^)end.Paso Gráfico de memoria Significado

Page 88: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

88

1. Se declará P y Q como una variable estática

2. Asigna espacio de memoria para P^ y almacena su dirección en P.

3. Asigna espacio de memoria para Q^ y almacena su dirección en Q.

4. Asignación del valor 'A' a la variable dinámica P.

5. Visualiza el valor 'A'.

6. El contenido de P se asigna a Q de modo que P^ y Q^ comparten la misma posición dememoria.

Page 89: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

89

7. Asignación a Q^ y P^.

8. Visualiza P^ = B ; Q^ = B

7.2.2 DisposeEl procedimiento Dispose libera la posición de memoria ocupada por una variable dinámica.

Formato:

Dispose (P)

P variable puntero

Dispose produce las siguientes acciones :

La posición de memoria cuya dirección se almacena en P se libera de la memoria montículo(heap). Es decir P^ deja de existir.

P se vuelve indefinido.Representación gráfica :

situación inicial

Page 90: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

90

situación después de dispose

Ejemplo:

Var 1. P,Q : ^char;begin 2. New(P); 3. P^:='A'; 4. Q:=P; 5. Q^:='B'; 6. Dispose(P)end.Paso Gráfico de memoria Significado

1. Se declará P y Q como variables estática

2. Asigna espacio de memoria para P^ y almacena su dirección en P.

3. Asignación del valor 'A' a la variable dinámica P.

Page 91: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

91

4. El contenido de P se asigna a Q de modo que P^ y Q^ comparten la mismaposición de memoria.

5. Asignación a Q^ y P^.

6. Como P y Q apuntan a la misma posición, dispose libera la memoria de P y Q.

7.2.3 Constante nilPascal proporciona una constante predefinida, nil (nulo). La constante nil se utiliza para dar unvalor a una variable puntero que no apunta a ninguna posición, nil puede ser asignada a unpuntero de cualquier tipo.

P:=nilComo nil no apunta a ninguna posición de memoria, una referencia a P^ es incorrecta si el valorde P es nil.

P:=nil;P^:= 22; {Asignación incorrecta}

Page 92: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

92

7.2.4 Apuntadores con registrosLas variables de apuntadores pueden contener la dirección de tipos de datos simples o datos detipo compuesto. En las estructuras dinámicas de datos es frecuente el uso de registros comoelementos. Se suelen conocer con el nombre de nodos.

Ejemplo :

type PunteroEmpleado = ^empleado; empleado = record nombre : string[30]; sueldo : integer end;Var P,Q,R : PunteroEmpleado;

Algunas operaciones típicas son:

Operación Gráfico de memoriaDeclaraciones

New(P)

New(Q)

P^.nombre = 'Ely'

Q^.nombre= 'Bety'

Page 93: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

93

P^.sueldo=2000

Q^.sueldo=3000

R:=Q

Write(P^.nombre,Q^.nombre,R^.nombre) Visualiza los nombres apuntados por Q,R,S'Ely Bety Bety'

7.2.5 Comparación de apuntadoresLos apuntadores sólo pueden ser comparados en expresiones de igualdad. En el caso de losobjetos direccionados por los punteros no existe ninguna restricción en cuanto al uso de losoperadores relacionales.

Ejemplo:

Var P,Q:^integer;begin New(P); New(Q); P^:=10; Q^:=20; . . .

Page 94: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

94

Sentencia Resultadoif P = Q then falseif P = Q then trueif P > Q then Sentencia no válida. En punteros no se pueden usar los siguientes operadores relacionales >,>=,<,<=.if P^ > Q^ then falseif P^ <= Q^then true

7.3 Tipo de apuntador genérico (pointer)Turbo Pascal permite un tipo especial de definición de apuntador: "genérico" o "no tipeado".Difiere del apuntador estándar en que no tiene un tipo base, no está definido como un punterohacia algún tipo, sino simplemente como una variable de tipo pointer.

Ejemplo:

Var enlace : pointer; P1,P2 : ^integer; Q1,Q2 : ^char;begin New(P1); New(P2); P1^:=10; enlace:=P1; {enlace apunta a un apuntador de enteros} P2:=enlace; New(Q1); New(Q2); Q1^:='A'; enlace:= Q1; {enlace apunta a un apuntador de carácter} Q2:=enlace; WriteLn('P1= ',P1^,' P2= ',P2^); WriteLn('Q1= ',Q1^,' Q2= ',Q2^)end.El resultado es:

P1=10 P2=10Q1=A Q2= A

7.4 La asignación de memoria en Turbo PascalTurbo Pascal divide la memoria de su computadora en cuatro partes: el segmento de código, elsegmento de datos, el segmento de pila (stack) y el segmento de montículo o almacenamientodinámico (heap). Técnicamente la pila y el montículo no están totalmente separados, perofuncionan como entidades separadas.

Page 95: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

95

Cima de la memoria DOS

Memoria baja

Figura 7.1 Mapa de memoria de Turbo Pascal 5.X,6.0 y 7.0

El segmento de datos está claramente dedicado al almacenamiento de datos, pero en los otros tressegmentos también pueden almacenarse datos. La figura 7.1 nos muestra el mapa de memoriasimplificada de Turbo Pascal 5.X, 6.0 y 7.0 cada módulo (que incluye el programa principal ycada unidad) tiene su propio segmento de código. El programa principal ocupa el primersegmento de unidades (en orden inverso de cómo están listadas en la cláusula Uses) y el últimosegmento de código está ocupado por la librería en tiempo de ejecución.

El tamaño de un segmento de código no puede exceder de 64k, pero el tamaño total del códigoestá limitado sólo por la memoria disponible. En segmento de datos contiene todas las constantescon tipo seguidas por todas las variables globales. El tamaño del segmento de pila no puedeexceder de 64k (el tamaño por defecto es 16k, que se pueden modificar con la directiva $M).

El buffer o memoria intermedia de recubrimiento (overlay) se utiliza por la unidad estandarOverlay para almacenar código recubierto. Si el programa no tiene recubrimiento, el tamaño dela memoria intermedia del recubrimiento es cero.

Page 96: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

96

Figura 7.2 Mapa práctico de memoria de Turbo Pascal 5.X,6.0 y 7.0

La figura 7.2 (modificación de la 7.1) muestra cómo queda la memoria cuando un programaarranca, y en ella se observa que todas las variables locales se almacenan en la pila (stack) y lasvariables globales (también llamada estáticas) se almacenan en el segmento de datos. El código yel segmento de datos están localizados en la parte baja de la memoria y la pila (stack) y elalmacenamiento dinámico o montículo (heap) ocupan la zona alta de memoria.

El diagrama de la figura 7.2 muestra también que la pila crece hacia abajo en la memoria y elmontículo crece hacia arriba en la memoria. Aunque la pila y el montículo comparten la mismazona de memoria, ellas nunca deben solaparse (recubrirse).

La mayoría de las variables que se declaran en Turbo Pascal son estáticas, su tamaño se fija entiempo de compilación y no pueden variar. Por el contrario, el montículo almacena variablesdinámicas.

7.4.1 El montículo (heap)El montículo o heap (pila de variables dinámicas o almacenamiento dinámico) almacenavariables dinámicas, esto es, las variables asignadas a través de los procedimientos estándar New

Page 97: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

97

y GetMem. El montículo puede crecer o disminuir en el segmento correspondiente, ya que utilizatipos de datos dinámicos: los apuntadores, que pueden crear o liberar variables dinámicasmientras el programa se está ejecutando. El resúmen, las variables tipo apuntador pueden utilizary reutilizar la memoria montículo.

El tamaño real del montículo depende de los valores mínimos y máximos que pueden fijarse conla directiva del compilador $M. El tamaño mínimo es de 0 bytes, y el máximo por defecto es de640Kb; esto significa que por defecto el montículo ocupará toda la memoria restante (640Kbviene definida por la máxima memoria direccionable por el DOS, aunque los procesadores8086/88 tienen dieciséis segmentos que por un valor de 64k de RAM resultaría 1,048,560 bytes= 1 MegaByte).

El límite inferior del montículo se almacena en la variable HeapOrg, y el límite o cota superior(límite inferior de la memoria libre) se almacena en la variable HeapPtr. Cada vez que unavariable dinámica se asigna en el montículo (vía New o GetMem), el gestor de la pila mueveGeatPtr hacia arriba del tamaño de la variable.

El uso de las variables puntero en el montículo ofrece dos ventajas principales: Primero seamplia la cantidad total del espacio de datos disponibles en un programa; el segmento de datosestá limitado a 64k, pero el montículo, como ya se ha citado, está limitado sólo por la cantidad deRAM en su computadora. La segunda ventaja es permitir que su programa se ejecute con menosmemoria. Por ejemplo, un programa puede tener dos estructuras de datos muy grandes, pero sólouna de ellas se utiliza en cada momento. Si estas estructuras de datos se declaran globalmente,ellas residen en el segmento de datos y ocupan memoria en todo momento. Sin embargo, si estasestructuras de datos se definen como apuntadores, se pueden poner en el montículo y quitarsecuando no se necesiten, reduciendo los requisitos de memoria.

7.4.2 Métodos de liberación de memoriaLos subprogramas que gestionan el montículo o almacenamiento dinámico son :

Asignación dinámica de memoria Espacio ocupado en memoria

NewDispose MaxAvail

MarkRelease MemAvail

GetMemFreeMem

7.4.3 New y DisposeCuando Dispose libera o destruye una variable dinámica, puede dejar un agujero en el montículo.Si se hace uso frecuente de New y Dispose, puede llegar a producirse una acumulación deespacio de memoria inservible "basura" (garbage). Algunos sistemas Pascal proporcionan rutinasespecificas para comprimir esa información inservible (garbage collection), Turbo Pascal no las

Page 98: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

98

soporta, pero sí utiliza un sistema de gestión de la memoria montículo muy sofisticada queminimiza la pérdida de esos espacios inservibles. Los procedimientos Mark y Releaseproporcionan un método alternativo de gestión de memoria montículo que eliminan la necesidadde la operación "eliminar basura". Sin embargo, hay un inconveniente: Dispose no es compatiblecon Mark y Release.

7.4.4 Mark y ReleaseMark y Release son una alternativa a utilizar New y Dispose para asignar memoriadinámicamente.

El procedimiento Mark registra la dirección de la parte superior del montículo en una variablepuntero. El procedimiento Release devuelve el montículo a un estado dado (restaura ladirección).

Formato:

Mark (varpunt) Release(varpunt)

varpunt Variable puntero

Nota :

Dispose y Release son métodos incompatibles de recuperación de memoria. Puede elegir utilizaruno u otro, nunca utilizar ambos en el mismo programa.

7.4.5 GetMem y FreeMemUn tercer método de asignar memoria dinámica es GetMem y FreeMem. Se asemejan a New yDispose, en que asignan o liberan memoria, pero GetMem y FreeMem pueden especificar cuántamemoria se desea asignar con independencia del tipo de variable que está utilizando. Se puedenasignar bloques de memoria en la pila de una unidad de datos cuyo tamaño no se conoce entiempo de compilación.

GetMem crea una nueva variable dinámica del tamaño especificado y pone la dirección delbloque en una variable puntero.

Formato:

GetMem(varapunt,tamaño)

varapunt variable puntero de cualquier tipo punterotamaño expresión de tipo word

FreeMem libera una variable dinámica de un tamaño dado.

Page 99: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

99

Formato:

FreeMem(varapunt,tamaño)

Las variables asignadas con GetMem se liberan con FreeMem.

Ejemplo

GetMem(i,50);i:=22;WriteLn(i);FreeMem(i,50);Nota :

El número de bytes especificado en FreeMem debe de concordar con el especificado enGetMem. No se debe utilizar Dispose en lugar de FreeMem.

7.4.6 MemAvail y MaxAvailEl conocimiento de cuánta memoria está realmente disponible para variables dinámicas puedeser crítico. Turbo Pascal lleva un registro de cuanta memoria queda en el montículo, de modoque si se solicita más de la disponible, se generará un error en tiempo de ejecución. La soluciónes no crear una variable dinámica que sea mayor que la memoria disponible en el montículo.Turbo Pascal proporciona dos funciones para medir la memoria disponible: MemAvail yMaxAvail.

MaxAvail devuelve el tamaño del bloque libre contíguo más grande del montículo,correspondiente al tamaño de la variable dinámica más grande que se puede asignar a la vez. (Elvalor devuelto es un entero largo.)

Formato:

MaxAvail

MemAvail devuelve un valor (del tipo entero largo) que indica, en bytes, la cantidad total dememoria disponible para variables dinámicas.

Formato:

MemAvail

Ejemplo:

begin WriteLn(MemAvail,' bytes disponible'); WriteLn('Bloque libre más grande : ',

Page 100: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

100

MaxAvail,' bytes')end.

7.5 Listas enlazadasCuando se procesan conjuntos de datos cuyo espacio de almacenamiento no se puede predecir apriori ( en tiempo de compilación) y además la actividad de los mismos (inserciones y borrados)es frecuente, las estructuras de datos estáticas (los arrays) no son adecuadas para suimplementación. Las razones son varias:

Los arrays deben ser declarados en tamaño en el programa fuente, de modo que si se elige unomayor que el necesario, entonces se desperdicia espacio de memoria.

La operación de añadir datos al final de la lista (el arrays) es un proceso rápido; sin embargo, lasinserciones y eliminaciones en el interior del array son lentas y complejas, ya que puede sernecesario desplazar cada elemento del array para hacer espacio al nuevo elemento, o bien cerrarel espacio dejado por una eliminación.Las listas enlazadas son una secuencia de nodos que se encuentran enlazados cada uno con elsiguiente mediante una liga (enlace) o apuntador. Cada elemento (nodo) de una lista enlazadadebe tener dos campos: un campo (datos) que contiene el valor de ese elemento y un campoliga(apuntador) que indica la posición del siguiente elemento.

Nodo de una lista enlazada

Los elementos de una lista están conectados o "enlazados" mediante sus campos liga oapuntador. Los componentes de un nodo se llaman campos. El campo liga apunta (indica ladirección) al siguiente nodo de la lista. Existe una marca de fin de lista, que es la constante nil,también representada por el signo eléctrico de tierra.

El campo datos puede contener cualquier tipo estándar o definido por el usuario. El campo ligacontiene el punto al siguiente elemento de la lista.

Formato de declaración de un nodo (por ejemplo, de enteros)

Type nodo = ^enteros;

Page 101: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

101

enteros = record numero :integer; liga : nodo end;

Lista enlazada de enteros

Por medio del siguiente programa se ejemplificarán las diversas operaciones con listas enlazadas:

inicialización, creación, recorrido, inserción, borrado , busqueda.

Program Listas_enlazadas; {El siguiente programa realiza las operaciones de altas,bajas y consultas del control de empleados por medio de listas enlazadas}Uses Crt;Const esc = #27;Type nodos = ^datos; datos = record clave : string[3]; nombre : string[30]; puesto : string[20]; sueldo : real; liga : nodos end;

Var p,q,inicio:nodos; tecla :char;

{procedimiento para insertar un nodo al final de la lista}

Page 102: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

102

procedure inserta_nodo(var p : nodos);begin if inicio=nil then inicio:=p else q^.liga:=p; q:=pend;

procedure elimina_nodo(var p,q:nodos);begin if p=inicio then begin if inicio^.liga=nil then inicio:=nil else inicio:=inicio^.liga end else q^.liga := p^.liga; dispose(p)end;

function busca_clave(var p,q:nodos;clave:string):boolean;begin if inicio <> nil then begin p:=inicio; While ((p^.clave<>clave)and (p^.liga<>nil)) do begin q:=p; p:=p^.liga end; if p^.clave=clave then busca_clave:=true else busca_clave:=false end else busca_clave:=falseend;

procedure libera_memoria;begin p:=inicio;

Page 103: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

103

while(p<>nil) do begin q:=p; p:=p^.liga; dispose(q) endend;

procedure altas;Var otro:char;begin Repeat ClrScr; gotoxy(30,5);Write('Altas de empleados'); New(p); p^.liga:=nil; {inicializa la liga a nil} gotoxy(25,7);Write('Clave : '); ReadLn(p^.clave); gotoxy(25,8);Write('Nombre : '); ReadLn(p^.nombre); gotoxy(25,9);Write('Puesto : '); ReadLn(p^.puesto); Repeat {$I-} {validación de entrada de datos} gotoxy(25,10);write('Sueldo : '); ReadLn(p^.sueldo); {$I+} until IOResult=0; inserta_nodo(p); gotoxy(20,22);write('Desea dar otra alta s/n? '); otro:=ReadKey until otro in ['n','N',Esc]end;

procedure bajas;Var otro :char; clave:string[3];begin Repeat ClrScr; gotoxy(30,5);Write('Bajas de empleados'); gotoxy(25,7);Write('Clave : ');

Page 104: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

104

ReadLn(clave); if busca_clave(p,q,clave) then begin gotoxy(25,8);Write('Nombre : '); Write(p^.nombre); gotoxy(25,9);Write('Puesto : '); Write(p^.puesto); gotoxy(25,10);write('Sueldo : '); Write(p^.sueldo:6:2); gotoxy(20,15);Write('Desea eliminarlo s/n? '); otro:=ReadKey;Write(otro); if otro in['s','S'] then elimina_nodo(p,q) end else begin gotoxy(20,10); Write('La clave no existe...') end; gotoxy(20,22);write('Desea dar otra baja s/n? '); otro:=ReadKey until otro in ['n','N',Esc]end;

procedure consultas;begin p:=inicio; while p<>nil do begin ClrScr; gotoxy(30,5);Write('Consulta de empleados'); gotoxy(25,7);Write('Clave : '); Write(p^.clave); gotoxy(25,8);Write('Nombre : '); Write(p^.nombre); gotoxy(25,9);Write('Puesto : '); Write(p^.puesto); gotoxy(25,10);write('Sueldo : '); Write(p^.sueldo:6:2); gotoxy(20,22);Write('Presione una tecla...'); p:=p^.liga; ReadKey endend;

Page 105: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

105

begin inicio:=nil; Repeat ClrScr; gotoxy(30,5);Write('Control de empleados'); gotoxy(35,8);Write('1. Altas'); gotoxy(35,9);Write('2. Bajas'); gotoxy(35,10);write('3. Consultas'); gotoxy(35,11);Write('4. Salir (Esc)'); gotoxy(35,13);Write('Opción [ ]'); gotoxy(43,13); tecla:=ReadKey; case tecla of '1' :altas; '2' :bajas; '3' :consultas end until tecla in ['4',esc]; libera_memoria; ClrScrend.

8.1 Conceptos básicosUn archivo es el módulo básico de información manejado por el Sistema Operativo. El SistemaOperativo es un conjunto de programas cuya función es administrar los recursos del Sistema deCómputo. Por ejemplo, un programa fuente es almacenado como un archivo. Primero esintroducido en la memoria RAM por medio de un programa editor, y después es almacenadocomo un archivo de texto en un medio de almacenamiento permanente (cinta, disco flexible,disco duro). Una vez que el programa fuente ha sido compilado, el programa resultante de lacompilación viene a ser un archivo binario.

En Pascal, un archivo es una secuencia de elementos que pertenecen al mismo tipo o estructura,esto es que un archivo puede ser una secuencia de caracteres, números o registros, por lo que surepresentación lógica puede hacerse como una secuencia de módulos del mismo tamaño, talcomo se presenta en la siguiente figura.

En el vocabulario de manejo de archivos, a cada elemento de un archivo se le llama registro. EnPascal, la numeración de los registros empieza con el número CERO , por lo que al elemento_1se le llamará registro 0, al elemento_2 registro 1, y así sucesivamente hasta llegar a la marca defin de archivo EOF.

Page 106: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

106

Turbo Pascal difiere significativamente de Pascal estándar por la forma en que maneja losarchivos.

En Pascal estándar, los archivos son formalmente definidos independientemente del medio enque residan. Este método de definición fue inspirado por los archivos de tarjetas perforadas ycintas magnéticas, las cuales eran los medios de almacenamiento comúnmente usados cuandoPascal fue definido por primera vez. Como resultado, todo acceso a cualquier archivo en Pascalestándar es secuencial( registro por registro ) tal como se realiza en las tarjetas perforadas ycintas magnéticas.

En Turbo Pascal los archivos son definidos como archivos de disco. Los discos son actualmentelos dispositivos de almacenamiento más utilizados en las microcomputadoras. Los mecanismosde acceso secuencial proporcionados por Pascal estándar son algunas veces inconvenientes einsuficientes para los archivos basados en discos de acceso aleatorio, por lo que Turbo Pascalprovee nuevas estructuras y mecanismos de acceso a los archivos.

La primera gran diferencia entre Turbo Pascal y Pascal estándar, es la forma en que enlazan losarchivos a un programa. En Pascal estándar, se abren los archivos referenciando su nombre dearchivo en el encabezado del programa, y se cierran cuando el programa termina. En TurboPascal, los archivos de disco deben enlazarse a una variable de archivo particular con elprocedimiento:

Assign(variable_archivo,nombre_archivo);y deben ser preparados para procesarse ( abiertos ) con: reset(variable_archivo) orewrite(variable_archivo) antes de ser utilizados.

Además, los archivos deben ser explícitamente cerrados por medio de close(variable_archivo),después de que han sido utilizados, o se perderán los datos que estén en la memoria auxiliar(variable_archivo) .

variable_archivo es el nombre de la memoria auxiliar (buffer), por medio de la cual el programamanejará los datos hacia o desde el archivo en disco.

nombre_archivo es el nombre que identifica al archivo en el disco.

reset abre un archivo existente para procesamiento y coloca el apuntador de registro en el primerregistro (0).

rewrite crea un nuevo archivo (o sobre-escribe en uno existente) y lo abre para procesamientocon el apuntador de registro colocado en el registro 0.

En el caso de un archivo de tipo text, reset hará que el archivo sólo pueda ser usado paraoperaciones de lectura , mientras que rewrite sólo permitirá operaciones de escritura.

Page 107: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

107

Los nombres de archivo válidos son cadenas de 1 a 8 caracteres seguidos por una extensiónopcional consistente de un punto y hasta tres caracteres. A estos nombres también se les llama"nombres de archivo externo", puesto que son los nombres con que se graban en el disco.

8.2 Tipos de archivosExisten tres tipos de archivos de datos en Turbo Pascal :

texto (text) o secuenciales (acceso secuencial),tipeados (tipificados) o con tipo (file of) (acceso aleatorio), aleatorios,no tipeados (no tipificados) o sin tipo (file).Archivos de texto : (secuenciales) Son archivos que contienen texto (carácter ASCII)Archivos con tipo :(aleatorios) Archivos que contienen datos de cualquier tipo como integer, real, byte, record,datos con estructuras.Archivos sin tipo : Archivos en los que no se conoce su estructura ni sucontenido; están concebidos para acceso de bajo nivela los datos de un disco (E/S de bytes).

8.3 Tipos de acceso a un archivoExisten dos modalidades para acceder a un archivo de datos : acceso secuencial y acceso directoo aleatorio. El acceso secuencial exige elemento a elemento, es necesario una exploraciónsecuencial comenzando desde el primer elemento. El acceso directo permite procesar o acceder aun elemento determinado haciendo una referencia directamente por su posición en el soporte dealmacenamiento. Pascal estándar sólo admite el acceso secuencial, pero Turbo Pascal permite elacceso directo.

Acceso secuencial

Acceso directo

8.4 Declaración de archivosLa declaración de un archivo consta de dos pasos :

Page 108: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

108

1. Declaración del tipo de archivo adecuado :

1.1 file of char archivo de texto file of text 1.2 file of <tipo> archivo con tipo 1.3 file archivo sin tipo2. Declaración de una variable archivo de un tipo de archivo declarado.

Declaración de un tipo archivo (file)

Un tipo archivo se declara de igual modo que cualquier otro tipo de dato definido por el usuario:en la sección de declaración de tipos (type).

Formato:

Type nombre = file of tipo de datos

nombre identificador que se asigna como nombre del tipo archivotipo de datos tipo de datos de los elementos del archivo

Ejemplos:

type ArchEntero = file of integer;{archivo de enteros}type ArchCarac = file of char;{archivo de carácteres}type nomina = file of empleado;{archivo de registros}type ciudad = file of string[20];{archivo de cadenas}Variable tipo archivo (file)

Para definir un archivo con tipos, simplemente declare una variable archivo.

Ejemplo:

Var arch_nomina : nomina; enteros : ArchEntero;

Page 109: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

109

O también

Var arch_nomina : file of empleado; enteros : file of integer;Variables de tipo texto y sin tipo

Este tipo de variables no requiere ninguna declaración de tipos; así pues, se puede declarar conun identificador predefinido (Text,File):

Var texto : text; Archivo : file;

8.5 Gestión de archivosLa siguiente tabla recopila todos los procedimientos y funciones estándar para tratamiento ymanipulación de archivos en Turbo Pascal.

Todos tipos de archivos Archivos de texto Archivos sin tipo

ProcedimientosAssign Append BlockReadChDir Flush BlockWriteClose ReadErase ReadLnGetDir SetTexBufMkDir WriteRename WriteLnResetRewriteRmDirFuncionesEof EolnIOResult SeekEof SeekEolnProcedimientos y funciones sobre cualquier tipo de variableexcepto archivos de texto

FilePosFileSizeSeekTruncate

Page 110: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

110

Assign

Éste procedimiento realiza la operación de asignar un archivo mediante una correspondenciaentre una variable tipo archivo con un archivo externo situado en un disco.

Formato :

assign (f,nombre)

f nombre interno del archivo por el que se conoce el archivo dentro del programa(por ejemplo, el utilizado en la declaraciónnombre nombre externo con el que se conoce el archivo por el sistema operativo (por ejemplo : 'a:program4.pas'); es una cadena que se define como una constante en el programa o bien una variable cuyo valor se lee interactivamente; puede ser una unidad:nombre.extensión o bien la ruta completa a un archivo.

Ejemplo :

Const ruta ='c:\tp\lista.pas';Var ArchText : Text; ArchBin : File;begin assign (ArchText,ruta); assign (ArchBin,'alumnos.dbf') . . .ChDir

Formato:

ChDir(s)

Cambia el subdirectorio actual al especificado por la variable de cadena s.

Ejemplo (asignación del archivo lista.pas ubicado en c:\tp\lista.pas)

Page 111: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

111

Var ArchText : Text;begin ChDir('C:\tp\'); assign (ArchText,'lista.pas'); . . .Close

Éste procedimiento nos permite cerrar los archivos después que han sido utilizados, si losarchivos no son cerrados se perderán los datos que se encuentran en la memoria auxiliar.

Formato :

Close (f)

f Variable de archivo.Ejemplo:

Var ArchText : Text;begin assign (ArchText,'c:\tp\lista.pas'); rewrite(ArchText); close(ArchText); . . .Erase

Éste procedimiento nos permite borrar un archivo, el archivo a borrar no debe estar abierto. Paraborrar un archivo se debe realizar lo siguiente :

Asignar el archivo externo a una variable de archivo.Llamar al procedimiento eraseFormato:

erase(s)

Borra (elimina) un archivo cuya ruta de acceso está especificada por s.

Ejemplo:

Var ArchText : Text;

Page 112: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

112

begin assign (ArchText,'c:\tp\lista.pas'); erase(ArchText); . . .GetDir

Formato :

GetDir(i,s)

Busca el nombre del subdirectorio actual. El primer parámetro i es un entero que representa launidad : i=0 (unidad de disco actual, por defecto), i=1 (unidad A), i=2 (unidad B), etc. Despuésde la llamada, la variable de cadena s contiene el subdirectorio actual de esa unidad.

Ejemplo:

Var s:string[80];begin ChDir('c:\tp\'); GetDir(0,s); WriteLn(s); {Resulta c:\tp} . . .MkDir

Formato:

MkDir(s)

Crea un nuevo subdirectorio de nombre s.Ejemplo:

begin MkDir('C:\nuevo\'); . . .Rename

Éste procedimiento renombra (cambia el nombre) un archivo externo. Para renombrar un archivose debe hacer los siguiente :

Page 113: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

113

Asignar un archivo a la variable archivoLlamar al procedimiento renameFormato:

Rename(f,nombre_archivo)

f variable de archivonombre_archivo nuevo nombre del archivoEjemplo :

Var ArchText : Text;begin Assign (ArchText,'viejo.pas'); Rename (ArchText,'nuevo.pas'); . . .Reset

Éste procedimiento abre un archivo existente para una operación de lectura. Si se intenta llamar aReset y el archivo especificado no existe, se producirá un error de E/S (entrada/salida).

Formato :

Reset(f)

f variable de tipo archivoEjemplo:

Var ArchText : Text;begin Assign (ArchText,'lista.pas'); Reset(ArchText); . . .Rewrite

Crea y abre un nuevo archivo. Si el archivo ya existe, Rewrite borra su contenido; en casocontrario, el archivo queda abierto para una operación de escritura.

Formato:

Rewrite(f)

Page 114: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

114

f variable de archivoEjemplo:

Var ArchText : Text;begin Assign (ArchText,'lista.pas'); Rewrite(ArchText); . . .RmDir

Formato

RmDir(s)

Elimina el subdirectorio de nombre s.begin RmDir('C:\nuevo\'); . . .Append

El procedimiento Append abre un archivo existente para añadir datos al final del mismo.

Formato:

Append(f)

f variable de archivo de texto que debe haber sido asociada con un archivo externo por medio deAssign.

Si el archivo no existe, se produce un error; y si ya estaba abierto, primero se cierra y luego sereabre.

Ejemplo:

Var ArchText : Text;begin Assign (ArchText,'lista.pas'); Rewrite(ArchText); WriteLn(ArchText,'Primera línea');

Page 115: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

115

Close(ArchText); Append(ArchText); WriteLn(ArchText,'Agrega esto al último'); Close(ArchText)end.

FlushEl procedimiento Flush vacía el buffer de un archivo de texto abierto para salida. Cuando unarchivo de texto es abierto para escritura usando Rewrite o Append, la llamada a Flush llenará elbuffer asociado al archivo. Esto garantiza que todos los carácteres escritos en el archivo en esetiempo sean escritos en el archivo externo. Flush no afecta los archivos abiertos para entrada.

Usando la directiva {$I}, IOResult devuelve 0 si esta operación fue realizada con éxito de locontrario retonará un código de error.

Formato:

Flush(f)

f variable de archivo

Ejemplo:

Var ArchText : Text;begin Assign (ArchText,'lista.pas'); Rewrite(ArchText); WriteLn(ArchText,'Primera línea'); WriteLn(ArchText,'Segunda línea'); Flush(ArchText); WriteLn(ArchText,'tercera línea'); WriteLn(ArchText,'Agrega esto al último'); Close(ArchText)end.

ReadEl procedimiento Read se utiliza para la lectura de datos situados en un archivo de tipo texto.

Formato:

Read(f,v1,v2,..)

f variable de archivo de textov1,v2,... variable de tipo char,integer,

Page 116: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

116

real o string

Ejemplo:

Var ArchText : Text; datos : string[20];begin Assign(ArchText,'lista.pas'); Reset(ArchText); Read(ArchText,datos); WriteLn(ArchText,datos); Close(ArchText)end.

ReadLnEl procedimiento ReadLn se utiliza para la lectura de datos situados en un archivo de tipo texto.A diferencia de Read, ReadLn salta al principio de la siguiente línea del archivo. Este salto delínea se produce cuando se han asignado valores a la lista de varibles del procedimiento; en casocontrario, el procedimiento hace caso omiso del control de línea y sigue asignando información.

Formato:

ReadLn(f,v1,v2,..)

f variable de archivo de textov1,v2,... variable de tipo char,integer, real o string

Ejemplo:

Var ArchText : Text; datos : string[20];begin Assign (ArchText,'lista.pas'); Reset(ArchText); ReadLn(ArchText,datos); WriteLn(ArchText,datos); Close(ArchText)end.

Page 117: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

117

SetTextBuf

El procedimiento SetTextBuf asigna un buffer de entrada/salida a un archivo de texto.SetTextBuffer podría nunca ser usado en la apertura de un archivo, aunque éste puede serllamado inmediatamente después de Reset, Rewrite, y Append.

Si se invoca a SetTextBuf en una apertura de archivo las operaciones de entrada/salida sontomadas por éste procedimiento, y se pueden perder datos como resultado de el cambio debuffer.

formato :

SetTextBuf(f,buffer)

Ejemplo:

Var ArchText: Text; Ch: Char; buffer: array[1..4096] of Char; { buffer de 4K}begin Assign(ArchText,'memoria.txt'); {Se utiliza un buffer grande para lecturas más rápidas} SetTextBuf(ArchText,buffer); Reset(ArchText); {Visualiza el archivo en la pantalla} while not Eof(ArchText) do begin Read(ArchText,Ch); Write(Ch) end; Close(ArchText)end.

WriteEl procedimiento Write sirve para escribir datos en un archivo.

Formato:

Write(f,v1,v2,...)

f variable de tipo archivov1,v2,... variables de tipo de datos

Page 118: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

118

Ejemplo:

Var ArchText : Text;begin Assign (ArchText,'nuevo.txt'); Rewrite(ArchText); Write(ArchText,'Está es la primera línea.'); Write(ArchText,'Fin del texto.'); Close(ArchText)end.El contenido del archivo será :Está es la primera línea.Fin del texto.

WriteLnEl procedimiento WriteLn sirve para escribir datos en un archivo. A diferencia de Write,WriteLn incluye un salto de línea para separar el texto.

Formato:

WriteLn(f,v1,v2,...)

f variable de tipo archivov1,v2,... variables de tipo de datos

Ejemplo:

Var ArchText : Text;begin Assign (ArchText,'nuevo.txt'); Rewrite(ArchText); WriteLn(ArchText,'Está es la primera línea.'); WriteLn(ArchText,'Fin del texto.'); Close(ArchText)end.El contenido del archivo será :Está es la primera línea.Fin del texto.

Page 119: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

119

BlockReadTransfiere un bloque de datos de un archivo sin tipo hacia un buffer.

Formato:

BlockRead(arch,buffer,bloques,resul)

arch archivo sin tipobuffer variable de cualquier tipo de longitud suficiente para acoger los datos transferidosbloques expresión que corresponde al número de bloques de 128 bytes a transferir.resul parámetro opcional que indica el número de bloques que se leyeron o escribieron realmente.

BlockWriteTransfiere un buffer de datos hacia un archivo sin tipo.

Formato:

BlockWrite(arch,buffer,bloques,resul)

arch archivo sin tipobuffer variable de cualquier tipo de longitud suficiente para acoger los datos transferidosbloques expresión que corresponde al número de bloques de 128 bytes a transferir.resul parámetro opcional que indica el número de bloques que se leyeron o escribieron realmente.

Ejemplo:

Program CopiaDeArchivos;Var fuente,destino : file; {archivo sin tipo} buffer : array[1..512] of byte;

Page 120: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

120

leidos : integer;begin Assign(fuente,'original.txt'); Assign(destino,'copia.txt'); Reset(fuente,1); Rewrite(destino,1); BlockRead(fuente,buffer,SizeOf(buffer),leidos); while leidos>0 do begin BlockWrite(destino,buffer,SizeOf(buffer),leidos); BlockRead(fuente,buffer,SizeOf(buffer),leidos) end close(fuente); close(destino)end.

EofLa función eof(end of file), fin de archivo, devuelve el estado de un archivo. Es una función detipo lógico que indica si el fin de archivo se ha encontrado; devuelve true si se encontró, false encasi contrario.

Formato:

Eof(f)

f variable de archivoEjemplo:

Var ArchText: Text; Ch: Char;begin Assign(ArchText,'memoria.txt'); Reset(ArchText); {Visualiza el archivo en la pantalla} while not Eof(ArchText) do begin Read(ArchText,Ch); Write(Ch) end; Close(ArchText)end.

Page 121: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

121

EolnLa función Eoln devuelve el estado de fin de línea de un archivo. Es una función de tipo lógico.Devuelve true si la posición actual del archivo (puntero) esta en la marca de fin de línea, o bien siEof(f) es true, el caso contrario devuelve false.

Formato:

Eoln(f)

f variable de archivo de textoVar car :char; ArchText:text;begin Clrscr; Assign(ArchText,'nuevo.txt'); Reset(ArchText); {muestra sola la primera línea} While not(Eoln(ArchText)) do begin Read(ArchText,car); Write(car) endend.

SeekEofRetorna el estado de fin de archivo. Es una función de tipo lógico. Sólo para archivos de texto. Sila posición actual del puntero de archivo se encuentra en la marca de fin de archivo devuelvetrue, de lo contrario retorna false. SeekEof es una función que avanza siempre al siguientecarácter, ignorando por completo los espacios en blanco.

Formato:

SeekEof(f)

f variable de archivo de textoEjemplo:

Var car :char; ArchText:text;begin Clrscr; Assign(ArchText,'nuevo.txt'); Reset(ArchText); {muestra el contenido del archivo}

Page 122: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

122

While not(SeekEof(ArchText)) do begin Read(ArchText,car); Write(car) endend.

SeekEolnRetorna el estado de fin de línea. Es una función de tipo lógico. Sólo para archivos de texto. Si laposición actual del puntero de archivo se encuentra en la marca de fin de línea devuelve true, delo contrario retorna false. SeekEoln es una función que avanza siempre al siguiente carácter,ignorando por completo los espacios en blanco.

Formato:

SeekEoln(f)

f variable de archivo de textoEjemplo:

Var car :char; ArchText:text;begin Clrscr; Assign(ArchText,'nuevo.txt'); Reset(ArchText); {muestra el contenido del archivo} While not(SeekEoln(ArchText)) do begin Read(ArchText,car); Write(car) end; Close(ArchText)end.

IOResultEs una función que devuelve un número entero que indica el código del error de la últimaoperación de E/S; si el valor de retorno es cero, esto nos indica que la operación se hadesarrollado sin problema.

Formato:

IOResult

Page 123: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

123

Ejemplo:

Var ArchText:text; Nerror :integer;begin Clrscr; Assign(ArchText,'nuevo.txt'); {$I-} Reset(ArchText); Nerror:=IOResult; {$I+} if Nerror<>0 then WriteLn('Código de error # ',Nerror) else Close(ArchText)end.

FilePosEstá función devuelve la posición actual del archivo (número de registro), en forma de un enterolargo (longint).

Formato:

FilePos (f)

f varible de tipo archivoNotas :

Devuelve 0 si esta al principio del archivo.Es igual a FileSize(f) si el puntero de posición del archivo esta al final del archivo.FileSize

Está función devuelve el tamaño actual del archivo(número de registros existentes en el archivo).Si el archivo esta vacío devuelve cero.

Formato:

FileSize(f)

f varible de tipo archivo

Page 124: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

124

SeekSitúa el puntero de posición del archivo en el número de registro correspondiente.

Formato:

Seek(f,numreg)

f nombre de archivo (no de tipo text)numreg número de posición del registro, el primer registro es cero; si numreg es menor que 0 o mayor que n (para un archivo de n registros), se producirán resultados impredecibles.

Ejemplo:

Seek(empleados,FileSize(empleados));{está sentecia posicionael puntero al final del archivo}

TruncateEstá función trunca (corta, mutíla) un archivo a partir de la posición actual del puntero delarchivo.

Formato:

Truncate(f)

f varible de tipo archivoSi Truncate se ha ejecutado con éxito IOResult tendrá un valor de cero. El archivo debe estarabierto. Truncate no trabaja en archivos de texto.

Ejemplo:

Var f: file of integer; i,j: integer;begin Assign(f,'prueba.int'); Rewrite(f); for i := 1 to 5 do Write(f,i);

Page 125: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

125

Writeln('Archivo antes de ser truncado :'); Reset(f); while not Eof(f) do begin Read(f,i); Writeln(i) end; Reset(f); for i := 1 to 3 do Read(f,j); { lectura de 3 registros } Truncate(f); { Trunca el archivo apartir de aquí } Writeln; Writeln('Archivo despues de ser truncado:'); Reset(f); while not Eof(f) do begin Read(f,i); Writeln(i) end; Close(f);end.

8.6 Archivos de texto (secuenciales)Un archivo de texto está constituido por elementos que son caracteres Pascal (pertenecientes alcódigo ASCII) .

Un archivo de texto consta de una serie de líneas y separadas por una marca de fin de línea (eoln,"end of file"). La marca de fin de línea es una secuencia de caracteres CR(carriage return) y LF(line feed), que se conoce como retorno de carro y avance de línea. La combinación CR/LF(códigos ASCII 10 y 13) se conoce como delimitador y se obtiene pulsando la tecla Intro (Entero Return).

Un archivo de texto está constituido por una serie de líneas de caracteres separados por CR/LF(pulsación de la tecla Enter, ).

Esto es una prueba de un archivo de textoDonde cada línea de texto finaliza con CR/LF, {línea vacía}Última línea del archivo de texto...Los archivos de texto se terminan con una marca de final de archivo CTRL-Z (eof, end of file).

El Turbo Pascal el delimitador eoln se trata como caracteres independientes: un retorno de carro,que posiciona el cursor (puntero) a la primera columna de la línea actual; un avance de línea, quemueve el cursor a la siguiente línea .

Page 126: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

126

Ejemplo:

archivo de entrada Fin.Tiene 6 caracteres (F, i, n, . ,#10, #13)

Nota: Un archivo de texto similar a un archivo de caracteres (char). La única diferencia es que unarchivo de texto se divide en líneas y un archivo de caracteres no. Los archivos de caracteres seleen y escriben de carácter en carácter, mientras que los archivos de texto se leen línea a línea. Ladeclaración es de la siguiente manera :

Var Arch : file of char;

8.6.1 Declaración de un archivoEl proceso de archivos de texto exige los siguientes pasos:

Declaración del archivo.

Apertura del archivo.

Leer datos del archivo o escribir datos en él.

Cierre del archivo.

La declaración de un archivo consta de dos operaciones:

Definir una variable de tipo archivo Text.

Asociar a esta variable el nombre de un archivo en disco (sentencia Assign).

Formato para la definición de una variable tipo Text:

Var nombre:Text;

Como cualquier otra variable el tipo Text se puede definir local o globalmente; pero al contrarioque otras estructuras, la longitud de una variable archivo no se precisa.

8.6.2 Asignación de archivosEste procedimiento realiza la operación de asignar un archivo mediante una correspondenciaentre una variable tipo archivo con un archivo externo situado en un disco.

Formato :

assign (f,nombre)

Page 127: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

127

f nombre interno del archivo por el que se conoce el archivo dentro del programa, por ejemplo, el utilizado en la declaraciónnombre nombre externo con el que se conoce el archivo por el sistema operativo (por ejemplo : 'a:program4.pas'); es una cadena que se define como una constante en el programa o bien una variable cuyo valor se lee interactivamente; puede ser una unidad: nombre.extensión o bien la ruta completa a un archivo.

Ejemplo :

Const ruta ='c:\tp\lista.pas';Var ArchText : Text; ArchBin : File;begin assign (ArchText,ruta); assign (ArchBin,'alumnos.txt') . . .Después que se ha asignado un identificador de archivo, se prepara el archivo con una de estastres órdenes (procedimientos): Reset, Rewrite, o Append.

8.6.3 Apertura de un ArchivoDespués de haber asignado, un archivo debe ser abierto. Esta operación se realiza por uno de losdos procedimientos predefinidos: rewrite y reset.

ResetEste procedimiento abre un archivo existente para una operación de lectura. Si se intenta llamar aReset y el archivo especificado no existe, se producirá un error de E/S (entrada/salida).

Formato :

Reset(s)

s variable de tipo archivoEjemplo:

Var ArchText : Text;

Page 128: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

128

begin Assign (ArchText,'lista.pas'); Reset(ArchText); . . .RewriteCrea y abre un nuevo archivo. Si el archivo ya existe, Rewrite borra su contenido; en casocontrario, el archivo queda abierto para una operación de escritura.

Formato:

Rewrite(s)

s variable de archivoEjemplo:

Var ArchText : Text;begin Assign (ArchText,'lista.pas'); Rewrite(ArchText); . . .Notas:Si al abrir un archivo de texto que ya existe en el disco con la sentencia Rewrite lo reescribirá (elcontenido anterior a la ejecución de la sentencia Rewrite se perderá).

Por el contrario las sentencias assign y reset suponen la existencia del archivo llamado en eldisco. Si el archivo no existe se producirán errores de ejecución (Runtime error 002 at0BE2:0039). Mediante la directiva {$I-} se puede desactivar la detección de errores deEntrada/Salida y prevenir una parada en la ejecución del programa. Una posible solución es lasiguiente:

Var ArchText : Text;begin Assign (ArchText,'lista.pas'); {$I-} Reset(ArchText); {$I+} if IOResult = 0 then {todo bien} else {error en apertura de archivo}

Page 129: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

129

. . .La valor IOResult será cero si Reset se ha ejecutado correctamente.

8.6.4 Escritura de un archivoUna vez que se ha abierto un archivo para escritura, las sentencias (procedimientos) Write yWriteLn sirven para escribir datos en el nuevo archivo.

Procedimiento Write.

Formato:

Write(f,v1,v2,...)

f variable de tipo archivov1,v2,... variables de tipo de datos

Ejemplo:

Var ArchText : Text;begin Assign (ArchText,'nuevo.txt'); Rewrite(ArchText); Write(ArchText,'Esta es la primera línea.'); Write(ArchText,'Fin del texto.') Close(ArchText)end.El contenido del archivo será :Esta es la primera línea.Fin del texto.

Procedimiento WriteLn

A diferencia de Write, WriteLn incluye un salto de línea para separar el texto.

Formato:

WriteLn(f,v1,v2,...)

f variable de tipo archivov1,v2,... variables de tipo de datos

Page 130: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

130

Ejemplo:

Var ArchText : Text;begin Assign (ArchText,'nuevo.txt'); Rewrite(ArchText); WriteLn(ArchText,'Esta es la primera línea.'); WriteLn(ArchText,'Fin del texto.'); Close(ArchText)end.El contenido del archivo será :Esta es la primera línea.Fin del texto.

8.6.5 Lectura de un archivoLos procedimientos Read y ReadLn se utilizan para la lectura de los datos situados en un archivode tipo texto.

Procedimiento Read.

Formato:

Read(f,v1,v2,..)

f variable de archivo de textov1,v2,... variable de tipo char,integer, real o string

Ejemplo:

Var ArchText : Text; datos : string[20];begin Assign (ArchText,'lista.pas'); Reset(ArchText); Read(ArchText,datos); WriteLn(ArchText,datos); Close(ArchText)end.

Page 131: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

131

Procedimiento ReadLn

EL procedimiento ReadLn se utiliza para la lectura de datos situados en un archivo de tipo texto.A diferencia de Read, ReadLn salta al principio de la siguiente línea del archivo. Esta salto delínea se produce cuando se han asignado valores a la lista de varibles del procedimiento; en casocontrario, el procedimiento hace caso omiso del control de línea y sigue asignando información.

Formato:

ReadLn(f,v1,v2,..)

f variable de archivo de textov1,v2,... variable de tipo char,integer, real o string

Ejemplo:

Var ArchText : Text; datos : string[20];begin Assign (ArchText,'lista.pas'); Reset(ArchText); ReadLn(ArchText,datos); WriteLn(ArchText,datos); Close(ArchText)end.

8.6.6 Añadir datos a un archivoEl procedimiento Append abre un archivo existente para añadir datos al final del mismo.

Formato:

Append(f)

f variable de archivo de texto que debe haber sido asociada con un archivo externo por medio deAssign.

Si el archivo no existe, se produce un error; y si ya estaba abierto, primero se cierra y luego sereabre.

Ejemplo:

Var ArchText : Text;

Page 132: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

132

begin Assign (ArchText,'lista.pas'); Rewrite(ArchText); WriteLn(ArchText,'Primera línea'); Close(ArchText); Append(ArchText); WriteLn(ArchText,'Agrega esto al último'); Close(ArchText)end.

8.7 Archivos de acceso secuencial (con tipo)Dependiendo de la manera en que se accesen los registros de un archivo, se le clasifica comoSECUENCIAL o como DIRECTO.

En el caso de los archivos de ACCESO SECUENCIAL, para tener acceso al registro localizadoen la posición N, se deben haber accesado los N-1 registros previos, en un orden secuencial.

Cuando se tienen pocos registros en un archivo, o que los registros son pequeños, la diferenciaentre los tiempos de acceso de forma secuencial y directa puede no ser perceptible para elusuario; sin embargo, la diferencia viene a ser significativa cuando se manejan archivos congrandes cantidades de información.

La forma de manejar los archivos de acceso secuencial es más sencilla en la mayoría de loslenguajes de programación, por lo que su estudio se antepone al de los archivos de accesodirecto.

El manejo secuencial de un archivo es recomendable cuando se deben procesar todos o lamayoría de los registros, como por ejemplo en los casos de una nómina de empleados o en laelaboración de reportes contables.

8.7.1 Declaración y asignación de ArchivosLa declaración de un archivo con tipo se efectúa con la ayuda de las palabras reservadas file of.

El procedimiento de asignación es idéntico al utilizado anteriormente.

Ejemplo:

Type datos = record clave : string[3]; nombre : string[30]; puesto : string[20]; sueldo : real; end;Var

Page 133: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

133

archivo:file of datos;begin Assign(archivo,'empleado.dat'); . . .

8.7.2 Escritura de un archivoUna vez que se ha abierto un archivo para escritura, con el procedimiento Rewrite o Append(caso de añadir registros) se utilizan las sentencias (procedimientos) Write para escribir datos enel archivo.

Como ejemplo, veamos el siguiente procedimiento que sirve para escribir en el archivo registrosque están formados por los campos :

clave :de tipo cadena ( 3 caracteres ) ,nombre :de tipo cadena ( 30 caracteres ),puesto :de tipo cadena ( 20 caracteres), ysueldo :de tipo real ( 6 octetos ) .

El siguiente ejemplo que se manejará a lo largo de está unidad es idéntico al realizado en launidad siete de listas enlazadas (Listas_enlazadas) . Con la única diferencia que el lugar de listasenlazadas utilizaremos archivos.

procedure altas;Var otro :char; CodError:integer;begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} Case CodError Of {Caso cero el archivo ya existe, ubicarse en el último registro, para añadir registros nuevos} 0: Seek(archivo,FileSize(archivo)); {caso dos el archivo no existe, se crea con Rewrite, listo para escritura} 2: Rewrite(archivo) {caso contrario existe un error} else

Page 134: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

134

begin error(CodError); exit; {Salta al fin del procedimiento} end end; With registro Do begin Repeat ClrScr; gotoxy(30,5);Write('Altas de empleados'); gotoxy(25,7);Write('Clave : '); ReadLn(clave); gotoxy(25,8);Write('Nombre : '); ReadLn(nombre); gotoxy(25,9);Write('Puesto : '); ReadLn(puesto); Repeat {$I-} {validación de entrada de datos} gotoxy(25,10);write('Sueldo : '); ReadLn(sueldo); {$I+} until IOResult=0; Write(archivo,registro); {Escribe los datos del registro en el archivo} gotoxy(20,22);write('Desea dar otra alta s/n? '); otro:=ReadKey until otro in ['n','N',Esc] end; Close(archivo)end;

Nota : Al final de la unidad se presentará todo el código completo del programa.

8.7.3 Lectura de un archivoNormalmente la lectura de un archivo no tiene sentido por si sola, sino que adquiere significadocuando se asocia con la actualización del archivo o con la generación de un reporte cualquiera.

De alguna manera podemos pensar en la lectura de un archivo como un proceso inverso al de sucreación, puesto que ahora se pasará la información desde el disco hacia la memoria auxiliar.

Veamos un procedimiento que lea todos los registros del archivo "empleados.dat", y losdespliegue en la pantalla.

En este procedimiento se asocia la lectura de los registros con la generación de un reporte através de la pantalla.

Page 135: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

135

procedure consultas;Var CodError:integer;begin {$I-} reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then error(CodError) else begin With registro Do begin while not(Eof(archivo)) Do begin ClrScr; Read(archivo,registro); gotoxy(30,5);Write('Consulta de empleados'); gotoxy(25,7);Write('Clave : '); Write(clave); gotoxy(25,8);Write('Nombre : '); Write(nombre); gotoxy(25,9);Write('Puesto : '); Write(puesto); gotoxy(25,10);write('Sueldo : '); Write(sueldo:6:2); gotoxy(20,22);Write('Presione una tecla...'); ReadKey end end; Close(archivo) end end;

Nota : Al final de la unidad se presentará todo el código completo del programa.

8.7.4 Actualización de un archivoLa actualización (modificación) de un archivo incluye las acciones de:

Borrar registros.Agregar registros (visto anteriormente 8.7.3).Modificar los datos contenidos en los campos de un registro.En un acceso secuencial, toda modificación de un archivo requiere la aplicación de un métodopadre-hijo (sólo para borrar y modificar datos), el cual se realiza con los siguientes pasos:

Page 136: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

136

Se abre el archivo a modificar (padre) en el modo de lecturaSe abre un nuevo archivo (hijo) en el modo de escritura, para guardar en él la versiónmodificada.Se copian de padre a hijo los registros que permanecerán inalterados.Se leen del padre los registros a modificar, los cuales una vez modificados se graban en hijo.Se cierran los archivos padre e hijo.Se borra el archivo padre.Se renombra el hijo con el nombre del padre.A continuación de presenta un procedimiento para borrar un registro del archivo "empleado.dat"utilizando el método padre-hijo.

function busca_clave(clave:string):Boolean;Var CodError:integer;begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then begin error(CodError); busca_clave:=false end else begin Read(archivo,registro); While (not(Eof(archivo)) and (clave<>registro.clave)) Do Read(archivo,registro); if(clave=registro.clave) then busca_clave:=true else busca_clave:=false; Close(archivo) end;end;

{tipo 1 eliminar un registro, tipo 2 se efectúo una modificación}procedure padre_hijo(clave:string;tipo:byte;aux:datos);Var copia : file of datos;begin Assign(copia,'hijo.dat'); Rewrite(copia);

Page 137: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

137

Reset(archivo); {proceso de intercambio padre hijo}

While not(Eof(archivo)) Do begin Read(archivo,registro); if ((registro.clave<>clave)) then Write(copia,registro); if((registro.clave=clave) and (tipo=2)) then

{caso modificación} Write(copia,aux); {escritura en hijo} end; Close(copia);Close(archivo); Erase(archivo); {borra el padre} Rename(copia,'empleados.dat') {renombra 'hijo.dat'con 'empleado.dat'}end;procedure bajas;Var otro :char; clave :string[3]; CodError:integer;begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then begin error(CodError); exit end; Close(archivo); Repeat ClrScr; gotoxy(30,5);Write('Bajas de empleados'); gotoxy(25,7);Write('Clave : '); ReadLn(clave); if busca_clave(clave) then begin gotoxy(25,8);Write('Nombre : '); Write(registro.nombre); gotoxy(25,9);Write('Puesto : '); Write(registro.puesto); gotoxy(25,10);Write('Sueldo : '); Write(registro.sueldo:6:2);

Page 138: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

138

gotoxy(20,15);Write('Desea eliminarlo s/n? '); otro:=ReadKey;Write(otro); if otro in['s','S'] then begin padre_hijo(clave,1,registro); gotoxy(20,17);Write('Registro Eliminado...') end; end else begin gotoxy(20,10); Write('La clave no existe...') end; gotoxy(20,22);Write('Desea dar otra baja s/n? '); otro:=ReadKey until otro in ['n','N',Esc]end;

{Procedimiento para modificación delos campos de un archivo}procedure cambios;Var otro :char; clave :string[3]; CodError:integer; aux :datos;begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then begin error(CodError); exit end; Close(archivo); Repeat ClrScr; gotoxy(30,5);Write('Modificaciones de empleados'); gotoxy(25,6);Write('Si no desea modificar presione Enter'); gotoxy(25,7);Write('Clave : '); ReadLn(clave); if busca_clave(clave) then begin move(registro,aux,SizeOf(aux)); gotoxy(1,10);Write('Nombre : ');Write(registro.nombre);

Page 139: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

139

gotoxy(35,10);Write('Nuevo nombre : ');ReadLn(aux.nombre); if(length(aux.nombre)=0) then begin aux.nombre:=registro.nombre; gotoxy(50,10);WriteLn(aux.nombre); end; gotoxy(1,11);Write('Puesto : ');Write(registro.puesto); gotoxy(35,11);Write('Nuevo puesto : ');ReadLn(aux.puesto); if(length(aux.puesto)=0) then begin aux.puesto:=registro.puesto; gotoxy(50,11);WriteLn(aux.puesto); end; gotoxy(1,12);write('Sueldo : ');Write(registro.sueldo:6:2); Repeat {$I-} {validación de entrada de datos} gotoxy(35,12);Write('Nuevo sueldo : ');ReadLn(aux.sueldo); {$I+} until (IOResult=0); if(aux.sueldo=0) then begin aux.sueldo:=registro.sueldo; gotoxy(50,12);WriteLn(aux.sueldo:6:2); end; gotoxy(20,15);Write('Las modificaciones están correctas s/n? '); otro:=ReadKey;Write(otro); if otro in['s','S'] then begin padre_hijo(clave,2,aux); gotoxy(20,17);Write('Registro modificado...') end; end else begin gotoxy(20,10); Write('La clave no existe...') end; gotoxy(20,22);write('Desea realizar otra modificación s/n? '); otro:=ReadKey until otro in ['n','N',Esc]end

Archivo con acceso secuencialProgram Secuencial; {El siguiente programa realiza las operaciones de altas,bajas y consultas del control de empleados por medio de acceso secuencial

Page 140: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

140

a un archivo con tipo}Uses Crt;Const esc = #27; enter= #13;Type datos = record clave : string[3]; nombre : string[30]; puesto : string[20]; sueldo : real; end;Var archivo :file of datos; registro :datos; tecla :char;

procedure error(error:integer);begin gotoxy(20,21); Case error Of 152:Write('UNIDAD NO PREPARADA'); 162:Write('FALLA EN EL HARDWARE'); 104:Write('ARCHIVO NO ABIERTO PARA ENTRADA'); 100:Write('ERROR DE LECTURA EN DISCO'); 150:Write('PROTEGIDO CONTRA ESCRITURA'); 2 :Write('EL ARCHIVO NO EXISTE') end; ReadKeyend;

function busca_clave(clave:string):Boolean;Var CodError:integer;begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then begin error(CodError); busca_clave:=false end else

Page 141: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

141

begin Read(archivo,registro); While (not(Eof(archivo)) and (clave<>registro.clave)) Do Read(archivo,registro); if(clave=registro.clave) then busca_clave:=true else busca_clave:=false; Close(archivo) end;end;

{tipo 1 eliminar un registro, tipo 2 se efectúo una modificación}procedure padre_hijo(clave:string;tipo:byte;aux:datos);Var copia : file of datos;begin Assign(copia,'hijo.dat'); Rewrite(copia); Reset(archivo); {proceso de intercambio padre hijo}

While not(Eof(archivo)) Do begin Read(archivo,registro); if ((registro.clave<>clave)) then Write(copia,registro); if((registro.clave=clave) and (tipo=2)) then {caso modificación} Write(copia,aux); {escritura en hijo} end; Close(copia);Close(archivo); Erase(archivo); {borra el padre} Rename(copia,'empleados.dat') {renombra 'hijo.dat'con 'empleado.dat'}end;

procedure altas;Var otro :char; CodError:integer;begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} Case CodError Of

Page 142: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

142

{Caso cero el archivo ya existe, ubicarse en el ultimo registro, para a±adir registros nuevos} 0: Seek(archivo,FileSize(archivo)); {caso dos el archivo no existe, se crea con Rewrite, listo para escritura} 2: Rewrite(archivo) {caso contrario existe un error} else begin error(CodError); exit; {Salta al fin del procedimiento} end end; With registro Do begin Repeat ClrScr; gotoxy(30,5);Write('Altas de empleados'); gotoxy(25,7);Write('Clave : '); ReadLn(clave); gotoxy(25,8);Write('Nombre : '); ReadLn(nombre); gotoxy(25,9);Write('Puesto : '); ReadLn(puesto); Repeat {$I-} {validación de entrada de datos} gotoxy(25,10);write('Sueldo : '); ReadLn(sueldo); {$I+} until IOResult=0; Write(archivo,registro); {Escribe los datos del registro en el archivo} gotoxy(20,22);write('Desea dar otra alta s/n? '); otro:=ReadKey until otro in ['n','N',Esc] end; Close(archivo)end;

procedure bajas;Var otro :char; clave :string[3]; CodError:integer;begin {$I-}

Page 143: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

143

Reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then begin error(CodError); exit end; Close(archivo); Repeat ClrScr; gotoxy(30,5);Write('Bajas de empleados'); gotoxy(25,7);Write('Clave : '); ReadLn(clave); if busca_clave(clave) then begin gotoxy(25,8);Write('Nombre : '); Write(registro.nombre); gotoxy(25,9);Write('Puesto : '); Write(registro.puesto); gotoxy(25,10);Write('Sueldo : '); Write(registro.sueldo:6:2); gotoxy(20,15);Write('Desea eliminarlo s/n? '); otro:=ReadKey;Write(otro); if otro in['s','S'] then begin padre_hijo(clave,1,registro); gotoxy(20,17);Write('Registro Eliminado...') end; end else begin gotoxy(20,10); Write('La clave no existe...') end; gotoxy(20,22);Write('Desea dar otra baja s/n? '); otro:=ReadKey until otro in ['n','N',Esc]end;

{Procedimiento para modificación de los campos de un archivo}procedure cambios;Var otro :char; clave :string[3]; CodError:integer; aux :datos;

Page 144: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

144

begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then begin error(CodError); exit end; Close(archivo); Repeat ClrScr; gotoxy(30,5);Write('Modificaciones de empleados'); gotoxy(25,6);Write('Si no desea modificar presione Enter'); gotoxy(25,7);Write('Clave : '); ReadLn(clave); if busca_clave(clave) then begin move(registro,aux,SizeOf(aux)); gotoxy(1,10);Write('Nombre : ');Write(registro.nombre); gotoxy(35,10);Write('Nuevo nombre : ');ReadLn(aux.nombre); if(length(aux.nombre)=0) then begin aux.nombre:=registro.nombre; gotoxy(50,10);WriteLn(aux.nombre); end; gotoxy(1,11);Write('Puesto : ');Write(registro.puesto); gotoxy(35,11);Write('Nuevo puesto : ');ReadLn(aux.puesto); if(length(aux.puesto)=0) then begin aux.puesto:=registro.puesto; gotoxy(50,11);WriteLn(aux.puesto); end; gotoxy(1,12);write('Sueldo : ');Write(registro.sueldo:6:2); Repeat {$I-} {validación de entrada de datos} gotoxy(35,12);Write('Nuevo sueldo : ');ReadLn(aux.sueldo); {$I+} until (IOResult=0); if(aux.sueldo=0) then begin aux.sueldo:=registro.sueldo; gotoxy(50,12);WriteLn(aux.sueldo:6:2); end; gotoxy(20,15);Write('Las modificaciones están correctas s/n? ');

Page 145: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

145

otro:=ReadKey;Write(otro); if otro in['s','S'] then begin padre_hijo(clave,2,aux); gotoxy(20,17);Write('Registro modificado...') end; end else begin gotoxy(20,10); Write('La clave no existe...') end; gotoxy(20,22);write('Desea realizar otra modificación s/n? '); otro:=ReadKey until otro in ['n','N',Esc]end;procedure consultas;Var CodError:integer;begin {$I-} reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then error(CodError) else begin With registro Do begin while not(Eof(archivo)) Do begin ClrScr; Read(archivo,registro); gotoxy(30,5);Write('Consulta de empleados'); gotoxy(25,7);Write('Clave : '); Write(clave); gotoxy(25,8);Write('Nombre : '); Write(nombre); gotoxy(25,9);Write('Puesto : '); Write(puesto); gotoxy(25,10);write('Sueldo : '); Write(sueldo:6:2); gotoxy(20,22);Write('Presione una tecla...'); ReadKey end end;

Page 146: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

146

Close(archivo) end end;

begin Assign(archivo,'empleado.dat'); Repeat ClrScr; gotoxy(30,5);Write('Control de empleados'); gotoxy(35,8);Write('1. Altas'); gotoxy(35,9);Write('2. Bajas'); gotoxy(35,10);Write('3. Cambios'); gotoxy(35,11);write('4. Consultas'); gotoxy(35,12);Write('5. Salir (Esc)'); gotoxy(35,14);Write('Opción [ ]'); gotoxy(43,14); tecla:=ReadKey; case tecla of '1' :altas; '2' :bajas; '3' :cambios; '4' :consultas end until tecla in ['5',esc]; ClrScrend.

8.8 Archivos de acceso directo (con tipo)Los archivos tipeados (con tipo), también llamados archivos binarios, contienen datos de tiposimple o estructurado, tales como integer, real , record, etc., excepto otro tipo de archivos.

Los archivos con tipos están estructurados en elementos o registros (record) cuyo tipo puede sercualquiera. A los elementos de estos archivos se accede directamente, al no situarse éstos enposiciones físicamente consecutivas, sino en posiciones lógicas. Esta es la razón por la cual seles denomina archivos de acceso aleatorio o directo. Los elementos de los archivos aleatorios sonde igual tamaño y el término acceso directo significa que es posible acceder directamente a unelemento con solo especificar su posición.

8.8.1 Declaración y asignación de archivosLa declaración de un archivo con tipo se efectúa con la ayuda de las palabras reservadas file of.

El procedimiento de asignación es idéntico al utilizado anteriormente.

Ejemplo:

Type

Page 147: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

147

datos = record clave : integer; nombre : string[30]; puesto : string[20]; sueldo : real; estado : boolean; {true activo,false baja lógica} end;Var archivo:file of datos;begin Assign(archivo,'empleado.dat'); . . .

Una vez que se ha abierto un archivo para escritura, con el procedimiento Rewrite o Append(caso de añadir registros) se utilizan las sentencias (procedimientos) Write para escribir datos enel archivo.

Como ejemplo, veamos el siguiente procedimiento que sirve para escribir en el archivo registrosque están formados por los campos :

clave :de tipo cadena ( 3 caracteres ) ,nombre :de tipo cadena ( 30 caracteres ),puesto :de tipo cadena ( 20 caracteres), ysueldo :de tipo real ( 6 octetos ) .

El siguiente ejemplo que se manejará a lo largo de esta unidad es identico al realizado en en elcápitulo anterior . La unica diferencia es que se tendrá un acceso directo en todas lasoperaciones.

procedure altas;Var otro :char; CodError:integer;begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} Case CodError Of {Caso cero el archivo ya existe, ubicarse en el último registro, para añadir registros nuevos}

Page 148: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

148

0: Seek(archivo,FileSize(archivo)); {caso dos el archivo no existe, se crea con Rewrite, listo para escritura} 2: Rewrite(archivo) {caso contrario existe un error} else begin error(CodError); exit {Salta al fin del procedimiento} end end; With registro Do begin Repeat ClrScr; gotoxy(30,5);Write('Altas de empleados'); clave:=FileSize(archivo); gotoxy(25,7);Write('Clave : ',clave); gotoxy(25,8);Write('Nombre : '); ReadLn(nombre); gotoxy(25,9);Write('Puesto : '); ReadLn(puesto); Repeat {$I-} {validación de entrada de datos} gotoxy(25,10);write('Sueldo : '); ReadLn(sueldo); {$I+} until IOResult=0; estado:=true; Write(archivo,registro); {Escribe los datos del registro en el archivo} gotoxy(20,22);write('Desea dar otra alta s/n?'); otro:=ReadKey until otro in ['n','N',Esc] end; Close(archivo)end;

Nota : Al final de la unidad se presentará todo el código completo del programa.

8.8.3 Lectura de un archivoNormalmente la lectura de un archivo no tiene sentido por si sola, sino que adquiere significadocuando se asocia con la actualización del archivo o con la generación de un reporte cualquiera.

Page 149: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

149

De alguna manera podemos pensar en la lectura de un archivo como un proceso inverso al de sucreación, puesto que ahora se pasará la información desde el disco hacia la memoria auxiliar.

Veamos un procedimiento que lea todos los registros del archivo "empleados.dat", y losdespliegue en la pantalla.

En este procedimiento se asocia la lectura de los registros con la generación de un reporte através de la pantalla.

procedure consultas;Var CodError:integer;begin {$I-} reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then error(CodError) else begin With registro Do begin while not(Eof(archivo)) Do begin ClrScr; Read(archivo,registro); gotoxy(30,5);Write('Consulta de empleados'); gotoxy(25,7);Write('Clave : '); Write(clave); gotoxy(25,8);Write('Nombre : '); Write(nombre); gotoxy(25,9);Write('Puesto : '); Write(puesto); gotoxy(25,10);write('Sueldo : '); Write(sueldo:6:2); gotoxy(20,22);Write('Presione una tecla...'); ReadKey end end; Close(archivo) end end;Nota : Al final de la unidad se presentará todo el código completo del programa.

Page 150: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

150

La actualización (modificación) de un archivo incluye las acciones de:

Borrar registros.Agregar registros (visto anteriormente 8.8.3).Modificar los datos contenidos en los campos de un registro.AgregarPara poder agregar datos a un archivo es preciso que éste exista, es decir, se necesita: si elarchivo no existe, se crea por primera vez para escritura (Rewrite), si el archivo ya existe seposiciona al final del archivo (Seek).

Borrar / ModificarEl procedimiento para borrar o modificar requiere los siguientes pasos:

1. Situarse en la posición del registro con Seek.2. Leer el registro.3. Borrar/Modificar. 3.1 Modificar ·Leer el nuevo registro modificado (Read). ·Situarse en la posición correspondiente (Seek). ·Escribir el nuevo registro en el archivo. 3.2 Borrar ·La eliminación será lógica por lo que quedarán huecos en el archivo.

La baja lógica que se aplica en el siguiente ejemplo se realiza por medio de una bandera deestado donde true significa activo y false no activo.

Si no se desea que queden huecos en el archivo, entonces la baja que se requiere es física. Lasolución a esto es aplicar el proceso padre-hijo visto anteriormente en los archivos con accesosecuencial.

procedure bajas;Var otro :char; clave :integer; CodError:integer;begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then begin error(CodError); exit end;

Page 151: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

151

Repeat ClrScr; gotoxy(30,5);Write('Bajas de empleados'); Repeat {$I-} {validación de entrada de datos} gotoxy(25,7);Write('Clave : '); ReadLn(clave); {$I+} until IOResult=0; registro.estado:=false; if((clave>=0)and(clave<=FileSize(archivo)-1)) then {validación para seek} begin seek(archivo,clave); Read(archivo,registro) end; if registro.estado=true then {si está activo} begin gotoxy(25,8);Write('Nombre : '); Write(registro.nombre); gotoxy(25,9);Write('Puesto : '); Write(registro.puesto); gotoxy(25,10);write('Sueldo : '); Write(registro.sueldo:6:2); gotoxy(20,15);Write('Desea eliminarlo s/n? '); if otro in['s','S'] then begin Seek(archivo,clave); registro.estado:=false; Write(archivo,registro); {datos actualizados} gotoxy(20,17);Write('Registro Eliminado...') end end else begin gotoxy(20,10); Write('La clave no existe...') end; gotoxy(20,22);write('Desea dar otra baja s/n? '); otro:=ReadKey until otro in ['n','N',Esc]; Close(archivo)end;

{Procedimiento para modificación de los campos de un archivo}procedure cambios;

Page 152: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

152

Var otro :char; clave :integer; CodError:integer; aux :datos;begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then begin error(CodError); exit end; Repeat ClrScr; gotoxy(30,5);Write('Modificaciones de empleados'); gotoxy(25,6);Write('Si no desea modificar presione Enter'); Repeat {$I-} {validación de entrada de datos} gotoxy(25,7);Write('Clave : '); ReadLn(clave); {$I+} until IOResult=0; registro.estado:=false; if((clave>=0)and(clave<=FileSize(archivo)-1)) then {validación para seek} begin seek(archivo,clave); Read(archivo,registro) end; if registro.estado=true then {si está activo} begin move(registro,aux,SizeOf(aux)); gotoxy(1,10);Write('Nombre : ');Write(registro.nombre); gotoxy(35,10);Write('Nuevo nombre : ');ReadLn(aux.nombre); if(length(aux.nombre)=0) then begin aux.nombre:=registro.nombre; gotoxy(50,10);WriteLn(aux.nombre); end; gotoxy(1,11);Write('Puesto : ');Write(registro.puesto); gotoxy(35,11);Write('Nuevo puesto : ');ReadLn(aux.puesto); if(length(aux.puesto)=0) then begin

Page 153: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

153

aux.puesto:=registro.puesto; gotoxy(50,11);WriteLn(aux.puesto); end; gotoxy(1,12);write('Sueldo : ');Write(registro.sueldo:6:2); Repeat {$I-} {validación de entrada de datos} gotoxy(35,12);Write('Nuevo sueldo : ');ReadLn(aux.sueldo); {$I+} until (IOResult=0); if(aux.sueldo=0) then begin aux.sueldo:=registro.sueldo; gotoxy(50,12);WriteLn(aux.sueldo:6:2); end; gotoxy(20,15);Write('Las modificaciones están correctas s/n? '); otro:=ReadKey;Write(otro); if otro in['s','S'] then begin Seek(archivo,clave); Write(archivo,aux); gotoxy(20,17);Write('Registro modificado...') end end else begin gotoxy(20,10); Write('La clave no existe...') end; gotoxy(20,22);write('Desea realizar otra modificación s/n? '); otro:=ReadKey until otro in ['n','N',Esc]end

Completo es:

Archivo con acceso directoProgram Directo; {El siguiente programa realiza las operaciones de altas,bajas y consultas del control de empleados por medio de archivos con acceso directo}Uses Crt;Const esc = #27;Type datos = record clave : integer; nombre : string[30];

Page 154: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

154

puesto : string[20]; sueldo : real; estado : boolean; {true activo,false baja lógica} end;Var archivo :file of datos; registro :datos; tecla :char;

procedure error(error:integer);begin Gotoxy(20,21); Case error Of 152:Write('UNIDAD NO PREPARADA'); 162:Write('FALLA EN EL HARDWARE'); 104:Write('ARCHIVO NO ABIERTO PARA ENTRADA'); 100:Write('ERROR DE LECTURA EN DISCO'); 150:Write('PROTEGIDO CONTRA ESCRITURA'); 2 :Write('EL ARCHIVO NO EXISTE') end; ReadKeyend;

procedure altas;Var otro :char; CodError:integer;begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} Case CodError Of {Caso cero el archivo ya existe, ubicarse en el último registro, para a±adir registros nuevos} 0: Seek(archivo,FileSize(archivo)); {caso dos el archivo no existe, se crea con Rewrite, listo para escritura} 2: Rewrite(archivo) {caso contrario existe un error} else begin error(CodError); exit {Salta al fin del procedimiento} end

Page 155: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

155

end; With registro Do begin Repeat ClrScr; gotoxy(30,5);Write('Altas de empleados'); clave:=FileSize(archivo); gotoxy(25,7);Write('Clave : ',clave); gotoxy(25,8);Write('Nombre : '); ReadLn(nombre); gotoxy(25,9);Write('Puesto : '); ReadLn(puesto); Repeat {$I-} {validación de entrada de datos} gotoxy(25,10);write('Sueldo : '); ReadLn(sueldo); {$I+} until IOResult=0; estado:=true; Write(archivo,registro); {Escribe los datos del registro en el archivo} gotoxy(20,22);write('Desea dar otra alta s/n? '); otro:=ReadKey until otro in ['n','N',Esc] end; Close(archivo)end;

procedure bajas;Var otro :char; clave :integer; CodError:integer;begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then begin error(CodError); exit end; Repeat ClrScr; gotoxy(30,5);Write('Bajas de empleados');

Page 156: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

156

Repeat {$I-} {validación de entrada de datos} gotoxy(25,7);Write('Clave : '); ReadLn(clave); {$I+} until IOResult=0; registro.estado:=false; if((clave>=0)and(clave<=FileSize(archivo)-1)) then {validación para seek} begin seek(archivo,clave); Read(archivo,registro) end; if registro.estado=true then {si está activo} begin gotoxy(25,8);Write('Nombre : '); Write(registro.nombre); gotoxy(25,9);Write('Puesto : '); Write(registro.puesto); gotoxy(25,10);write('Sueldo : '); Write(registro.sueldo:6:2); gotoxy(20,15);Write('Desea eliminarlo s/n? '); if otro in['s','S'] then begin Seek(archivo,clave); registro.estado:=false; Write(archivo,registro); {datos actualizados} gotoxy(20,17);Write('Registro Eliminado...') end end else begin gotoxy(20,10); Write('La clave no existe...') end; gotoxy(20,22);write('Desea dar otra baja s/n? '); otro:=ReadKey until otro in ['n','N',Esc]; Close(archivo)end;

{Procedimiento para modificación de los campos de un archivo}procedure cambios;Var otro :char; clave :integer; CodError:integer; aux :datos;

Page 157: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

157

begin {$I-} Reset(archivo); CodError:=IOResult; {$I+} if CodError<>0 then begin error(CodError); exit end; Repeat ClrScr; gotoxy(30,5);Write('Modificaciones de empleados'); gotoxy(25,6);Write('Si no desea modificar presione Enter'); Repeat {$I-} {validación de entrada de datos} gotoxy(25,7);Write('Clave : '); ReadLn(clave); {$I+} until IOResult=0; registro.estado:=false; if((clave>=0)and(clave<=FileSize(archivo)-1)) then {validación para seek} begin seek(archivo,clave); Read(archivo,registro) end; if registro.estado=true then {si está activo} begin move(registro,aux,SizeOf(aux)); gotoxy(1,10);Write('Nombre : ');Write(registro.nombre); gotoxy(35,10);Write('Nuevo nombre : ');ReadLn(aux.nombre); if(length(aux.nombre)=0) then begin aux.nombre:=registro.nombre; gotoxy(50,10);WriteLn(aux.nombre); end; gotoxy(1,11);Write('Puesto : ');Write(registro.puesto); gotoxy(35,11);Write('Nuevo puesto : ');ReadLn(aux.puesto); if(length(aux.puesto)=0) then begin aux.puesto:=registro.puesto; gotoxy(50,11);WriteLn(aux.puesto); end; gotoxy(1,12);write('Sueldo : ');Write(registro.sueldo:6:2); Repeat {$I-} {validación de entrada de datos}

Page 158: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

158

gotoxy(35,12);Write('Nuevo sueldo : ');ReadLn(aux.sueldo); {$I+} until (IOResult=0); if(aux.sueldo=0) then begin aux.sueldo:=registro.sueldo; gotoxy(50,12);WriteLn(aux.sueldo:6:2); end; gotoxy(20,15);Write('Las modificaciones están correctas s/n? '); otro:=ReadKey;Write(otro); if otro in['s','S'] then begin Seek(archivo,clave); Write(archivo,aux); gotoxy(20,17);Write('Registro modificado...') end end else begin gotoxy(20,10); Write('La clave no existe...') end; gotoxy(20,22);write('Desea realizar otra modificación s/n? '); otro:=ReadKey until otro in ['n','N',Esc]end;

8.9 Archivos sin tipoTodos los archivos utilizados hasta ahora suponen algún tipo de estructura. Si no se conoce laestructura del registro se debe utilizar un archivo sin tipo. Los archivos sin tipo son canales deE/S de bajo nivel, principalmente utilizados para acceso directo a cualquier archivo de disco conindependencia del tipo y estructura.

Cualquier archivo de disco puede ser declarado como sin tipo. Turbo Pascal permite tratar unarchivo como una serie de bloques sin necesidad de conocer el tipo de datos que contiene.

8.9.1 Declaración de un archivoLa declaración de un archivo sin tipo omite el tipo de archivo :

Var nombre: file;

Page 159: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

159

Usando la declaración de archivos sin tipo, no importa como se haya escrito originalmente elarchivo. Los archivos de texto, archivos binarios, archivos de programas o cualquier otro, puedenser declarados y abiertos como archivos sin tipo.

Los archivos sin tipo tienen una longitud de registro por defecto de 128 bytes, y se transfierendirectamente entre la variable registro y el archivo.

El formato de los procedimientos Reset y Rewrite en archivos sin tipo difiere del ya conocidopara archivos de texto y con tipo.

Reset (nombre,bloque)Rewrite(nombre,bloque)

nombre variable de tipo archivoBloque un número de tipo word

Ejemplo:

Reset(archivo,1);Prepara a un archivo para ser leído y específica que la longitud de registro es de 1 byte.

8.9.2 Acceso a los archivos (sin tipo)El acceso al los archivos se realiza con los siguientes procedimientos:

BlockRead BlockWrite

Formatos:

BlockRead

Transfiere un bloque de datos de un archivo sin tipo hacia un buffer.

Formato:

BlockRead(arch,buffer,bloques,resul)

arch archivo sin tipobuffer variable de cualquier tipo de longitud suficiente para acoger los datos transferidosbloques expresión que corresponde al número de bloques de 128 bytes a transferir.resul parámetro opcional que indica el número de bloques que se leyeron o escribieron

Page 160: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

160

realmente.

BlockWrite

Transfiere un buffer de datos hacia un archivo sin tipo.

Formato:

BlockWrite(arch,buffer,bloques,resul)

arch archivo sin tipobuffer variable de cualquier tipo de longitud suficiente para acoger los datos transferidosbloques expresión que corresponde al número de bloques de 128 bytes a transferir.resul parámetro opcional que indica el número de bloques que se leyeron o escribieron realmente.

Los archivos sin tipo son más rápidos, debido a que los datos no necesitan ser organizados enlíneas o estructuras; son simplemente bloques que se transfieren entre el disco y un buffer.

El siguiente ejemplo muestra una de las aplicaciones que se les puede dar a los archivos sin tipo.La función del siguiente ejemplo es el de copiar el contenido de un archivo a una ruta específica(idéntico al comando Copy de MS-DOS).

Ejemplo:

Program Copiar;Var fuente,destino : file; {archivo sin tipo} buffer : array[1..512] of byte; temp : string; leidos : integer;

begin if ((ParamCount<2)or (ParamCount>2)) then begin if (ParamCount<2)then

Page 161: Sacado de -  · tarjetas mal perforadas o regrabando en el disco flexíble o en el disco duro. Este paso de la ... el programador puede tener que escoger entre soluciones alternativas

161

WriteLn('Faltan párametros...') else WriteLn('Exceso de párametros...'); WriteLn('Ejemplo: Copiar [Nombre de archivo a copiar]', '[Ruta destino del archivo]'); WriteLn('//Copiar datos.doc a://'); Halt(1); end; Assign(fuente,ParamStr(1)); temp:=ParamStr(2)+ParamStr(1); {archivo destino con ruta} Assign(destino,temp); {$I-} Reset(fuente,1); {$I+} if IOResult <> 0 then begin WriteLn('Error en archivo fuente..'); Halt(1); end; {$I-} Rewrite(destino,1); {$I+} if IOResult <> 0 then begin WriteLn('Error en la ruta destino..'); Halt(1); end; BlockRead(fuente,buffer,SizeOf(buffer),leidos); while leidos>0 do begin BlockWrite(destino,buffer,SizeOf(buffer),leidos); BlockRead(fuente,buffer,SizeOf(buffer),leidos) end; close(fuente); close(destino)end.