Documentos de Académico
Documentos de Profesional
Documentos de Cultura
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, frmulas y otros recursos necesarios.
Una recomendacin muy prctica 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. Tambin da buenos resultados hacer similitudes con la labor de un empleado que hace el mismo trabajo que deseamos programarle al computador. 3.- SELECCIN DE LA MEJOR ALTERNATIVA Analizado el problema, posiblemente tengamos varias formas de resolverlo; lo importante es determinar cal es la mejor alternativa: la que produce los resultados
esperados en el menor tiempo y al menor costo. Claro que aqu tambin es muy vlido el principio de que las cosas siempre se podrn hacer de una mejor forma. 4.- DIAGRAMACIN Una vez que sabemos cmo resolver el problema, pasamos a dibujar grficamente la lgica de la alternativa seleccionada. Eso es precisamente un Diagrama de Flujo: la representacin grfica de una secuencia lgica de pasos a cumplir por el computador para producir un resultado esperado. La experiencia nos ha demostrado que resulta muy til trasladar esos pasos lgicos planteados en el diagrama a frases que indiquen lo mismo; es decir, hacer una codificacin del programa pero utilizando instrucciones en Espaol. Como si le estuviramos hablando al computador. Esto es lo que denominaremos Algoritmo o Pseudocdigo. Cuando logremos habilidad para desarrollar programas, es posible que no elaboremos el diagrama de flujo; en su lugar podremos hacer directamente el pseudocdigo del programa. 5.- PRUEBA DE ESCRITORIO Para cerciorarnos de que el diagrama (y/o el pseudocdigo) esta bien, y, para garantizar que el programa que codifiquemos luego tambin funcione correctamente, es conveniente someterlo a una Prueba de Escritorio . Esta prueba consiste en que damos diferentes datos de entrada al programa y seguimos la secuencia indicada en el diagrama, hasta obtener los resultados. El anlisis 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 posibles casos, aun los de excepcin o no esperados, para asegurarnos de que el programa no producir errores en ejecucin cuando se presenten estos casos. 6.- CODIFICACIN Una vez que hayamos verificado el diagrama mediante las pruebas de escritorio, codificamos el programa en el lenguaje de computador seleccionado. Esto es, colocamos cada paso del diagrama en una instruccin o sentencia, utilizando un lenguaje que el computador reconoce. Todos los lenguajes de programacin proveen facilidades para incluir lneas de comentarios en los programas. Estos comentarios aclaran lo que se ordena al computador y facilitan entender el programa. Puesto que estos comentarios no son tenidos en cuenta como instrucciones, y aparecen en los listados del programa, resulta muy conveniente agregar abundantes comentarios a todo programa que codifiquemos. Esto es lo que se denomina Documentacin Interna.
7.- TRANSCRIPCIN El programa codificado es necesario que lo llevemos a un medio que sea aceptado como entrada por el computador: lo perforamos en tarjetas, lo grabamos en un disco flexble o lo grabamos en un disco duro. Este programa es el que se conoce como Programa Fuente (Source). 8.- COMPILACIN Utilizamos ahora un programa de computador llamado Compilador o Traductor, el cal analiza todo el programa fuente y detecta errores de sintaxis ocasionados por fallas en la codificacin o en la transcripcin. Las fallas de lgica que pueda tener nuestro programa fuente no son detectadas por el compilador. Cuando no hay errores graves en la compilacin, el compilador traduce cada instruccin del programa fuente a instrucciones propias de la mquina (Lenguaje de Maquina), creando el Programa Objeto. Algunos computadores utilizan Interpretadores, (Generalmente para el Lenguaje Basic), en reemplazo de programas compiladores. La diferencia consiste en que el interpretador recibe, desde una terminal, slo una instruccin a la vez, la analiza y, si esta bien, la convierte al formato propio de la maquina. Si la instruccin tiene algn error, el interpretador llama la atencin de la persona para que corrija dicha instruccin. 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 las tarjetas mal perforadas o regrabando en el disco flexble o en el disco duro. Este paso de la compilacin lo repetimos hasta eliminar todos los errores y obtener el programa ejecutable. 9.- PRUEBAS DE COMPUTADOR Cuando tenemos el programa ejecutable (en lenguaje de maquina), ordenamos al computador que lo ejecute, para lo cal suministramos datos de prueba, como lo hicimos en la prueba de escritorio (paso 5). Los resultados obtenidos los analizamos, luego de lo cal puede ocurrir cualquiera de estas situaciones: a.- La lgica del programa esta bien, pero hay errores sencillos, los cuales los corregimos modificando algunas instrucciones o incluyendo unas nuevas; el proceso debemos repetirlo desde el paso 6 .
b.- Hay errores ocasionados por fallas en la lgica, lo que nos obliga a regresar a los pasos 4 y 5 para revisin y modificacin del diagrama. c.- Hay errores muy graves y lo ms aconsejable es que regresemos al paso 2 para analizar nuevamente el problema, y repetir todo el proceso. d.- No hay errores y los resultados son los esperados. En este caso, el programa lo podemos guardar permanentemente en una librera o biblioteca del computador, para sacarlo de all cuando necesitemos ejecutarlo nuevamente. 10.- DOCUMENTACIN EXTERNA Cuando el programa ya se tiene listo para ejecutar, es conveniente que hagamos su documentacin externa siguiendo las normas de la instalacin o las recomendaciones indicadas por el profesor. Una buena documentacin incluye siempre: a. b. c. d. Enunciado del problema Diagrama de pasada Narrativo con la descripcin de la solucin Relacin de las variables o campos utilizados en el programa, cada uno con su respectiva funcin e. Diagrama del programa f. Listado de la ltima compilacin g. Resultados de la ejecucin del programa.
EXACTITUD Un objetivo obvio en la escritura de cualquier programa de computador es que tiene que satisfacer su especificacin exactamente. A menudo, sin embargo, a causa de la complejidad de la labor del programa, y de un entendimiento o cuidado inadecuados de parte del programador, un programa falla en satisfacer alguna parte de su especificacin. Un programador tiene que ser en todo tiempo cuidadoso de la exactitud o pertinencia del programa para su propsito especificado. 4
Un factor clave en el logro de exactitud es la simplicidad. Escogiendo el algoritmo o tcnica ms simple disponible, es ms probable que un programador vea si satisface o no los requerimientos de la especificacin del programa, y es menos probable que la describa incorrectamente en su programa. La innecesaria complejidad no cumple propsito alguno en la programacin de computadores. Algunos programas son, por supuesto, inherentemente complejos. Para tales programas, el programador debe adoptar un tratamiento sistemtico que controle y limite la complejidad de la que tiene que ocuparse en cada etapa. CLARIDAD Un programa es necesariamente tan complejo como el algoritmo que describe. Sin embargo, es importante que la forma en que el algoritmo est descrito, por el texto del programa, no sea mas complicada de lo que es necesario. La claridad del programa es una ayuda importante para el programador mismo en el diseo y limpieza del programa; y para otros que puedan tener que leer y alterar el programa en alguna etapa posterior. La claridad del programa es lograda casi en la misma forma que para cualquier texto escrito, tal como un ensayo o un libro en los cuales se requiere: a).- Una separacin lgica del texto en partes comprensibles (captulos, secciones, etc.) que reflejen la distincin entre los temas que describen, y su presentacin en una secuencia lgica que refleje las relaciones entre ellas; b).- Una seleccin cuidadosa de las caractersticas del lenguaje, usadas en cada parte para expresar su sentido propuesto tan precisamente como sea posible; c).- Otra seleccin cuidadosa de las palabras usadas para denotar los objetos y conceptos involucrados; d).- La inclusin de comentarios y prembulos para clarificar el texto principal cuando sea necesario; e).- Un aprovechamiento de los dispositivos para presentacin de textos, tales como las lneas en blanco y la sangra, para enfatizar la relacin entre partes componentes de textos. Un programador podra ser tan diligente en el uso de stas tcnicas para lograr claridad como el autor de cualquier texto. En muchos casos, la utilidad de un programa es determinada tanto por la claridad de su texto como por las cualidades del algoritmo que describe. EFICIENCIA
El costo de ejecutar un programa de computador, es medido normalmente en trminos de : a).- El tiempo tomado por el computador para llevar a cabo la secuencia de operaciones involucradas; b).- La cantidad de memoria de computador usada en hacerlo. En muchos ambientes (de mquina), el programa competir con otros programas por el uso de esos recursos del computador, y es, por tanto, lgico minimizar los requerimientos del programa para cada uno. El tiempo tomado para ejecutar el programa, es directamente proporcional al nmero de operaciones 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 evitar cualquier operacin redundante al expresar el algoritmo como un programa de computador. La memoria usada por el programa durante su ejecucin, es determinada por la cantidad de datos que tienen que ser guardados, y por el nmero de instrucciones del procesador requeridas para definir el programa, ya que stas tambin tienen que ser guardadas en la memoria. Para minimizar el almacenamiento usado por su programa, el programador debe, por tanto, considerar los datos manipulados y el nmero de operaciones especificadas por el programa. Para algunos programas, o partes de programas, el uso eficiente del tiempo o del almacenamiento puede ser crtico; para otros puede serlo menos. El programador debe estar enterado de cualquiera de tales requerimientos de eficiencia cuando escriba su programa.
PSEUDOCDIGO Con la PE, el pseudocdigo sigue siendo un excelente medio para expresar la lgica de un programa. A continuacin se muestran algunos ejemplos de palabras para construir algoritmos en pseudocdigo.
PALABRA ABRE CASO CIERRA ENTONCES ESCRIBE FIN HASTA HAZ INICIO LEER NO O Abre un archivo
UTILIZACIN Seleccin entre mltiples alternativas Cierra un archivo Complemento de la seleccin SI - ENTONCES Visualiza un dato en pantalla Finaliza un bloque de instrucciones Cierra la iteracin HAZ - HASTA Inicia la iteracin HAZ - HASTA Inicia un bloque de instrucciones Leer un dato del teclado Niega la condicin que le sigue Disyuncin lgica
Complemento opcional de la seleccin SI - ENTONCES Inicia un nmero fijo de iteraciones Inicia la seleccin SI-ENTONCES Opcional en la instruccin CASO Conjuncin lgica Inicio de comentario Fin de comentario Asignacin
DEFINICIN DE LAS ESTRUCTURAS BSICAS DE CONTROL LGICO 1.- SECUENCIA Indica que las instrucciones de un programa se ejecutan una despus de la otra, en el mismo orden en el cual aparecen en el programa. Se representa grficamente como una caja despus de otra, ambas con una sola entrada y una nica salida.
Las cajas A y B pueden ser definidas para ejecutar desde una simple instruccin hasta un mdulo o programa completo, siempre y cuando que estos tambin sean programas apropiados. 2.- SELECCIN Tambin conocida como la estructura SI-CIERTO-FALSO, plantea la seleccin entre dos alternativas con base en el resultado de la evaluacin de una condicin o predicado; equivale a la instruccin IF de todos los lenguajes de programacin y se representa grficamente de la siguiente manera :
En el diagrama de flujo anterior, C es una condicin que se evala; A es la accin que se ejecuta cuando la evaluacin de este predicado resulta verdadera y B es la accin ejecutada cuando indica falso. La estructura tambin tiene una sola entrada y una sola salida; y las funciones A y B tambin pueden ser cualquier estructura bsica o conjunto de estructuras. 3.- ITERACIN
Tambin llamada la estructura HACER-MIENTRAS-QUE, corresponde a la ejecucin repetida de una instruccin mientras que se cumple una determinada condicin. El diagrama de flujo para esta estructura es el siguiente :
Aqu el bloque A se ejecuta repetidamente mientras que la condicin C se cumpla o sea cierta. Tambin tiene una sola entrada y una sola salida; igualmente A puede ser cualquier estructura bsica o conjunto de estructuras. VENTAJAS DE LA PROGRAMACIN ESTRUCTURADA Con 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 las siguientes ventajas : 1. Los programas son ms fciles de entender. Un programa estructurado puede ser ledo en secuencia, de arriba hacia abajo, sin necesidad de estar saltando de un sitio a otro en la lgica, lo cual es tpico de otros estilos de programacin. La estructura del programa es ms clara puesto que las instrucciones estn ms ligadas o relacionadas entre si, por lo que es ms fcil comprender lo que hace cada funcin. 2. Reduccin del esfuerzo en las pruebas. El programa se puede tener listo para produccin normal en un tiempo menor del tradicional; por otro lado, el seguimiento de las fallas o depuracin (debugging) se facilita debido a la lgica ms visible, de tal forma que los errores se pueden detectar y corregir ms fcilmente. 3. Reduccin de los costos de mantenimiento. 4. Programas ms sencillos y ms rpidos. 5. Aumento en la productividad del programador. 6. Se facilita la utilizacin de las otras tcnicas para el mejoramiento de la productividad en programacin. 7. Los programas quedan mejor documentados internamente.
Adems de la PE, existen las siguientes tcnicas o mtodos de trabajo para mejorar la productividad del personal que trabaja en programacin de computadores : 1.- DESARROLLO DESCENDENTE DE PROGRAMAS El concepto de Desarrollo Descendente (tambin conocido como Desarrollo AribaAbajo, Desarrollo Estructurado o Desarrollo Top-Down), se aplica tanto a la fase de diseo del sistema o aplicacin como a la fase de programacin y codificacin de los programas. El desarrollo descendente de programas consiste en construir un programa tratando de descomponerlo en mdulos (funciones o segmentos), cada uno encargado de realizar un trabajo especfico. Esta organizacin se va logrando de arriba hacia abajo en forma de rbol y podemos representarla grficamente como un DIAGRAMA DE ESTRUCTURA. 2.- DOCUMENTACION JEPS Conocida originalmente como la tcnica HIPO (Hierarchy plus Input-ProcessOutput), permite producir las especificaciones funcionales de un programa y al mismo tiempo su documentacin. Consiste en una tabla visual de contenido que apunta a los diagramas HIPO del paquete y muestra las funciones y subfunciones que efecta el programa y las interrelaciones de las mismas. 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 diseo y se complementa muy bien con la PE . 3.- INSPECCIONES DE TRABAJO Son sesiones de revisin en las cuales el creador de los programas los explica a sus compaeros; de sta forma asegura la deteccin y correccin de errores en un momento en el cual no resultan tan costosos. La legibilidad de los programas estructurados facilita estas inspecciones de trabajo. 4.- BIBLIOTECAS DE DESARROLLO Es la recopilacin organizada del material que contiene la ltima versin de toda la informacin de un proyecto (diseos, especificaciones, diagramas, listados de computador, etc.). Aunque este tipo de organizacin es muy prctico con cualquier estilo de programacin, encaja muy bien con la PE .
11
5.- GRUPOS CON PROGRAMADOR EN JEFE Incluye grupos de trabajo con mnimo tres integrantes organizados de la siguiente manera : a).- Programador jefe b).- Programador de respaldo c).- Encargado de la biblioteca de desarrollo. El grupo puede incluir otros programadores, analstas y usuarios finales. El Programador en Jefe es responsable del diseo y codificacin de los programas producidos por su grupo. La PE es adecuada con estos grupos de trabajo puesto que facilita al Programador Jefe la revisin del material producido por los dems miembros. La combinacin de las tcnicas de Desarrollo Descendente de programas y la Programacin Estructurada ofrece las siguientes ventajas, adicionales a las ya enumeradas antes : a.- El programa puede ser distribuido entre varias personas, y la posterior integracin de los diferentes mdulos no debe presentar mayores inconvenientes. b.- Durante la etapa de pruebas del programa, los mdulos superiores (que generalmente son los ms crticos) reciben ms atencin. c.- El mantenimiento de los programas resulta menos costoso debido a que la atencin se concentra en un determinado modulo, reduciendo as la posibilidad de error. LA TRANSFERENCIA INCONDICIONAL Algunas veces se asocia la PE con la eliminacin total de las instrucciones GO TO ("vaya a") en un programa, lo cual no es absolutamente cierto. Un programa construido con las tres estructuras bsicas de control no requiere el uso de instrucciones GO TO para transferir el control de un sitio a otro; esto es una consecuencia del desarrollo descendente de los programas estructurados y de la limitante misma que tiene el programador para transferir el control, cuando slo utiliza las tres estructuras bsicas. El empleo exagerado de la instruccin GO TO puede hacer incomprensible un programa no estructurado; sin embargo, el empleo moderado de sta instruccin aporta ms claridad a los programas no estructurados. Es posible que se presenten casos en PE en los cuales el empleo de una instruccin GO TO le de ms claridad y efectividad a un programa estructurado.
12
Tambin utilizamos GO TO en los casos en que el lenguaje utilizado no tiene una instruccin equivalente a la estructura de iteracin empleada, de tal suerte que sta slo la podemos simular con un GO TO, tal como sucede con algunas versiones de BASIC y FORTRAN.
sentencias end. Las cinco secciones de declaracin -Label, Const, Type y Procedure y/o Function , as como la clusula Uses y Program, no tiene que estar presentes en todos los programas. Turbo Pascal es muy flexible al momento de escribir las secciones de declaracin, ya que se pueden hacer en cualquier orden (en Pascal estndar ISO si se require este orden). Sin embargo es conveniente seguir 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 informacin en pantalla} ReadLn(nombre);{Leer un dato del teclado} WriteLn ('Bienvenido ', nombre); {Visualiza informacin en pantalla} Readkey; {Espera la pulsacin de una tecla} ClrScr end.
Nota: Las declaraciones de constantes, tipos y variables tambin se pueden poner en los procedimientos 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
14
................................... end.
El programa anterior es incorrecto ya que hacemos referencia a la constante Max en la declaracin de variables sin haberla definido en la declaracin de constantes.
2.2 Identificadores
En la mayora de los programas de computador, es necesario manejar datos de entrada o de salida, los cuales necesitan almacenarse en la memoria principal del computador en el tiempo de ejecucin. Para poder manipular dichos datos, necesitamos tener acceso a las localidades de memoria donde se encuentran almacenados; esto se logra por medio de los nombres de los datos o IDENTIFICADORES. Los identificadores tambin se utilizan para los nombres de los programas, los nombres de los procedimientos y los nombres de las funciones, as como para las etiquetas, constantes y variables. Las reglas para formar los identificadores en Pascal son las siguientes : 1. Pueden estar compuestos de caracteres alfabticos, numricos y el carcter de subrayado ( _ ). 2. Deben comenzar con un carcter alfabtico o el carcter de subrayado. 3. Puede ser de cualquier longitud (slo los 63 primeros caracteres son significativos). 4. No se hace distincin entre maysculas y minsculas. 5. No se permite el uso de los IDENTIFICADORES RESERVADOS en los nombres de variables, constantes, programas o sub-programas. Identificadores vlidos
Nombre Cadena Edad_Maxima X_Y_Z Etiqueta2
Identificadores no vlidos
Num&Dias X nombre begin eje@s : : : : carcter & no vlido Contiene un blanco es una palabra reservada carcter @ no vlido
Eleccin de identificadores
15
La eleccin de identificadores permite una mejor lectura y comprensin de un programa. No es aconsejable utilizar identificadores que no sugieran ningn significado.
La siguiente tabla muestra los IDENTIFICADORES RESERVADOS en TurboPascal. Los marcados con un asterisco no estn definidos en Pascal estndar . Los marcados con ? no se utilizan en Turbo-Pascal *ABSOLUTE IN *AND ARRAY FILE FORWARD NIL *SHL AND FILE NOT *SHR *STRING FOR OF THEN CASE OR TYPE CONST VAR ?PACKED TO DIV *INLINE UNTIL IF PROGRAM DOWNTO RECORD ELSE WHILE LABEL REPEAT WITH MOD SET *XOR
*OVERLAY GOTO
*EXTERNAL BEGIN
PROCEDURE END
FUNCTION DO
Turbo-Pascal define los siguientes IDENTIFICADORES ESTANDAR de tipos predefinidos, constantes, variables, procedimientos y funciones. Cualquiera de ellos puede ser redefinido, perdindose as la facilidad de utilizar su definicin original. ADDR ARCTAN ASSIGN AUX AUXINPTR AUXOUTPTR BLOCKREAD BOOLEAN BUFLEN BYTE DELAY DELETE EOF EOLN ERASE EXECUTE EXIT FALSE FILEPOS FILESIZE LENGTH LN LO LOWVIDEO LST MARK MAXINT MEM MEMAVAIL MOVE RELEASE RENAME RESET REWRITE ROUND SIN SIZEOF SEEKEOF SEEKEOLN SQR
LSTOUTPTR SEEK
BLOCKWRITE EXP
16
CHAIN CHAR CHR CLOSE CLREOL CLRSCR CON CONINPTR CONOUTPTR CONCAT CONSTPTR COPY COS CRTEXIT CRTINIT DELLINE
FILLCHAR FLUSH FRAC GETMEM GOTOXY HALT HEAPPTR HI IORESULT INPUT INSLINE INSERT INT INTEGER KBD KEYPRESSED
NEW ODD ORD OUTPUT PI PORT POS PRED PTR RANDOM READ READLN REAL
SQRT SUCC SWAP TEXT TRM TRUE TRUNC UPCASE USR USRINPTR VAL WRITE WRITELN
NORMVIDEO STR
RANDOMIZE USROUTPTR
17
El identificador reservado Const debe encabezar la instruccin, seguido por una lista de asignaciones de constantes. Cada asignacin de constante debe consistir de un identificador seguido por un signo de igual y un valor constante, como se muestra a continuacin:
Const valor_maximo =255; precision =0.0001; palabra_clave='Tutankamen'; encabezado =' NOMBRE DIRECCION TELEFONO ';
Un valor constante puede consistir de un nmero ( entero o real ), o de una constante de caracteres. La constante de caracteres consiste de una secuencia de caracteres encerrada entre apstrofes ( ' ), y, en Turbo-Pascal, tambin puede formarse concatenndola con caracteres de control ( sin separadores ), por ejemplo :
'Teclee su opcin ==>'^G^G^G ;
y a continuacin suena el timbre tres veces. Las constantes de caracteres pueden estar formadas por un solo carcter de control, p.ej. :
hoja_nueva = ^L
Existen dos notaciones para los caracteres de control en Turbo Pascal, a saber : 1. El smbolo # seguido de un nmero entero entre 0 y 255 representa el carcter al que corresponde dicho valor decimal en el codigo ASCII. 2. El smbolo ^ seguido por una letra, representa el correspondiente carcter de control. Ejemplos :
#12 representa el valor decimal 12 ( hoja_nueva o alimentacin de forma ). #$1B representa el valor hexadecimal 1B ( escape ). ^G representa el carcter del timbre o campana. ^M representa el carcter de retorno de carro.
18
MaxInt integer 32767 idems de las constantes literales para los tipos integer y real con representacin decimal y hexadecimal, y las constantes literales para el conjunto de caracteres ASCII, ms los caracteres especiales ( no incluidos en el conjunto estndar del ASCII )
19
Tipos enteros
Tipos enteros predefinidos Tipo byte 0 .. 255 Rango Formato 8 bits sin signo 16 bits con signo 8 bits con signo 16 bits sin signo
BYTE El tipo byte es un subconjunto del tipo integer, en el rango de 0 a 255 . Donde quiera que se espere un valor byte, se puede colocar un valor integer; y viceversa ( EXCEPTO cuando cuando son pasados como PARAMETROS ). Asimismo, se pueden mezclar identificadores de tipo byte y de tipo integer en las expresiones. Los valores de tipo byte se guardan en UN OCTETO de memoria. INTEGER El rango de los valores definidos por el tipo integer , en Turbo Pascal, se encuentra entre -32768 y 32767 . Cada valor de este tipo se guarda en DOS OCTETOS de memoria. LONGINT (enteros largos) A partir de la versin 4.0 se han incorporado nmeros que amplan el rango de variacin de los enteros a -2,147,483,648. Este tipo de datos se denomina longint (enteros largos). Ocupan CUATRO OCTETOS de memoria. Existe una constante predefinida de tipo longint, denominada MaxLongInt, cuyo valor es 2,147,483,647. SHORTINT (enteros cortos) En ciertos casos, puede ser prctico disponer de valores enteros positivos y negativos cuyo alcance sea ms restringido que el de los tipos enteros. Los tipos shortint pueden tomar valores entre -128 y 127. Ocupan UN OCTETO de memoria. WORD
20
Existen casos en los que se desea representar nicamente valores positivos. Este es el caso. Por ejemplo, cuando se desea acceder desde un programa hasta una direccin de memoria. En tal situacin, no tiene sentido una direccin negativa. Turbo Pascal dispone del tipo word (o palabra, de palabra de memoria), cuyo intervalo posible de valores es de 0 a 65535. Ocupa DOS OCTETOS de memoria.
Tipos reales
REAL En el contexto de Pascal, un nmero real es aquel que est compuesto de una parte entera y una parte decimal, separadas por un punto. El rango de estos nmeros est dado entre los valores 1E-38 y 1E+38 . Cada valor de este tipo se guarda en SEIS OCTETOS de memoria. Durante una operacin aritmtica con nmeros reales, un valor mayor que 1E+38 (sobreflujo) causar la detencin del programa y desplegar un mensaje de error ; mientras que un valor menor 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 nmeros reales estn siempre disponibles en Turbo Pascal, pero si su sistema incluye un coprocesador matemtico como 8087, 80287 u 80387, se dispone adems de otros tipos de nmeros reales:
real (real) single (real corto) comp (entero ampliado) double (real de doble precisin) extended (real ampliado)
Computadoras sin coprocesador matemtico (emulacin por software) datos disponibles : real, comp, double, extended y single.
21
Computadoras con coprocesador matemtico datos disponibles : real, comp, double, extended y single (reales IEEE) Desde la versin 5.0 se permite utilizar los datos tipo coprocesador matemtico aunque su computadora no lo tenga incorporado. La razn es que se emula dicho coprocesador. Los diferentes tipos reales se diferencian por el dominio de definicin, el nmero de cifras significativas (precisin) y el espacio ocupado en memoria.
Turbo Pascal 4.0 requiere obligatoriamente un chip coprocesador matemtico para hacer uso de nmeros reales de coma flotante IEEE. Turbo Pascal 5.0 a 7.0 emula el chip coprocesador matemtico totalmente en software, permitiendo ejecutar tipos IEEE tanto si tiene como si no un chip 8087/287/387 instalado en su mquina. Tipo real single double comp Rango 2.910 E -39 .. 1.710 E 38 1.510 E -45 .. 3.410 E 38 5.010 E -324 .. 1.710 E 308 -2 E 63 +1 .. 2 E 63 - 1 Cifras Tamao y bytes 11 -12 7-8 15 - 16 19 - 20 6 4 8 10 8
BOOLEAN Un valor de tipo boolean puede asumir cualquiera de los valores de verdad denotados por los identificadores true y false, los cuales estn definidos de tal manera que false < true . Un valor de tipo boolean ocupa UN OCTETO en la memoria. CHAR Un valor de tipo char es cualquier carcter que se encuentre dentro del conjunto ASCII ampliado, el cual est formado por los 128 caracteres del ASCII ms los 128 caracteres especiales que presenta, en este caso, IBM. Los valores ordinales del cdigo ASCII ampliado se encuentran en el rango de 0 a 255. Dichos valores pueden representarse escribiendo el carcter correspondiente encerrado entre apstrofes. As podemos escribir :
'A' < 'a'
Que significa : " El valor ordinal de A es menor que el de a " o " A est antes que a "
22
CADENA (STRING) Un tipo string (cadena) es una secuencia de caracteres de cero o ms caracteres correspondientes al cdigo ASCII, escrito en una lnea sobre el programa y encerrado entre apstrofos. El tratamiento de cadenas es una caracterstica muy potente de Turbo Pascal que contiene ISO Pascal estndar. Ejemplos:
'Turbo Pascal','Tecnolgico', #13#10
Nota:
Una cadena sin nada entre los apstrofos se llama cadena nula o cadena vaca. La longitud de una cadena es el nmero de carcteres encerrados entre los apstrofos.
2.6 Operadores
Los operadores sirven para combinar los trminos de las expresiones. En Pascal, se manejan tres grupos de operadores : 1. ARITMTICOS 2. RELACIONALES 3. LGICOS
23
Los operadores UNARIOS son aquellos que trabajan con UN OPERANDO. Pascal permite el manejo de un operador unario llamado : MENOS UNARIO Este operador denota la negacin 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 el inverso aditivo del operando. Los operadores BINARIOS, son los que combinan DOS OPERANDOS , dando como resultado un valor numrico cuyo tipo ser igual al mayor de los tipos que tengan los operandos. La siguiente tabla muestra los smbolos de los operadores binarios de Pascal as como los nombres de las operaciones que realizan. Operadores aritmticos bsicos Operador + * / div mod shl shr Suma Resta Multiplicacin Divisin Divisin entera Mdulo Desplazamiento a la izquierda Desplazamiento a la derecha Operacin Operandos Ejemplo real , integer a + b real , integer a - b real , integer a * b real , integer a / b integer integer a div b Resultado suma de a y b Diferencia de a y b Producto de a por b Cociente de a por b Cociente entero de a por b Desplazar a la izquierda b bits 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.
24
3. Cuando, en la operacin 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 es negativo y el truncamiento tiene lugar hacia el cero.
Ejemplos :
7 (-7) (-7) 7 15.0 15 div div div div div div 3 (-3) 3 (-3) 3.0 (4/2) = = = = = = 2 2 -2 -2 no vlido no vlido
La operacin div almacena slo la parte entera del resultado, perdindose la parte fraccionaria (truncamiento). 4. La operacin MODULO est definida solamente para OPERANDO-2 positivo. El resultado se dar como el entero no negativo ms pequeo que puede ser restado de OPERANDO-1 para obtener un mltiplo de OPERANDO-2 ; por ejemplo :
6 7 (-6) (-7) (-5) (-15) mod mod mod mod mod mod 3 3 3 3 3 (-7) = = = = = = 0 1 0 -1 -2 -1
En la operaciones aritmticas, debe asegurarse que el resultado de sumar, restar o multiplicar dos valores, no produzca un resultado fuera de los rangos definidos por la implementacin para los diferentes tipos.
25
MENOR que MAYOR que MENOR o IGUAL que MAYOR o IGUAL que
Al igual que las relaciones, en las operaciones con operadores lgicos se tienen resultados cuyo valor de verdad toma uno de los valores booleanos true o false. Los operadores lgicos en Pascal son : NOT Sintaxis : not operando Descripcin : Invierte el valor de verdad de operando. Ejemplo : Si bandera tiene un valor de verdad true, not bandera produce un resultado con valor de verdad false. AND Sintaxis : operando.1 and operando.2 Descripcin : Produce un resultado con valor de verdad true cuando ambos operandos
26
tienen valor de verdad true; en cualquier otro caso el resultado tendr un valor de verdad false. OR Sintaxis : operando.1 or operando.2 Descripcin : Produce un resultado con valor de verdad false cuando ambos operadores tienen valores de verdad false; en cualquier otro caso el resultado tendr un valor de verdad true. XOR Sintaxis : operando.1 xor operando.2 Descripcin : Un operando debe tener valor de verdad true y el otro false para que el resultado tenga valor de verdad true. Turbo Pascal tambin permite las siguientes operaciones entre los bits de operandos exclusivamente de tipo entero : AND Sintaxis : operando.1 and operando.2 Descripcin: Pone a ceros los bits de operando.2 cuyos correspondientes en operando.1 estn en ceros. Los valores se pasan a binario, y, sobre cada bit de operando.1 se realiza la operacin and lgica con el correspondiente bit de operando.2. Ejemplo : 29 and 30 = 28 Cuya forma en binario es :
0000000000011101 = 29 (operando.1) and 0000000000011110 = 30 (operando.2) _____________________ 0000000000011100 = 28 (resultado)
OR ( o inclusiva ) Sintaxis : operando.1 or operando.2 Descripcin : Pone a uno los bits de operando.1 cuyos correspondientes bits en operando.2 estn a uno.
27
Ejemplo : 17 or 30 = 31 En binario:
0000000000010001 = 17 (operando.1) or 0000000000011110 = 30 (operando.2) _____________________ 0000000000011111 = 31 (resultado)
XOR ( o exclusiva ) Sintaxis : operando.1 xor operando.2 Descripcin : Invierte el estado de los bits de operando.1, cuyos correspondientes en operando.2 estn a uno. Ejemplo : 103 xor 25 = 126 En binario:
0000000001100111 = 103 (operando.1) xor 0000000000011001 = 25 (operando.2) ______________________ 0000000001111110 = 126 (resultado)
SHL Sintaxis : operando.1 shl operando.2 Descripcin : Desplaza hacia la izquierda los bits de operando.1, el nmero de posiciones establecidas por operando.2. Los bits que salen por el extremo izquierdo se pierden. Ejemplo : 10 shl 2 = 40 En binario:
0000000000001010 = 10 (operando.1) shl 2 <= 0000000000101000 = 40 (resultado) (operando.2)
SHR Sintaxis : operando.1 shr operando.2 Descripcin : Desplaza hacia la derecha los bits de operando.1 el nmero de posiciones establecidas por operando.2.
28
Los bits que salen por el extremo derecho se pierden Ejemplo : 125 shr 3 = 15 En binario :
0000000001111101 = 125 (operando.1) shr 3 => 0000000000001111 = 15 (resultado) (operando.2)
2.7 Expresiones
Las expresiones son secuencias de constantes y/o variables separadas por operadores vlidos. Se puede construir una expresin vlida por medio de : 1. Una sola constante o variable, la cual puede estar precedida por un signo + - . 2. Una secuencia de trminos (constantes, variables, funciones) separados por operadores. Adems debe considerarse que: Toda variable utilizada en una expresin debe tener un valor almacenado para que la expresin, al ser evaluada, d como resultado un valor. Cualquier constante o variable puede ser reemplazada por una llamada a una funcin. Como en las expresiones matemticas, una expresin en Pascal se evala de acuerdo a la precedencia de operadores. La siguiente tabla muestra la precedencia de los operadores en Turbo Pascal: Precedencia de operadores 5 - (Menos unario) 4 not 3 * / div mod and shl shr 2 + - or xor 1 = <> > < >= <= Las reglas de evaluacin para las expresiones son :
29
1. Si todos los operadores en una expresin tienen la misma precedencia, la evaluacin de las operaciones se realiza de izquierda a derecha. 2. Cuando los operadores sean de diferentes precedencias, se evalan primero las operaciones de ms alta precedencia (en una base de izquierda a derecha ), luego se evalan las de precedencia siguiente, y as sucesivamente. 3. Las reglas 1) y 2) pueden ser anuladas por la inclusin de parntesis en una expresin. Ejemplos :
1. 3 + 2*5 {*,+} 2. 4 + 10 =14 3. 20*4 div 5 {Igual prioridad de izquierda a derecha : *,div} 80 div 5 = 16 4. 3 - 5 * (20+(6/2)) 3 - 5 * (20+(6/2)) = 3 - 5 * (20 + 3) {parntesis ms interno} = 3 - 5 * 23 {segundo parntesis} = 3 - 115 {Multiplicacin} = -112 {resta}
2.8 Instrucciones
Aunque un programa en Pascal puede contar con una sola instruccin (tambin llamada enunciado, sentencia o estatuto), normalmente incluye una cantidad considerable de ellas. Uno de los tipos de instrucciones ms importantes lo forman las instrucciones de asignacin; las cuales asignan a una variable (por medio del smbolo := ) , el resultado de la evaluacin de una expresin. La sintaxis para las instrucciones de asignacin es :
identificador := expresin ;
Al smbolo := le llamaremos, en lo sucesivo : "simbolo de asignacin" 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 instruccin vaca escribiendo slamente el punto y coma de una instruccin. As podemos escribir :
valor := valor + 1;;
30
Bloques de instrucciones
En todo lugar donde sea vlido utilizar una instruccin simple, es posible utilizar una instruccin compuesta o bloque de instrucciones, el cual se forma agrupando varias instrucciones simples por medio de los identificadores begin y end. Por ejemplo:
begin suma := 1000.0; incr := 20.0; total := suma + incr {Obsrvese la ausencia de punto y coma al final de la instruccin} end.
No es necesario escribir el punto y coma antes de end ya que el punto y coma se usa para separar instrucciones, no para terminarlas. begin y end son delimitadores de bloque.
Los procedimientos predefinidos Read y ReadLn (contraccin de Read Line), constituyen la base para las instrucciones de entrada estndar. Las instrucciones de entrada proporcionan datos durante la ejecucin de un programa. Las instrucciones 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 datos que se pueden leer son : enteros, caracteres, o cadenas. No se puede leer un boolean o un elemento de tipo enumerado. Los datos estructurados , arrays, registros o conjuntos, no se pueden leer globalmente y se suele recurrir a disear procedimientos especficos. La accin de la instruccin es obtener, del teclado, tantos valores de datos como elementos hay en lista_de_variables. Los datos debern ser compatibles con los tipos de las variables correspondientes en la lista. Cada valor entero o real en el flujo de entrada puede ser representado como una secuencia de caracteres en alguna de las formas permitidas para tales nmeros, y puede estar inmediatamente precedido por un signo ms o un signo menos. Cada valor entero o real puede ser precedido por cualquier cantidad de caracteres blancos o fines de lnea, pero no deber haber blancos o fines de lnea entre el signo y el nmero. La diferencia entre las instrucciones Read y ReadLn consiste en que Read permite que la siguiente instruccin contine leyendo valores en la misma lnea; mientras que, con ReadLn la siguiente lectura se har despus de que se haya tecleado el carcter de fin de lnea. Cuando se tienen datos de tipo char en una instruccin Read, los caracteres blancos y los de fin de lnea son considerados en el conteo de los elementos de las cadenas de caracteres mientras no se complete el total especificado para cada una de ellas. Cada fin de lnea es tratado como un carcter, pero el valor asignado a la variable ser un carcter blanco. Es aconsejable que cada cadena de caracteres se lea en una instruccin Read o ReadLn por separado, para evitar el tener que ir contando hasta completar la cantidad exacta de caracteres que forman la cadena ( o de lo contrario se tendrn resultados sorpresivos y frustrantes al verificar los datos ledos ). Ejemplo:
32
Var nombre :string[30] ; edad :integer; estatura :real; . . . ReadLn(nombre); ReadLn(edad); ReadLn(estatura);
donde : lista_de_salida es una lista de variables, expresiones y/o constantes, cuyos valores van a ser desplegados en la pantalla. El procedimiento Write permite que la siguiente instruccin se realice en la misma lnea , mientras que WriteLn alimenta una nueva lnea, antes de finalizar. Por ejemplo, las instrucciones :
Write ('! HOLA '); WriteLn('AMIGOS !');
producirn la salida :
! HOLA AMIGOS ! cursor en la siguiente lnea.
Mientras que :
Write('TECLEE <CTRL> F PARA FINALIZAR ==> ');
desplegar :
TECLEE <CTRL> F PARA FINALIZAR ==> CURSOR
33
producir :
20 + 30 = 50 ES TRUE
dejando el cursor en la misma lnea, al final de TRUE. Cuando un valor de salida se escribe sin una especificacin de longitud de campo, se utilizar la especificacin de campo por omisin. La especificacin de longitud de campo por omisin depender del tipo de valor de salida y de la implementacin de Pascal. As tenemos que, para todas las implementaciones : 1. La especificacin de longitud de campo por omisin para los valores de tipo char es 1 2. Si el valor a ser desplegado requiere menos del nmero de caracteres especificado, se imprimirn tantos caracteres blancos como sean necesarios para completar dicho nmero. 3. Si el valor a ser desplegado requiere un nmero de caracteres mayor que el especificado, se usa la mnima especificacin de longitud de campo que se requiera para representar un valor de tipo real o entero, pero las cadenas sern truncadas ajustndolas al campo especificado y desechar los caracteres en exceso que se encuentren ms a la derecha. 4. En el caso de valores de tipo real, se puede utilizar una especificacin de longitud de fraccin. Por omisin en Turbo Pascal, los valores de tipo real se desplegarn en formato de punto flotante (tambin 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.nnnnnnnnnnEsnn donde : b = blanco n = nmero ( 1-9 )
34
para R >= 0.0 , SIETE caracteres. para R < 0.0 , OCHO caracteres.
Ejemplos: Sentencias WriteLn ('Hola Mundo'); WriteLn('22' + '20'); WriteLn(pi); WriteLn(3.0); Resultados Hola Mundo 2220 3.1415926536E+00 3.0000000000E+00
Debido a que Pascal alinea (justifica) las impresiones hacia la derecha del campo correspondiente, cuando es necesario acomodar tabularmente los caracteres de cadenas que no ocupan la totalidad de columnas especificadas. Por ejemplo, suponiendo que nombre es un identificador de tipo string[20] (cadena con formato de 20 caracteres), para que la impresin de todos los valores de nombre empiece en la misma columna, podemos utilizar la instruccin :
WriteLn(numero,'.- ',nombre, ' ':20-length(nombre),calif:3);
y, al ejecutar el programa se tendr algo parecido a : 1.- JUAN FLORES 2.- EGRID L. CASTRO 3.- RAMON RAMIREZ 90(Ntese la justificacin de los nombres 100hacia la izquierda y los nmeros hacia 99la derecha)
Formatos de salida
Formato 1 : WriteLn (tem:anchura...); Anchura: Expresin entera (literal, constante, variable o llamada a funcin) que especifca la anchura total del campo en que se escribe tem.
35
Formato 2 : WriteLn (tem:anchura:dgitos ...); Dgitos: dgitos decimales de un nmero real Anchura: Total de dgitos del nmero real contando parte entera, punto decimal y dgitos decimales. Ejemplos: Valor:= 25.0776; Sentencias WriteLn (Valor); WriteLn(Valor:2); WriteLn(Valor:2:1); WriteLn(Valor:2:4); WriteLn(Valor:2:8); WriteLn('Tec':1); WriteLn('Tec':3); WriteLn('Tec':5); Resultados 2.5077600000E+01 2.5E+01 25.1 25.0776 25.07760000 Tec Tec _ _ Tec Comentario
Notese el redondeo
Espacios vacios _
4.1 Secuencia
En este caso, las instrucciones se ejecutan una despus de la otra sin omitir ninguna de ellas. La sintaxis para las instrucciones ejecutadas en secuencia es :
................ ................ <instruccin.1> ; <instruccin.2> ; ................ ................ <instruccin.N> ; ................ ................
4.2 Seleccin
36
La seleccin de alternativas en Pascal se realiza con alguna de las dos siguientes formas : 1. La sentencia if 2. La sentencia case
4.2.1 IF-THEN-ELSE
Dado que una condicin produce un valor verdadero o falso, se necesita una sentencia de control que ejecute determinada sentencia si la condicin es verdadera , y otra si es falsa. En Pascal esta alternativa se realiza con la sentencia IF-THEN-ELSE. A continuacin se describe el diagrama de flujo y el formato de la sentencia.
En este caso, primero se evala condicin y si el resultado arroja un valor de verdad(verdadero), se ejecuta instruccin_1 ; en caso contrario se ejecuta instruccin_2. La condicin es una expresin Booleana que puede ser verdadera o falsa (true o false). Una expresin Booleana se forma comparando valores de las expresiones utilizando operadores de relacin (relacionales) o comparacin y los operadores lgicos vistos anteriormente.
37
Ejemplos :
Nota: Antes de la palabra end no se debe anteponer un punto y coma como se muestra en este ejemplo. El hacerlo generaria una sentencia vacia (sentencia que no hace nada).
Nota: Antes de la clusula else no se antepone un punto y coma, si lo hubiese el compilador producir un mensaje de error, puesto que no existe ninguna sentencia en Pascal que comience con else. La parte else es opcional, pero la ejecucin siempre continuar en otra instruccin. En lugar de utilizar instrucciones simples, se pueden usar bloques de instrucciones, como acontinuacin se muestra :
Program Edades; Uses Crt; Var edad : integer ;
38
begin WriteLn('Escribe tu edad : ') ; ReadLn(edad) ; if edad >= 18 then begin WriteLn('!Eres Mayor de edad !'); WriteLn('!Ya puedes Votar!') end else begin WriteLn('!Eres Menor de edad !'); WriteLn('!An no puedes votar!') end; WriteLn('Esta instruccin siempre se ejecuta'); ReadKey end.
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); ReadKey end.
4.2.2 CASE-OF-ELSE
Esta forma es muy til cuando se tiene que elegir entre ms de dos opciones, por lo que le llamaremos forma de seleccin mltiple. La siguiente figura representa la seleccin mltiple.
39
Su formato es :
case <selector> of constante.1 : begin <instrucciones>; end; constante.2 : begin <instrucciones> ; end; ..................... ..................... constante.N : begin <instrucciones> ; end
else
Dependiendo del valor que tenga la expresin selector, se ejecutarn las instrucciones etiquetadas por constante . Aqu tambin 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.
40
Reglas: 1. La expresin <selector> se evala y se compara con las constantes;las constantes son listas de uno o ms posibles valores de <selector> separados por comas. Ejecutadas la(s) <instrucciones>, el control se pasa a la primera instruccin a continuacin de end (fin de case). 2. La clusula else es opcional. 3. Si el valor de <selector> no est comprendido en ninguna lista de constantes y no existe la clusula else, no sucede nada y sigue el flujo del programa; si existe la clusula else se ejecutan la(s) <instrucciones> a continuacin de la clusula else. 4. El selector debe ser un tipo ordinal ( integer, char, boolean o enumerado). Los nmeros reales no pueden ser utilizados ya que no son ordinales. Los valores ordinales de los lmites inferiores y superiores deben de estar dentro del rango -32768 a 32767. Por consiguiente, los tipos string, longint y word no son vlidos. 5. Todas las constantes case deben ser nicas y de un tipo ordinal compatible con el tipo del selector. 6. Cada sentencia, excepto la ltima, deben ir seguidas del punto y coma. Ejemplo:
Program Tecla; {El siguiente programa lee un carcter del teclado y despliega un mensaje en pantalla si es letra o nmero o carcter especial} Uses Crt; Var caracter : char; begin Write('Escribe un caracter : '); caracter:=ReadKey;WriteLn; case caracter of '0'..'9' : WriteLn('Es un nmero'); 'a'..'z','A'..'Z' : WriteLn('Es una letra') else WriteLn('Es un caracter especial') end; ReadKey end.
4.3 Iteracin
Las formas de iteracin sirven para ejecutar ciclos repetidamente, dependiendo de que se cumplan ciertas condiciones. Una estructura de control que permite la repeticin de una serie determinada de sentencias se denomina bucle1 (lazo o ciclo). El cuerpo del bucle contiene las sentencias que se repiten. Pascal proporciona tres estructuras o sentencias de control para especificar la repeticin:
41
En ingls, loop.
4.3.1 WHILE-DO
La estructura repetitiva while(mientras) es aquella en la que el nmero de iteraciones no se conoce por anticipado y el cuerpo del bucle se ejecuta repetidamente mientras que una condicin sea verdadera . Su formato es :
while <condicin> do begin <instrucciones>; end;
y su diagrama :
Reglas de funcionamiento : 1. La condicin se evala antes y despus de cada ejecucin del bucle. Si la condicin es verdadera, se ejecuta el bucle, y si es falsa, el control pasa a la sentencia siguiente al bucle. 2. Si la condicin se evala a falso cuando se ejecuta el bucle por primera vez, el cuerpo del bucle no se ejecutar nunca. 3. Mientras la condicin 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 condicin haciendo que su valor pase a falso. Si la expresin
42
nunca cambia de valor, entonces el bucle no termina nunca y 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 end end.
4.3.2 REPEAT-UNTIL
La accin de repeat-until es repetir una serie de instrucciones hasta que se cumpla una determinada condicin . Su formato es :
repeat <instruccin.1> ; <instruccin.2> ; .................. .................. <instruccin.N> ; until <condicin>;
Aqu las palabras repeat y until sirven tambin como delimitadores de bloque. Su diagrama de flujo es :
43
Reglas de funcionamiento: 1. La condicin se evala al final del bucle, despus de ejecutarse todas las sentencias. 2. Si la condicin es falsa, se vuelve a repetir el bucle y se ejecutan todas sus instrucciones. 3. Si la condicin es falsa, se sale del bucle y se ejecuta la siguiente instruccin a until. 4. La sintaxis no requiere begin y end. Analcense los diagramas de while-do y repeat-until, para comprender las diferencias entre ambas formas. 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.
44
4.3.3 FOR-TO-DO
Cuando se sabe de antemano el nmero de veces que deber ejecutarse un ciclo determinado, sta es la forma ms conveniente. El formato para for-to-do es :
for <contador>:=<expresin.1> to <expresin.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 continuacin se ejecutan las intrucciones del interior del bucle, enseguida se verifica si el valor final (expresin.2) es mayor que el valor inicial (expresin.1); en caso de no ser as se incrementa contador en uno y se vuelven a ejecutar las instrucciones, hasta que el contador sea mayor que el valor final, en cuyo momento se termina el bucle. 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 nmero de iteraciones : '); ReadLn(valor_final); for contador:=1 to valor_final do WriteLn('Iteracin : ',contador); ReadKey end.
45
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 nmero de iteraciones : '); ReadLn(valor_final); for contador:=valor_final downto 1 do WriteLn('Iteracin : ',contador); ReadKey end.
46
TIPO SUBRANGO
El tipo de dato ms simple que se puede definir en un programa Pascal es el tipo subrango o intervalo. Estos tipos son tiles, sobre todo por la facilidad que ofrecen para verificar automticamente errores. Un tipo subrango se define de un tipo ordinal, especificando dos constantes de ese tipo, que actan como lmite inferior y superior del conjunto de datos de ese tipo. Un tipo subrango es un tipo ordinal y sus valores se ordenan de igual modo que en el tipo patrn de que se deducen. Ejemplos:
este tipo subrango consta de los elementos 0,1,2,3,4,5,6,7,8,9 este subrango consta de los caracteres 2. '0'..'9' '0' a '9' este subrango consta de los caracteres 3. 'A'..'F' 'A' a 'F' 1. 0..9
Se pueden crear variables cuyos valores se restrinjan a un subrango dado. Las declaraciones de tipo subrango se sitan entre las declaraciones de constantes y de variables. Formato:
type Nombre = lmite inferior .. lmite superior
Ejemplos:
{$R+} {Directiva de compilador R} Program Positivos; Uses Crt; {El siguiente programa realiza una validacin para que slo 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 instruccin provocara un error} Write('Escribe un nmero entero positivo : '); ReadLn(numero); ReadKey end.
Nota: Puesto que Turbo Pascal no siempre produce un error cuando el valor de un tipo subrango est fuera de su rango definido. Sin embargo se puede tener la posibilidad de visualizar dichos errores mediante la directiva de compilador: 47
{$R+} {$R-}
activada desactivada
Por default esta desactivada. Slo se debe usar durante la fase de depuracin.
TIPOS ENUMERADOS
En estos tipos de datos simples, se listan los identificadores que sern asociados con cada valor a utilizar. Por ejemplo :
Type dias_semana =(lunes,martes,miercoles,jueves, viernes,sabado,domingo); colores_baraja =(espada,oro,basto,copa);
Formato:
Type nombre = (constante1,constante2,...,constanteN)
Los datos de tipo colores_baraja slo podrn tomar los valores denotados por : espada, oro, basto, copa . La posicin de cada valor en la lista define su orden, por lo que para el tipo dias_semana tenemos que :
domingo > viernes da como resultado true sabado < martes da como resultado false jueves <> miercoles da como resultado true
Caractersticas:
Un tipo de dato enumerado es un tipo ordinal cuyo orden se indica por la disposicin de los valores en la definicin. El nmero de orden de cada elemento comienza en 0 para el primer elemento. Las variables de tipo enumerado slo pueden tomar valores de estos tipos. Los nicos operadores que pueden acompaar a los tipos ordinales son los operadores de relacin y asignacin.
48
A los valores de los tipos enumerados se les pueden aplicar las funciones estndar succ (de sucesor), pred (de predecesor) y ord (de ordinal). En el caso del valor mximo de un tipo enumerado, succ no est definido, y, para su valor mnimo, no est definido pred. La funcin estndar ord es aplicable a los argumentos que sean valores de tipo enumerado. La relacin biunvoca 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 estndar boolean es equivalente a un tipo enumerado de la forma :
boolean = ( false, true);
Aplicacin de las funciones Ord, Pred, Succ Argumento(x) Tipos de datos Ord(x) Pred(x) lunes oro 22 0 -20 MaxInt false Ejemplo:
Program Dias_Semana; Uses Crt; {El siguiete 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 ');
0 22 0 -20 0
colores_baraja 1
49
')
50
Declaracin en Type:
Type cad30 cad40 Var nombre domicilio ciudad : string[30]; : string[40]; : cad30; : cad30; : cad40;
Una Vez declaradas las variables se pueden realizar asignaciones u operaciones de lectura/escritura. nombre := 'Egrid Lorely Castro Gonzalez' ; domicilio := 'Altamirano #220'; ciudad := 'La Paz B.C.S.';
El contenido de la cadena se debe encerrar entre apstrofes. Si se desea que figure un apstrofe en una cadena, es preciso doblarlo en la cadena. Los procedimientos de Entrada/Salida son de la siguiente forma :
ReadLn (nombre); WriteLn('Hola ',nombre);
Obsrvese que el primer byte no es el carcter '6' si no el nmero 6 en binario (0000 0110) y los ltimos bytes de la cadena hasta 10 (7-10) contienen datos aleatorios. 51
Una cadena en Turbo Pascal tiene dos longitudes : 1. Longitud fsica : Es la cantidad de memoria que ocupa realmente, est se establece en tiempo de compilacin y nunca cambia 2. Longitud lgica : Es el nmero de caracteres almacenados actualmente en la varible cadena. Este dato puede cambiar durante la ejecucin del programa. Es posible acceder a posiciones individuales dentro de una variable cadena, mediante la utilizacin de corchetes que dentro de ellos se especifca el nmero indice dentro de la cadena a utilizar as para el ejemplo anterior se tiene :
nombre[1] nombre[2] nombre[3] nombre[4] nombre[5] nombre[6] ==> ==> ==> ==> ==> ==> 'S' 'u' 's' 'a' 'n' 'a'
El resultado de la asignacin en la variable nombre ser la cadena 'Instituto Tecnolgico'. Las comparaciones de las cadenas de caracteres se hacen segn el orden de los caracteres en el cdigo ASCII y con los operadores de relacin.
'0' < '1' '2' > '1' 'A' < 'B' 'm' > 'l'
Reglas de comparacin de cadenas Las dos cadenas se comparan de izquierda a derecha hasta que se encuentran dos caracteres diferentes. El orden de las dos cadenas es el que corresponde al orden de los dos caracteres diferentes. Si las dos cadenas son iguales pero una de ella es ms corta que la otra, entonces la ms corta es menor que la ms larga.
52
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 operacin bsica es la concatenacin. La concatenacin es un proceso de combinar dos o ms cadenas en una sola cadena. El signo + se puede usar para concatenar cadenas ( al igual que la funcin 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 expresin de cadena a una variable cadena, por ejemplo :
fecha := 'lunes';
Si la longitud mxima de una cadena es excedida, se pierden los caracteres sobrantes a la derecha. Por ejemplo, si fecha hubiera sido declarada del tipo string[7], despus de la asignacin contendra los siete primeros caracteres de la izquierda (CENTENA).
53
Val
Pos
Procedimiento Delete Delete borra o elimina una subcadena de una cadena contenida en otra cadena de mayor longitud. Formato : Delete (s, posicin, nmero)
S Cadena original o fuente Posicin Expresin entera que indica la posicin del primer carcter a suprimir. Nmero Cantidad de caracteres a suprimir.
Si posicin es mayor que la longitud de la cadena, no se borra ningn carcter. Si nmero especifca ms caracteres que los existentes desde la posicin inicial hasta el final de la cadena, slo se borran tantos caracteres como estn en la cadena. Ejemplo :
Cad := 'Tecnolgico' Delete(cad,1,5) Resulta la cadena 'lgico'
Procemiento Insert Insert inserta una subcadena en una cadena. Formato : Insert (cad1, s, posicin)
cad1 cadena a insertar s cadena donde se inserta posicin carcter a partir del cual se inserta
Ejemplo:
cad:= 'Mxico ' Insert (' lindo y querido',cad,7) Resulta 'Mxico lindo y querido'
54
Procedimiento Str Este procedimiento efecta la conversin de un valor nmerico en una cadena. Formato : Str (valor,s)
Valor expreson nmerica s 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 nmerica. Para que esta conversin sea efectiva, el contenido de la cadena de caracteres debe corresponderse a las reglas de escritura de nmeros: no debe de existir ningn blanco en la primera o ltima posicin. Formato: Val (S, variable, cdigo)
S cadena Variable variable de tipo entero o real cdigo si la conversin ha podido ser efectuada toma el valor cero; en caso contrario contiene la primera posicin del primer carcter de la cadena S que impide la conversin y en ese caso variable no queda definida
Ejemplo:
Var
55
cad : string[10]; num1,codigo : integer; 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.
Funcin Concat Adems del uso de '+' para la concatenacin, Turbo Pascal tiene la funcin concat que permite concatenar una secuencia de caracteres. Formato: Concat (S1,S2,...,Sn)
S1,S2...cadenas o variables de caracteres (expresin 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'
Funcin Copy
56
Esta funcin devuelve una cadena de caracteres (subcadena) extrada de una cadena. Formato: Copy(s,posicin,nmero)
s cadena (fuente) posicin primer carcter a extraer (tipo entero) nmero total de caracteres a extraer (tipo entero)
Si posicin es mayor que la longitud de S, se devuelve una cadena vaca; si nmero especifca ms caracteres que los indicados desde posicin, slo se devuelve el resto de la cadena. Ejemplo:
cad := 'Instituto Tecnolgico de La Paz'; cad2 := Copy(cad,26,6); Write(cad2); Lo que produce la cadena 'La Paz' contenida en cad2.
Funcin Lenght (longitud) La funcin Lenght proporciona la longitud lgica de una cadena de caracteres y devuelve un valor entero. Formato : Length (s)
s expresin tipo cadena
Ejemplo :
Var cad : string[20]; begin cad:='Hola'; WriteLn(Length ('Hola como estas')); {devuelve el valor 15} WriteLn(Length ('')); {devuelve cero (cadena vaca)} WriteLn(Length (cad)); {devuelve el valor 4} WriteLn(Ord(cad[0])) {devuelve el valor 4} end.
57
Funcin Pos Esta funcin permite determinar si una cadena est contenida en otra. En este caso, la funcin devuelve la posicin donde comienza la cadena buscada en la cadena fuente, si la cadena no existe, 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 posicin de 'd'} WriteLn(Pos('ocho',cad)); {Resulta 0 no existe la cadena 'ocho'}
El formato para definir un tipo array es : nombre_array = array [tipo subndice] of tipo
58
nombre_array identificador vlido tipo subndice puede ser de tipo ordinal: boolean o char, un tipo enumerado o un tipo subrango. Existe un elemento por cada valor del tipo subndice tipo describe el tipo de cada elemento del vector; todos los elementos de un vector son del mismo tipo
Declaracin en Var:
Var nombres calif numero : array[1..30] of string[30]; : array[1..30] of real; : array[0..100] of 1..100;
Declaracin en Type:
Type nombres calif numero Var nom califica num : array[1..30] of string[30]; : array[1..30] of real; : array[0..100] of 1..100; : nombres; : calif; : numero;
Arrays unidimensionales
Un array de una dimensin (vector o lista) es un tipo de datos estructurado compuesto de un nmero de elementos finitos, tamao fijo y elementos homogneos. Supongamos que desea conservar las edades de 10 personas. Para almacenar estas edades se necesita reservar 10 posiciones de memoria, darle un nombre al array, y a cada persona asignarle su edad correspondiente.
59
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; {ordenacin} 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; Readkey end.
Arrays paralelos
Dos o ms arrays que utilizan el mismo subndice para referirse a trminos homlogos se llaman arrays paralelos. Basados en el programa anterior se tienen las edades de 'x' personas, para saber a que persona se refiere dicha edad se puede usar otro arreglo en forma paralela y asociarle los nombres de manera simultnea con las edades.
60
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 simultnea} 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; {ordenacin} 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;
61
Readkey end.
Para localizar o almacenar un valor en el array se deben especificar dos posiciones (dos subndices), uno para la fila y otro para la columna. Formato: 1. identificador = array [ndice1, indice 2] of tipo de elemento 2. identificador = array [ ndice 1 ] of array [ indice 2 ] of tipo de elemento Supongase que se desea almacenar las calificaciones de 5 alumnos obtenidas en 3 examenes y mostrar en orden ascendente sus promedios respectivamente. En este caso se usar un array bidimensional (tabla o matrz) de 5 filas y 4 columnas en la cual se almacenar las calificaciones de 3 examenes en 3 columnas y la cuarta columna se utilizar para almacenar su promedio respectivo, adems de un array unidimensional (vector) donde en forma paralela se almacenarn los nombres de los alumnos de la siguiente forma :
Ejemplo:
Program Matriz_Vector; {El siguiente programa captura las calificaciones
62
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 simultnea} 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); 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 matrz} 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; {ordenacin} 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 matrz} 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 matrz y vector} gotoxy(25,14);Write('Datos ordenados'); gotoxy(5,16);Write('Nombre');
63
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 end; col:=5; inc(ren) end; readkey end.
Arrays multidimensionales
Turbo Pascal no limita el nmero de dimensiones de un array, pero s que debe estar declarado el tipo de cada subndice. Formato :
1. identificador = array [ndice1] of array [ndice 2].. of array [ndice n] of tipo de elemento 2. identificador = array [ndice 1, ndice 2,...,ndice n] of tipo de elemento Ampliando el ejemplo anterior supongase que ahora deseamos capturar calificaciones para 3 materias en cuyo caso aplicaremos un array tridimensional. De la siguiente forma :
64
(nombre,examen,materia) Ejemplo:
Program Tridimensional; {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 simultnea} 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 matrz} 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); inc(ren); col:=5 end; gotoxy(15,22); Write('Presione una tecla para continuar....');
65
ReadKey end; {ordenacin} 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 matrz} 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 matrz 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) end; gotoxy(15,22); Write('Presione una tecla para continuar....'); readkey end end.
La definicin de un tipo registro debe consistir de la palabra reservada record, seguida de una lista 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 registro lista id lista de uno o ms nombres de campos separados por comas tipo puede ser cualquier tipo de dato estndar o definido por el usuario
Ejemplo :
Type registro_empleado = Record nombre profesion puesto sueldo end;
: : : :
El registro como un todo tiene el nombre registro_empleado. Este nuevo tipo que se acaba de definir puede utilizarse en la seccin Var, para declarar variables como por ejemplo :
Var empleado : registro_empleado ;
67
Para asignar valores a cada campo del registro empleado, puede procederse de la siguiente manera :
....................... ....................... ....................... empleado.nombre := 'MENDEZ ROMERO FEDERIC'; empleado.profesion := 'INGENIERO CIVIL'; empleado.puesto := 'DIRECTOR'; empleado.sueldo := 5000.00 ; ....................... ....................... .......................
Para simplificar la notacin de los registros, se pueden utilizar instrucciones With Do. Por ejemplo, la instruccin :
WriteLn(empleado.nombre:35, empleado.puesto:25, empleado.sueldo:15:0);
puede escribirse :
With empleado Do WriteLn(nombre:35,puesto:25,sueldo:15:0);
68
end; datos = Record nombre : string[30] ; sueldo : real ; fecha_ingreso : fecha end; Var personal : datos ; ............................... ............................... ...............................
La asignacin del valor 15 al campo dia del registro personal se hace de la siguiente manera :
personal.fecha_ingreso.dia := 15 ;
donde :
personal.fecha_ingreso
se refiere al campo dia del campo fecha_ingreso, que a su vez es un registro de tipo fecha. Usando la forma With Do quedara :
With personal Do With fecha_ingreso Do dia := 15 ;
que es equivalente a :
With personal, fecha_ingreso Do dia := 15 ;
o tambin 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 utilizacin de registros} Uses Crt;
69
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 Profesin Puesto Sueldo'); col:=1;ren:=2; for i:=1 to MaxEmpleados do begin With registro do 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; ReadKey end.
70
Aunque se puede utilizar notacin de tipo subrango para especificar secuencia de valores que pertenezcan a un conjunto, los elementos del conjunto no tienen una ordenacin interna particular. La nica relacin entre los miembros de un conjunto es: existe o no existe en el conjunto. [5,5] y [5] son equivalentes (contienen un slo elemento) Ejemplos de conjuntos: [1,3,5] [1..3,8..10] [] conjunto de tres enteros conjunto de seis enteros [1,2,3,8,9,10] conjunto vaco (ningn elemento)
['a','b','A'..'D'] conjunto de seis elementos ['a','b','A','B','C','D'] Un conjunto especial, denominado conjunto vaco, es aquel que no contiene ningn elemento. El formato para la definicin de un tipo conjunto es :
type <identificador> = set of <tipo_base>
Ejemplos :
Type dias_mes mayusculas caracteres equipos = = = = set of 0..31; set of 'A'..'Z'; set of char; (Chivas,Santos,Pumas, Toluca,Tigres,America, Leon); = set of equipos;
En Turbo Pascal, el mximo nmero de elementos permitidos en un conjunto es 256, y los valores ordinales del tipo base deben estar en el rango de 0 a 255 .
Asignacin en conjuntos
71
Si dos tipos de conjuntos son compatibles (tienen los tipos de base compatibles: igual tipo de dato, o uno subrango de otro, o ambos del mismo tipo patrn), sus variables representativas se pueden utilizar en sentencias de asignacin.
GrupoA := GrupoB; GrupoB := [];{asignacin del conjunto vaco}
La relacin In
El operador relacional In y una expresin relacional nos permite conocer si un elemento dado pertenece a un conjunto dado. Formato: elemento in [ lista de elementos ] El resultado de evaluar la expresin relacional puede ser true o false. El tipo de datos de elemento 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]; ClrScr end.
Una vez creados los conjuntos y las variables tipo conjunto es posible realizar tres operaciones binarias sobre ellos: unin, interseccin y diferencia. La siguiente tabla resume el funcionamiento de las operaciones con conjuntos A y B.
Operaciones sobre dos conjuntos A y B Notacin Operacin Pascal Unin Interseccin Diferencia Ejemplo: Operacin Resultado + * A+B es el conjunto que contiene todos los elementos que estn en A, en B o en ambos. A*B es el conjunto cuyos elementos pertenecen a A y B simultneamente. A-B es el conjunto cuyos elementos son de A pero no de B. Conjunto resultante
[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,4]*[3,5,6] [1,2,3]-[ ] Reglas de prioridad Cuando una expresin de conjuntos contiene dos o ms operadores de conjunto, stos se evalan de acuerdo a la siguiente prioridad: * Prioridad ms alta [1,2,3] [] []
+,- Prioridad ms baja En caso de operaciones con igual prioridad se evalan de izquierda a derecha.
73
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 comparacin es un valor lgico: true o false. Operadores de relacin de conjuntos A y B Operador <= = <> >= Nombre del operador Subconjunto Igualdad Desigualdad Superconjunto Resultado El valor de A< = B es true. Si cada elemento de A es tambin de B. En caso contrario es false. El valor de A = B es true si cada elemento de A est en B y cada elemento de B est en A. En caso contrario A = B es falso, A=B equivale a (A<=B) and (B<=A). El valor de A < > B es true si el valor de A = B es false y viceversa. A < > B equivale a not (A = B), A >= B es true si B<=A es true.
Ejemplos : Comparacin [3,5] = [3,5] [ ] = [1] [ ] <= [1,5] [ ] >= [1,2] [1,4,5] = [4,5,1] Prioridad de operadores : Operador not *,/,div,mod,and +,-,or 2 3 Prioridad 1 (ms alta) Resultado true false true false true
74
Lectura de conjuntos
Algunas operaciones no se pueden ejecutar sobre variables de conjunto. Por ejemplo, no se puede leer cinco ciudades en un conjunto Mundo con la siguiente sentencia:
ReadLn(Mundo)
La razn 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 : 1. Inicializar A al conjunto vaco. A := [ ]; 2. Leer cada elemento x del conjunto y aadirlo al conjunto A con la operacin unin (+) ReadLn(x); A := A + [x];
Escritura de conjuntos
Los 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: 1. Copiar los elementos de A en un conjunto auxiliar Aux que tenga un tipo base compatible con el de A. 2. Declarar x una variable del tipo base de Aux e inicializar x al primer elemento de est tipo base.
75
3. Mientras x es diferente del ltimo elemento de est tipo base y Aux no est vaca, hacer : I. Si x pertenece a Aux, entonces visualizar x y eliminarlo de Aux II. Sustituir x con su sucesor.
Ejemplo:
Program Impares; {El siguiente programa encuentra y muestra todos los nmeros impares menores o igual a un nmero dado n que est entre el lmite 1..255} Uses Crt; Type numeros = set of 1..255; Var impares,Aux :numeros; x,MaxNum,i :byte; begin ClrScr; Write('Escribe un nmero entero : '); ReadLn(MaxNum); impares:=[]; {inicializa a conjunto vaco} for i:=1 to MaxNum do begin if odd(i) then impares:=impares + [i] {aadir elementos al conjunto} end; {visualizar elementos del conjunto} Aux:=impares; 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; ClrScr end.
Por ejemplo :
Type empleado = file of Record nombre:string[30]; sueldo:real; end; Var nomina : empleado ;
6.1 Subprogamas
Un programa en Pascal consiste de uno o ms mdulos, los cuales a su vez tambin pueden estar constitudos por otros mdulos, y as sucesivamente. Estos mdulos sern llamados, en trminos generales, SUBPROGRAMAS, y en particular PROCEDIMIENTOS y FUNCIONES. Un subprograma es un bloque de programa que realiza una tarea determinada, y que al llamrsele o invocrsele puede necesitar que se le pasen PARAMETROS. Los parmetros son identificadores que proveen un mecanismo para pasar informacin hacia los subprogramas invocados. Los parmetros que se utilizan en la declaracin de subprogramas se llaman PARAMETROS FORMALES. Un subprograma puede ser invocado desde cualquier punto del programa, por medio de una instruccin INVOCADORA, la cual puede contener una lista de parmetros llamados PARAMETROS ACTUALES.
6.2 Procedimientos
Un procedimiento es un subprograma que realiza alguna de las tareas del programa, y que no devuelve ningn valor al subprograma que lo invoc.
77
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 se ejecuta siempre que Pascal encuentra el nombre del procedimiento. En Turbo Pascal resulta obligatorio declarar los procedimientos antes de ser referenciados en el cuerpo del programa.
Formato 2:
procedure nombre_procedimiento(parmetros formales); declaraciones locales begin cuerpo del procedimiento end;
La existencia de parmetros_formales depender de la naturaleza del procedimiento, esto es, de la tarea que va a realizar y de la forma en que lo ha estructurado su creador.
78
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 FIN FIN.
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; Var mat_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('='); WriteLn end; {Lee las dimensiones de las matrices} procedure dim ; begin
79
WriteLn('DIMENSIONES DE LA MATRIZ A'); WriteLn; Write('Nmero de renglones ==> '); ReadLn(ren_a); Write('Numero de columnas ==> '); ReadLn(col_a); WriteLn; WriteLn; WriteLn('DIMENSIONES DE LA MATRIZ B'); WriteLn; Write('Nmero de renglones ==> '); ReadLn(ren_b); Write('Nmero de columnas ==> '); ReadLn(col_b) end; {Verifica la compatibilidad para la suma} 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 :=true end; {Verifica la compatibilidad para la multiplicacin} 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 multiplicacin'); bandera_f := false end else bandera_f := true end; {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]) end end;
80
{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 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 end end; {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; WriteLn end; {Mdulo Principal} begin inicio; 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
81
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 end end.
Observe que el MDULO PRINCIPAL est formado por un bloque de instrucciones que invocan a procedimientos.
Ejemplos :
function verifica : boolean ; { Funcin sin parmetros formales} function cambia(Var valor_1, valor_2: real):real; function potencia( base, exponente : real ):real;
82
donde : parmetros_locales es una lista de variables y/o constantes separadas por comas. La existencia de parmetros_locales depender de que existan parmetros formales en la declaracin de la funcin. Por ejemplo, resolvamos el problema de cacular la raz cuadrada de un nmero, utilizando el algoritmo de Newton: x(i+1) = x(i) + 0.5 ( a/x(i) -x(i) ) La codificacin del programa sera :
Program Raiz_cuadrada; {El siguiente programa calcula la raz cuadrada de un nmero} Uses Crt; Var raiz, numero : real; {Declaracin de la funcin 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 c := x ; x := x + 0.5 * ( a/x -x ) end; raiz_cuad := x {El resultado se asigna a nombre_funcin} end; begin ClrScr; Write('La raz cuadrada de : '); ReadLn(numero) ; raiz:=raiz_cuad(numero); {Invoca a la funcin raiz_cuad} WriteLn ; WriteLn('Es igual a : ',raiz:6:8); ReadKey; ClrScr end.
limita a ese subprograma y a los mdulos que ste contiene. Cuando otro subprograma utiliza el mismo nombre de variable, se crea una variable diferente en otra posicin de la memoria. Por eso, si un subprograma asigna un valor a una de las variables locales, tal valor no es accesible a los otros subprogramas. Cuando se desea que otros subprogramas tengan acceso al valor de una variable, sta debe declararse como GLOBAL, lo cual se logra declarndola en el mdulo que abarca a dichos subprogramas. Para tener la seguridad de que una variable va a tener un alcance GLOBAL, conviene declararla en el MODULO PRINCIPAL. Los conceptos anteriores se aclaran por medio de la siguiente figura :
Program anidado;
Referencias de identificadores vlidos : Bloque Identificador anidado M i,,j A A i r,s B Significado de cada identificador constante global varibles globales procedimiento declarado en anidado parmetros de A variables locales funcin local 84
j B M B g m,n r,s i y A B M
variable declarada en anidado funcin declarado en anidado constante global parmetros de B variables locales variable declarada en A parmetro de A variable declarada en anidado procedimiento declarado en anidado funcin declarada en anidado constante global
85
Var A,B,C:integer; procedure suma(A,B,C :integer); begin C := A + B end; begin ClrScr; C:=10; A:=10; B:=10; suma(A,B,C); WriteLn(A,',',B,',',C); ReadKey; ClrScr end.
El resultado de la ejecucin del programa sera : 10,10,10 El valor de C no se modifica puesto que es un parmetro por valor.
86
Vemos que en la declaracin del procedimiento suma existe la parte: Var mat_f_c : mat la cual significa lo siguiente : "La variable mat_f_c contiene la direccin de la variable correspondiente en la invocacin ( mat_c ) , y es de tipo mat " Esto significa que el paso del parmetro mat_c se hizo por referencia, y que el procedimiento invocado (suma) puede modificar el valor de mat_c . Ejemplo:
Program Suma_por_Referencia; {El siguiente programa realiza la suma de dos nmeros } Uses Crt; Var A,B,C:integer; procedure suma(A,B:integer;Var C:integer); begin C := A + B end; begin ClrScr; C:=10; A:=10; B:=10; suma(A,B,C); WriteLn(A,',',B,',',C); ReadKey; ClrScr end.
El resultado de la ejecucin del programa sera : 10,10,20 El valor de C se modifica puesto que es un parmetro por referencia. Nota : En Turbo Pascal no se permite el paso de procedimientos y funciones como parmetros
6.6 Recursin
87
En Pacal, a un procedimiento o funcin le es permitido no slo invocar a otro procedimiento o funcin, sino tambin invocarse a s mismo. Una invocacin de ste tipo se dice que es recursiva. La funcin recursiva ms utilizada como ejemplo es la que calcula el factorial de un nmero entero no negativo, partiendo de las siguientes definiciones :
factorial (0) = 1 factorial (n) = n*factorial(n-1), para n>0
1. factorial(4) := 4 * factorial(3) Se invoca a si misma y crea una segunda variable cuyo nombre es numero y su valor es igual a 3. 2. factorial(3) := 3 * factorial(2) Se invoca a si misma y crea una tercera variable cuyo nombre es numero y su valor es igual a 2. 3. factorial(2) := 2 * factorial(1) Se invoca a si misma y crea una cuarta variable cuyo nombre es numero y su valor es igual a 1. 88
4. factorial(1) := 1 * factorial(0) Se invoca a si misma y crea una quinta variable cuyo nombre es numero y su valor es igual a 0. 5. Como factorial(0) := 1, con ste valor se regresa a completar la invocacin: factorial(1) := 1 * 1 , por lo que factorial(1) := 1 6. Con factorial(1) := 1, se regresa a completar: factorial(2) := 2 * 1, por lo que factorial(2) := 2 7. Con factorial(2) := 2, se regresa a completar : factorial(3) := 3 * 2, por lo que factorial(3) := 6 8. 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 funcin factorial devolver al mdulo que la haya invocado con un valor de parmetro local igual a 4 .
Un ejemplo de procedimiento recursivo es el siguiente: Supngase que una persona se mete a una piscina cuya profundidad es de 5 metros. Su intencin es tocar el fondo de la piscina y despus salir a la superficie. Tanto en el descenso como en el ascenso 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 Apuntadores
En una computadora cada posicin de memoria tiene una direccin y un valor especfico almacenado en esa posicin. Se han utilizado nombres de variables en lugar de direcciones porque los nombres son ms fciles de recordar. Para almacenar un
89
nuevo valor en memoria se asigna a una variable, y la computadora enva una direccin a la memoria seguida por el valor a almacenar en esa posicin. Pascal proporciona un tipo especial de variable denominado apuntador, que es una variable cuyo valor es una direccin de una posicin de memoria.
Al definir un tipo apuntador se debe indicar el tipo de valores que se almacenarn en las posiciones designadas por los apuntadores. La razn es que los diferentes tipos de datos requieren diferentes cantidades de memoria para almacenar sus constantes, una variable apuntador puede contener una direccin de una posicin de memoria adecuada slo para un tipo dado. Por esta razn se dice que un apuntador apunta a una variable particular. Una variable tipo apuntador contiene la direccin de la posicin de otra variable Para declarar una variable de tipo apuntador en Pascal se debe especificar el nombre de la variable y el tipo del valor que se almacenar en la posicin de memoria a la que el apuntador se refiere. Formato:
Type tipo_apuntador = ^tipo dato
Una variable de tipo tipo_apuntador es un apuntador hacia un dato de tipo nombre del tipo. El signo '^' se lee "apunta hacia". Ejemplos:
1. Type 2. Apuntador = ^real; 3. Var 4. P : Apuntador; 5. {define el tipo,cuyos valores apuntan 6. a posiciones que contienen nmeros reales 7. P apunta a posiciones que 8. contienen nmeros reales} 9. Var 10. P : ^real;
11.
90
14. nombre:string[10]; 15. edad :integer; 16. sexo :char 17. end; 18. Var 19. P :integer; 20. Q :^registro;
P slo puede contener direcciones de posiciones de memoria adecuada para almacenar enteros. Q se limita a datos de tipo registro.
P es una variable tipo ApuntadorEntero que apunta a posiciones que contienen enteros. La posicin de memoria designada por el valor de la variable apuntador P se representa por P^. La siguiente figura representa la relacin entre P y P^.
P^:=1000 3 * P^ + 500 el valor de P^ es 1000 = 3500
Como P^ designa una posicin de memoria, se puede utilizar como cualquier otra variable. Se pueden asignar valores a P^ y utilizar valores P^ en expresiones como cualquier otra variable. Si P apunta a posiciones que contienen reales, P^ es una variable real. Sin embargo, estas operaciones no se pueden realizar directamente tras la declaracin, debido a que el objeto o direccin apuntada P^ no tiene existencia. Antes de que un programa utilice un puntero, se requiere primero espacio para el tipo de datos objeto de la direccin del puntero. En otras palabras, un programa debe inicializar sus punteros - su declaracin no basta- ; para inicializar un puntero se debe utilizar el procedimiento New.
91
7.2.1 New
El procedimiento New crea una variable dinmica y establece que una variable tipo apuntador apunte a ella. Formato: New (P) P variable puntero La nueva variable creada es la ya conocida con el smbolo P^. La llamada a New exige que exista suficiente espacio de memoria libre en el montculo -la pila de variables dinmicas- (heap) para asignar a la nueva variable. En caso contrario se producir un error en tiempo de ejecucin. New(P) Llamada al procedimiento New que asigna almacenamiento para un valor de tipo real y sita la direccin de esta posicin de memoria en la variable de tipo apuntador P.
La sentencia de asignacin
P^ := 22
Ejemplo:
Var 1. P,Q : ^char; begin 2. New(P); 3. New(Q);
92
4. 5. 6. 7. 8. end.
Paso 1.
Grfico de memoria
2.
3.
4.
5.
6.
7.
Asignacin a Q^ y P^.
8.
Visualiza P^ = B ; Q^ = B
93
7.2.2 Dispose
El procedimiento Dispose libera la posicin de memoria ocupada por una variable dinmica. Formato: Dispose (P) P variable puntero Dispose produce las siguientes acciones : 1. La posicin de memoria cuya direccin se almacena en P se libera de la memoria montculo (heap). Es decir P^ deja de existir. 2. P se vuelve indefinido. Representacin grfica : situacin inicial situacin despus de dispose
Ejemplo:
Var 1. begin 2. 3. 4. 5. 6. end. P,Q : ^char; New(P); P^:='A'; Q:=P; Q^:='B'; Dispose(P)
Paso 1.
Grfico de memoria
94
2.
3.
4.
5.
Asignacin a Q^ y P^.
6.
Como nil no apunta a ninguna posicin de memoria, una referencia a P^ es incorrecta si el valor de P es nil.
95
New(Q)
P^.nombre = 'Ely'
Q^.nombre= 'Bety'
96
P^.sueldo=2000
Q^.sueldo=3000
R:=Q
Write(P^.nombre,Q^.nombre, Visualiza los nombres apuntados por Q,R,S R^.nombre) 'Ely Bety Bety'
Sentencia
if P = Q if P = Q if P > Q then then then
Resultado false true Sentencia no vlida. En punteros no se pueden usar los siguientes operadores relacionales >,>=,<,<=. false true
97
El resultado es:
P1=10 P2=10 Q1=A Q2= A
98
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 tres segmentos tambin pueden almacenarse datos. La figura 7.1 nos muestra el mapa de memoria simplificada de Turbo Pascal 5.X, 6.0 y 7.0 cada mdulo (que incluye el programa principal y cada unidad) tiene su propio segmento de cdigo. El programa principal ocupa el primer segmento de unidades (en orden inverso de cmo estn listadas en la clusula Uses) y el ltimo segmento de cdigo est ocupado por la librera en tiempo de ejecucin. El tamao de un segmento de cdigo no puede exceder de 64k, pero el tamao total del cdigo est limitado slo por la memoria disponible. En segmento de datos contiene todas las constantes con tipo seguidas por todas las variables globales. El tamao del segmento de pila no puede exceder de 64k (el tamao 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 estandar Overlay para almacenar cdigo recubierto. Si el programa no tiene recubrimiento, el tamao de la memoria intermedia del recubrimiento es cero.
99
La figura 7.2 (modificacin de la 7.1) muestra cmo queda la memoria cuando un programa arranca, y en ella se observa que todas las variables locales se almacenan en la pila (stack) y las variables globales (tambin llamada estticas) se almacenan en el segmento de datos. El cdigo y el segmento de datos estn localizados en la parte baja de la memoria y la pila (stack) y el almacenamiento dinmico o montculo (heap) ocupan la zona alta de memoria. El diagrama de la figura 7.2 muestra tambin que la pila crece hacia abajo en la memoria y el montculo crece hacia arriba en la memoria. Aunque la pila y el montculo comparten la misma zona de memoria, ellas nunca deben solaparse (recubrirse). La mayora de las variables que se declaran en Turbo Pascal son estticas, su tamao se fija en tiempo de compilacin y no pueden variar. Por el contrario, el montculo almacena variables dinmicas.
El montculo o heap (pila de variables dinmicas o almacenamiento dinmico) almacena variables dinmicas, esto es, las variables asignadas a travs de los procedimientos estndar New y GetMem. El montculo puede crecer o disminuir en el segmento correspondiente, ya que utiliza tipos de datos dinmicos: los apuntadores, que pueden crear o liberar variables dinmicas mientras el programa se est ejecutando. El resmen, las variables tipo apuntador pueden utilizar y reutilizar la memoria montculo. El tamao real del montculo depende de los valores mnimos y mximos que pueden fijarse con la directiva del compilador $M. El tamao mnimo es de 0 bytes, y el mximo por defecto es de 640Kb; esto significa que por defecto el montculo ocupar toda la memoria restante (640Kb viene definida por la mxima memoria direccionable por el DOS, aunque los procesadores 8086/88 tienen diecisis segmentos que por un valor de 64k de RAM resultara 1,048,560 bytes = 1 MegaByte). El lmite inferior del montculo se almacena en la variable HeapOrg, y el lmite o cota superior (lmite inferior de la memoria libre) se almacena en la variable HeapPtr. Cada vez que una variable dinmica se asigna en el montculo (va New o GetMem), el gestor de la pila mueve GeatPtr hacia arriba del tamao de la variable. El uso de las variables puntero en el montculo ofrece dos ventajas principales: Primero se amplia la cantidad total del espacio de datos disponibles en un programa; el segmento de datos est limitado a 64k, pero el montculo, como ya se ha citado, est limitado slo por la cantidad de RAM en su computadora. La segunda ventaja es permitir que su programa se ejecute con menos memoria. Por ejemplo, un programa puede tener dos estructuras de datos muy grandes, pero slo una 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 estas estructuras de datos se definen como apuntadores, se pueden poner en el montculo y quitarse cuando no se necesiten, reduciendo los requisitos de memoria.
Asignacin dinmica de memoria Espacio ocupado en memoria New Dispose Mark Release GetMem FreeMem MaxAvail MemAvail
101
Mark (varpunt) Release(varpunt) varpunt Variable puntero Nota : Dispose y Release son mtodos incompatibles de recuperacin de memoria. Puede elegir utilizar uno u otro, nunca utilizar ambos en el mismo programa.
102
GetMem crea una nueva variable dinmica del tamao especificado y pone la direccin del bloque en una variable puntero. Formato: GetMem(varapunt,tamao)
varapunt variable puntero de cualquier tipo puntero tamao expresin de tipo word
FreeMem libera una variable dinmica de un tamao dado. Formato: FreeMem(varapunt,tamao) Las variables asignadas con GetMem se liberan con FreeMem. Ejemplo
GetMem(i,50); i:=22; WriteLn(i); FreeMem(i,50);
Nota : El nmero de bytes especificado en FreeMem debe de concordar con el especificado en GetMem. No se debe utilizar Dispose en lugar de FreeMem.
103
MemAvail devuelve un valor (del tipo entero largo) que indica, en bytes, la cantidad total de memoria disponible para variables dinmicas. Formato: MemAvail Ejemplo:
begin WriteLn(MemAvail,' bytes disponible'); WriteLn('Bloque libre ms grande : ', MaxAvail,' bytes') end.
104
Los elementos de una lista estn conectados o "enlazados" mediante sus campos liga o apuntador. Los componentes de un nodo se llaman campos. El campo liga apunta (indica la direccin) al siguiente nodo de la lista. Existe una marca de fin de lista, que es la constante nil, tambin representada por el signo elctrico de tierra. El campo datos puede contener cualquier tipo estndar o definido por el usuario. El campo liga contiene el punto al siguiente elemento de la lista. Formato de declaracin de un nodo (por ejemplo, de enteros)
Type nodo = ^enteros; enteros = record numero :integer; liga : nodo end;
Por medio del siguiente programa se ejemplificarn las diversas operaciones con listas enlazadas: inicializacin, creacin, recorrido, insercin, 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
105
p,q,inicio:nodos; tecla :char; {procedimiento para insertar un nodo al final de la lista} procedure inserta_nodo(var p : nodos); begin if inicio=nil then inicio:=p else q^.liga:=p; q:=p end; 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:=false end; procedure libera_memoria; begin p:=inicio; while(p<>nil) do begin q:=p; p:=p^.liga; dispose(q) end
106
end; 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-} {validacin 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 : '); 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...')
107
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 end end;
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('Opcin [ ]'); gotoxy(43,13); tecla:=ReadKey; case tecla of '1' :altas; '2' :bajas; '3' :consultas end until tecla in ['4',esc]; libera_memoria; ClrScr end.
108
Un archivo es el mdulo bsico de informacin manejado por el Sistema Operativo. El Sistema Operativo es un conjunto de programas cuya funcin es administrar los recursos del Sistema de Cmputo. Por ejemplo, un programa fuente es almacenado como un archivo. Primero es introducido en la memoria RAM por medio de un programa editor, y despus es almacenado como 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 la compilacin 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, nmeros o registros, por lo que su representacin lgica puede hacerse como una secuencia de mdulos del mismo tamao, tal como se presenta en la siguiente figura.
En el vocabulario de manejo de archivos, a cada elemento de un archivo se le llama registro. En Pascal, la numeracin de los registros empieza con el nmero CERO , por lo que al elemento_1 se le llamar registro 0, al elemento_2 registro 1, y as sucesivamente hasta llegar a la marca de fin de archivo EOF. Turbo Pascal difiere significativamente de Pascal estndar por la forma en que maneja los archivos. En Pascal estndar, los archivos son formalmente definidos independientemente del medio en que residan. Este mtodo de definicin fue inspirado por los archivos de tarjetas perforadas y cintas magnticas, las cuales eran los medios de almacenamiento comnmente usados cuando Pascal fue definido por primera vez. Como resultado, todo acceso a cualquier archivo en Pascal estndar es secuencial( registro por registro ) tal como se realiza en las tarjetas perforadas y cintas magnticas. En Turbo Pascal los archivos son definidos como archivos de disco. Los discos son actualmente los dispositivos de almacenamiento ms utilizados en las microcomputadoras. Los mecanismos de acceso secuencial proporcionados por Pascal estndar son algunas veces inconvenientes e insuficientes para los archivos basados en discos de acceso aleatorio, por lo que Turbo Pascal provee nuevas estructuras y mecanismos de acceso a los archivos. La primera gran diferencia entre Turbo Pascal y Pascal estndar, es la forma en que enlazan los archivos a un programa. En Pascal estndar, se abren los archivos referenciando su nombre de archivo en el encabezado del programa, y se cierran cuando el programa termina. En Turbo Pascal, los archivos de disco deben enlazarse a una variable de archivo particular con el procedimiento:
Assign(variable_archivo,nombre_archivo);
109
y deben ser preparados para procesarse ( abiertos ) con: reset(variable_archivo) o rewrite(variable_archivo) antes de ser utilizados. Adems, los archivos deben ser explcitamente cerrados por medio de close(variable_archivo), despus de que han sido utilizados, o se perdern los datos que estn en la memoria auxiliar (variable_archivo) . variable_archivo es el nombre de la memoria auxiliar (buffer), por medio de la cual el programa manejar 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 primer registro (0). rewrite crea un nuevo archivo (o sobre-escribe en uno existente) y lo abre para procesamiento con el apuntador de registro colocado en el registro 0. En el caso de un archivo de tipo text, reset har que el archivo slo pueda ser usado para operaciones de lectura , mientras que rewrite slo permitir operaciones de escritura. Los nombres de archivo vlidos son cadenas de 1 a 8 caracteres seguidos por una extensin opcional consistente de un punto y hasta tres caracteres. A estos nombres tambin se les llama "nombres de archivo externo", puesto que son los nombres con que se graban en el disco.
110
Acceso secuencial
Acceso directo
Declaracin 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 seccin de declaracin de tipos (type).
111
Formato:
Type nombre = file of tipo de datos nombre identificador que se asigna como nombre del tipo archivo tipo de datos tipo de datos de los elementos del archivo
Ejemplos:
type ArchEntero = file of {archivo de enteros} type ArchCarac = file of {archivo de carcteres} type nomina = file of {archivo de registros} type ciudad = file of {archivo de cadenas} integer; char; empleado; string[20];
Variable tipo archivo (file) Para definir un archivo con tipos, simplemente declare una variable archivo. Ejemplo:
Var arch_nomina : nomina; enteros : ArchEntero;
O tambin
Var arch_nomina : file of empleado; enteros : file of integer;
Variables de tipo texto y sin tipo Este tipo de variables no requiere ninguna declaracin de tipos; as pues, se puede declarar con un identificador predefinido (Text,File):
Var texto : text; Archivo : file;
112
La siguiente tabla recopila todos los procedimientos y funciones estndar para tratamiento y manipulacin de archivos en Turbo Pascal.
Todos tipos de archivos Archivos de texto Archivos sin tipo Procedimientos Assign ChDir Close Erase GetDir MkDir Rename Reset Rewrite RmDir Funciones Eof IOResult Eoln SeekEof SeekEoln Procedimientos y funciones sobre cualquier tipo de variable excepto archivos de texto FilePos FileSize Seek Truncate Assign ste procedimiento realiza la operacin de asignar un archivo mediante una correspondencia entre 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
BlockRead BlockWrite
113
programa(por ejemplo, el utilizado en la declaracin nombre 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.extensin 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 (asignacin del archivo lista.pas ubicado en c:\tp\lista.pas)
Var ArchText : Text; begin ChDir('C:\tp\'); assign (ArchText,'lista.pas'); . . .
Close ste procedimiento nos permite cerrar los archivos despus que han sido utilizados, si los archivos no son cerrados se perdern los datos que se encuentran en la memoria auxiliar. Formato : 114
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. Para borrar un archivo se debe realizar lo siguiente : 1. Asignar el archivo externo a una variable de archivo. 2. Llamar al procedimiento erase Formato: erase(s) Borra (elimina) un archivo cuya ruta de acceso est especificada por s. Ejemplo:
Var ArchText : Text; begin assign (ArchText,'c:\tp\lista.pas'); erase(ArchText); . . .
GetDir Formato : GetDir(i,s) Busca el nombre del subdirectorio actual. El primer parmetro i es un entero que representa la unidad : i=0 (unidad de disco actual, por defecto), i=1 (unidad A), i=2 (unidad B), etc. Despus de la llamada, la variable de cadena s contiene el 115
Ejemplo:
begin MkDir('C:\nuevo\'); . . .
Rename ste procedimiento renombra (cambia el nombre) un archivo externo. Para renombrar un archivo se debe hacer los siguiente : 1. Asignar un archivo a la variable archivo 2. Llamar al procedimiento rename Formato: Rename(f,nombre_archivo)
f nombre_archivo variable de archivo nuevo nombre del archivo
Ejemplo :
Var ArchText : Text; begin Assign (ArchText,'viejo.pas');
116
Rename (ArchText,'nuevo.pas'); . . .
Reset ste procedimiento abre un archivo existente para una operacin de lectura. Si se intenta llamar a Reset y el archivo especificado no existe, se producir un error de E/S (entrada/salida). Formato : Reset(f)
f variable de tipo archivo
Ejemplo:
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 caso contrario, el archivo queda abierto para una operacin de escritura. Formato: Rewrite(f)
f variable de archivo
Ejemplo:
Var ArchText : Text; begin Assign (ArchText,'lista.pas'); Rewrite(ArchText); . . .
RmDir
117
Formato RmDir(s)
Elimina el subdirectorio de nombre s. begin RmDir('C:\nuevo\'); . . .
Append El procedimiento Append abre un archivo existente para aadir 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 de Assign. Si el archivo no existe, se produce un error; y si ya estaba abierto, primero se cierra y luego se reabre. Ejemplo:
Var ArchText : Text; begin Assign (ArchText,'lista.pas'); Rewrite(ArchText); WriteLn(ArchText,'Primera lnea'); Close(ArchText); Append(ArchText); WriteLn(ArchText,'Agrega esto al ltimo'); Close(ArchText) end.
Flush El procedimiento Flush vaca el buffer de un archivo de texto abierto para salida. Cuando un archivo de texto es abierto para escritura usando Rewrite o Append, la llamada a Flush llenar el buffer asociado al archivo. Esto garantiza que todos los carcteres escritos en el archivo en ese tiempo sean escritos en el archivo externo. Flush no afecta los archivos abiertos para entrada. Usando la directiva {$I}, IOResult devuelve 0 si esta operacin fue realizada con xito de lo contrario retonar un cdigo de error.
118
Formato: Flush(f)
f variable de archivo
Ejemplo:
Var ArchText : Text; begin Assign (ArchText,'lista.pas'); Rewrite(ArchText); WriteLn(ArchText,'Primera lnea'); WriteLn(ArchText,'Segunda lnea'); Flush(ArchText); WriteLn(ArchText,'tercera lnea'); WriteLn(ArchText,'Agrega esto al ltimo'); Close(ArchText) end.
Read El 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 texto v1,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.
ReadLn
119
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 lnea del archivo. Este salto de lnea se produce cuando se han asignado valores a la lista de varibles del procedimiento; en caso contrario, el procedimiento hace caso omiso del control de lnea y sigue asignando informacin. Formato: ReadLn(f,v1,v2,..)
f variable de archivo de texto v1,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.
SetTextBuf El procedimiento SetTextBuf asigna un buffer de entrada/salida a un archivo de texto. SetTextBuffer podra nunca ser usado en la apertura de un archivo, aunque ste puede ser llamado inmediatamente despus de Reset, Rewrite, y Append. Si se invoca a SetTextBuf en una apertura de archivo las operaciones de entrada/salida son tomadas por ste procedimiento, y se pueden perder datos como resultado de el cambio de buffer. 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
120
lecturas ms rpidas} 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.
Write EL procedimiento Write sirve para escribir datos en un archivo. Formato: Write(f,v1,v2,...)
f v1,v2,... variable de tipo archivo variables de tipo de datos
Ejemplo:
Var ArchText : Text; begin Assign (ArchText,'nuevo.txt'); Rewrite(ArchText); Write(ArchText,'Est es la primera lnea.'); Write(ArchText,'Fin del texto.'); Close(ArchText) end.
WriteLn EL procedimiento WriteLn sirve para escribir datos en un archivo. A diferencia de Write, WriteLn incluye un salto de lnea para separar el texto. Formato: WriteLn(f,v1,v2,...)
f v1,v2,... variable de tipo archivo variables de tipo de datos
121
Ejemplo:
Var ArchText : Text; begin Assign (ArchText,'nuevo.txt'); Rewrite(ArchText); WriteLn(ArchText,'Est es la primera lnea.'); WriteLn(ArchText,'Fin del texto.'); Close(ArchText) end.
El contenido del archivo ser : Est es la primera lnea. Fin del texto.
BlockRead Transfiere un bloque de datos de un archivo sin tipo hacia un buffer. Formato: BlockRead(arch,buffer,bloques,resul)
arch buffer archivo sin tipo variable de cualquier tipo de longitud suficiente para acoger los datos transferidos bloques expresin que corresponde al nmero de bloques de 128 bytes a transferir. resul parmetro opcional que indica el nmero de bloques que se leyeron o escribieron realmente.
BlockWrite Transfiere un buffer de datos hacia un archivo sin tipo. Formato: BlockWrite(arch,buffer,bloques,resul)
arch buffer archivo sin tipo variable de cualquier tipo de longitud suficiente para acoger los datos transferidos
122
bloques expresin que corresponde al nmero de bloques de 128 bytes a transferir. resul parmetro opcional que indica el nmero de bloques que se leyeron o escribieron realmente.
Ejemplo:
Program CopiaDeArchivos; Var fuente,destino : file; {archivo sin tipo} buffer : array[1..512] of byte; 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.
Eof La funcin eof(end of file), fin de archivo, devuelve el estado de un archivo. Es una funcin de tipo lgico que indica si el fin de archivo se ha encontrado; devuelve true si se encontr, false en casi contrario. Formato: Eof(f)
f variable de archivo
Ejemplo:
Var ArchText: Text; Ch: Char; begin Assign(ArchText,'memoria.txt'); Reset(ArchText); {Visualiza el archivo en la pantalla} while not Eof(ArchText) do begin
123
Eoln La funcin Eoln devuelve el estado de fin de lnea de un archivo. Es una funcin de tipo lgico. Devuelve true si la posicin actual del archivo (puntero) esta en la marca de fin de lnea, o bien si Eof(f) es true, el caso contrario devuelve false. Formato: Eoln(f)
f variable de archivo de texto Var car :char; ArchText:text; begin Clrscr; Assign(ArchText,'nuevo.txt'); Reset(ArchText); {muestra sola la primera lnea} While not(Eoln(ArchText)) do begin Read(ArchText,car); Write(car) end end.
SeekEof Retorna el estado de fin de archivo. Es una funcin de tipo lgico. Slo para archivos de texto. Si la posicin actual del puntero de archivo se encuentra en la marca de fin de archivo devuelve true, de lo contrario retorna false. SeekEof es una funcin que avanza siempre al siguiente carcter, ignorando por completo los espacios en blanco. Formato: SeekEof(f)
f variable de archivo de texto
Ejemplo:
Var car :char; ArchText:text; begin Clrscr;
124
Assign(ArchText,'nuevo.txt'); Reset(ArchText); {muestra el contenido del archivo} While not(SeekEof(ArchText)) do begin Read(ArchText,car); Write(car) end end.
SeekEoln Retorna el estado de fin de lnea. Es una funcin de tipo lgico. Slo para archivos de texto. Si la posicin actual del puntero de archivo se encuentra en la marca de fin de lnea devuelve true, de lo contrario retorna false. SeekEoln es una funcin que avanza siempre al siguiente carcter, ignorando por completo los espacios en blanco. Formato: SeekEoln(f)
f variable de archivo de texto
Ejemplo:
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.
IOResult Es una funcin que devuelve un nmero entero que indica el cdigo del error de la ltima operacin de E/S; si el valor de retorno es cero, esto nos indica que la operacin se ha desarrollado sin problema.
125
FilePos Est funcin devuelve la posicin actual del archivo (nmero de registro), en forma de un entero largo (longint). Formato: FilePos (f)
f varible de tipo archivo
Notas : 1. Devuelve 0 si esta al principio del archivo. 2. Es igual a FileSize(f) si el puntero de posicin del archivo esta al final del archivo. FileSize Est funcin devuelve el tamao actual del archivo(nmero de registros existentes en el archivo). Si el archivo esta vaco devuelve cero. Formato: FileSize(f)
f varible de tipo archivo
126
Seek Sita el puntero de posicin del archivo en el nmero de registro correspondiente. Formato: Seek(f,numreg)
f numreg nombre de archivo (no de tipo text) nmero de posicin del registro, el primer registro es cero; si numreg es menor que 0 o mayor que n (para un archivo de n registros), se producirn resultados impredecibles.
Ejemplo:
Seek(empleados,FileSize(empleados)); {est sentecia posiciona el puntero al final del archivo}
Truncate Est funcin trunca (corta, mutla) un archivo a partir de la posicin actual del puntero del archivo. Formato: Truncate(f)
f varible de tipo archivo
Si Truncate se ha ejecutado con xito IOResult tendr un valor de cero. El archivo debe estar abierto. 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
127
Write(f,i); 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.
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 lnea actual; un avance de lnea, que mueve el cursor a la siguiente lnea . Ejemplo: 128
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 un archivo de texto se divide en lneas y un archivo de caracteres no. Los archivos de caracteres se leen y escriben de carcter en carcter, mientras que los archivos de texto se leen lnea a lnea. La declaracin es de la siguiente manera :
Var Arch : file of char;
Como cualquier otra variable el tipo Text se puede definir local o globalmente; pero al contrario que otras estructuras, la longitud de una variable archivo no se precisa.
129
assign (f,nombre)
f nombre interno del archivo por el que se conoce el archivo dentro del programa, por ejemplo, el utilizado en la declaracin nombre 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.extensin 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') . . .
Despus que se ha asignado un identificador de archivo, se prepara el archivo con una de estas tres rdenes (procedimientos): Reset, Rewrite, o Append.
Ejemplo:
Var ArchText : Text;
130
Rewrite Crea y abre un nuevo archivo. Si el archivo ya existe, Rewrite borra su contenido; en caso contrario, el archivo queda abierto para una operacin de escritura. Formato: Rewrite(s)
s variable de archivo
Ejemplo:
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 (el contenido anterior a la ejecucin de la sentencia Rewrite se perder). Por el contrario las sentencias assign y reset suponen la existencia del archivo llamado en el disco. Si el archivo no existe se producirn errores de ejecucin (Runtime error 002 at 0BE2:0039). Mediante la directiva {$I-} se puede desactivar la deteccin de errores de Entrada/Salida y prevenir una parada en la ejecucin del programa. Una posible solucin es la siguiente:
Var ArchText : Text; begin Assign (ArchText,'lista.pas'); {$I-} Reset(ArchText); {$I+} if IOResult = 0 then {todo bien} else {error en apertura de archivo} .
131
. .
Ejemplo:
Var ArchText : Text; begin Assign (ArchText,'nuevo.txt'); Rewrite(ArchText); Write(ArchText,'Esta es la primera lnea.'); Write(ArchText,'Fin del texto.') Close(ArchText) end.
Procedimiento WriteLn A diferencia de Write, WriteLn incluye un salto de lnea para separar el texto. Formato: WriteLn(f,v1,v2,...)
f v1,v2,... variable de tipo archivo variables de tipo de datos
Ejemplo:
132
Var ArchText : Text; begin Assign (ArchText,'nuevo.txt'); Rewrite(ArchText); WriteLn(ArchText,'Esta es la primera lnea.'); WriteLn(ArchText,'Fin del texto.'); Close(ArchText) end.
El contenido del archivo ser : Esta es la primera lnea. Fin del texto.
Ejemplo:
Var ArchText : Text; datos : string[20]; begin Assign (ArchText,'lista.pas'); Reset(ArchText); Read(ArchText,datos); WriteLn(ArchText,datos); Close(ArchText) end.
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 lnea del archivo. Esta salto de lnea se produce cuando se han asignado valores a la lista de
133
varibles del procedimiento; en caso contrario, el procedimiento hace caso omiso del control de lnea y sigue asignando informacin. Formato: ReadLn(f,v1,v2,..)
f variable de archivo de texto v1,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.
134
: : : :
135
Assign(archivo,'empleado.dat'); . . .
136
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 cdigo completo del programa. El siguiente ejemplo que se manejar a lo largo de est unidad es idntico al realizado en la unidad siete de listas enlazadas (Listas_enlazadas) . Con la nica diferencia que el lugar de listas enlazadas 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 aadir 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
137
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-} {validacin 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;
138
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 efecto una modificacin} 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 modificacin} 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-}
139
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 modificacin de los 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);
140
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-} {validacin 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 estn 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 modificacin s/n? '); otro:=ReadKey until otro in ['n','N',Esc] end;
141
{El siguiente programa realiza las operaciones de altas,bajas y consultas del control de empleados por medio de acceso secuencial 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; ReadKey end; 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)
142
end; end; {tipo 1 eliminar un registro, tipo 2 se efecto una modificacin} 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 modificacin} 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 {Caso cero el archivo ya existe, ubicarse en el ultimo registro, para aadir 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);
143
gotoxy(25,8);Write('Nombre : '); ReadLn(nombre); gotoxy(25,9);Write('Puesto : '); ReadLn(puesto); Repeat {$I-} {validacin 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-} 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
144
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 modificacin de los 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); 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-} {validacin de entrada de datos} gotoxy(35,12);Write('Nuevo sueldo : ');ReadLn(aux.sueldo); {$I+} until (IOResult=0); if(aux.sueldo=0) then begin
145
aux.sueldo:=registro.sueldo; gotoxy(50,12);WriteLn(aux.sueldo:6:2); end; gotoxy(20,15);Write('Las modificaciones estn 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 modificacin 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; Close(archivo) end end; begin Assign(archivo,'empleado.dat'); Repeat
146
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('Opcin [ ]'); gotoxy(43,14); tecla:=ReadKey; case tecla of '1' :altas; '2' :bajas; '3' :cambios; '4' :consultas end until tecla in ['5',esc]; ClrScr end.
147
El siguiente ejemplo que se manejar a lo largo de esta unidad es identico al realizado en en el cpitulo anterior . La unica diferencia es que se tendr un acceso directo en todas las operaciones.
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 aadir 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);
148
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-} {validacin 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;
149
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;
Agregar
Para poder agregar datos a un archivo es preciso que ste exista, es decir, se necesita: si el archivo no existe, se crea por primera vez para escritura (Rewrite), si el archivo ya existe se posiciona al final del archivo (Seek).
Borrar / Modificar
El procedimiento para borrar o modificar requiere los siguientes pasos:
150
1. Situarse en la posicin del registro con Seek. 2. Leer el registro. 3. Borrar/Modificar. 3.1 Modificar Leer el nuevo registro modificado (Read). Situarse en la posicin correspondiente (Seek). Escribir el nuevo registro en el archivo. 3.2 Borrar La eliminacin ser lgica por lo que quedarn huecos en el archivo.
La baja lgica que se aplica en el siguiente ejemplo se realiza por medio de una bandera de estado 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 fsica. La solucin a esto es aplicar el proceso padre-hijo visto anteriormente en los archivos con acceso secuencial.
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'); Repeat {$I-} {validacin 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 {validacin 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);
151
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;
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
{Procedimiento para modificacin de los campos de un archivo} procedure cambios; 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-} {validacin 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 {validacin para seek} begin seek(archivo,clave); Read(archivo,registro) end; if registro.estado=true then {si est activo}
152
');
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-} {validacin 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 estn 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 modificacin s/n? '); otro:=ReadKey until otro in ['n','N',Esc] end
153
esc = #27; Type datos = record clave : nombre : puesto : sueldo : estado : end; Var archivo :file of registro :datos; tecla :char;
integer; string[30]; string[20]; real; boolean; {true activo,false baja lgica} datos;
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; ReadKey end; 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 aadir 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');
154
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-} {validacin 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'); Repeat {$I-} {validacin 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 {validacin 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);
155
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;
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
{Procedimiento para modificacin de los campos de un archivo} procedure cambios; 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-} {validacin 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 {validacin para seek} begin seek(archivo,clave); Read(archivo,registro) end;
156
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-} {validacin 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 estn 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 modificacin 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
157
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; 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('Opcin [ ]'); gotoxy(43,14); tecla:=ReadKey; case tecla of '1' :altas; '2' :bajas; '3' :cambios; '4' :consultas end until tecla in ['5',esc]; ClrScr end
158
Cualquier archivo de disco puede ser declarado como sin tipo. Turbo Pascal permite tratar un archivo como una serie de bloques sin necesidad de conocer el tipo de datos que contiene.
Usando la declaracin de archivos sin tipo, no importa como se haya escrito originalmente el archivo. Los archivos de texto, archivos binarios, archivos de programas o cualquier otro, pueden ser declarados y abiertos como archivos sin tipo. Los archivos sin tipo tienen una longitud de registro por defecto de 128 bytes, y se transfieren directamente entre la variable registro y el archivo. El formato de los procedimientos Reset y Rewrite en archivos sin tipo difiere del ya conocido para archivos de texto y con tipo.
Reset (nombre,bloque) Rewrite(nombre,bloque) nombre variable de tipo archivo Bloque un nmero de tipo word
Ejemplo:
Reset(archivo,1);
Prepara a un archivo para ser ledo y especfica que la longitud de registro es de 1 byte.
159
Transfiere un bloque de datos de un archivo sin tipo hacia un buffer. Formato: BlockRead(arch,buffer,bloques,resul)
arch buffer archivo sin tipo variable de cualquier tipo de longitud suficiente para acoger los datos transferidos bloques expresin que corresponde al nmero de bloques de 128 bytes a transferir. resul parmetro opcional que indica el nmero de bloques que se leyeron o escribieron realmente.
BlockWrite Transfiere un buffer de datos hacia un archivo sin tipo. Formato: BlockWrite(arch,buffer,bloques,resul)
arch buffer archivo sin tipo variable de cualquier tipo de longitud suficiente para acoger los datos transferidos bloques expresin que corresponde al nmero de bloques de 128 bytes a transferir. resul parmetro opcional que indica el nmero de bloques que se leyeron o escribieron realmente.
Los archivos sin tipo son ms rpidos, debido a que los datos no necesitan ser organizados en lneas 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 funcin del siguiente ejemplo es el de copiar el contenido de un archivo a una ruta especfica (idntico al comando Copy de MS-DOS).
Ejemplo:
Program Copiar; Var fuente,destino : file; {archivo sin tipo}
160
begin if ((ParamCount<2)or (ParamCount>2)) then begin if (ParamCount<2)then WriteLn('Faltan prametros...') else WriteLn('Exceso de prametros...'); 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.
161
1.1 Pasos para la solucin de problemas............................................................1 1.2 Objetivos de la programacin......................................................................4 1.3 Herramientas de programacin....................................................................6 1.4 Programacin estructurada...........................................................................8 2.1 Estructuras general de programas en Pascal..............................................13
Eleccin de identificadores...........................................................................................15 Tipos enteros.................................................................................................................20 Tipos reales...................................................................................................................21
2.8 Instrucciones..............................................................................................30
Bloques de instrucciones...............................................................................................31
4.2.2 CASE-OF-ELSE ....................................................................................39 4.3 Iteracin.....................................................................................................41 4.3.1 WHILE-DO ............................................................................................42 4.3.2 REPEAT-UNTIL....................................................................................43 5.1 Tipos de datos............................................................................................46 5.2 Tipos simples.............................................................................................46
TIPO SUBRANGO.......................................................................................................47 TIPOS ENUMERADOS ..............................................................................................48
75 76
162
6.1 Subprogamas..............................................................................................77 6.2 Procedimientos ..........................................................................................77 6.2.1 Declaracin de un procedimiento...........................................................78 6.2.2 Invocacin al procedimiento...................................................................78 6.3.1 Declaracin de funciones........................................................................82 6.3.2 Invocacin de funciones..........................................................................82 6.4 Ambito de variables...................................................................................83 6.5 Paso de parmetros.....................................................................................85 6.5.1 Paso por valor..........................................................................................85 6.5.2 Paso por referencia..................................................................................86 6.6 Recursin ..................................................................................................87 7.1 Apuntadores...............................................................................................89 7.2 Operaciones con apuntadores.....................................................................91 7.2.1 New.........................................................................................................92 7.2.2 Dispose....................................................................................................94 7.2.3 Constante nil...........................................................................................95 7.2.4 Apuntadores con registros.......................................................................96 7.2.5 Comparacin de apuntadores..................................................................97 7.3 Tipo de apuntador genrico (pointer).........................................................98 7.4 La asignacin de memoria en Turbo Pascal 98 7.4.1 El montculo (heap) 100 7.4.2 Mtodos de liberacin de memoria 101 7.4.3 New y Dispose 102 7.4.4 Mark y Release 102 7.4.5 GetMem y FreeMem 102 7.4.6 MemAvail y MaxAvail 103 7.5 Listas enlazadas 104 8.1 Conceptos bsicos 108 8.2 Tipos de archivos 110 8.3 Tipos de acceso a un archivo 111 8.4 Declaracin de archivos 111 8.5 Gestin de archivos..................................................................................112 8.6 Archivos de texto (secuenciales)..............................................................128 8.6.1 Declaracin de un archivo.....................................................................129 8.6.2 Asignacin de archivos.........................................................................129 8.6.3 Apertura de un Archivo.........................................................................130 8.6.4 Escritura de un archivo.........................................................................132 8.6.5 Lectura de un archivo............................................................................133 8.6.6 Aadir datos a un archivo.....................................................................134
163
8.7 Archivos de acceso secuencial (con tipo)........................................................................................................135 8.7.1 Declaracin y asignacin de Archivos..................................................135 8.7.2 Escritura de un archivo.........................................................................136 8.7.3 Lectura de un archivo............................................................................136 8.7.4 Actualizacin de un archivo..................................................................138 Archivo con acceso secuencial......................................................................141 8.8 Archivos de acceso directo (con tipo)......................................................147 8.8.1 Declaracin y asignacin de archivos...................................................147 8.8.2 Escritura de un archivo.........................................................................148 8.8.3 Lectura de un archivo............................................................................149 8.8.4 Actualizacin de un archivo..................................................................150
Agregar .......................................................................................................................150 Borrar / Modificar.......................................................................................................150
Archivo con acceso directo............................................................................153 8.9 Archivos sin tipo......................................................................................158 8.9.1 Declaracin de un archivo ....................................................................159 8.9.2 Acceso a los archivos (sin tipo)............................................................159
164