Estructura de un programa Tipos predefinidos y operaciones

Anuncio
Paradigmas de Programación
Año 2005
LENGUAJE ADA
Estructura de un programa
Todo programa Ada tiene 4 componentes:
· la especificación del contexto;
· la especificación del programa;
· la parte declarativa;
· el cuerpo.
La parte de especificación del contexto son directivas al compilador Ada. Pueden incluir
determinadas librerías, por ejemplo: la sentencia ”with ada_io” incluye la librería de
entrada/salida, en donde se encuentran los procedimientos que realizan la entrada/salida.
La especificación del programa da el nombre del programa.
La parte declarativa incluye las declaraciones de cualquier objeto. Puede contener
definiciones de variables y procedimientos.
El cuerpo del programa está compuesto de la secuencia de sentencias.
Ejemplo:
especificación del contexto
with ada_io; use ada_io;
procedure Doble is
x, y: integer;
begin
especificación del programa
parte declarativa
comienzo del cuerpo
get(x);
-- lee un número
y:=x*2; -- lo multiplica por 2
put(y);
--imprime el resultado
new_line; -- avanza a la siguiente línea
end Doble;
fin del cuerpo
Tipos predefinidos y operaciones
Tipo integer: Representa una secuencia de uno o más dígitos. Ada permite que cualquiera
de los dígitos (excepto el primero) esté precedido por el carácter “_” para dar legibilidad al
programa.
Ejemplo:
57
18_502_007
nro. de documento
10_18502007_001 nro. de IOMA
Por defecto, se asume que son números decimales, pero existen mecanismos para expresar
enteros en otra base:
Ejemplo:
8#377#
377 octal (255 en decimal)
Lenguaje ADA – Página 1
Paradigmas de Programación
Año 2005
16#FF#
2#1111_1111#
FF hexadecimal (255 en decimal)
1111_1111 binario (255 en decimal)
La base siempre se define en decimal y puede ser entre 2 y 16.
Están definidas las operaciones aritméticas tradicionales tales como +,-,*,/, y -(negación)
(los números negativos técnicamente son expresiones y no literales)
Existen dos procedimientos en ada_io para leer y escribir números enteros: get(i) y put(i)
Tipo flotante: se distinguen por la presencia de un punto decimal. Pueden incluir un
exponente.
Ejemplo:
10.0
0.5
3.14159_26
1.15E-12
1.0e+6
Las mismas operaciones que para los reales de Pascal.
Nota: Es importante aclarar que los valores flotantes y enteros NO pueden
mezclarse en una expresión
Tipo Boolean: Los valores booleanos están denotados por unos de dos literales
predefinidos: true y false.
Los operadores para este tipo son:
x and y
x or y
x xor y
not x
y los operadores relacionales (=,!=,<,>,etc.)
Tipo Character: Los valores de este tipo representan valores ASCII. Son caracteres
encerrados entre comillas simples.
Ejemplo:
‘a’,’A’,’’
Las únicas operaciones definidas para el tipo character son las relacionales.
Tipo string: todos los tipos anteriores son tipos escalares, esto es, que tiene valores que no
pueden ser divididos en partes más pequeñas. Ada tiene un tipo predefinido que es un tipo
compuesto, el tipo String, que consiste de una secuencia de valores character.
Un literal string es una secuencia de cero, o más caracteres encerrados entre comillas
dobles.
Lenguaje ADA – Página 2
Paradigmas de Programación
Año 2005
Ejemplo:
“estos es un string”
“
“
“123·
Expresiones
No es posible mezclar variables de distintos tipos en una misma expresión.
Ejemplo:
i: integer;
x: float;
x:=3.7;
i:=1;
x:=x+i;
No es correcto.
La forma correcta sería realizando un casting (conversión de tipo explícita)
x:=x + float(i)
Una conversión de tipo consiste del nombre del tipo seguido por una expresión entre
paréntesis.
Declaraciones
Existen dos tipos de objetos: variables y constantes.
Ejemplo:
x: integer;
y: constant float:=1.9;
x es una variable e y es una constante de tipo flotante.
La declaración de constantes como en Pascal, debe incluir una inicialización. Las
declaraciones de variables pueden incluir una inicialización que especifica el valor inicial
de las variables.
Ejemplo:
n: integer:= 10;
p: integer:= n+1:
Lenguaje ADA – Página 3
Paradigmas de Programación
Año 2005
Estructuras de control
Asignación:
“:=”
Sentencias condicionales
if condición
then sentencias
endif;
if condición
then sentencias
else sentencias
endif;
if condición
then sentencias
elseif cond then
elseif cond then
else
endif;
case n is
when 0 | 1 => sentencias
when 3 =>………
when 4..10 =>
when others =>
end case;
Nota: la cláusula others debe ir obligatoriamente cuando no se especifican todos los
posibles valores de n.
Sentencias de repetición
while condición loop
...................
end loop;
for i in 0..10 loop
……...
end loop;
Lenguaje ADA – Página 4
Paradigmas de Programación
Año 2005
for i in reverse 0..10 loop
……....
end loop;
Subprogramas
Ada define dos tipos de subprogramas: procedimientos y funciones.
Ejemplo:
with ada_io; use ada_io;
procedure demo is
n: integer := 4;
parámetro formal
procedure space (cant:integer) is
begin
for i in 1..cant loop
put (‘ ’);
end loop;
end space;
opcional
begin
space(6);
space(n+2);
end demo;
especificación del procedimiento
cuerpo del procedimiento
parámetro real
Aclaración: notar que la variable i del loop no está declarada. Esto es porque Ada
permite declarar implícitamente las variables de control del for y son definidas como
de lectura únicamente, esto es, no es posible alterar su valor.
Parámetros formales
Recordamos que los parámetros formales representan objetos locales al procedure. Hay 3
tipos de pasaje de parámetro: in, out e in out.
•
•
•
in: parecido al pasaje por copia, pero el parámetro actúa como una constante, y,
por lo tanto no se puede modificar su valor.
out: parámetro por resultado
in out: actúa como una variable local que se inicializa con el valor del parámetro
real y es asignado al parámetro real cuando finaliza el procedimiento. (Según el
caso es valor-resultado o referencia)
Si no se especifica explícitamente ninguno de estos tipos, se asume in.
Lenguaje ADA – Página 5
Paradigmas de Programación
Año 2005
Los parámetros pueden tener valores por defecto.
Ejemplo:
procedure space(cant: integer:= 1) is.
……..
end space;
De esta manera se puede invocar al procedimiento space sin parámetros reales:
space;
Los nombres de los subprogramas se pueden”sobrecargar”. Es decir, que diferentes
subprogramas pueden tener el mismo nombre, pero distinto tipo y/o número de parámetros.
Ejemplo:
Procedure put(item:character)
Procedure put(item:integer);
Funciones
Ejemplo:
function pepe(n: intejer) return integer is
………….
return….
end pepe;
Los parámetros de una función siempre son in.
Alcance de variables
El alcance de las variables va desde su definición hasta el final del subprograma que la
engloba. (parecido a Pascal.-alcance estático-)
Es posible calificar una variable, de esta manera se puede acceder a un identificador que
está enmascarado.
Ejemplo:
procedure A is
x: integer:=10;
procedure B is
x:float:= 1.9;
begin
put(x);
put(A.x);
Lenguaje ADA – Página 6
Paradigmas de Programación
Año 2005
end B;
begin
B;
end A;
El alcance de la variable x entera definida en A es todo el procedure A y TODO el
procedure B (ya que es posible calificar y, por lo tanto, acceder a la variable).
Tipos enumerativos
Un tipo define un conjunto de valores posible para una variable o expresión y las
operaciones sobre ellos. Veamos la siguiente declaración:
type días_de_la_semana is (dom, lun,….sab);
hoy: días_de_la_semana;
Con esta declaración definimos un nuevo tipo (días_de_la_semana) enumerando todos los
posibles valores. La variable hoy es del tipo días_de_la_semana y, por lo tanto puede
asumir cualquiera de sus valores.
Ejemplo:
hoy:=dom;
Los tipos enumerativos son tipos discretos y sus valores pueden usarse como limites en un
rango discreto:
Ejemplo:
for ch in character loop;
for i in integer loop;
for dia in dias_de_la_semana loop;
for dia in lun..jue loop;
Además definen un orden en la enumeración y por lo tanto pueden utilizarse los operadores
relacionales.
Ejemplo: lun<mie
Subrangos y subtipos
x:integer;
y:integer range 1..10
-- y puede tomar valores del 1 al 10.
no defino un nuevo tipo, sino una restricción del tipo base (en este caso integer)
x:=y;
Lenguaje ADA – Página 7
Paradigmas de Programación
Año 2005
y:=x;
Ambas asignaciones son correctas, solo que la segunda puede causar error de ejecución si
x contiene valores fuera del rango 1..10
Nota: El operador in: Me permite testear si un valor está en un rango determinado
Ejemplo:
i in 1..n
.
es equivalente a 1<=i<=n
Atributos
Ada define varios atributos de tipos discretos. Los atributos de un tipo se obtienen de la
siguiente forma:
nombre del tipo‘ nombre de atributo
Ejemplo:
dias_de_la_semana’ first --retorna dom
Los atributos que se pueden aplicar a tipos discretos son:
Atributo
first
last
pos
val
succ
pred
image
Descripción
el 1ro.
el último
posición del valor dentro del tipo
dada la posición (integer) retorna el valor correspondiente
sucesor
predecesor
retorna el string que representa a su argumento
Ejemplo:
dias_de_la_semana’first
dias_de_la_semana’last
dias_de_la_semana’pos(dom)
dias_de_la_semana’val(2)
dias_de_la_semana’succ(lun)
dias_de_la_semana’image(lun)
integer’image(7)
--dom
--sab
--0
--mar
--mar
--“lun”
--“7”
Tipo arreglo
La forma de declarar un arreglo en Ada es
vec: array (1..5) of integer
La forma de acceder a cada componente de vec es similar a Pascal:
Lenguaje ADA – Página 8
Paradigmas de Programación
Año 2005
vec(3):=0;
vec(i):=10;
--siendo i integer
Es posible iniciar arreglos sin la necesidad de utilizar un for:
vec:=(0,0,0,0,0);
vec:=(1=>0, 2=>0, 3=>0, 4=>0, 5=>0);
vec:=(1|2|3|4|5=>0);
vec:=(1..5=>0);
vec:=(others=>0);
Arreglos irrestrictos (var. semidinámicas)
Definen una clase de tipos de array posibles. Cada miembro de la clase tiene el mismo tipo,
el mismo número de índices y el mismo tipo de índice.
Ejemplo:
type matriz is (integer range<>, integer range<>) of integer;
si quiero declarar una variable matriz debería limitar el índice
x: matriz(1..5, 1..5);
y: matriz(10..20, 2..3);
Atributos de los arreglos:
first
last
lenght
range
Ejemplo:
procedure imprimir (m:matriz) is
begin
for i in m’range(1)
for j in m’range(2)
put(x(i,j));
end loop;
end loop;
end imprimir;
Registros
type alumno is
Lenguaje ADA – Página 9
Paradigmas de Programación
Año 2005
record
nombre: string(10);
numero: integer;
end record
a: alumno;
La forma de acceder a los campos es similar a Pascal:
a.numero:=10;
Además es posible realizar las siguientes asignaciones:
a:=(“pepe”,10);
a:=(nombre=>“pepe”, numero=>10);
Tipos derivados y subtipos
Cuando se declaran tipos derivados se crean tipos nuevos que heredan todas las
características del tipo base pero incompatibles con él.
Ejemplo:
type longitud is new integer;
longitud es un nuevo tipo que no es compatible con el tipo integer. Para mezclarlos en
expresiones será necesario realizar un casting.
subtype cantidad is integer;
cantidad es un subtipo de integer que sí es compatible con él.
l: longitud;
c: cantidad;
i: integer;
l:= i;
l:= c;
c:=i;
i:=c;
Cualquiera de las dos asignaciones son
incorrectas. La forma de hacer esto es:
l:= longitud (i) o
l:= longitud ©
asignaciones
correctas
Abstracción de datos
Un TAD es un tipo definido por el usuario que provee dos características principales:
encapsulamiento y ocultamiento de información.
Para encapsular la definición del nuevo tipo y las operaciones utilizamos los paquetes.
Lenguaje ADA – Página 10
Paradigmas de Programación
Año 2005
Un paquete (package) consiste de dos partes: una especificación y un cuerpo. La
especificación da el nombre al paquete y describe sus características externas, mientras que
el cuerpo define los detalles de implementación.
Ejemplo:
package nombre is
....
end nombre;
package body nombre is
….
end nombre;
Acá va la parte visible o interfase
Acá van las variables locales y la
implementación del paquete
Ejemplo 1: Vamos a implementar el TAD persona. Una persona tiene un nombre, apellido,
edad, dni y domicilio. Además disponemos de las siguientes operaciones VerNombre,
CumplirAnios y CambiarDomicilio.
package paq_persona is
-- Declaración de los tipos
type Cadena is string (1..30);
type Persona is record
nombre: Cadena;
apellido: Cadena;
edad: integer;
dni: integer;
domicilio: Cadena;
end record
-- Declaración de las operaciones
function VerNombre(p: Persona) return cadena;
procedure CumplirAnios(p: in out Persona);
procedure CambiarDomicilio(p: in out Persona; nuevo_dom: Cadena);
end paq_persona;
package body paq_persona is
-- Implementación de las operaciones
function VerNombre(p: Persona) return Cadena is
begin
return p.nombre;
end VerNombre;
procedure CumplirAnios (p:in out Persona) is
begin
p.edad:=p.edad +1;
end CumplirAnios;
procedure CambiarDomicilio(p: in out Persona; nuevo_dom: Cadena) is
begin
p.domicilio:=nuevo_dom;
Lenguaje ADA – Página 11
Paradigmas de Programación
Año 2005
end CambiarDomicilio;
end paq_persona;
Con esto logramos encapsular la definición del nuevo tipo y las operaciones para
manipularlo. Aunque la estructura es visible desde afuera del paquete. Por lo tanto, no
logramos ocultar la estructura de nuestro TAD. Para esto Ada provee mecanismos. Es
posible definir tipos privados y limitados privados. Los tipos privados sólo aparecen en la
especificación de un paquete. Fuera del paquete las únicas operaciones posibles son la
asignación, testeos por igualdad y las operaciones definidas en la especificación del
paquete.
Ejemplo:
package paq_persona is
--Declaración de tipos
type Cadena is string (1..30);
type Persona is private;
--Declaración de las operaciones
function VerNombre(p:Persona) return Cadena;
procedure CumplirAnios (p:in out Persona);
procedure CambiarDomicilio(p: in out Persona; nuevo_dom:Cadena);
--Definición de los tipos privados
private
type Persona is record
nombre:Cadena;
apellido:Cadena;
edad:integer;
dni:integer;
domicilio:Cadena;
end record;
end paq_persona;
Los tipos declarados como limitados privados son menos visibles desde afuera del paquete,
ya que las únicas operaciones permitidas para objetos de este tipo son las definidas en la
especificación del paquete (ni siquiera la asignación ni testeos por igualdad)
Ejemplo:
Vamos a implementar en ADA el TAD lista ordenada de enteros definido anteriormente
utilizando arreglos.
package paq_lista is
--Declaración de tipos y constantes
maxlen:constant integer:=100;
type listaOrdenada is private;
--Decalaración de operaciones
procedure Crear (l:in out listaOrdenada);
Lenguaje ADA – Página 12
Paradigmas de Programación
Año 2005
function Longitud( l:lista Ordenada) return integer;
ADT genéricos
Vamos a generalizar la lista ordenada definida previamente.
generic
type tipo_items is private;
package paq_lista is
--Declaración de tipos de datos y constantes
maxlen: constant integer:= 100;
type listaOrdenada is private;
--Declaración de las operaciones
procedure Crear (l: in out listaOrdenada);
function Longitud (l:listaOrdenada) return integer;
procedure Insertar (l: in out listaOrdenada; i:integer; nuevo_item:tipo_items);
procedure Eliminar ( l: in out listaOrdenada; i:integer);
function Recuperar (l: listaOrdenada; i:integer) return tipo_items;
--Definición de los tipos privados
private
type listaOrdenada is record
long:integer;
items:array(1..maxlen) of tipo_items;
end record;
end paq_lista;
package body paq_lista is
-Implementación de las operaciones
.................
end paq_lista;
¿Cómo utilizo el Tad genérico?
En la aplicación debería declarar:
.......
package lista_de_enteros is new paq_lista(integer);
package lista_de_personas is new paq_lista(Persona);
........
donde se define una lista ordenada de enteros y una lista ordenada de Personas
procedure Insertar (l: in out listaOrdenada; i:integer; nuevo_item:integer);
procedure Eliminar (l: in out listaOrdenada; i:integer);
function Recuperar (l:listaOrdenada; i:integer) return integer;
Lenguaje ADA – Página 13
Paradigmas de Programación
Año 2005
--Definición de los tipos privados
private
type listaOrdenada is record
long: integer;
items: array(1..maxlen) of integer;
end record;
end paq_lista;
package body paq_lista is
-Implementación de las operaciones
procedure Crear (l: in out listaOrdenada) is
begin
l.long:=0;
end Crear;
function Longitud (l:listaOrdenada) return integer is
begin
return l.long;
end Longitud;
procedure Insertar (l: in out listaOrdenada; i:integer; nuevo_item:integer) is
begin
…….
end Insertar;
procedure Eliminar (l: in out listaOrdenada; i:integer) is
begin
if (i>1) or (i>Longitud(l)
then Indicar error
else
--desplazar los items
for j in 1..Longitud(l) - 1 1oop
l.items(j):= l:items(j+1);
end loop;
l.long:= l.long -1;
endif;
end Eliminar;
function Recuperar (l:listaOrdenada; i:integer) return integer is
begin
......
end Recuperar;
end paq_lista;
Lenguaje ADA – Página 14
Descargar