Universidad Central de Venezuela Facultad de Ciencias Escuela de Computación Lecturas en Ciencias de la Computación ISSN 1316-6239 Lenguaje Pseudoformal Para la Construcción de Algoritmos Ernesto Coto ND 2002-08 Laboratorio de Computación Gráfica Octubre, 2002 Lenguaje Pseudoformal Para la Construcción de Algoritmos Ernesto Coto [email protected] Universidad Central de Venezuela. Facultad de Ciencias. Escuela de Computación. Laboratorio de Computación Gráfica (LCG) Venezuela. Caracas Apdo. 47002, 1041-A. ND 2002-08 Resumen Estas notas proponen un Lenguaje Pseudoformal sencillo para la construcción de algoritmos en cursos básicos de programación, en un intento de proveer al estudiantado de un Lenguaje Pseudoformal de Programación que no solo soporte los conceptos más básicos de algoritmia sino que también pueda soportar conceptos más avanzados, como la conversión explícita de tipos de datos, el manejo dinámico de la memoria y la orientación a objetos. Asi mismo, se introduce el uso del Lenguaje de Modelación Unificado (UML) como la notación básica para los diagramas de clases. De la misma manera, estas notas plantean un estructura de programa orientada a objetos que podría ayudar al estudiante apenas comienza a estudiar algoritmia, a entender este paradigma que es tan importante en las ciencias de la computación. Palabras Claves: Construcción de Algoritmos. Lenguaje PseudoFormal. Algoritmos y Programación. Introducción a la Programación. Orientado a Objetos. Octubre, 2002 CONTENIDO 1 INTRODUCCIÓN 3 2 LAS SENTENCIAS BASICAS 4 2.1 2.2 2.3 2.4 2.5 3 TIPOS ESTRUCTURADOS, MODULARIZACION Y CONTROL 3.1 3.2 3.3 3.4 3.5 3.6 4 RÓTULOS (1 ERA. PARTE) TIPOS DE DATO ELEMENTALES OPERACIONES BÁSICAS COMENTARIOS ESTRUCTURA DE UN PROGRAMA (1 ERA. PARTE) TIPOS DE DATO ESTRUCTURADOS ESTRUCTURAS DE CONTROL DE PROGRAMA Y ESTRUCTURAS ITERATIVAS TIPOS DEFINIDOS POR EL PROGRAMADOR RÓTULOS (2DA. PARTE) UNIDADES DE M ODULARIZACIÓN : ACCIONES Y FUNCIONES ESTRUCTURA DE UN PROGRAMA (2 DA. PARTE) EL ENFOQUE ORIEN TADO A OBJETOS 4.1 CLASES 4.2 DIAGRAMAS DE CLASE 4.3 ESTRUCTURA DE UN PROGRAMA (3 RA. PARTE) 5 APUNTADORES 5.1 OPERACIONES BÁSICAS 4 5 6 7 7 9 9 11 13 13 14 15 16 16 16 17 19 19 6 CONVERSION EXPLICITA DE TIPOS DE DATO 21 7 BIBLIOGRAFIA 22 1 INTRODUCCIÓN Como es bien sabido, hasta ahora hemos venido utilizando la notación algorítmica propuesta por el Prof. Jhonny Sepúlveda [2] para enseñar algoritmia en los primeros cursos de programación de la carrera. Si bien el lenguaje es adecuado para la enseñanza, ya han pasado varios años luego de que fuera adoptado por la escuela y por lo tanto no cuenta con el soporte para las nuevas tecnologías en programación que han surgido en los últimos años. Actualmente necesitamos una notación algorítmica que, además de proveer las herramientas más básicas de programación, también sea capaz de representar conceptos más avanzados. El lenguaje pseudoformal a utilizar deberá ser capaz de: − Proveer un estructura básica de programa − Proveer los tipos de datos elementales y los tipos de datos estructurados más comunes − Declaraciones de constantes y variables asociadas a cualquier tipo de dato − Proveer operaciones de entrada/salida básicas − Definir acciones y funciones parametrizadas − Definir los tipos de pase de parámetro básicos − Proveer la definición de tipos de datos por parte del usuario − Proveer la representación de los conceptos del enfoque orientado a objetos A continuación se presenta una propuesta de dicho lenguaje pseudoformal, basado en la notación algorítmica previa del Prof. Sepúlveda [2]. 3 2 LAS SENTENCIAS BASICAS La notación que se presenta a continuación trata de ser lo más general posible, en el sentido de que las construcciones pueden ser traducidas fácilmente a la mayoría de los lenguajes de programación dominantes actualmente, mediante sencillas reglas de traducción. Precisamente pensando en estas traducciones del lenguaje pseudoformal se han tomando cuenta varios detalles de implementación de varios lenguajes de programación para la especificación del lenguaje y por lo tanto se usan varios términos que necesariamente están ligados al contexto de un lenguaje de programación real. Básicamente, el lenguaje provee los siguientes elementos básicos para la construcción de algoritmos: Palabras reservadas, rótulos, operaciones y estructuras básicas. Al mismo tiempo, estas construcciones se pueden componer mediante secuenciamiento y se pueden unir para formar grupos de sentencias. Las palabras reservadas se denotan como palabras subrayadas para representar palabras dentro de la sintaxis que no pueden ser utilizadas como identificadores de ningún tipo, debido a que forman parte de las sentencias del lenguaje. Estas palabras pueden estar escritas en mayúscula o minúsculas y en la mayoría de los casos NO DEBEN ser omitidas al utilizar la notación. Las palabras reservadas del lenguaje se mostraran a medida que se explique cada una las sentencias. Los grupos de sentencias se denotan como un nombre (el nombre del grupo) entre [ ]. Un grupo puede aparecer o no en un algoritmo en particular, pero en el caso en que lo este se define de una manera específica que se explicara más adelante para cada grupo. Los rótulos son palabras entre los símbolos < > y corresponden a un valor final o terminal, por lo general un identificador, un nombre de tipo de dato o un valor. Las operaciones y estructuras básicas se presentar más adelante en este documento. El lenguaje también brinda la posibilidad de añadir comentarios al algoritmo. 2.1 Rótulos (1era. parte) Los rótulos que se utilizan en la notación son los siguientes: • <Tipo_elemental>: se corresponde a la representación de un tipo de dato elemental. • Los identificadores se utilizan como nombres de variables, constantes, estructuras de datos, clases o tipos definidos por el usuario. Un identificador se corresponde a una cadena de caracteres alfanuméricos que debe comenzar con una letra y no puede contener ningún carácter especial ni alguno de los siguientes caracteres *, -, /, \, ”, <, >, | . <Identificador>(o <Id>): 4 • 2.2 este rótulo se corresponde a un valor dentro del rango de representación de algún tipo de dato elemental. También puede ser el resultado de una expresión u operación. <valor>: Tipos de dato elementales Los tipos elementales son los tipos: entero, real, lógico y carácter. Los cuales se especifican en la notación con las palabras subrayadas correspondientes a sus nombres: entero, real, logico y caracter . Cada uno de estos tipos representa un conjunto de valores y tiene asociado un conjunto de operaciones elementales cerradas en dicho conjunto de valores. • entero Conjunto de valores: S ⊂ Z Operaciones elementales: Aritméticas: +,-,*, div, mod . De comparación: =, >, <, ≥ , ≤ , ≠ • real Conjunto de valores: S ⊂ R Operaciones elementales: Aritméticas: +,-,*, / De comparación: =, >, <, ≥ , ≤ , ≠ • logico Conjunto de valores: {verdadero, falso} Operaciones elementales: De comparación: =, ≠ Lógicas: no, o , y • caracter Conjunto de valores: Tabla ASCII o Tabla ASCII extendida Operaciones elementales: De comparación: =, >, <, ≥ , ≤ , ≠ • string Conjunto de valores: secuencia de caracter sin limite predefinido Operaciones elementales: De comparación: =, ≠ Otras: + (concatenación) 5 • subrango La definición de un tipo subrango necesita un tipo base, de la siguiente manera: subrango <Tipo_elemental> <Identificador>=[<valori>...<valors>]; Conjunto de Valores: El intervalo [<valori>,<valors>]heredado del tipo base. Conjunto de operaciones: Heredados del tipo base. • enumerado La definición de un tipo enumerado requiere una especificación como la siguiente: enumerado <Identificador>=[<Id1>,<Id2>, ... <IdN>]; o bien, se puede extender la definición de la manera siguiente: enumerado <Id>=[<Id1>=<valor1>,<Id2>=<valor2>,...<IdN>=<valorN>]; Conjunto de Valores: el subconjunto de los enteros especificado por el programador, o bien el intervalo [1,N] si el usuario no especifica los valores de los identificadores del enumerado. Conjunto de Operaciones: Las operaciones heredadas del tipo entero. 2.3 Operaciones básicas La notación define las siguientes operaciones básicas: • Asignación simple: <Identificador> ← <Identificador>; o bien, • Salida simple: Escribir(<Identificador>); o bien, <Identificador> ← <valor>; Escribir(<valor>); Se puede utilizar el operador de concatenación para impresión con formato, por ejemplo: una Escribir(”Este PC cuesta ”+Precio+” dolares”); Cada instrucción Escribir va acompañada de un retorno de carro al final. • Entrada simple: Leer(<Identificador>); Sean tres operaciones cualquiera A, B, y C. Estas acciones simples pueden ser compuestas en forma de secuencia de dos maneras posibles: • En orden textual: 6 A B C • Mediante un operador de secuenciamiento: A;B;C (operador de secuenciamiento “;”) Las operaciones A, B, C no solo pueden ser operaciones básicas sino invocaciones a Acciones o Funciones, alguna estructura de control de programa o alguna forma de estructura iterativa, las cuales serán explicadas más adelante. 2.4 Comentarios Una diferencia peculiar entre esta notación y el pseudoformal original propuesto por el Prof. Sepúlveda [2] es la perdida del LEXICO. Esta herramienta didáctica ha sido substituida por el uso de los comentarios, los cuales se definen como una simple cadena de texto precedida por el carácter “#”, por ejemplo: #Este programa fue realizado por Pedro Pérez el 30/12/2000 Los comentarios solo ocupan una línea, por lo que un comentario de dos líneas se representaría así: #Este programa fue realizado por #Pedro Pérez el 30/12/2000 Todos los lenguajes de programación conocidos implementan los comentarios de alguna forma, mientras que el LEXICO no puede traducirse a ningún lenguaje. El uso de comentarios para documentar la función de una variable o procedimiento terminará por crear la buena costumbre en el programador de documentar el código fuente de sus programas, haciéndolos más legibles. 2.5 Estructura de un programa (1era. parte) Con lo poco que se ha definido hasta ahora del lenguaje se pueden construir algoritmos sencillos, solo hace falta definir como se ponen juntos todos estos elementos. La forma en que esto se lleva a cabo es lo que llamaremos estructura del programa. La estructura de programa es la de un lenguaje de programación totalmente orientado a objetos, a saber: Clase <Identificador> #aquí pueden ponerle nombre a su programa Accion Principal [Constantes] [Variables] [Secuencia de Operaciones] 7 FAccion FClase Decimos que esta la primera parte de la estructura de control de programa porque a medida que se vayan introduciendo conceptos más avanzados podremos ir ampliando estas estructuras en una segunda y tercer parte. El grupo [Constantes], si esta presente, se define como una o más sentencias con la siguiente sintaxis: <Tipo_elemental> constante <Identificador> = <valor>; El grupo [Variables], si esta presente, se define como uno o más sentencias con la siguiente sintaxis: <Tipo> <Identificador>; #para una sola variable o bien: <Tipo> <Identificador1>,...,<Identificadorn>; #para varias variables El grupo [Secuencia de Operaciones], si esta presente, se define como una secuencia finita de las operaciones básicas definidas anteriormente. 8 3 TIPOS ESTRUCTURADOS, MODULARIZACION Y CONTROL Con las herramientas estudiadas anteriormente se pueden construir programas sencillos. En este capítulo estudiaremos herramientas más poderosas que nos permitirán construir algoritmos que serían muy difíciles de construir con lo que conocemos hasta ahora del lenguaje. 3.1 Tipos de dato estructurados Los tipos estructurados más comunes son los registros, los arreglos y los archivos. Las declaraciones de variables de estos tipos forman su propio grupo, el grupo de [Estructuras]. • Arreglos Los arreglos unidimensionales se declaran mediante una sentencia con la sintaxis siguiente: Arreglo <Identificador> de <Tipo> [Li...Ls] Las operación básicas sobre un arreglo son: - La Operación Selectora que se representa de la siguiente manera: <Identificador>[<posicion>] - La Operación Constructora, la cual sólo se utiliza en el momento de la declaración del arreglo. Por ejemplo, la sentencia: Arreglo A de entero [] = {1,2,3,4,5} declara un arreglo de 5 enteros llamado A, que contiene en sus cinco posiciones los valores 1,2,3,4 y 5 respectivamente. Estas semánticas se pueden extender para arreglos multidimensionales. Por ejemplo para declarar un arreglo bidimensional, la sentencia seria: Arreglo <Identificador> de <Tipo> [Li1...Ls1], [Li2...Ls2] La operación selectora sería: <Identificador>[<posicion>1][<posicion>2] y la operación constructora: Arreglo A de entero [][]={{1,1},{5,5},{10,10}} 9 declararía un arreglo bidimensional de 2 filas por 3 columnas llamado A, conteniendo dos 1 en la primera columna, dos 5 en la segunda y dos 10 en la tercera. • Registros Fijos Para declarar un registro se debe utilizar la siguiente sentencia: Registro <Identificador> <Tipo>1 <Tipo>2 ..... <Tipo>N = <Identificador>1 <Identificador>2 <Identificador>N FRegistro La operación básica sobre un registro es la Operación Selectora que se representa de la siguiente manera: <Identificador>.<Identificador>I • con I ∈ [1,N] Registros Variantes Sean α 1 ,... α N, un subconjunto de los valores que puede tomar la variable <Identificador>D de tipo <Tipo>D llamada discriminante. Un registro variante basado en dicho discriminante se declara utilizando la siguiente sentencia: Registro <Identificador> = <Tipo>1 <Identificador>1 ..... <Tipo>N <Identificador>N en caso de <Tipo>D <Identificador>D α1 : [Variables]1 α2 : [Variables]2 ..... αN : [Variables]N FRegistro La operación básica sobre este tipo de registro también es la Operación Selectora, pero el alcance de las variables que se encuentran en la parte “variante” del registro van a depender del valor del discriminante. • Archivos La declaración de un archivo secuencial sería: Archivo <Identificador>A Las operaciones básicas sobre un archivo secuencial son: - Abrir el archivo 10 AbrirArchivo(<Identificador>A ,“nombre del archivo”, <Argumentos>) Donde <Argumentos> es uno o más reservadas: de las siguientes palabras Escribir: indica que el archivo se abre de solo escritura Lectura: indica que el archivo de abre de solo lectura Texto: indica que el archivo a abrir es un archivo de texto Binario: indica que el archivo a abrir es un archivo binario Añadir: indica que el archivo se abre de escritura pero todo lo que se escriba se añade al final del archivo Los argumentos ejemplo: de combinan con el operador lógico y. Por Abrir(A, “prueba.txt”, Lectura y Texto ) - Cerrar el archivo - Fin de archivo - Leer del archivo - Escribir en el archivo CerrarArchivo(<Identificador>A ) FDA(<Identificador>A ) LeerArchivo(<Identificador>A , <Identificador>) EscribirArchivo(<Identificador> 3.2 A , <Identificador>) Estructuras de control de programa y Estructuras iterativas Las estructuras de control de programa y las estructuras iterativas vendrían a formar parte del grupo[Secuencia de Operaciones], por lo que amplían su definición. Las estructuras de control de programa son otra forma de composición de operaciones, que a la vez brindan la posibilidad al programador de condicionar la ejecución de distintas operaciones. El lenguaje define la selección múltiple y la selección simple. • Selección múltiple Sean α, β, δ los predicados que caracterizan a los tres casos posibles en un problema. Las selección múltiple se expresa como: Seleccion α: [Secuencia de Operaciones]α β: [Secuencia de Operaciones]β δ: [Secuencia de Operaciones]δ FSeleccion Donde α, β, δ deben cumplir: - α o β o δ = verdadero α y β = falso 11 - α y δ = falso δ y β = falso Estas condiciones garantizan que todo valor de entrada posible satisface uno y solo uno de los predicados. • Selección Simple Sea α un predicado. La selección simple se expresa como: Si α entonces [Secuencia de Operaciones] FSi Una variación de la selección múltiple permite usar un solo predicado para condicionar la ejecución de otra acción B, de la siguiente manera: Si α entonces [Secuencia de Operaciones]1 sino [Secuencia de Operaciones]2 FSi Otra forma de composición de operaciones y control de programa, que además le brinda la posibilidad al programador de aplicar un mismo tratamiento un número condicionado de veces son las estructuras iterativas. El lenguaje define las estructuras básicas: repetir, mientras y para. Algunos lenguajes de programación implementan estas estructuras junto con otras variantes, pero en general, estas son las más conocidas. • Estructura iterativa: Repetir Sea α un predicado que caracteriza la terminación del proceso iterativo. La “repetición” se expresa de la siguiente forma: Repetir [Secuencia de Operaciones] Hasta α • Estructura Iterativa: Mientras Sea α un predicado que caracteriza el comienzo o la continuación de un proceso iterativo. La “repetición”, mediante la herramienta “mientras”, se expresa de la siguiente forma: Mientras α hacer [Secuencia de Operaciones] FMientras 12 • Estructura Iterativa: Para En la estructura “Para” también se cuenta con un predicado que caracteriza la terminación del proceso iterativo, con la particularidad de que dicho predicado consiste en una comparación aritmética contra el valor que define la iteración. Para <Identificador>←<valor>1 hasta <valor>2 en <valor>inc hacer [Secuencia de Operaciones] Fpara En este ciclo la variable <Identificador> se inicializa con <valor>1 y el ciclo continuará hasta que <Identificador> sobrepase el <valor>2. <valor>inc es el tamaño del paso en el que se incrementa la variable <Identificador>. 3.3 Tipos definidos por el programador El lenguaje provee al programador de la capacidad de definir nuevos tipos de dato. Simplemente debe anteponer la palabra reservada Tipo a la declaración de una variable para indicarle al lenguaje que de ahora en adelante se usara el identificador como un <Tipo>. Este le da la capacidad de definir como tipo de dato cualquiera estructura, por ejemplo: Tipo Arreglo NuevoTipo de Entero [1...10]; define un nuevo tipo de dato llamado NuevoTipo, que tiene la estructura de un arreglo unidimensional de10 posiciones. Luego puede declarar una variable del nuevo tipo de dato de la misma manera como se hace con los tipos predefinidos, por ejemplo: NuevoTipo UnaVariable; Esto le permitirá declarar una o varias variables con la estructura del nuevo tipo de datos así como pasar parámetros con dicha estructura. Las definiciones de nuevos tipos por parte del programador se ubican en su propio grupo, el grupo de [Definiciones]. 3.4 Rótulos (2da. Parte) Con lo que hemos definido hasta ahora podemos definir nuevos rótulo y expandir la definición de los que definimos anteriormente. Los rótulos nuevos serían: • • • se corresponde a un <Tipo_elemental>, un tipo estructurado o a un tipo definido por el usuario. <posicion>: se corresponde con un valor entero correspondiente a una posición dentro de una estructura de datos. <Argumentos>: se corresponde a un conjunto de palabras reservadas para la apertura de archivos secuenciales. <Tipo>: 13 Y podemos expandir la definición del rótulo <valor>, de la siguiente manera: • 3.5 en adición a la definición anterior, este rótulo puede corresponderse también a un valor con la estructura de un tipo estructurado o uno definido por el usuario. <valor>: Unidades de Modularización: Acciones y Funciones La declaración de acciones y funciones forman su propio grupo, el grupo de [Procedimientos]. Sin embargo, es bien sabido que dichas acciones y funciones pueden ser invocadas en cualquier parte de un algoritmo, por lo que sus invocaciones vienen a formar parte también del grupo de [Secuencia de operaciones], y por lo tanto amplían su definición. Las acciones y funciones se declaran de la manera siguiente: Accion <Identificador> ([Parametros]) [Estructuras] [Definiciones] [Variables] [Secuencia de operaciones] FAccion Funcion <Identificador> ([Parámetros]) → <Tipo> [Estructuras] [Definiciones] [Variables] [Secuencia de operaciones] ← <valor> o <Identificador> FFuncion Nótese que dentro de una acción o de una función también se pueden declarar variables, estructuras y se puede hacer definiciones. Todas estas declaraciones son locales al procedimiento y por lo tanto pierden validez y alcance fuera del contexto del procedimiento. En la notación especificada anteriormente se puede observar la utilización del grupo [Parametros]. Este grupo se define como una o más de las siguientes sentencias: <Tipo> <Identificador> si el parámetro se pasa por valor var <Tipo> <Identificador> si el parámetro se pasa por referencia Si se utiliza más de una de estas sentencias, las mismas debe ser compuestas mediante el operador de secuenciamiento “;”. Por ejemplo: entero X; real Y; var caracter Z 14 3.6 Estructura de un programa (2da. parte) Ahora introduciremos los conceptos nuevos de este capítulo a la estructura básica que estudiamos en el capítulo anterior. La ampliaremos aún más en una tercera parte. Clase <Identificador> #aquí pueden ponerle nombre a su programa [Constantes] [Estructuras] [Variables] [Definiciones] [Procedimientos] Accion Principal [Constantes] [Estructuras] [Variables] [Definiciones] [Secuencia de Operaciones] FAccion FClase Nótese que hemos resaltado con letras en negrita los nombres de los nuevos grupos agregados a la estructura. De nuevo, se puede observar fácilmente que lo que antes era el algoritmo principal no es más que una acción llamada “Principal” dentro de la clase. De la misma manera se puede observar que se repiten varios grupos dentro del método principal y fuera de él, esto permite definir variables, constantes, definiciones y estructuras globales a todos los métodos de la clase y otras locales a los métodos. 15 4 4.1 EL ENFOQUE ORIENTADO A OBJETOS Clases Las clases son el elemento principal dentro del enfoque orientado a objetos. En este lenguaje las declaraciones forman parte de su propio grupo, el grupo [Clases]. Cada una de las declaraciones de clase debe tener el siguiente formato: Clase <Identificador> Atributos Publico: [Constantes] [Estructuras] [Variables] Privado: [Constantes] [Estructuras] [Variables] Protegido: [Constantes] [Estructuras] [Variables] Operaciones Publico: [Procedimientos] Privado: [Procedimientos] Protegido: [Procedimientos] FClase En el caso de la especificación de Atributos, la palabra Publico puede omitirse solamente en el caso en el que no se utilicen [Estructuras], [Variables] o [Constantes] publicas. El mismo criterio se aplica para las palabras Privado y Protegido. Este criterio también se aplica para las Operaciones. 4.2 Diagramas de clase Para los diagramas de clase se utilizaría la notación que provee el Lenguaje de Modelación Unificado (UML) propuesto por Jacobson et al. [1] , a saber: • Las clase se denotan como rectángulos divididos en tres compartimentos. El primer compartimento contiene el nombre de la clase. El segundo contiene los atributos y el tercero las operaciones. Los modificadores de acceso a datos y operaciones, a saber: público, protegido y privado; se representan con los símbolos +, # y – respectivamente, al lado derecho del atributo. 16 Ventana +area: real #visible: lógico +color():entero +escalar(razon:real) En la figura se muestra el método “escalar” que tiene un real como parámetro y no retorna nada (es una acción) y el método “color” que no tiene ningún parámetro y retorna un valor entero. • La herencia se representa mediante una generalización/especificación, que se denota con la flecha siguiente: de padre hijo • relación La relación de uso, se denota con una dependencia estereotipada: <<uso>> • La relación forma parte de, no es más que una asociación, que se denota: multiplicidad Si motor forma parte de carro, la flecha apunta a la clase motor, y el diamante va pegado a carro. La multiplicidad es el rango de cardinalidad permitido que puede asumir la asociación, se denota LI..LS. Se puede usar * en el limite superior para representar una cantidad ilimitada (ejemplo: 3..*). 4.3 Estructura de un programa (3ra. parte) Ahora introduciremos el concepto de clase a la estructura que estudiamos en el capítulo anterior. [Clases] Clase <Identificador> #aquí pueden ponerle nombre a su programa [Constantes] [Estructuras] [Variables] [Definiciones] [Procedimientos] 17 Accion Principal [Constantes] [Estructuras] [Variables] [Definiciones] [Secuencia de Operaciones] FAccion FClase Nótese el nombre del grupo de declaraciones de clases en negrita. Esto quiere decir que se pueden declarar en el algoritmo, declarándolas antes de la clase que contiene el método “Principal”. 18 5 APUNTADORES Un apuntador es una referencia a una dirección de memoria a partir de la cual se encuentra almacenada una determinada cantidad de información, asignada a una variable de un tipo elemental o estructurado. Para declarar un variable que sirva de apuntador a un valor de un cierto tipo se utiliza la sentencia: ↑<Tipo> <Identificador>; #para una sola variable o bien: ↑<Tipo> <Identificador1>,...,<Identificadorn>;#para varias variables por ejemplo, para declarar un apuntador a un real, la sentencia correcta sería: ↑real MiApuntador; 5.1 Operaciones Básicas Las operaciones básicas que se pueden realizar con el apuntador son: • Asignación: Una variable de tipo apuntador a un tipo de dato funciona como una variable normal en el contexto del operador de asignación. Si se cuenta con dos variables A y B, y ambas son apuntadores al mismo tipo de dato, entonces es posible realizar cualquiera de las operaciones A ← B o B ← A; en ambos casos el resultado será que ambas variables apuntan a la misma dirección de memoria. • Comparación: El espacio de direcciones de un computador es finito y discreto. Esto nos permite comparar las direcciones de memoria utilizando los operadores de comparación comunes de igualdad (=) y desigualdad (≠). Dos apuntadores que hagan referencia a la misma dirección de memoria serán iguales y serán diferentes en caso contrario. • Dereferenciación: Esta operación retorna el dato al que apunta o indica la referencia a memoria. Se simboliza mediante un flecha hacia arriba ( ↑ ) luego del nombre de la variable apuntador en cuestión. Por ejemplo, si se tiene una variable A de tipo ↑real, la operación de dereferenciación A↑ retornaría el valor real almacenado en la posición de memoria a la que hace referencia A. • Referenciación: Es la operación contraria a la dereferenciación y se simboliza mediante el símbolo & antes del nombre de la variable apuntador en cuestión (Ejemplo: &A). Esta operación retorna la dirección del tipo base en memoria. • Reservar: Esta función reserva el espacio en memoria suficiente para el tipo de dato especificado como parámetro y retorna la dirección de memoria que hace referencia a dicho espacio, sino no se logro reservar el espacio entonces retorna NULL. Por ejemplo, 19 la instrucción: A ← Reservar(real), reserva el espacio en memoria para un dato de tipo real y asigna la dirección de referencia a la variable A. • Liberar: Esta acción libera la memoria reservada por una llamada a la función Reservar. La liberación de memoria consiste en que el espacio liberado queda disponible para ser utilizado por otras variables y el apuntador que se pasa por parámetro (el que referencia la memoria a liberar) queda apuntando a NULL. Por ejemplo, continuando el ejemplo anterior, la instrucción: Liberar(A) liberaría la memoria reservada anteriormente y la variable A haría referencia a NULL. 20 6 CONVERSION EXPLICITA DE TIPOS DE DATO Todos los lenguajes de programación realizan algunas conversiones implícitas de tipos de dato elementales durante el calculo del resultado de expresiones que envuelven tipos distintos. Por ejemplo, al ejecutar una operación en la que se multiplica un entero por un real, el lenguaje realiza una conversión de tipo de dato en alguno de los operadores para que ambos operadores sean del mismo tipo y así llevar a cabo la operación. Los criterios para llevar a cabo las conversiones y que tipos pueden ser convertidos varían de lenguaje a lenguaje. Sin embargo, algunas veces el programador se ve en la necesidad de realizar una conversión de tipo explicita, esto es, que el programador le indique al lenguaje mediante una instrucción que se debe llevar a cabo una conversión de tipo. Por supuesto, el programador es el que decide, mediante la instrucción que le da al lenguaje, el tipo de dato “origen” y el tipo de dato “destino”. El lenguaje pseudoformal que se plantea en este informe permite la conversión explicita entre cualquiera de sus tipos de datos elementales, pero el estudiante debe tener en cuenta que este no es el caso de todos los lenguajes de programación y por lo tanto debe referirse a la documentación del lenguaje a la hora de realizar una conversión de tipos. Los perfiles de las funciones que provee este lenguaje pseudoformal para realizar las diferentes conversiones son: • Para convertir a entero: Funcion AEntero(<Tipo> <Identificador>) → entero • Para convertir a real: Funcion AReal(<Tipo> <Identificador>) → real • Para convertir a logico: Funcion ALogico(<Tipo> <Identificador>) → logico • Para convertir a caracter: Funcion ACaracter(<Tipo> <Identificador>) → caracter • Para convertir a string: Funcion AString(<Tipo> <Identificador>) → string 21 7 BIBLIOGRAFIA [1] Jacobson I., Booch, Rumbaugh, J. The Unified Modeling Language User Guide. Addison Wesley. 1999 [2] Sepúlveda, Jhonny. Construcción de Algoritmos: Metodología y Notación. Trabajo de Ascenso (Prof. Asistente). Universidad Central de Venezuela, Facultad de Ciencias, Escuela de Computación, 1988. 22