INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. PROGRAMANDO EN PASCAL. Cuando se piensa en escribir un programa en Pascal, deben tenerse en cuenta dos puntos principales: La codificación en sí del programa. El “entorno” de trabajo de Pascal. La codificación en sí implica un conjunto de reglas sintácticas e instrucciones permitidas, y el entorno, las herramientas para Editar y almacenar códigos, compilarlos, ejecutarlos, obtener ayuda sobre comandos, depurar programas, opciones de configuración del propio entorno, etc. El entorno que vamos a utilizar se denomina "Sublime text" y tiene el siguiente aspecto: Este es un entorno que permite escribir un programa de computación en distintos lenguajes, puesto que a través del menú Tools puede decidir con cuál compilador va a trabajar. Si abrimos esta opción: Clase Teórica Nro 7 Pág. 1/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. vemos que tenemos conectado este entorno al compilador de Pascal (que previamente instalamos con la versión Free Pascal). En la página de la materia existen instructivos sobre cómo realizar esta instalación. La mecánica a seguir es muy sencilla: Si escribimos un programa por primera vez (significa que no vamos a trabajar sobre una versión anterior), vamos al menú File: Clase Teórica Nro 7 Pág. 2/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. y seleccionamos "New File". Escribimos el código de nuestro programa y lo salvamos con Save: este abrirá la ventana del Explorador de Windows y podremos elegir en cuál carpeta y que con qué nombre vamos a guardar. Una vez guardado, si mañana deseamos volver a trabajar en él, lo abriremos con "Open File....". De esta suerte tipeamos el código indicado al comienzo, lo salvamos con el nombre "Mi primer programa.pas" y ya estamos listos para compilarlo. Para ello vamos de nuevo al menú Tools y esta vez seleccionamos la opción "Build". Ello hará que el programa se compile, o sea se convierta en un código ejecutable. En la parte inferior del Sublime se visualizará el resultado de la compilación: si fue exitosa o si se produjeron errores. En los errores se indican el número de línea, el número de caracter y cuál fue el error. Lo corregimo, SALVAMOS NUEVAMENTE y volvemos a compilar hasta depurarlo por completo. Una vez que desaparecen los errores y podemos ejecutarlo con la opción Run del menú Tools. Existen otras herramientas de edición dentro del entorno como selección, búsquedas, visualizaciones, etc. que no vienen al caso para esta materia. Con lo explicado hasta aquí es más que suficiente. Ahora vamos a analizar el sencillo programa que acabamos de tipear: La primera línea se denomina cabecera y en realidad no es imprescindible: puede omitirse, pero es una buena práctica colocarla. Puede hacerse una breve descripción de qué es lo que hace el programa, quién es el autor, la fecha en que se escribió, etc. Esta información puede ser importante cuando este programa va a ser leido por otras personas o por el propio autor pasado un cierto tiempo. También para realizar búsquedas de un programa en particular dentro de una carpeta donde existe una gran cantidad de códigos. La sintaxis (* .... *) indica al compilador que se trata de códigos no ejecutables, sino de comentarios aclaratorios o documentación del programa. No debe abusarse de esta sintaxis para que no resulte demasiado pesada ni tan breve que no se entienda nada. Los comentarios pueden ir en cualquier parte, por ejemplo acompañar al bloque declarativo para significar qué función cumplen determinados identificadores a la hora de los códigos ejecutables. La línea que dice uses tiene el siguiente significado: Pascal propiamente dicho contiene un número limitado de instrucciones y un conjunto más o menos grande de comandos adicionales, pero por separado, y que comúnmente se denominan funciones de librería. Si vamos a hacer uso de algunos de estos comandos, por ejemplo deseamos trabajar con comandos gráficos, debemos indicarle al compilador dónde buscarlos. La directiva uses significa que lo que viene a continuación son las librerías que proveerán los comandos que no son parte del lenguaje en sí. En el ejemplo se indicó la librería crt (cathodic ray tube) que proporciona todos los comandos para manejo de pantalla. Si hubiésemos necesitado otras librerías, las colocaríamos a continuación separadas por comas. Luego aparece la palabra reservada var que indica la existencia de un bloque declarativo, en este caso de variables, y aquí nos detendremos un momento. En primer lugar las variables son elementos del programa que pueden tomar distintos valores durante la ejecución de un programa. Pueden asignarse y reasignarse tantas veces como fuera necesario mientras el programa se halla corriendo (recuerde este concepto con lo visto en Planillas Electrónicas). Clase Teórica Nro 7 Pág. 3/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. En cambio una constante es un identificador que toma su valor UNA SOLA VEZ al asignársele una magnitud en el momento de declaralo, y jamás puede modificarse a lo largo de toda la ejecución. También aquí vale lo visto al respecto en EXCEL con los direccionamientos absolutos. Cómo escribir nombre de variables y constantes. Los nombres de todas las variables (y de las constantes si las hubiere), se denominan identificadores, y están sujetos a las siguientes reglas sintácticas: Deben comenzar siempre con una letra. Las mayúsculas y minúsculas son indistinguibles. Pueden contener hasta 128 caracteres. Pueden incluir guiones bajos ( _ ) y números. No puede haber más de un identificador con el mismo nombre. No deben contener espacios en blanco entre caracteres. No deben tener acentos ni símbolos que no sean ASCII puros. No deben tener nombres de palabras reservadas del lenguaje Los siguientes ejemplos corresponden a identificadores válidos: Velocidad Dig0 Dig1 Aceleracion_inicial DivisiblePor2 etc. Los identificadores Dig0 y dig0 son indistinguibles para el compilador que dará el mensaje de error: Duplicación de identificadores. Los siguientes son ejemplos no-válidos: DíaHábil aceleración inicial 7moMes Orden# etc. (posee acentos). (tiene blancos intermedios). (comienza con un dígito). (utiliza un carácter no permitido). Resulta muy útil combinar mayúsculas con minúsculas (si bien para Pascal son indistinguibles) a fin de dar mayor claridad al texto. Suelen utilizarse dos estilos: ImpulsoInicial impulso_inicial que facilitan igualmente la legibilidad. Nótese que a la par de cada identificador y separado por dos puntos verticales ( : ) se halla la palabra integer (entero). Esto especifica que la variable pertenece a ese tipo. Clase Teórica Nro 7 Pág. 4/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. La declaración de tipo es fundamental porque permite determinar qué valores y qué operaciones podemos asignarle. He aquí varios tipos de enteros permitidos en Pascal: También se indica la ocupación de memoria necesaria para cada uno de ellos. Así por ejemplo un dato de tipo byte sólo ocupa 1 posición de memoria, mientras que un longint requiere de 4 posiciones (bytes). También las magnitudes que pueden manejar varían sustancialmente de un tipo a otro. IMPORTANTE: En realidad los identificadores son traducidos por el compilador como una dirección de memoria donde se almacenará o leerá el dato. Obviamente para el usuario es muchísimo más cómodo referirse a la variable por un nombre mnemotécnico que por su dirección en el mapa de memoria. Otro detalle importante es que al ser declarado un indentificador (por ej. a : byte) el mismo no ha sido aún inicializado con ningún valor. Este tipo de detalle es muy valioso si luego de la declaración de la variable se ejecuta por ejemplo la acción: a: = a +1 ¿Qué valor posee a en el momento previo a la suma? Tal vez cero si el compilador inicializa en ese valor por defecto al declarar una variable, o la basura que había en esa posición de memoria. Luego del bloque declarativo (variables y constantes) comienzan los códigos ejecutables. Ello se debe indicar con los delimitadores begin – end. Como puede haber muchos begin – end dentro de este bloque, al primero de ellos le anexamos el comentario (* main *) para indicar que allí comienza el bloque principal del programa. La última instrucción de cualquier programa Pascal es end. (con un punto final) y esto hace que cualquier código adicional que se hallare después de ese indicador, no será tomado en cuenta por el compilador. Sólo puede haber UN end con punto final. Las palabras claves: clrscr; highvideo; (clear screen limpieza de pantalla) (video intenso) pertenecen a la librería crt declarada en la línea uses. Clase Teórica Nro 7 Pág. 5/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. Las notaciones: n:=1; Suma:=0; se denominan asignaciones. Los dos puntos verticales (:) son parte obligatoria de la sintaxis al igual que el ( ; ) final. La ausencia de estos dos puntos indica que el igual (=) es una condición lógica, por ejemplo: if(Suma=0) then …… ó bien una asignación de constantes: const g = 9.81; Son los dos casos donde el ( = ) va solo. En cuanto al ( ; ) se denomina finalizador e indica que allí termina la instrucción que le precede. Esto permite escribir muchas instrucciones en una misma línea. El bloque repeat – until ya lo conocíamos de clase por medio de los pseudocódigos, de manera que no añadiremos nada al respecto. Lo que sí conviene aclarar es la instrucción writeln( ). Este comando se utiliza para mostrar mensajes por pantalla y al final de los mismos bajar una línea y llevar el cursor de impresión al primer carácter de dicha línea. En otras palabras: aplicar un retorno de carro como en las viejas máquinas de escribir. Normalmente writeln lleva dos tipos de argumentos: cadenas de caracteres entre comillas simples ( ‘ ), o variables cuyo contenido se vuelca en pantalla. De esta suerte, la orden: writeln(‘Suma = ‘, Suma); realiza lo siguiente: muestra el literal Suma =, y a continuación extrae de memoria el contenido de la variable Suma y lo coloca a la par del símbolo =. Por último la instrucción readkey (que también pertenece a la librería crt) “lee” un caracter de teclado (se queda esperando que el usuario “toque” cualquier tecla). Es un truco para lograr una “detención” o congelamiento de pantalla y darle tiempo al usuario para que inspeccione lo que está mostrando en el monitor. Al pulsar una tecla el programa finaliza y se vuelve al entorno integrado. NOTA: las palabras claves begin – end se llaman delimitadores e indican dónde comienza y dónde finaliza un bloque dado de instrucciones. Código Fuente y Códigos Ejecutables. La codificación en instrucciones de Pascal que acabamos de escribir se denomina Código Fuente, y es un texto en ASCII puro. Sin embargo todavía está lejos de ser un programa ejecutable. Para ello necesitamos recurrir a otro menú del entorno: Build: Clase Teórica Nro 7 Pág. 6/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. El compilador realiza una serie de trabajos en forma completamente transparente para el usuario: Verifica la sintaxis (instrucciones correctamente escritas). Verifica que no haya duplicidad de identificadores. Realiza los enlaces con las funciones de librerías (las propias y las declaradas en la sección Uses). Convierte todo a lenguaje máquina (instrucciones del micro) y crea un archivo .EXE que deja almacenado en memoria transitoria. El resto de las opciones no son de la incumbencia de este curso. ¡¡ Correr nuestro primer programa!! Si todo anduvo bien y no salió ningún error de compilación o ya fueron corregidos, llegó el momento de ejecutar (correr) nuestro código ejecutable: Run (debajo de Build en el menú anterior). En pantalla deberán aparecer nuestros mensajes y quedar detenida momentáneamente la ejecución hasta tanto pulsemos una tecla, lo cual retornará al editor y al entorno integrado. NOTA: Habrá notado que para las etapas de Compilación y Corrida existen combinaciones de tecla que hacen más ágil el proceso. Clase Teórica Nro 7 Pág. 7/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. Conclusión. Con este breve programa hemos aprendido un montón de cosas: La conformación de un programa Pascal. Declaración de librerías adicionales. Introducción de comentarios. Bloques declarativos de identificadores. Los datos de tipo “enteros” que maneja el lenguaje. Qué son los finalizadores de instrucción. Qué son los delimitadores. Operaciones de asignación. Notación de condiciones lógicas. Notación de constantes. Limpieza de pantalla. Salida de mensajes hacia el monitor. Congelamiento de pantalla. Finalización de códigos ejecutables. Compilación del programa fuente. Ejecución y verificación de funcionamiento. De vuelta a los tipos de datos. Pascal admite los siguientes tipos de datos: Numéricos. Lógicos. Cadenas de caracteres. Definidos por usuario. De todos estos, por el momento sólo nos interesan los numéricos. Anteriormente hicimos una descripción de los datos de tipo entero, tanto en su notación como en su rango y cantidad de bytes que requieren para su almacenamiento. Sin embargo no dijimos nada sobre las operaciones propias para enteros: Operación Descripción ---------------------------------------------------------------------------DIV División entera. MOD Resto de una división entera. SUCC Sucesor (siguiente). PRED Antecesor. Los enteros pertenecen, a lo que se denomina datos ordinales (ordenados), o sea que poseen un único antecesor y un único sucesor. Precisamente los comandos Succ y Pred obtienen esos valores sobre el argumento al que se aplican. La división entera DIV directamente trunca la parte decimal y se queda con la entera. Mod realiza la división entera y retorna el Resto. Clase Teórica Nro 7 Pág. 8/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. En el próximo material incluiremos otros tipos de datos, como los de punto flotante y los de tipo char (carácter)l Algo más sobre el bloque declarativo. Imaginemos que estamos declarando variables: Var Nomb1 : <tipo>; Nomb2 : <tipo>; Nomb3 : <tipo>; Etc. (* velocidad del móvil 1 *) (* velocidad del móvil 2 *) (* ................................... ) Resulta conveniente no poner muchas variables en una misma línea aún cuando éstas pertenezcan al mismo tipo: suele resultar problemático encontrarlas cuando estamos modificando o depurando el programa. En cambio todas encolumnadas hacen muy fácil su visualización, permitiendo además la inserción de comentarios que aclaren para qué se las utiliza en el programa. Otra: La palabra reservada Var implicará que TODOS los identificadores que le sucedan (no importa si aparecen en 20 ó en 100 líneas adicionales), continuarán siendo variables hasta tanto aparezca otra palabra reservada como por ejemplo const. Var Vo : double; H : integer; m : double; const g = 9.81; PI = 3.1415; Lo dicho para el bloque Var también vale para el bloque const: todos los identificadores declarados a continuación de esta palabra serán constantes hasta tanto aparezca otra palabra reservada. Si por ejemplo necesitásemos otras variables a continuación de const, las mismas pueden agregarse insertando líneas en el bloque Var original, o bien crear un nueva declarativa Var: Var Vo : double; H : integer; m : double; const g = 9.81; PI = 3.1415; Var Vf : double; Vi : double; Etc. Clase Teórica Nro 7 Pág. 9/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. El estilo de programación. Siempre resulta aconsejable seguir algunos lineamientos de escritura para que los códigos sean claros y fáciles de seguir: recuerde que algunas veces otras personas deberán leerlos, continuarlos o modificarlos, o Ud. mismo dentro de algún tiempo y seguramente habrá olvidado muchos detalles. La Cabecera. Puede contener diversa información de referencia. Por ejemplo: Autor. Fecha. Breve descripción del programa. Algunos datos relevantes. Por ejemplo: (* ---------------------------------------------------------------------------------------------------Autor : Juan Pérez. Fecha: 14/10/2007 Programa para ordenar matrices numéricas de n filas por m columnas. Se utilizó el método de la burbuja por razones de sencillez. ------------------------------------------------------------------------------------------------------ *) Bloques Declarativos. Como dijimos anteriormente, conviene escribirlos en forma perfectamente encolumnada, a lo sumo con uno o dos identificadores por línea, agregando sólo aquellos comentarios que fuesen estrictamente necesarios. Utilizar nombres mnemotécnicos que sugieran su uso, por ejemplo: Vel_ini Vel_fin PesoEspPb DensH2SO4 Etc. para velocidad inicial. para velocidad final. Para peso específico del Plomo. Para densidad del ácido Sulfúrico. Utilizar sangrías. Ayudan sobremanera a visualizar el orden jerárquico de las estructuras: dónde se hallan las cabeceras de cada una y dónde el bloque de instrucciones ejecutables. Considere por ejemplo los siguientes casos: Clase Teórica Nro 7 Pág. 10/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. For x:=1 to 10 do begin write(‘Ingrese a : ‘); readln(a); write(‘ingrese b :’); readln(b); c:=a+b; writeln(‘Suma a+b = ‘,c); end; For x:=1 to 10 do begin write(‘Ingrese valor de a : ’); readln(a); write(‘Ingrese valor de b : ’); readln(b); c:=a+b; writeln(‘SUMA a+b = ‘,c); end; Para el Compilador es exactamente lo mismo tanto el primero como el segundo código, pero para el usuario no: la segunda versión es muchísimo más clara y fácil de seguir. Salvar periódicamente. Es común que, llevados por el entusiasmo o la concentración puestas al resolver un problema, nos olvidemos de ir salvando de tanto en tanto. ¡¡Un pequeño bajón de la tensión de línea y perdemos todo!! Conviene por lo tanto cada tanto líneas realizar un salvado preventivo. Hacer un respaldo. Por lo general siempre arribamos a una primera versión que luego modificamos para optimizarla o hacerla más genera. Siempre conviene salvar la versión que YE ESTÁ FUNCIONANDO BIEN y trabajar sobre una copia de la misma: esta precaución evita muchos dolores de cabeza. ESTRUCTURAS DE CONTROL EN PASCAL. Estructuras repetitivas. Son aquellas que “repiten”, como su nombre lo indica, un bloque de instrucciones ejecutables que puede ser tan simple como UNA SOLA INSTRUCCIÓN o bien UN CONJUNTO GRANDE DE INSTRUCCIONES. La estructura FOR. Se utiliza cuando el número de iteraciones es conocido EN EL MOMENTO DE EJECUTARSE. La variable que gobierna las iteraciones se denomina “variable de control” y DEBE SER un identificador de tipo ORDINAL (recordando que este tipo de dato posee la característica que tiene UN SOLO ANTECESOR y UN SOLO SUCESOR). Desde este punto de vista, Pascal admite 3 tipos de datos como variable de control: Clase Teórica Nro 7 Pág. 11/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. ENTEROS. CHAR. BOOLEAN. DEFINIDOS POR USUARIO. Por el momento nos quedaremos con los enteros. La sintaxis de un lazo for es la siguiente: Lazo creciente: FOR VarControl:=ValorInicial TO ValorFinal DO Begin Instrucciones ejecutables. End; Lazo decreciente: FOR VarControl:=ValorMayor DOWNTO ValorMenor DO Begin Instrucciones ejecutables. End; Los incrementos o decrementos de la variable de control se realizan en forma completamente automática y de UNO EN UNO. Pascal no admite alteraciones del paso puesto que el lazo tiene un sentido específico: sólo realizar un número definido de repeticiones. La variable de control normalmente se utiliza en procesos de cálculo dentro del bloque ejecutable, pero teniendo la prudencia DE NO MODIFICARLA para no alterar el normal funcionamiento de la estructura. Imaginemos algo tan elemental como generar una tabla de funciones senoidales dentro de un cierto rango: por ejemplo entre 30 y 60 grados. const Krad var Fi Seno Ampl = PI/180; : integer; : double; : double; begin Ampl:=10; For Fi:=30 to 60 do begin Seno:=Ampl*sin(Fi*Krad); writeln(‘Seno(‘,Fi,’)=’,Seno:2:3); end; end. Aquí Fi forma parte del cálculo de los valores senoidales, pero su valor en sí no es modificado en ningún momento. Clase Teórica Nro 7 Pág. 12/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. Dentro del bloque ejecutable se admite cualquier estructura o instrucción válida en Pascal, incluyendo anidamientos del propio for, por ejemplo: For n:=10 to 20 do For i:=2 to 5 do if(n MOD I =0)then writeln(‘n=’,n,’ es divisible por ‘,i); NOTA: En este caso como cada bloque ejecutable está constituído por una sola instrucción, no es necesario colocar los delimitadores Begin – End, pero tampoco existe ningún impedimento para utilizarlo: For n:=10 to 20 do begin For i:=2 to 5 do begin if(n MOD I =0)then writeln(‘n=’,n,’ es divisible por ‘,i); end; end; El compilador “optimiza” el código fuente y elimina todo aquello que le resulta innecesario. Los valores iniciales y finales de cada lazo pueden también provenir a través de variables o constantes: For n:=ValorInicial to ValorFinal do donde ValorInicial y ValorFinal son identificadores ordinales previamente declarados y asignados. La estructura Repeat Until. Util cuando el número de iteraciones NO SE CONOCE de antemano y se sabe que AL MENOS UNA VEZ debe ejecutarse el bloque de instrucciones. Su sintaxis es: Repeat Bloque ejecutable Until (CondLogica) Al igual que en el for, su bloque ejecutable puede contener anidamientos de ella misma y/o cualquier otra estructura permitida en Pascal. No debe perderse de vista que dentro del bloque ejecutable debe existir alguna instrucción que modifique la condición lógica permitiendo un valor de salida. Ejemplo: realizar una suma de enteros aleatorios de magnitud entre 10 y 20 y cuando el valor de esta acumulada sea mayor o igual que 250, finalizar. Mostrar además cuántas iteraciones se realizaron en una corrida. Clase Teórica Nro 7 Pág. 13/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. Suma:=0; Cuenta:=0; repeat n:=10+random(11); Suma:=Suma+n; Cuenta:=Cuenta+1; until(Suma>=250); writeln(‘Suma=’,Suma); writeln(‘Iteraciones=’,Cuenta); Aquí no podíamos saber a priori cuántas iteraciones son necesarias puesto que dependen de las magnitudes aleatorias generadas. Observe cómo la instrucción de acumulación de valores generados, Suma, va modificando la condición de salida. Podríamos agregarle cosas como por ejemplo: cuántas cifras mayores de 15 se generaron. O cuántos valores pares, etc. Otros detalles destacables, aunque ya vistos en pseudocódigo son: La evaluación de la condición de salida se realiza AL FINAL. El lazo se ejecuta AL MENOS UNA VEZ. No requiere de los delimitadores Begin – End. Las iteraciones se realizan por CONDICIÓN NEGADA. Generación de números aleatorios. Pascal posee un generador de números aleatorios bastante aceptable y que facilita enormemente la prueba de programas que requieren de muchos ingresos numéricos ya que nos evitan el tener que tipear estos valores. Su sintaxis es la siguiente: n:=random(Valor) donde “n” puede ser tanto entero como de punto flotante. En cambio “Valor” DEBE SER un entero por exigencia sintáctica. El valor aleatorio que se genera está comprendido entre 0 y Valor – 1. Ejemplo: random(20) produciría un número aleatorio entre 0 y 19. Es posible realizar muchas combinaciones y rangos con esta herramienta aleatoria: n:=100 + random(101) n:=500 – random(51) Números entre 100 y 200 Números entre 500 y 450. etc. Esta instrucción normalmente va precedida de la siguiente: randomize; que REINICIALIZA el secuenciador para que siempre arranque de valores diferentes y NO REPITA siempre la misma serie aleatoria. Clase Teórica Nro 7 Pág. 14/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. La instrucción random( ) también puede utilizarse en procesamientos más complicados como el siguiente: repeat n:=random(200); until(n MOD 3 = 0); El lazo hace que la generación aleatoria se repita hasta tanto se haya logrado un número divisible por 3. Además este ejemplo muestra otra aplicación de repeat until. La estructura while( ) do. Otra utilidad muy conveniente cuando no conocemos el número de iteraciones. Su sintaxis es la siguiente: While(CondLogica) do begin Bloque ejecutable; end; Resulta el complemento perfecto de la anterior: repeat until : La evaluación de la condición de salida se realiza AL COMIENZO del bloque. Repite por CONDICION VERDADERA. Puede NO EJECUTARSE NUNCA si la condición resulta falsa. Lleva delimitadores Begin End cuando engloba más de una instrucción. Ejemplo: Hallar los “n” pares consecutivos que se obtienen dividiendo sucesivamente un entero dado en 2. La ejecución finaliza en el momento en que encuentra el primer impar. program EnterosConsecutivas; (* ------------------------------------------------------Ingresada una magnitud entera N, mientras sea par, divi dir consecutivamente por 2 e ir mostrando por pantalla. ----------------------------------------------------- *) uses crt; var N : word; begin (* main *) clrscr; highvideo; Clase Teórica Nro 7 Pág. 15/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. N:=12000; while(N MOD 2 =0) do begin writeln(' N=',N); N:=N DIV 2; end; readkey; end. Si N hubiese sido impar desde el momento de su asignación el lazo while( ) no se hubiese ejecutado jamás. ¿Qué hubiese pasado si hubiéramos empleado repeat ? Este otro ejemplo es sumamente interesante porque engloba la estructura repeat con un par de while do: program FiboEntreLimites; (* ----------------------------------------------------------------------------------------------------------------Generar dos números enteros aleatorios N1 y N2 que serán los limites de un rango dentro del cual se buscaran números de Fibonacci. Cuando los números hallados dentro de este rango sea mayor o igual a 5, el programa finalizara. Ir mostrando por pantalla los Fibos hallados. ------------------------------------------------------------------------------------------------------------- *) uses crt; const TOT_FIBOS = 5; var N1 : integer; (* limite inferior del rango para Fibos *) N2 : integer; (* limite superior del rango para Fibos *) Prim : integer; Seg : integer; Fibo : integer; Cuenta : integer; begin (* main *) clrscr; highvideo; randomize; repeat N1:=random(101); N2:=N1+random(201); writeln(' N1=',N1,' N2=',N2); writeln(' ------------------------'); Prim:=0; Seg:=1; Fibo:=Prim+Seg; Cuenta:=0; Clase Teórica Nro 7 Pág. 16/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. while(Fibo<N1)do begin Prim:=Seg; Seg :=Fibo; Fibo:=Prim+Seg; end; Cuenta:=Cuenta+1; write(' ',Fibo,' '); while(Fibo<N2)do begin Prim:=Seg; Seg :=Fibo; Fibo:=Prim+Seg; if(Fibo<N2)then begin write(Fibo,' '); Cuenta:=Cuenta+1; end; end; writeln; writeln; if(readkey=#27)then exit; until(Cuenta>=TOT_FIBOS); writeln(' Pulse una tecla para finalizar'); readkey; end. Estructuras de decisión condicional: if( ) Tiene dos versiones: Simple: if(CondLog) then begin Instrucciones ejecutables; end; Compuesta: if(CondLog) then begin Instrucciones ejecutables A; Clase Teórica Nro 7 Pág. 17/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. end else begin Instrucciones ejecutables B; end; IMPORTANTE: Note que la instrucción inmediatamente anterior al else NO LLEVA (;) Un buen ejemplo sobre utilización de estas estructuras de control, consiste en pasar un número complejo de la forma binaria a la forma exponencial, o sea conocida la componente real (Re) y la componente imaginaria (Im), hallar el módulo M y el ángulo Fi (en grados). program NumerosComplejos; (* ------------------------------------------------------------Dado un complejo en forma binómico, pasarlo a forma polar estableciendo su Modulo y su ángulo en grados. ---------------------------------------------------------- *) uses crt; const Kgrad = var Re : Im : Fi : Modu : Seno : 180/PI; real; real; real; real; real; begin (* main *) clrscr; highvideo; Re :=-4; Im :=-4; Modu:= sqrt(Re*Re+Im*Im); if(Modu>0)then begin Seno:= Im/Modu; if(Seno>0)then if(Re=0)then Fi:=90 else if(Re<0)then Fi:=180-Kgrad*arctan(abs(Im/Re)) else Fi:=Kgrad*arctan(abs(Im/Re)) else if(Re=0)then Fi:=270 else if(Re<0)then Fi:=180+Kgrad*arctan(abs(Im/Re)) else Fi:=270+Kgrad*arctan(abs(Im/Re)); end else Fi:=0; writeln(' Mod = ',Modu:2:2); writeln(' Fi = ',Fi:2:2); readkey; end. Clase Teórica Nro 7 Pág. 18/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. Introducción de datos por teclado. La instrucción readln( ). Su sintaxis completa es: readln(var1, var2, var3, .... etc). Tiene como argumento una o muchas variables previamente declaradas pudiendo ser del mismo o diferentes tipos. Por ejemplo: Var Vel1, Vel2 : double; m1,m2 : integer; begin write(‘Ingrese Vel1, Vel2, m1, m2 : ‘); readln(Vel1,Vel2,m1,m2); ......................................... end. Al ejecutarse el programa aparecerá: Ingrese Vel1, Vel2, m1, m2 : _ quedando el cursor a la espera de que el usuario introduzca los valores separados por blancos: Ingrese Vel1, Vel2, m1, m2 : 10,5 12,48 2 4 <Enter> La última indicación significa que luego de escribir el valor de m2 (4) debe pulsarle la tecla Enter a fin de que los valores escritos pasen del buffer del teclado a las variables receptoras. IMPORTANTE: Los valores deben escribirse: a) En el mismo orden en que se esperan. b) En la misma cantidad que las variables receptoras. c) Del mismo tipo que los esperados por las variables. La terminación “ln” de readln( ) implica que una vez pulsado Enter, el cursor baja una línea y se posiciona en le primer caracter del nuevo renglón. Sin embargo, esta instrucción no permite ningún texto de orientación por lo que normalmente debe ir acompañada por una instrucción write( ) para saber qué está esperando el programa que ingresemos. Clase Teórica Nro 7 Pág. 19/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. Salidas por pantalla. write( .... ) y writeln( ..... ) Ambas poseen los mismos posibles argumentos: una lista de identificadores ya sea sólos o mezclados con cadenas de caracteres. Por ejemplo: writeln(‘Valor de la suma : ‘,Suma,’ pesos.’); Nótese que las cadenas van entre apóstrofes simples (‘) y no dobles como en otros lenguajes. Al ejecutarse esta instrucción aparecerá: Valor de la suma : 528 pesos. asumiendo que el valor de la variables Suma haya tomado ese valor. Pueden coexistir varias variables con sus respectivos textos: writeln(‘Velocidad1 = ‘,Vel,’ Velocidad2 = ‘,Vel2,’ Aceleración= ‘,a); Etc. Al igual que con la instrucción readln( ), la terminación ln indica bajar una línea y posicionarse en el primer caracter del nuevo renglón. En cuanto a su otra versión: write( ), vale todo lo dicho para su argumento, excepto que el cursor queda a la par del último caracter mostrado en pantalla. Salidas a pantalla con formato. Cuando se desea mostrar alguna magnitud de punto flotante Pascal tiene una forma muy particular de hacerlo: utiliza notación científica normalizada bastante poco presentable. Por ejemplo: 1.23004000E+2 ó más largo aún. Pero a no preocuparse que tenemos forma de evitarlo: writeln(‘PI = ‘,PI:16:4); Lo cual significa tomar un campo de 6 caracteres de los cuales 4 serán decimales: 3.1415 4 decimales 16 lugares Clase Teórica Nro 7 Pág. 20/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. Generación de números aleatorios. Es un truco especialmente útil que evita valores numéricos ingresados por teclado cuando debe ajustarse un programa. Por ejemplo el caso de tener que ingresar 50 enteros y determinar el máximo y el mínimo, o aquéllos que son divisibles por 2 y por 3, etc. También en el llenado de matrices numéricas que requerirían mucho esfuerzo hacerlo por teclado. randomize; inicializa el generador de números aleatorios. random(N); N es un entero y los números generados se hallan en el rango [0;N-1] Sin embargo podemos tener muchas posibilidades. Supongamos que debemos generar valores enteros entre -50 a +120. Entonces hacemos: N:=-50 + random(171) 170 -50 120 Esto se analiza de la siguiente manera: cuando el aleatorio sea 0, el valor de N debe ser de -50, entonces este deberá ser una constante que se sume al aleatorio. Ahora ¿cuánto deberá valer el máximo aleatorio para que, sumado a -50, arroje una magnitud de 120? Obviamente 170, pero como el generador trabaja entre 0 y N-1, el valor extremos superior será 171 en lugar de 170. Ejercicios. Dado un entero N, por ejemplo 1538, separar cada uno de sus dígitos y mostrarlos por pantalla indicando además qué tipo de unidad es: 8 Unidades 3 Decenas etc. Para ello deberá tener en cuenta algunas funciones nuevas en Pascal: DIV División entera (no toma en cuenta la parte decimal) y sólo puede operar con magnitudes enteras. 9 DIV 2 arroja un resultado 4 (sin la parte decimal). 15 DIV 2 arroja un resultado 7 etc. MOD Resto de una división entre enteros. 9 MOD 2 17 MOD 3 Da como resultado 1 Da como resultado 2 etc. Clase Teórica Nro 7 Pág. 21/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. Para analizar este problema, tendríamos que pensar cómo lo haríamos en la vida cotidiana: con lápiz y papel. Una simple observación nos indica que si dividimos en 10: 1538 / 10 = 153.8 --> estamos aislando el último dígito que entra a ser el “resto” de la división. Por lo tanto: 1538 MOD 10 nos daría 8 y ya tendríamos el dígito de las unidades. Ahora debemos hacer lo mismo, pero con 153, a fin de obtener nuevamente el último dígito. Entonces: 1538 DIV 10 --> 153 Con esto tenemos la base para repetir los pasos hasta aislar el dígito de más a la izquierda. En la próxima implementaremos un pseudo código que nos lleve a la solución del problema. Algoritmo: Descomponer un entero en sus dígitos individuales. N <-- 1538 i <-- 1 Mientras (N >0) hacer Comenzar Resto <-- N MOD 10 N <-- N DIV 10 Mostrar en pantalla el valor de Resto En el caso de que i valga: 1 : Agregar a la par el texto UNIDADES. 2 : Agregar a la par el texto DECENAS. 3 : Agregar a la par el texto CENTENAS. etc. Finalizar i <-- i+1 Finalizar (mientras) Finalizar algoritmo. El código en Pascal sería el siguiente: uses crt; var Coc,Resto : integer; N : integer; i : integer; begin clrscr; highvideo; Clase Teórica Nro 7 N:=1538; i:=0; writeln(' N = ',N); Pág. 22/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. while(N>0) do begin i:=i+1; Resto:=N MOD 10; N:=N DIV 10; write(' ',Resto); case 1 2 3 4 5 6 7 8 9 end; i : : : : : : : : : of writeln(' writeln(' writeln(' writeln(' writeln(' writeln(' writeln(' writeln(' writeln(' unidades'); decenas'); centenas'); unidades de mil'); decenas de mil'); centenas de mil'); unidades de millon'); decenas de millon'); centenas de millon'); end; readkey; end. Ha aparecido otra instrucción nueva: case. Se trata de una herramienta de decisión múltiple que evita un conjunto de if then anidados. La variable a evaluar debe ser de tipo ordinal, ya sea numérica entera, booleana, o caracter. Su formato es: case <varordinal> of caso1 : begin ............ end; caso2 : begin ............ end; etc. end; caso1, caso2, etc. son los posibles valores de <varordinal> que deben evaluarse. Si el bloque de instrucciones que gobierna cada opción es una sola instrucción, los delimitadores begin end pueden obviarse. Esta estructura es similar a hacer: if(varordinal=caso1)then begin ....... end else if(varodinal=caso2)then begin ...... end else if(varodinal=caso3)then .................... etc. He aquí otro ejemplo para resolución de problemas: Clase Teórica Nro 7 Pág. 23/24 INFORMATICA – C.B.I. (Ciclo Básico de Ingeniería) - 2014 Departamento de Ciencias de la Computación – FACET / UNT Grupo II – Dictado: Ing. Juan Manuel Conti. (* --- DETERMINACION DE NUMEROS PRIMOS -----------------------Determinar los números primos entre los valores 2000 y 2135 e ir mostrándolos en pantalla. Al final mostrar el total de números primos encontrados. ---------------------------------------------------------- *) Dejamos para el alumno el desarrollo del algoritmo y su correspondiente diagrama de flujo. El código Pascal al cual deberá arribar es el siguiente: uses crt; var N i EsPrimo TotPrimos : : : : integer; integer; boolean; integer; begin clrscr; highvideo; TotPrimos:=0; for N:=2000 to 2135 do begin EsPrimo:=true; for i:=2 to trunc(sqrt(N)) do if(N MOD i=0)then begin EsPrimo:=false; break; end; if(EsPrimo=true)then begin writeln(' N = ',N); TotPrimos:=TotPrimos+1; end; end; writeln(' Total de Primos = ',TotPrimos); readkey; end. Clase Teórica Nro 7 Pág. 24/24