Especificación del pseudolenguaje - Universidad de Las Palmas de

Anuncio
2.-Especificación del pseudolenguaje
El lenguaje es el vestido de los pensamientos
- Samuel Johnson
El pseudolenguaje empleado en este proyecto está basado en los apuntes de las
asignaturas de la Universidad de Las Palmas de Gran Canaria [HER 97]:
-
Metodología de la Programación (Facultad de Informática)
-
Metodología de la Programación I (Escuela de Informática)
Para que no exista confusión a partir de este momento, cuando se haga referencia al
lenguaje explicado en las asignaturas señaladas anteriormente, se usará el término
pseudolenguajeMP.
Lo expuesto en este capítulo es una definición de un pseudolenguaje, basado en dichos
apuntes, con pequeñas adaptaciones para conseguir un lenguaje aceptado por el
computador.
Para realizar una asociación entre ambos lenguajes a partir de sus diferencias, se
escribirá en superíndice
diferencia tipo y un número
. El número en superíndice esta relacionado
con el tipo de diferencia asociada. La explicación
de dichas diferencias serán
comentadas una vez concluya la especificación del lenguaje.
2.1.- Estructura de un programa
La estructura de un algoritmo es representada de la siguiente forma:
PROGRAMA
DEC_ALGORITMO
DEC_GLOBALES
DEC_SUBPROGRAMA
DEC_GLOBALES
DEC_TIPO
DEC_CONSTANTES
DEC_VARIABLES
DEC_SUBPROGRAMA
DEC_FUNCIÓN
DEC_PROCEDIMIENTO
DEC_ALGORITMO
DECLARACIONES
algoritmo
ID
fin algoritmo
CUERPO
DECLARACIONES
DEC_CONSTANTES
DEC_VARIABLES
Lo primero que debe declararse en un programa son, si los hubiera, los tipos definidos
por el usuario, las constantes y las variables globales.
Posteriormente los subprogramas y después el programa principal que debe contener la
palabra reservada algoritmo seguida por un identificador que indica su nombre.
A continuación deben declararse todas las constantes y las variables que vayan a
emplearse en el programa principal. Para ello se utilizan las zonas de declaración que
comienzan con las palabras reservadas constante (o constantes) y variable (o
variables) respectivamente.
Detrás vendrían las sentencias propias del programa principal y por último la palabra
reservada fin algoritmo.
Todo algoritmo debe contener la palabra reservada parar como mínimo una vez.
Las declaraciones y sentencias aún no siendo obligatorias, deben respetar su orden, es
decir, el traductor no aceptará que se declaren los subprogramas antes que los tipos
definidos por el usuario.
Comentarios
Los comentarios comienzan con abrellave y terminan con un cierrallave. Los
comentarios pueden tener varias líneas.
Ejemplo 2.1.1. El siguiente ejemplo muestra cómo sería un comentario
{Esto es un comentario
válido con varias líneas}
Sin embargo, no están permitidos los comentarios anidados, por ejemplo, el siguiente
comentario produciría un error sintáctico:
Ejemplo 2.1.2. Muestra cómo no sería un comentario
{Esto es un
{ anidado }
comentario
no valido}
También se permiten los comentarios de línea, para ello se hará uso de //diferencia tipo 2
Ejemplo 2.1.3. Muestra cómo sería un comentario de línea
En pseudolenguajeMP es con
una barra /.
//Comentario de línea
Algunos programas sencillos
Se presentan varios programas que ilustran algunas de las características más utilizadas
del lenguaje. Todos los programas tienen como meta calcular el área de uno o varios
círculos. No se debe intentar comprender todos los detalles sintácticos de estos
ejemplos, ya que en apartados posteriores se explicarán, siendo el objetivo de estos
ejemplos entender la lógica del programa en general.
Ejemplo 2.1.4. Lee el radio de un círculo, calcula el área y escribe el resultado calculado
{No hay declaración de estructuras
ni declaración de subprogramas}
algoritmo Calcula_area
{Declaración de constantes}
constante real PI = 3.1416
//Declaración de variables
variables reales radio, area
//Sentencias del algoritmo
escribir "Radio = "
leer radio
area <- PI * radio * radio
escribir "Area es: ",area
parar
fin algoritmo
Ejemplo 2.1.5. Lee el radio de un círculo, calcula el área y escribe el resultado calculado haciendo uso
de constantes y subprogramas
función real procesar(r)
variables entrada real r
local real a
a <- r * r
devolver a
fin función
algoritmo Calcula_area
constante real PI = 3.1416
variables reales radio, area
escribir "Radio = "
leer radio
area <- PI * procesar(radio)
escribir "Area es: ",area
parar
fin algoritmo
Ejemplo 2.1.6. Lee el radio de un círculo, calcula el área y escribe el resultado con comprobación de
error
función real procesar(r)
variables entrada real r
local real a
a <- r * r
devolver a
fin función
algoritmo Calcula_area
constante real PI = 3.1416
variables reales radio, area
escribir "Radio = "
leer radio
si radio < 0 entonces
area <- 0
si no
area <- PI * procesar(radio)
escribir "Area es: ",area
fin si
parar
fin algoritmo
Ejemplo 2.1.7. Calcula el área de varios círculos.
tipo Elemento es estructura real[100] fin tipo
función real procesar(r)
variables entrada real r
local real a
a <- r * r
devolver a
fin función
algoritmo Calcula_area
constante real PI = 3.1416
variables Elemento radio, area
entera n,i
escribir "Para PARAR, introducir 0 en el radio"
escribir "Radio = "
i <- 1
leer radio[i]
mientras radio[i] # 0 hacer
si radio[i] < 0 entonces
area[i] <- 0
si no
area[i] <- PI * procesar(radio[i])
fin si
escribir "Radio = "
i <- i + 1
leer radio[i]
fin mientras
para n desde 1 hasta i-1 hacer
escribir "Radio =", radio[n], "Area =", area[n]
fin para
parar
fin algoritmo
Ejemplo 2.1.8. Calcula el área de varios círculos haciendo uso de estructuras heterogéneas
tipo TCirculo es estructura
campo real radio
campo real area
fin tipo
tipo Elemento es estructura TCirculo[100] fin tipo
función real procesar(r)
variables entrada real r
local real a
a <- r * r
devolver a
fin función
algoritmo Calcula_area
constante real PI = 3.1416
variables Elemento circulo
entera n,i
escribir "Para PARAR, introducir 0 en el radio"
escribir "Radio = "
i <- 1
leer circulo[i].radio
mientras circulo[i].radio # 0 hacer
si circulo[i].radio < 0 entonces
circulo[i].area <- 0
si no
circulo[i].area <- PI * procesar(circulo[i].radio)
fin si
escribir "Radio = "
i <- i + 1
leer circulo[i].radio
fin mientras
para n desde 1 hasta i-1 hacer
escribir "Radio =", circulo[n].radio,
"Area =", circulo[n].area
fin para
parar
fin algoritmo
2.2.- Elementos básicos
En este apartado se presentan los elementos básicos para la construcción de sentencias
simples: las palabras clave, tipos de datos, constantes y variables.
El conjunto de caracteres
Para formar los elementos básicos del programa (constantes, variables, operadores,
expresiones, etc.), pseudolenguaje utiliza como bloques de construcción las letras de la
A a la Z, las minúsculas de la a a la z, los dígitos del 0 al 9 y ciertos caracteres
especiales.
A continuación se muestra una lista de estos caracteres especiales:
+ - * / = % & #
! ? ^ " ' ~ \ |
< > ( ) [ ] { }
: ; . , _ (espacio en blanco)
Identificadores
ID
LETRA
-
LETRA
En pseudolenguajeMP no
se especifica si se pueden
-
diferenciar mayúsculas y
minúsculas.
DÍGITO
Un identificador está formado por letras y dígitos en cualquier orden, excepto el primer
carácter que debe ser una letra. No se pueden intercambiar mayúsculas y
minúsculasdiferencia
tipo
4
, esto es, una letra mayúscula no es equivalente a la
correspondiente minúscula.
El carácter de subrayado (_) se puede incluir también y es considerado como una letra.
No se limita la longitud de los identificadores.
No pueden existir dos identificadores en el mismo ámbito con el mismo nombre,
excepto los identificadores de campo, por estar asociados a un nuevo tipo, aunque
dentro de dicho tipo no pueden existir dos campos con el mismo nombre.
No puede existir un identificador en el programa con el mismo nombre que un
subprograma, así como un subprograma llamado main.
Ejemplo 2.2.1. Los siguientes nombres son identificadores válidos
x
y12
suma_1
_temperatura
nombres
area
porcentaje
TABLA
Los siguientes nombres no son identificadores válidos por las razones señaladas
4num
el primer carácter debe ser una letra
orden-no
carácter ilegal (-)
indicador error
carácter ilegal (espacio en blanco)
Palabras clave
Las palabras clave sólo se pueden utilizar para su propósito ya establecido; no se pueden
utilizar como identificadores definidos por el programador.
Las palabras clave son:
abs
Abrir
algoritmo
campo
campos
carácter
caracteres
Cerrar
constantes
CrearFichero
constant
Correcto
desde
cos
devolver
Eliminar
entero
enteros
enteras
entonces
entrada
es
escribir
Escribir
EscribirLínea
Escritura
estructura
entrada/salida
falso
Fichero
FicheroTexto
fin
FinFichero
FinLínea
función
hacer
hasta
Lectura
entera
IrA
Lectura/Escritura leer
Leer
LeerLínea
Liberar
local
locales
lógico
lógica
lon
lógicos
lógicas
mientras
mod
natural
naturales
no
NuevaLínea
NULO
Orden
para
parar
paso
pos
Posición
Predecesor
Primero
real
procedimiento
reales
puntero
Renombrar
retornar
repetir
ristra
salida
SaltarLínea
según
sen
si
sub
Sucesor
Tamaño
tag
tipo
TomarBloque
Último
Valor
variable
variables
verdadero
Tipos de datos
Los tipos básicos de datos que pueden emplearse son los siguientes:
TIPO BASICO
natural(es)
entero(s)/a(s)
real(es)
lógico(s)/a(s)
carácter/caracteres
Tipo de datos
Descripción
natural(es)
Números
bits
32
Rango
0 a 4294967295
positivos y el cero.
entero(s)/a(s)
Números enteros.
real(es)
Números de coma flotante.32
lógico(s)/a(s)
Los valores permitidos
son verdadero y falso.
32 -2147483648 a 2147483647
1.18e-38 a 3.40e38
8
carácter /
caracteres
Carácter.
8
-128 a 127
Los tipos de datos se pueden escribir de la siguiente forma, siendo todas totalmente
validas:
natural:
natural
naturales
entero:
entero
entera
enteros
enteras
real:
real
reales
lógico:
lógico
lógicos
lógica
lógicas
carácter:
carácter
caracteres
Constantes
Se permiten cinco tipos básicos de constantesdiferencia tipo 4: constantes enteras, constantes
de coma flotante, constantes de carácter, constantes lógicas y constantes de cadena de
caracteres.
En
pseudolenguajeMP
no
se
especifican que tipos de constante
se permiten.
Constantes enteras
Las constantes enteras representan un entero, y pueden estar expresadas en los
sistemas de numeración decimal, octal o hexadecimal.
Las constantes enteras en formato decimal puede ser cualquier combinación de dígitos
tomados del conjunto de 0 a 9. Si la constante tiene dos o más dígitos, el primero de
ellos debe ser distinto de 0.
Ejemplo 2.2.2. Se muestra a continuación varias constantes enteras decimales.
0
1
743
6754
32654
9999
Una constante entera en formato octal puede ser cualquier combinación de dígitos
tomados del conjunto de 0 a 7. El primer dígito debe ser obligatoriamente 0, con el fin
de identificar la constante como un número octal.
Ejemplo 2.2.3. Se muestra a continuación varias constantes enteras octales.
0
01
074
0176
0726
07777
Una constante entera en formato hexadecimal debe comenzar por 0x o 0X. Puede
aparecer después cualquier combinación de dígitos tomados del conjunto de 0 a 9 y de
a a f (tanto minúsculas como mayúsculas). Las letras de la a a la f (o de la A a la F)
representan las cantidades (decimales) 10 a 15, respectivamente.
Ejemplo 2.2.4. Se muestra a continuación varias constantes enteras hexadecimales.
0x
0X1
0X7FF
0X876
0xabc
Constantes de coma flotante
Una constante de coma flotante es un número en base 10 que contiene un punto decimal
y/o exponente en base 10.
Ejemplo 2.2.5. Se muestra a continuación varias constantes de coma flotante
0.
1.
0.2
345.675
5000.
0.00045
12.3
345.0098
1.2E-8
0.006e-3
1.6667E+8
0.1212112e12
Si existe un exponente, su efecto es el de desplazar la posición del punto decimal a la derecha si el
exponente es positivo, o a la izquierda si es negativo. Si no se incluye punto decimal en el número, se
supone que se encuentra a la derecha del último dígito.
Constantes de carácter
Una constante de carácter es un solo carácter, encerrado con comillas simples ( ' ).
Ejemplo 2.2.6. Se muestra a continuación varias constantes de carácter
'B'
'b'
'&'
' '
La última constante consiste en un espacio en blanco encerrado con comillas simples
Constantes de cadena de caracteres
Una constante de cadena de caracteres consta de cualquier número de caracteres
consecutivos (o ninguno) encerrado entre comillas dobles (").
Ejemplo 2.2.7. Se muestra a continuación varias constantes de cadena de caracteres
"amarillo"
"La salida "
"3*(x+t) "
" "
"\n"
La penúltima constante consiste en una cadena de caracteres vacía , y la última constante en un salto de
línea
Constantes lógicas
Las constantes lógicas representan un valor booleano, siendo los valores permitidos
verdadero y falso.
Declaración de constantes
DEC_CONSTANTE
constante(s)
TIPO_CONSTANTE
ID
=
CONSTANTE
TIPO CONSTANTE
TIPO_BASICO
TIPO_RISTRA
CONSTANTE
CONST_SIN_SIGNO
-
CONS_SIN_SIGNO
NUM_ENTERO
NUM_REAL
'
CARÁCTER
'
ID
NULO
verdadero
falso
NOTA: ID debe ser de tipo constante
La sección debe comenzar con la palabra reservada constante (o constantes). La
constante se declara con un tipo, un nombre, un signo igual y el valor de la misma.
Los valores que se han definido en el momento de escribir el código del programa no
pueden ser modificados más tarde en tiempo de ejecución.
No pueden existir dos constantes con el mismo nombre.
Ejemplo 2.2.8. Declaración de constantes
constantes
real pi = 3.1416
entera i = 1
Variables y declaración de variables
DEC_VARIABLES
variable(s)
DEC_VAR_CAMPOS
DEC_VAR_CAMPOS
,
TIPO
ID
INDICES
[
]
Cuando se declara una variable, se le da un tipo y un nombre. Esto se hace detrás de la
palabra reservada variable (o variables).
No pueden existir dos variables con el mismo nombre.
Los tipos de datos de una variable pueden ser: natural(es), entero(s)/a(s),
real(es),
lógico(s)/a(s),
carácter
(o
caracteres),
ristra,
ristra
fija, puntero, Fichero, FicheroTexto ó un identificador de tipo asociado a una
estructura, enumerado ó subrango.
Ejemplo 2.2.9. Declaración de variables
variables
real X
entera I
Se puede declarar más de una variable del mismo tipo, separadas por una coma.
Ejemplo 2.2.10.
variables
reales X, Y, Z
enteras I, J
Variables ristra
TIPO_RISTRA
ristra
ristra fija
[
NUM_ENTERO
]
ristra variable
Una constante ristra consta de cualquier número de caracteres consecutivos (o ninguno)
encerrados entre comillas dobles (").
Se pueden distinguir tres clases de ristras: de tamaño fijo, de tamaño limitado y de
tamaño dinámico.
- Las variables ristra de tamaño fijo se declaran como ristra fija[Tamaño]
- Las variables ristra de tamaño limitadodiferencia
tipo 2
se declaran como ristra
variable[Tamaño] y su contenido podrá ser una ristra de cualquier longitud
comprendida entre los valores naturales 0 y Tamaño.
En pseudolenguajeMP las variables
de tamaño limitado se declaran
ristra [Tamaño].
- Las variables ristra de tamaño dinámico se declaran simplemente como ristra y
pueden albergar ristras de cualquier longitud.
Ejemplo 2.2.10. Declaraciones de variables ristras
variables
ristra fija[10]
ristra variable[10]
ristra
texto_fijo
texto_limitado
texto_dinamico
Operaciones asociadas a Ristras
Hay cuatro operaciones asociadas a las ristras:
Función lon
LONGITUD
lon
(
EXPRESIÓN
)
La función devuelve el número de caracteres asociado a una expresión de tipo ristra.
Ejemplo 2.2.11. Uso de la función lon
algoritmo ejemplo2_2_11
variables
ristra s
entera longitud
s <- "Hola a todos"
longitud <- lon(s)
escribir "La longitud de la ristra es: ",longitud
//longitud es igual a 12
parar
fin algoritmo
La longitud de la ristra nula es 0.
Función localización
POS_ristra
pos
(
EXPRESIÓN
EXPRESIÓN
,
)
NOTA: EXPRESIÓN debe ser de tipo ristra
Consiste en averiguar en qué posición se localiza subristra dentro de una ristra dada; por
ejemplo, en la ristra "Las Palmas de Gran Canaria", encontramos la subristra
"Palmas" comenzando en la posición 5. La localización de subristras se implementa
como pos(R,S), siendo R la ristra, S la subristra a buscar y pos(R,S) la posición
comenzando en uno en R del primer carácter de la primera aparición de izquierda a
derecha de la subristra S, si se encuentra, o cero en caso de que S no sea una subristra de R.
Ejemplo 2.2.12. Uso de la función pos
algoritmo ejemplo2_2_12
variables
ristra r,s
entera posición
r <- "Hola a todos"
s <- "a"
posición <- pos(r,s)
escribir "La primera aparición de a en la ristra es:",posición
//posición es igual a 4
parar
fin algoritmo
Función copia
COPIA
sub
(
EXPRESIÓN
,
EXPRESIÓN
)
,
EXPRESIÓN
Se trata de, dada una ristra, obtener otra tomando un trozo de ella. Se ha de especificar
la ristra fuente, la posición de comienzo de la subristra a tomar y el tamaño de la misma.
Aplicamos esta operación con el formato sub(R,P,T), de forma que sub("Las
Palmas G.C. ",6,5) produce la ristra "almas". En el caso de que el tercer parámetro
se omita, o sea mayor que lon(R) - P + 1, la ristra resultante se formará tomando los
caracteres de R desde P hasta el final: sub("Las Palmas",5,9) = sub("Las
Palmas",5) = "Palmas".
Ejemplo 2.2.13. Uso de la función sub
algoritmo ejemplo2_2_13
variables
ristra r,s,t
r <- "Hola a todos"
s <- sub(r,1,4) //s contendrá "Hola"
t <- sub(s,2) //t contendrá "ola"
escribir "Los valores de las ristras son:",r,s,t
parar
fin algoritmo
Concatenación
La concatenación es la unión de dos subristras para formar una mayor por simple
yuxtaposición. Para expresar la concatenación se emplea el símbolo +; de este modo la
expresión: "Las" + " Palmas", producirá la ristra "Las Palmas".
Ejemplo 2.2.14. Uso de la concatenación
algoritmo ejemplo2_2_14
variables
ristra r,s
r <- "Hola "
s <- r + "a todos"
escribir "El contenido de s es:",s
parar
fin algoritmo
2.3.-Operadores y expresiones
Los datos sobre los que actúan los operadores se denominan operandos. Algunos
operadores requieres dos operandos, mientras que otros actúan sólo sobre un operando.
En este apartado veremos cómo utilizar operadores para formar expresiones.
EXPRESIÓN
EXPR_LÓGICA
\/
EXPR_LÓGICA
EXPR_LÓGICA
EXPR_RELACIONAL
/\
EXPR_RELACIONAL
EXPR_RELACIONAL
EXPR_SIMPLE
OP_RELACIONAL
EXPR_SIMPLE
OP_RELACIONAL
<
<=
=
#
>
>=
EXPR_SIMPLE
TERMINO
+
-
-
TERMINO
TERMINO
FACTOR
mod
FACTOR
*
/
FACTOR
VARIABLE
CONSTANTE
(
EXPRESIÓN
no
FACTOR
)
LLAMADA_FUNCIÓN
RESERVA_MEMORIA
FUNCIONES_RISTRA
FUNCIONES_FICHERO
FUNCIONES_ORDINALES
FUNCIONES_MATEMÁTICAS
CADENA_CARACTERES
tamaño
(
ID
)
NOTA: ID debe ser de tipo definido por el usuario
Operadores aritméticos
- Operador suma (+)
- Operador resta (-)
- Operador multiplicación (*)
- Operador división (/)
- Operador módulo (mod)
Los operandos sobre los que actúan los operadores aritméticos deben representar
valores numéricos. El operador módulo requiere que los dos operandos sean enteros y el
segundo operador distinto de cero. Análogamente, el operador de división (/) requiere
que el segundo operando sea distinto de cero, aunque los operandos no necesitan ser
enteros. La división de una cantidad entera por otra también entera es denominada
división entera. Esta operación siempre tiene como resultado el cociente entero truncado
(se desprecia la parte decimal del cociente). Por otra parte, si una operación de división
se lleva a cabo con dos números de coma flotante, o con un número de coma flotante y
un entero, el resultado será un cociente en coma flotante.
Ejemplo 2.3.1 Supóngase que unas variables enteras a y b tienen valores 10 y 3, respectivamente. Se
muestran a continuación varias expresiones aritméticas en las que aparecen estas variables, acompañadas
del resultado.
Expresión
Valor
a + b
13
a – b
7
a * b
30
a / b
3
a mod b
1
Nótese el cociente truncado resultante de la operación de división, ya que ambos operandos representan
cantidades enteras. Nótese también el resto entero del uso del operador módulo en la última expresión.
Supongamos ahora que x e y son variables de coma flotante cuyos valores son 12.5 y 2.0,
respectivamente.
Expresión
Valor
x + y
14.5
x – y
10.5
x * y
25.0
x / y
6.25
Los operandos que difieren en el tipo pueden sufrir una conversión de tipo antes de que
la expresión alcance su valor final. Si un operando es de tipo de coma flotante y el otro
es un entero, el entero se convertirá al tipo de coma flotante del otro operando, y el
resultado se expresará de igual forma. Por tanto, una operación entre un entero y un
real tendrá como resultado un real.
Operadores relacionales y lógicos
Los operadores relacionales son diferencia tipo 1:
- Operador igualdad (=)
En
pseudolenguajeMP
los
operadores son: = ≠ > ≥ < ≤
- Operador de desigualdad (#)
- Operador mayor (>)
- Operador mayor o igual (>=)
- Operador menor (<)
- Operador menor o igual (<=)
Además se admiten dos operadores lógicos diferencia tipo 3:
En pseudolenguajeMP los operadores
lógicos son:
- o lógica (\/) (barra \ + barra / )
- y lógica (/\) (barra / + barra \ )
- o lógica: o ∨
- y lógica: y ∧
Los operadores lógicos actúan sobre operandos que son a su vez expresiones lógicas.
Permiten combinar expresiones lógicas individuales, formando otras condiciones
lógicas más complicadas que pueden ser ciertas o falsas. El resultado de una operación y
lógica será verdadero sólo si los dos operandos son verdaderos, mientras que el
resultado de una operación o lógica será verdadero si alguno de los operandos es
verdadero o ambos a la vez.
También se incluye el operador monario no, que niega el valor de una expresión lógica,
es decir, hace que una expresión que era originalmente cierta se haga falsa y viceversa.
Este operador se denomina operador no lógico.
Relación de las precedencias y la asociatividad de los operadores, de mayor a
menor.
Categoría de operador
Operadores
Operadores monarios
Asociatividad
no
* / mod
IÆD
Suma y resta aritméticas
+ -
IÆD
Operadores relacionales
< <= > >= = <>
No hay
y lógica
/\
IÆD
o lógica
\/
IÆD
Multiplicación, división y resto aritméticos
Ejemplo 2.3.2. Supongamos que i es una variable entera cuyo valor es 2, f una variable de coma
flotante cuyo valor es 3.5 y c una variable de carácter que representa el carácter ‘z’. A continuación
aparecen varias expresiones lógicas que hacen uso de estas variables.
Expresión
Interpretación
i + f <= 10
falso
i >= 6 /\ c = 'z'
verdadero
c # 'p' \/ i + f <= 10
verdadero
Los paréntesis no son necesarios a causa de las precedencias propias de los operadores. Por consiguiente,
las operaciones aritméticas se efectuarán automáticamente antes que las operaciones de relación e
igualdad, y las operaciones de relación e igualdad se efectuarán automáticamente antes que las conectivas
lógicas.
Fijémonos en la última expresión. La primera operación que se llevará a cabo será la de adición (i
después las operaciones relacionales (i
+ f <= 10)
y (c
# 'p'
+ f);
), y finalmente la condición o lógica.
Una expresión lógica compuesta no se evaluará completamente si su valor se puede
establecer a partir de la evaluación de, por ejemplo, la primera expresión lógica
individual.
Operador de asignación
La sintaxis de asignación de este operador se escribe a continuación diferencia tipo 1:
En pseudolenguajeMP el operador de asignación es ←
ASIGNACIÓN
<-
VARIABLE
EXPRESION
VARIABLE
ID
[
,
EXPRESIÓN
]
ID
->
El operador de asignación se forma mediante la unión del símbolo menor que (<) y el
guión (-), no permitiéndose espacios en blanco en medio.
Ejemplo 2.3.3. En las siguientes expresiones de asignación, supongamos que i es una variable de tipo
entero.
Expresión
Valor
i <- 3.3
3
i <- 3.9
3
i <- -3.9
3
Supongamos ahora que i y j son variables de tipo entero y que a j se le ha asignado el valor 5.
Expresión
Valor
i <- j
5
i <- j / 2
2
i <- j / 2 * 2
4
i <- 2 * (j / 2)
4
Cuando en una expresión se mezclan variables de distinto tipo se convierte al tipo de
mayor rango antes de realizar la operación.
Los rangos de las variables de mayor a menor se ordenan del siguiente modo:
real > entero > natural > carácter
Funciones matemáticas
FUNCIONES_MATEMÁTICAS
abs
(
EXPRESIÓN
)
sen
(
EXPRESIÓN
)
cos
(
EXPRESIÓN
)
tan
(
EXPRESIÓN
)
Las funciones matemáticas que se permiten son:
-
El valor absoluto de una expresión. abs
-
El seno de una expresión. sen
-
El coseno de una expresión. cos
-
La tangente de una expresión. tan
El valor devuelto en las funciones seno, coseno y tangente es en radianes.
2.4.- Entrada y salida de datos
En este apartado utilizaremos las instrucciones: leer y escribir. Estas instrucciones
permiten la transferencia de información entre la computadora y los dispositivos de
entrada/salida estándar.
Introducción
Se puede acceder a una instrucción de entrada o salida desde cualquier sitio de un
programa con simplemente escribir leer o escribir., seguido de una lista de
argumentos separados por comas. Los argumentos representan los datos que le son
enviados a la función.
Ejemplo 2.4.1 Esquema de un programa típico que hace uso de rutinas de entrada/salida.
algoritmo RaízCuadrada
...
escribir "Desea calcular la raíz cuadrada de: "
leer X
si ...
...
escribir "La raíz cuadrada es: ", Y
si no
escribir "no existe una raíz cuadrada real de", X
fin si
parar
fin algoritmo
Entrada de datos. La operación leer
Se pueden introducir datos en la computadora procedentes del dispositivo de entrada
estándar mediante la operación leer. Esta operación se puede utilizar para introducir
cualquier combinación de valores numéricos, caracteres sueltos y cadenas de caracteres.
La sintaxis de la instrucción leer:
INSTRUCCIÓN_LEER
VARIABLE
leer
,
Donde VARIABLE son variables previamente declaradas, pudiendo ser de los tipos
siguientes:
natural(es),
entero(s)/a(s),
real(es),
lógico(s)/a(s),
carácter (o caracteres), ristra, ristra fija, puntero, ó un identificador
de tipo asociado a una estructura homogénea o heterogénea .
No existe conversión de tipos, el valor leído será del tipo de la variable previamente
declarada.
Ejemplo 2.4.2 Esquema de un programa con la función leer
algoritmo ejemplo2_4_2
variables
ristra letras
entero i
real
f
………
leer letras,i,f
………
parar
fin algoritmo
Se podrían introducir los siguientes datos por el dispositivo de entrada estándar cuando se ejecutase el
programa:
Hola 123 0.3
Se le asignarían a los cuatro primeros elementos de la ristra letras los caracteres que integran la
cadena Hola; a i se le asignaría el valor entero 123, y a f le sería asignado el valor de coma flotante
0.3.
Los datos se introducen en una línea, separados por espacios en blanco. También se podrían haber
introducidos los datos en líneas separadas, ya que los caracteres de nueva línea se considerarían como
caracteres de espaciado. Por tanto los datos de entrada se podrían haber escrito así:
Hola
123
0.3
O así:
Hola
123 0.3
O
Hola 123
0.3
Etcétera.
Hay que tener en cuenta que una cadena de caracteres que incluye caracteres de
espaciado no se puede introducir de esta forma.
Ejemplo 2.4.3. Esquema de un programa donde se quiere leer por pantalla una ristra que incluye
espaciados
algoritmo ejemplo2_4_3
variables
ristra línea
………
leer línea
………
parar
fin algoritmo
Cuando se ejecuta la función leer, se leerá del teclado una cadena de caracteres de longitud no
determinada y se la asignará a línea. No habrá restricciones en los caracteres que la compongan, salvo
que quepan en una línea. Por ejemplo, la cadena
Santiago de Compostela
Se podría introducir por el teclado y se le asignaría a línea.
Salida de datos. La operación escribir
Se puede escribir datos en el dispositivo de salida estándar utilizando la operación
escribir. Se puede utilizar esta función para escribir cualquier combinación de valores
numéricos, caracteres sueltos y cadenas de caracteres.
La sintaxis de la instrucción escribir :
SENTENCIA_ESCRIBIR
escribir
EXPRESIÓN
,
La EXPRESIÓN puede ser una constante, variables simples o expresiones más
complicadas. También se pueden incluir referencias a funciones.
La EXPRESIÓN puede ser de los tipos siguientes: natural(es), entero(s)/a(s),
real(es),
lógico(s)/a(s),
carácter
(o
caracteres),
ristra,
ristra
fija, puntero, ó un identificador de tipo asociado a una estructura homogénea o
heterogénea .
Ejemplo 2.4.4. Programa sencillo en el que se utiliza la función escribir
algoritmo ejemplo2_4_4
variables
real i,j
i <- 2.0
j <- 3.0
escribir "El valor de i es: ",i
escribir "El valor de j es: ",j
parar
fin algoritmo
Cuando se ejecuta el programa, se genera la siguiente salida:
El valor de i es: 2.0El valor de j es: 3.0
Para poder poner una nueva línea como separador, es necesaria una secuencia de
escape.
Secuencia de escape
Una secuencia de escape siempre comienza con una barra \ y es seguida por uno o más
caracteres especiales. Cada sentencia de escape ocupa un carácter. Se lista a
continuación las dos secuencias de escape permitidasdiferencia tipo 4.
En
- Salto de línea, se representa como \n.
pseudolenguajeMP
no
especifican las secuencias de escape.
- Tabulador horizontal, se representa como \t.
Ejemplo 2.4.5. Programa sencillo en el que se utiliza la función escribir y secuencias de escape
algoritmo ejemplo2_4_5
variables
real i,j
i <- 2.0
j <- 3.0
escribir "El valor de i es: ",i
escribir "\n\tEl valor de j es: ",j
parar
fin algoritmo
Cuando se ejecuta el programa, se genera la siguiente salida:
El valor de i es: 2.0
se
El valor de j es: 3.0
Utilizando las funciones leer y escribir
Se presenta un programa sencillo que lee el nombre de un estudiante y tres
calificaciones de exámenes, y después calcula la calificación media. Los datos se
introducen de forma interactiva, la computadora pide la información al usuario y el
usuario proporciona la información con un formato libre. La entrada de cada dato se
hace en una línea. Una vez que se han introducido todos los datos, la computadora
calculará la media deseada y escribirá todos los datos.
algoritmo calificaciones
variables
ristra nombre
real nota1, nota2, nota3, media
escribir "\nPor favor, introduce tu nombre: "
leer nombre
escribir "\nPor favor, introduce la primera nota: "
leer nota1
escribir "\nPor favor, introduce la segunda nota: "
leer nota2
escribir "\nPor favor, introduce la tercera nota: "
leer nota3
media <- (nota1 + nota2 + nota3)/3
escribir "\n\nNombre:",nombre
escribir "\n\n Nota 1: ",nota1
escribir "\n Nota 2:",nota2
escribir "\n Nota 3:",nota3
escribir "\n\n La media es:",media
parar
fin algoritmo
Se muestra a continuación el resultado que saldría por pantalla, el texto en cursiva
corresponde a las respuestas del usuario:
Por favor, introduce tu nombre: Fayna del Cano
Por favor, introduce la primera nota: 7.5
Por favor, introduce la segunda nota: 6.8
Por favor, introduce la tercera nota: 9.4
Nombre: Fayna del Cano
Nota1: 7.5
Nota2: 6.8
Nota3: 9.4
La media es: 7.9
2.5.- Sentencias de control
Hay muchos programas que requieren que un grupo de instrucciones se ejecute
repetidamente, hasta que alguna condición lógica se satisfaga (bucles). Otros programas
requieren que se realice un test o comprobación lógica en algún punto concreto de ellos
(ejecución condicional), y otros necesitarán que un grupo de sentencias sea
seleccionado entre varios grupos disponibles (selección).
Todas estas operaciones se pueden realizar utilizando diversas sentencias de control.
Sentencia mientras
La sentencia mientras se utiliza para generar bucles. La forma general de la sentencia
es:
MIENTRAS
mientras
EXPRESIÓN
hacer
CUERPO
fin
mientras
Entre las palabras reservadas mientras y hacer debe aparecer una EXPRESIÓN de tipo
lógico. El CUERPO debe incluir algún elemento que altere el valor de expresión,
proporcionando así la condición de salida del bucle.
Reglas de funcionamiento:
-
La EXPRESIÓN se evalúa antes y después de cada ejecución del CUERPO. Si la
EXPRESIÓN es verdadera, se ejecuta el CUERPO, y si es falsa, el control pasa a la
sentencia siguiente al CUERPO.
-
Si la EXPRESIÓN se evalúa a falso cuando se ejecuta el CUERPO por primera vez,
el CUERPO no se ejecutará.
-
Mientras la EXPRESIÓN sea verdadera el bucle se ejecutará. Esto significa que la
EXPRESIÓN se ejecutará indefinidamente a menos que "algo" en el interior del
bucle modifique la EXPRESIÓN haciendo que su valor pase a falso.
Ejemplo 2.5.1. Esquema que muestra la función mientras
algoritmo RaízCuadrada
...
mientras X-Z >= 0.00005 hacer
Y <- ((X / Y) + Y) / 2
Z <- Y * Y
fin mientras
...
Sentencia repetir
La forma general de la sentencia repetir es:
REPETIR
repetir
CUERPO
hasta
que
EXPRESIÓN
Se trata de una sentencia de control repetitiva que ejecuta siempre al menos una
iteración. Entre las palabras reservadas repetir y hasta que se colocan las
sentencias que se ejecutan en cada iteración, componiendo el CUERPO. Tras la palabra
reservada hasta que debe colocarse una EXPRESIÓN lógica.
Reglas de funcionamiento:
-
La EXPRESIÓN se evalúa al final del CUERPO, después de ejecutarse todas las
sentencias.
-
Si la EXPRESIÓN es verdadera, se vuelve a repetir el bucle y se ejecutan todas
sus instrucciones.
-
Si la EXPRESIÓN es falsa, se sale del CUERPO y se ejecuta la siguiente
instrucción a repetir.
Ejemplo 2.5.2. Programa que visualiza los dígitos 0, 1, 2, …., 9
algoritmo visualizar
variable entera digito
digito <- 0
repetir
escribir digito, "\n" //los números aparecen uno en cada línea
digito <- digito + 1
hasta que digito > 9
parar
fin algoritmo
Sentencia para
La forma general de la sentencia para es:
PARA
ID
para
desde
EXPRESIÓN1
hasta
EXPRESIÓN
fin para
NOTA: ID debe ser una variable declarada
CUERPO
hacer
EXPRESIÓN2
paso
en donde ID controla la repetición del bucle, debiendo ser una variable previamente
declarada, denominada variable de control, desde EXPRESIÓN1 hasta EXPRESIÓN2
representan:
EXPRESIÓN1, la especificación de un valor inicial para empezar el conteo
EXPRESIÓN2, la especificación del valor final que debe alcanzarse antes de
terminar.
De forma opcional puede aparecer la palabra reservada paso seguida de una EXPRESIÓN
por la que debe incrementarse o decrementarse la variable de control en cada paso. Si no
se indica de forma explícita el valor por defecto es 1.
Ejemplo 2.5.3. Programa que calcula la multiplicación de dos naturales
algoritmo Multiplica
variables
naturales
Multiplicando,
Multiplicador,
Cont
escribir "Multiplicando= "
leer Multiplicando
escribir "Multiplicador= "
leer Multiplicador
Producto <- 0
para Cont desde 1 hasta Multiplicador hacer
Producto <- Producto + Multiplicando
fin para
escribir "el producto es: ", Producto
parar
fin algoritmo
Producto,
Sentencia si
SI
EXPRESIÓN
si
entonces
si no
CUERPO
CUERPO
fin si
Entre las palabras reservadas si y entonces debe aparecer una EXPRESIÓN de tipo
lógico que determina si se ejecutan las sentencias contenidas en el bloque entonces o
en el bloque si no. El bloque si no es opcional y cuando no aparece no se ejecuta
ninguna opción en caso de que no se cumpla la EXPRESIÓN de tipo lógico.
Ejemplo 2.5.5. Calcula la raíz cuadrada de un número
algoritmo RaízCuadrada
variables reales X, Y, Z, aux
leer X
si X >= 0 entonces
Y <-
X / 2
Z <-
Y * Y
si X > Z entonces
Z <- X - Z
si no
Z <- Z - X
fin si
mientras
Z >= 0.00005 hacer
Y <- ((X / Y) + Y) / 2
Z <- Y * Y
si X > Z entonces
Z <- X - Z
si no
Z <- Z - X
fin si
fin mientras
escribir "La raíz cuadrada es: ", Y
si no
escribir "no existe una raíz cuadrada real de", X
fin si
parar
fin algoritmo
Sentencia según
La sentencia según hace que se seleccione un grupo de sentencias entre varios grupos
disponibles. La selección se basa en el valor de una expresión que se incluye en la
sentencia según.
La forma general de la sentencia según es:
SEGUN
según
EXPRESIÓN
hacer
ETIQUETAS
:
CUERPO
fin según
CUERPO
en otro caso
ETIQUETAS
,
CONSTANTE
CONSTANTE
..
CONSTANTE
NOTA: CONSTANTE debe ser de tipo ordinal
en donde ETIQUETAS representan expresiones constantes de valores enteros, lógicos o
carácter.
Cuando se ejecuta la sentencia según, la EXPRESIÓN se evalúa y se transfiere el control
directamente al grupo de sentencias (CUERPO) cuya etiqueta tenga el mismo valor que el
de EXPRESIÓN. Si ninguno de los valores de las etiquetas coincide con el valor de
EXPRESIÓN, entonces no se seleccionará ninguno de los grupos de la sentencia según.
En este caso se transfiere el control directamente a la sentencia que se encuentre a
continuación de la sentencia según.
La palabra reservada en otro caso es opcional y tiene como función seleccionarse si
ninguna de las etiquetas coincide con el valor de EXPRESIÓN.
Reglas de funcionamiento:
-
La EXPRESIÓN se evalúa y se compara con las CONSTANTES; las CONSTANTES
son listas de uno o más posibles valores de EXPRESIÓN separados por comas,
y/o rangos de valores separados por dos puntos. Ejecutado el CUERPO, el
control pasa a la primera instrucción a continuación del fin según.
-
La cláusula en otro caso es opcional.
-
Si el valor de la EXPRESIÓN no está comprendido en ninguna lista de
CONSTANTES y no existe la cláusula en otro caso, no sucede nada y sigue
el flujo del programa; si existe la cláusula en otro caso, se ejecuta el
CUERPO a continuación de la cláusula en otro caso.
-
La EXPRESIÓN debe ser un tipo ordinal. Los números reales no pueden ser
utilizados ya que no son ordinales.
-
Todas las CONSTANTES deben ser únicas y de un tipo ordinal compatible con
el tipo de la EXPRESIÓN .
Ejemplo 2.5.7. Muestra el uso de la sentencia según
algoritmo Calculadora
variables
carácter Operación
reales Op1, Op2, Res
leer Operación
leer Op1,Op2
según Operación hacer
'+': Res <- Op1+Op2
'-': Res <- Op1-Op2
'*': Res <- Op1*Op2
'/': Res <- Op1/Op2
fin según
escribir Res
parar
fin algoritmo {Calculadora}
2.6.-Subprogramas
Este apartado se centra en la creación y utilización de funciones y procedimientos
definidos por el programador. Se verá cómo se definen los subprogramas y cómo se
puede acceder a ellos desde diferentes partes de un programa, viéndose también cómo
se puede pasar información a / o desde un subprograma.
Introducción
En computación, una subrutina o subprograma, como idea general, se presenta como
un algoritmo separado del algoritmo principal, el cual permite resolver una tarea
específica.
Si un programa contiene varios subprogramas, sus definiciones pueden aparecer en
cualquier orden.
Un subprograma no puede estar incluido en otro.
Cuando se accede a un subprograma desde alguna determinada parte del programa, se
ejecutan las instrucciones de que consta. Se puede invocar a un mismo subprograma
desde varios lugares distintos del programa. Una vez que se ha completado la ejecución
de un subprograma, se devuelve el control al punto siguiente desde el que se accedió a
él.
Los dos tipos de subprogramas que se manejan son:
-
Funciones.
-
Procedimientos.
Declaración de una función
DECLARACION FUNCION
función
TIPO
ID
(
)
DEC_VARIABLE_SUB
ID
CUERPO
,
fin función
DEC_VARIABLES_SUB
variables
MODO
DEC_VAR_CAMPOS
La definición de una función tiene tres componentes principales: la cabecera, la
declaración de parámetros y el cuerpo de la función.
función tipo nombre (parám_formal_1, parám_formal_2, ..., parám_formal_n)
declaración de parámetros
cuerpo
fin función
La primera línea de la definición contiene la palabra reservada función, la
especificación del tipo de valor devuelto por la función seguida del nombre de la
función y (opcionalmente) un conjunto de argumentos, separados por comas y cerrados
entre paréntesis.
Deben seguir al nombre de la función un par de paréntesis vacíos si la definición de la
función no incluye ningún argumento.
En términos generales, la cabecera de función se puede escribir:
función tipo nombre (parám_formal_1, parám_formal_2, ..., parám_formal_n)
en donde tipo representa el tipo de datos del valor que devuelve la función y nombre el
nombre de la función.
parám_formal representan los parámetros formales que permiten que se transfiera
información desde el punto del programa en donde se llama a / o desde la función a ésta.
Los
tipos
que
puede
devolver
entero(s)/a(s),
real(es),
ristra,
fija,
ristra
una
función
lógico(s)/a(s),
puntero,
pueden
carácter
ser:
natural(es),
(o
caracteres),
ó un identificador de tipo asociado a una
estructura homogénea o heterogénea .
Sigue a la cabecera la declaración de parámetros.
En su forma más general la definición sería:
variable
modo tipo nombre
Donde variable puede ser las palabras reservadas variable o variables, modo puede
ser: entrada, entrada/salida, salida y local (ó locales), tipo representa el tipo
de datos y nombre el nombre de la variable.
Todos los parámetros deben ser declarados en este lugar de la función, bajo el modo
entrada, entrada/salida o salida. Cada parámetro formal debe ser del mismo tipo
que el dato que recibe desde el punto de llamada. El resto de las variables que se
necesiten en el subprograma, que no correspondan con un parámetro, se declararán de
modo local.
El modo local en caso de existir debe ir colocado el último en la declaración.
Se puede declarar en una misma declaración más de una variable del mismo tipo,
separadas por una coma.
El resto de la definición de la función es una sentencia compuesta que define las
acciones que debe realizar ésta. Como consecuencia de ésto, también puede acceder a
otras funciones declaradas anteriores a ella, incluso a sí misma (recursividad).
Se devuelve información desde la función hasta el punto del programa desde donde se
llamó mediante la sentencia devolver y se devuelve el control al punto de llamada.
En términos generales la sentencia devolver es:
DEVOLVER
EXPRESION
devolver
Se devuelve el valor de EXPRESIÓN al punto de llamada. Sólo se puede incluir una
expresión en la sentencia devolver. Por tanto, una función sólo puede devolver un
valor al punto de llamada mediante la sentencia devolver.
Una definición de función puede incluir varias sentencias devolver.
Ejemplo 2.6.1. Función Multiplicación
función natural Multiplicación (Multiplicando,Multiplicador)
variables
entrada naturales Multiplicando, Multiplicador
locales naturales Producto, Contador
Producto <- 0
para Contador desde 1 hasta Multiplicador hacer
Producto <- Producto + Multiplicando
fin para
devolver Producto
fin función
Llamada a una función
LLAMADA_FUNCIÓN
ID
(
)
EXPRESIÓN
,
NOTA: ID debe ser de tipo función
Se puede invocar (llamar) a una función especificando su nombre, seguido de una lista
de parámetros cerrados entre paréntesis y separados por comas. Si la llamada a la
función no requiere ningún parámetro, se debe escribir a continuación del nombre de la
función un par de paréntesis vacíos.
La llamada a la función puede aparecer sola, o puede ser uno de los operandos de una
expresión más compleja.
Ejemplo 2.6.2. Programa que llama a la función Multiplicación definida en el ejemplo 2.6.1
algoritmo Factorial
variables naturales n, f, i
escribir "déme un valor natural: "
leer n
f <- 1
para i desde 2 hasta n hacer
f <- Multiplicación(f,i) {Llamada a la función Multiplicación}
fin para
escribir "el factorial es: ", f
parar
fin algoritmo
Declaración de un procedimiento
DECLARACION PROCEDIMIENTO
procedimiento
ID
(
)
DEC_VARIABLE_SUB
ID
CUERPO
,
retornar
fin procedimiento
DEC_VARIABLES_SUB
variables
MODO
DEC_VAR_CAMPOS
La definición de un procedimiento tiene tres componentes principales: la cabecera, la
declaración de parámetros y el cuerpo del procedimiento.
La cabecera contiene la palabra reservada procedimiento, seguida del nombre del
procedimiento y (opcionalmente) un conjunto de argumentos, separados por comas y
cerrados entre paréntesis.
Deben seguir al nombre del procedimiento un par de paréntesis vacíos si la definición
del procedimiento no incluye ningún argumento.
En términos generales, la cabecera se puede escribir:
procedimiento nombre (parám formal 1, parám formal 2, ..., parám formal n)
en donde nombre representa el nombre del procedimiento, parám formal representan
los parámetros formales que permiten que se transfiera información desde el punto del
programa en donde se llama al procedimiento a éste.
Sigue a la cabecera la declaración de parámetros (ver definición de una función).
El resto de la definición del procedimiento son sentencias que definen las acciones que
debe realizar, concluyendo el procedimiento con las palabras reservadas retornar y
fin procedimiento.
Ejemplo 2.6.3. Función Multiplicación
procedimiento Multiplicar (Multiplicando,Multiplicador,Producto)
variables
entrada naturales Multiplicando, Multiplicador
salida natural Producto
local natural Contador
Producto <- 0
para Contador desde 1 hasta Multiplicador hacer
Producto <- Producto + Multiplicando
fin para
retornar
fin procedimiento
Llamada a un procedimiento
LLAMADA_PROC
ID
(
)
EXPRESIÓN
,
NOTA: ID debe ser de tipo procedimiento
Se puede invocar (llamar) a un procedimiento especificando su nombre, seguido de una
lista de números de parámetros cerrados entre paréntesis y separados por comas. Si la
llamada al procedimiento no requiere ningún parámetro, se debe escribir a continuación
del nombre del procedimiento un par de paréntesis vacíos.
La llamada a un procedimiento es tratada como una sentencia más del programa, no
formando parte de ninguna expresión.
Ejemplo 2.6.4. Programa que llama a la función Multiplicar definida en el ejemplo 2.6.3
algoritmo Factorial
variables naturales n, f, i
escribir "déme un valor natural: "
leer n
f <- 1
para i desde 2 hasta n hacer
Multiplicar(f,i,f) {Llamada al procedimiento Multiplicar}
fin para
escribir "el factorial es: ", f
parar
fin algoritmo
Paso de parámetros a un subprograma
Existen tres
modos para el paso de parámetros a un subprograma entrada,
entrada/salida o salida.
La correspondencia de las variables es por posición, por lo que los parámetros en el
punto de llamada, se tienen que corresponder en tipo y posición con los declarados en el
subprograma.
Ejemplo 2.6.5. Programa que contiene un procedimiento que no modifica el valor de su parámetro
formal.
procedimiento modificar(a)
variable entrada entera a
a <- a * 3
escribir "\nEl valor de a es: ",a
retornar
fin procedimiento
algoritmo argumento
variable entera a
a <- 2
escribir "\nEl valor de a es: ",a
modificar(a)
escribir "\nEl valor de a es: ",a
parar
fin algoritmo
Cuando se ejecuta el programa, la salida sería:
El valor de a es: 2
El valor de a es: 6
El valor de a es: 2
Imaginemos que modificáramos el modo del parámetro del procedimiento, quedando:
procedimiento modificar(a)
variable salida entera a
a <- a * 3
escribir "El valor de a es:",a
retornar
fin procedimiento
Cuando se ejecutará el programa, la salida sería:
El valor de a es: 2
El valor de a es: 6
El valor de a es: 6
2.7.- Tipos definidos por el usuario
DEC_TIPO
DEC_ESTRUCTURA
DEC_ENUMERADO
ID
tipo
fin tipo
es
DEC_SUBRANGO
DEC_PUNTERO
En este capítulo se verá cómo permitir a los usuarios definir nuevos tipos de datos para
que sean equivalentes a los tipos de datos existentes. Una vez que el tipo de datos
definido por el usuario ha sido establecido, entonces las variables pueden ser declaradas
en términos de este nuevo tipo de dato.
Tipo enumerado
El usuario puede definir tipos enumerados mediante la enumeración del conjunto de
identificadores que forman los valores del nuevo tipo. Estos identificadores se utilizan
entonces como constantes en los programas, lo que proporciona mayor claridad.
La forma de un tipo enumerado es:
tipo
ID1
es
ID
,
ID
fin tipo
donde ID1 es el nombre del tipo e ID corresponde a los identificadores que se utilizan
como constantes en los programas.
Ejemplo 2.7.1. Programa que hace uso de un tipo enumerado
tipo Día es
lunes, martes, miércoles, jueves, viernes, sábado, domingo
fin tipo
algoritmo Caso
variables
Día día
día <- viernes
según día hacer
caso lunes..jueves,viernes: escribir "hoy es laborable"
caso sábado,domingo: escribir "hoy es fiesta"
en otro caso escribir "¿Que día será?"
fin según
parar
fin algoritmo
Operaciones especificas para los tipos ordinales
Para los tipos ordinales se definen operaciones específicas que dan acceso a la
correspondencia con los naturales, tales como:
-
Primero(Tipo_Ordinal). Devuelve el primer valor de un tipo ordinal.
-
Último(Tipo_Ordinal). Devuelve el último valor de un tipo ordinal.
-
Sucesor(Valor_Ordinal). Devuelve el valor sucesor de uno dado.
-
Predecesor(Valor_Ordinal). Devuelve el valor predecesor de uno dado.
-
Orden(Valor_Ordinal). Devuelve el valor natural correspondiente a un valor
ordinal .
-
Valor(Tipo_Ordinal,Valor_Natural). Devuelve el valor que corresponde en
un tipo ordinal especificado al valor natural dado.
Ejemplo 2.7.1. Programa que hace uso de un tipo enumerado y operaciones con ordinales
tipo Día es
lunes, martes, miércoles, jueves, viernes, sábado, domingo
fin tipo
algoritmo enumerado
variable Día días
días <- lunes
mientras días # sábado hacer
escribir "Día laborable\n"
días <- Sucesor(días)
fin mientras
días <- domingo
según días hacer
lunes..viernes: escribir "Día laborable dentro del según\n"
sábado,domingo: escribir "Día libre\n"
en otro caso escribir "Día no dentro del rango\n"
fin según
mientras días # lunes hacer
días <- Predecesor(días)
fin mientras
si días = lunes entonces
escribir "Es lunes\n"
fin si
si Valor(Día,2) =
martes entonces
escribir "Ha sido martes\n"
fin si
si Primero(Día)= lunes entonces
escribir "El primero de la semana es lunes\n"
fin si
si Último(Día)= domingo entonces
escribir "El último de la semana es domingo\n"
fin si
parar
fin algoritmo
Tipo subrango
Permite declarar variables que estén entre dos límites, un máximo y un mínimo que se
especifican. Los tipos subrangos pueden definirse en base a tipos ordinales.
La forma de un tipo subrango es:
tipo
ID
es
NOM_TIPO
CONSTANTE
..
CONSTANTE
NOTA: CONSTANTE debe ser de tipo ordinal
donde ID es el nombre del tipo subrango, el NOM_TIPO corresponde al tipo ordinal base,
y CONSTANTE a los valores que definen los límites del tipo subrango.
Ejemplo 2.7.2. Programa que hace uso de un tipo subrango
tipo Día es
lunes, martes, miércoles, jueves, viernes, sábado, domingo
fin tipo
tipo DíasLaborables es Día lunes..viernes fin tipo
algoritmo enumerado
variable DíasLaborables días
si (días = lunes) entonces
escribir "Empieza la semana"
si no
escribir "Ya queda menos para el fin de semana"
fin si
parar
fin algoritmo
fin tipo
Tipo estructurado homogéneo
Una estructura homogénea —lo que en inglés se conoce como array— es un conjunto
dimensionado de elementos del mismo tipo base. Este tipo estructurado define un
conjunto de elementos ordenados de tal forma que un valor dentro de un rango de un
(sub)rango de valores define unívocamente la posición de cada elemento dentro de la
estructura homogénea.
Definición de un tipo estructurado homogéneo
La forma de un tipo estructurado homogéneo es:
tipo
ID
es
estructura
TIPO
INDICES
[
]
fin tipo
donde ID indica el nombre de la estructura y por lo tanto el nombre del nuevo tipo, TIPO
el tipo de datos de los elementos de la estructura e INDICES puede ser una de las
opciones siguientes:
INDICES
..
CONSTANTE
CONSTANTE
ID
,
NOTA: ID debe ser de tipo definido por el usuario
CONSTANTE debe ser de tipo ordinal
donde CONSTANTE
representan valores de tipo ordinal, e ID el nombre de un tipo
ordinal.
Se pueden formar estructuras de varias dimensiones, añadiendo índices adicionales
mediante el carácter coma (,) o con abre y cierra corchete.
Los rangos si no se especifica el índice de comienzo empiezan en 1.
Ejemplo 2.7.3. El siguiente ejemplo muestra definiciones de estructuras homogéneas
tipo Vector es estructura entero[100] fin tipo //rango 1..100
tipo Matriz es estructura real[100,50] fin tipo //rangos comienzan
en 1
tipo Otro_Vector es estructura entero[0..100] fin tipo
tipo Otra_Matriz es estructura real[0..100,-10..50] fin tipo
Referenciado a un elemento
Cada elemento de la estructura es referido especificando el nombre de la variable
estructura seguido por uno o más índices, con cada índice encerrado entre corchetes o
separados por comas. El valor de cada índice se expresa como una expresión. Por
ejemplo x[1] refiere a un elemento en la estructura homogénea unidimensional x. De la
misma manera, y[i][j] ó y[i,j] refiere a un elemento en la estructura homogénea
bidimensional y.
Ejemplo 2.7.4. Programa que hace uso de estructuras homogéneas
tipo Vector es estructura entero[100] fin tipo
algoritmo estructura_homogenea
variables Vector V
natural i,NumElementos
leer NumElementos {NumElementos tendrá que ser menor que 100}
para i desde 1 hasta NumElementos hacer
leer V[i] {Se rellenan los primeros NumElementos de V}
fin para
parar
fin algoritmo
Paso de estructuras homogéneas a subprogramas
Una estructura homogénea completa se puede usar como parámetro de un subprograma.
Para ello, el nombre de la estructura homogénea debe aparecer solo, sin corchetes o
índices, como un parámetro actual dentro de la llamada al subprograma.
Ejemplo 2.7.5. Programa que pasa una estructura homogénea de tres elementos enteros a un
procedimiento donde estos elementos son alterados.
tipo Elementos es estructura entero[3] fin tipo
procedimiento modificar(a)
variables entrada/salida Elementos a
local entera contador
escribir "\nDentro del procedimiento los valores de son: "
para contador desde 1 hasta 3 hacer
a[contador] <- 27
escribir "\n a[",contador,"] = ", a[contador]
fin para
retornar
fin procedimiento
algoritmo modificaciones
variables Elementos a
entera contador
escribir "\n Valores antes de llamar al procedimiento: "
para contador desde 1 hasta 3 hacer
a[contador] <- contador
escribir "\n a[",contador,"] = ", a[contador]
fin para
modificar(a)
escribir "\n Valores después de llamar al procedimiento: "
para contador desde 1 hasta 3 hacer
escribir "\n a[",contador,"] = ", a[contador]
fin para
parar
fin algoritmo
Cuando el programa se ejecuta, se genera la siguiente salida:
Valores antes de llamar al procedimiento:
a[1] = 1
a[2] = 2
a[3] = 3
Dentro del procedimiento los valores de son:
a[1] = 27
a[2] = 27
a[3] = 27
Valores después de llamar al procedimiento:
a[1] = 27
a[2] = 27
a[3] = 27
Tipo estructurado heterogéneo
La estructura heterogénea es una estructura de datos —comúnmente conocidas por la
denominación inglesa de record— cuyos elementos individuales pueden ser de distinto
tipo.
Los elementos individuales de una estructura heterogénea reciben el nombre de campos,
Se puede acceder a cada campo por separado, o manejar la estructura como un todo.
Definición de una estructura
En general, la composición de una estructura heterogénea puede ser definida como:
tipo
ID
es
campos(s)
estructura
DEC_VAR_CAMPOS
fin tipo
DEC_VAR_CAMPOS
,
TIPO
ID
[
INDICES
]
donde ID referencia al nombre de tipo que identifica este tipo de estructuras.
DEC_VAR_CAMPOS corresponde a la declaración de los miembros individuales.
Los miembros individuales pueden ser de tipo simple, estructuras homogéneas y
estructuras heterogéneas. Los nombres de los miembros dentro de una estructura
heterogénea deben ser todos diferentes, pero el nombre de un miembro puede ser el
mismo que el de una variable definida fuera de la estructura heterogénea.
Ejemplo 2.7.6. Declaración de estructura heterogénea.
tipo Persona es estructura
campos ristra Nombre, PApellido, SApellido
campo ristra fija[9] NIF
fin tipo
para declarar variables de tipo Persona:
variables Persona Persona1, Persona2
Referencia a una estructura heterogénea
Los miembros de una estructura se utilizan generalmente, de modo individual, como
entidades separadas. Un miembro de una estructura puede accederse escribiendo.
variable.miembro
donde variable refiere el nombre de una variable de un tipo de estructura y miembro el
nombre de un miembro dentro de la estructura. Notar el punto (.) que separa el nombre
de la variable del nombre del miembro. Este punto es un operador y su asociatividad es
de izquierda a derecha.
Se pueden escribir expresiones más complejas usando repetidamente el operador punto.
Por ejemplo, si un miembro de una estructura es a su vez otra estructura, entonces el
miembro de la estructura más interna puede ser accedido escribiendo:
variable.miembro.submiembro
donde miembro refiere el nombre del miembro dentro de la estructura externa y
submiembro el nombre del miembro dentro de la estructura interna. Similarmente, si un
miembro de una estructura heterogénea es un array, entonces un elemento individual del
array puede ser accedido escribiendo:
variable.miembro[expresión]
donde expresión es un valor no negativo que indica el elemento del array.
El uso del operador punto puede extenderse a arrays de records escribiendo
array[expresión].miembro
donde
array
refiere
el
nombre
de
la
estructura
homogénea
(array)
y
array[expresión] es un elemento individual del array (una variable estructura). Por
tanto, array[expresión].miembro referirá un miembro específico dentro de una
estructura heterogenea particular.
Ejemplo 2.7.8. El siguiente ejemplo muestra declaraciones y asignaciones de estructuras heterogéneas.
tipo Tfecha
es estructura
campos entero mes, día, año
fin tipo
tipo Tcuenta es estructura
campo entero cuenta_no
campo carácter cuenta_tipo
campo ristra nombre
campo real saldo
campo Tfecha ultimopago
fin tipo
algoritmo Estructuras
variable Tcuenta cliente
cliente.saldo <- 0
cliente.ultimopago.mes <- 12
leer cliente.cuenta_tipo
si cliente.cuenta_tipo = ‘P’ entonces
escribir "Cliente preferente"
si no
escribir "Cliente regular"
fin si
parar
fin algoritmo
Paso de estructuras a Subprogramas
Hay varias maneras de pasar información de una estructura a un subprograma. Se
pueden transferir los miembros individuales o las estructuras completas.
Los miembros individuales de estructura se pueden pasar a un subprograma como
parámetros en la llamada al subprograma, y un miembro de una estructura puede ser
devuelto mediante la sentencia devolver.
Ejemplo 2.7.9. Esqueleto de un programa para pasar miembros de la estructura a un subprograma
tipo Tfecha
es estructura
campos entero mes, día, año
fin tipo
tipo Tcuenta es estructura
campo entero cuenta_no
campo carácter cuenta_tipo
campo ristra nombre[80]
campo real saldo
campo Fecha ultimpopago
fin tipo
función real ajustar(nombre,cuen_no,saldo)
variables
entrada/salida ristra nombre
entrada
entera cuen_no
entrada
real saldo
local
real nuevo_saldo
.....
nuevo_saldo <- ....
....
devolver nuevo_saldo
fin función
algoritmo ejemplo_paso_de_estructuras_a_función
variable Tcuenta cliente
....
cliente.saldo <- ajustar(cliente.nombre, cliente.cuenta_no,
cliente.saldo)
....
parar
fin algoritmo
Una estructura completa puede transferirse a un subprograma pasando la estructura
como parámetro. Una estructura pasada de esta manera será pasada por referencia en
vez de por valor, esto es, solo puede tomar el modo entrada/salida o salida
Ejemplo 2.7.10. El siguiente ejemplo muestra un esqueleto de un programa para pasar una estructura a
un subprograma
tipo Tcuenta es estructura
campo entero cuenta_no
campo ristra nombre
campo real saldo
fin tipo
procedimiento ajustar(cliente)
variables
entrada/salida Tcuenta cliente
cliente.nombre <- "Rafael"
cliente.cuenta_no <- 9999
cliente.saldo <- 5369.62
retornar
fin procedimiento
algoritmo ejemplo_paso_de_estructuras_a_función
variable Tcuenta cliente
ajustar(cliente)
parar
fin algoritmo
2.8.-Punteros
Un puntero es una variable que representa la posición (más que el valor) de otro dato,
tal como una variable o un elemento de una estructura.
Declaración de punteros
Los punteros, como cualquier otra variable, deben ser declarados antes de ser usados.
Una declaración de puntero puede ser escrita en términos generales como:
DEC_PUNTERO
puntero
TIPO
<
>
Ejemplo 2.8.1. Declaración de punteros
variables
puntero<real> a {dirección de una variable real}
puntero<ristra> b {dirección de una variable ristra}
puntero<entero> c {dirección de una variable entera}
puntero<puntero<real>> pp {dirección de una dirección de una
variable real}
Memoria dinámica: TomarBloque y Liberar
RESERVA_MEMORIA
TomarBloque
TIPO
(
LIBERAR_MEMORIA
Liberar
(
VARIABLE
)
)
Por medio de punteros se puede crear o eliminar vaiables dinámicamente, es decir,
según se necesite.
La función TomarBloque sirve para solicitar un bloque de memoria del tamaño
suministrado como parámetro.
variable_puntero <- TomarBloque (tipo)
donde variable_puntero es una variable de tipo puntero previamente declarada, y
tipo es el tipo de la variable que se crea dinámicamente y cuya dirección devuelve
TomarBloque, debiendo coincidir el tipo con el tipo base de variable_puntero.
Cuando una zona de memoria reservada con TomarBloque ya no se necesita, puede ser
liberada mediante el procedimiento Liberar.
Liberar (puntero)
donde puntero es un puntero que ha reservado previamente memoria con la función
TomarBloque
Si se intenta liberar un puntero que ya estaba libre el programa dará un error.
Ejemplo 2.8.2. Uso de TomarBloque y Liberar
Q <- TomarBloque(entero)
Liberar(Q)
El valor NULO
Un valor especial que puede tomar una variable de tipo puntero es NULO, e indica que
esa variable no apunta actualmente a ninguna dirección de memoria.
Ejemplo 2.8.3. El siguiente ejemplo muestra el uso del valor NULO
pp <- NULO
Operador de dereferencia
Siendo Q una variable puntero, cuando en un programa se escriba Q se estará refiriendo a
dicha variable, pero si se escribe Q->diferencia tipo 1, se estará refiriendo a "lo que está detrás
de la flecha", es decir, a la variable apuntada por Q. Si esta variable fuese de un tipo
compuesto de campos, se referirá a cada campo como Q->.NombreCampo diferencia tipo 2, y si
fuese un vector, se indicará el i_ésimo elemento como Q->[i]. La operación consistente
en acceder a la variable referenciada por un puntero recibe el nombre de
desrefenciación.
Ejemplo 2.8.3. Programa que muestra el uso de punteros
En pseudolenguajeMP el operador de
referencia es →
algoritmo uso_punteros
En pseudolenguajeMP se refiere a
variables
entera I
puntero<entero> P, Q
entera J
puntero<entero> R
I <- 3
P <- TomarBloque(entero)
Q <- TomarBloque(entero)
J <- 5
R <- TomarBloque(entero)
P-> <- I
Q-> <- J*P->
R-> <- Q->
Liberar(P)
Liberar(Q)
Liberar(R)
parar
fin algoritmo
cada campo como:
Q->NombreCampo
Ejemplo 2.8.4. Programa que muestra el uso de punteros con estructuras
tipo Tcuenta es estructura
campo entero cuenta_no
campo ristra nombre
campo real saldo
fin tipo
algoritmo punteros_y_estructuras
variables
puntero<Tcuenta> cliente
cliente <- TomarBloque(Tcuenta)
cliente->.cuenta_no <- 65985
cliente->.nombre <- "Rafael"
cliente->.saldo <- 25693.5
Liberar(cliente)
parar
fin algoritmo
Ejemplo 2.8.5. Procedimiento que inserta al principio de una lista
diferencia tipo 5
tipo PLista es puntero<Nodo> fin tipo
En pseudolenguajeMP el tipo PLista
tipo Nodo es estructura
campo ristra Info
puede estar debajo del tipo Nodo, en
campo PLista Siguiente
pseudolenguaje tiene que declararse
antes.
fin tipo
procedimiento InsertarDelante(L,V)
variables entrada/salida PLista L
entrada ristra V
locales PLista Nuevo
local puntero<entero> aux
local Tcuenta cliente
aux <- TomarBloque(entero)
aux-> <- 5
cliente.ultimopago.mes <-
12
V <- "Hola"
Nuevo <- TomarBloque(Nodo) V <- "Hola"
Nuevo->.Info <- V
Nuevo->.Siguiente <- L
L <- Nuevo
retornar
fin procedimiento
2.9.-Ficheros
Muchas aplicaciones requieren leer y escribir información de un periférico auxiliar de
almacenamiento. Tal información se almacena en el periférico en la forma de un
fichero, distinguiéndose tres tipos de ficheros:
- Fichero uniforme es una secuencia de elementos que son todos del mismo tipo y, por
tanto, ocupan el mismo número de bytes en el dispositivo de almacenamiento.
- Fichero no uniforme se interpreta como una secuencia marcada de elementos que
pueden ser de distintos tipos, ocupando por tanto, cantidades distintas de espacio físico.
- Fichero de texto es una secuencia estructurada de caracteres; la estructuración se
consigue mediante marcas que son combinaciones específicas de caracteres.
Declaración de variables de ficheros
En la declaración se especifica cómo va a interpretar la información contenida en el
fichero que se asocie con la variable; se contemplan tres posibilidades:
variable Fichero NombreVariable //componentes no uniformes
variable Fichero<TipoComponente> NombreVariable//componentes uniformes
variable FicheroTexto NombreVariable //fichero de texto
donde NombreVariable indica el nombre de la variable que podrá estar asociada a un
fichero de los tipos indicados.
Ejemplo 2.9.1. Diferentes declaraciones de ficheros
variable FicheroTexto Fich_Entrada, Fich_Salida
variable Fichero Fich_binario
variable Fichero<TRegFrec> Fsalida
Apertura y cierre de un fichero
Un fichero uniforme, no uniforme y de texto debe estar creado o procesado antes de ser
abierto. Esto asocia la variable del fichero con el fichero físico. También se especifica
cómo se va a usar el fichero, sólo para lectura, sólo para escritura o para lectura y
escritura.
Para abrir un fichero se usa el procedimiento Abrir diferencia tipo 5
En pseudolenguajeMP la operación
Abrir
es una función lógica.
ABRIR
Abrir
NOM_RISTRA
ID
(
,
,
Lectura
)
Escritura
NOTA: ID debe ser de tipo fichero
Lectura/Escritura
donde ID es la variable de fichero —también llamada "fichero lógico"—, NOM_RISTRA
es una variable o literal de tipo ristra que identifica el fichero físico que se pretende
abrir, y Lectura, Escritura y Lectura/Escritura, son palabras reservadas que
actúan como indicadores del sentido de transferencia de la información.
Lectura -> Abre el fichero en modo lectura no pudiendo escribir en él
Escritura -> Abre el fichero en modo escritura, si hay datos en el fichero los datos
nuevos se añadirían al final del mismo
Lectura/Escritura -> Abre el fichero en modo lectura/escritura, escribe todos los
datos nuevos al final del fichero hasta que el programa mueve el indicador del fichero,
en cuyo momento los datos del fichero se escriben en la posición actual
Para comprobar que el procedimiento Abrir ha tenido éxito se emplea la función
Correcto
diferencia tipo 5
En pseudolenguajeMP la
operación Correcto no existe.
CORRECTO
Correcto
(
ID
)
NOTA: ID debe ser de tipo fichero
La función Correcto es una función lógica que se devuelve verdadero si el fichero se
abrió correctamente y falso en caso contrario.
Para cerrar un fichero se usa el procedimiento Cerrar
CERRAR
Cerrar
(
ID
)
NOTA: ID debe ser de tipo fichero
donde ID es la variable controladora.
El intercambio de información entre el fichero y el algoritmo queda finalizado mediante
este procedimiento, siendo necesario el cierre del fichero.
Ejemplo 2.9.2. Esquema donde se usan las operaciones Abrir, Correcto y Cerrar
algoritmo Copiar_Fichero
variable FicheroTexto Fich_Entrada
...
Abrir(Fich_Entrada, "ejemplo.txt", Lectura)
si Correcto(Fich_Entrada) entonces
......
si no
escribir "No se puede abrir el archivo indicado"
fin si
Cerrar(Fich_Entrada)
parar
fin algoritmo
Creación de un fichero
Para crear un fichero uniforme, no uniforme y de texto se usa el procedimiento
CrearFichero .
CREARFICHERO
CrearFichero
NOM_RISTRA
(
)
NOM_RISTRA
CADENA_CARACTERES
ID
NOTA: ID debe ser de tipo ristra
NOM_RISTRA es una variable o un literal de tipo ristra que contiene el nombre del fichero
físico que se pretende crear.
El fichero es creado con tamaño cero.
Operaciones de entrada/salida
Las operaciones de entrada/salida en los ficheros uniformes y no uniformes son Leer y
Escribir.
Se pueden leer datos del fichero mediante el procedimiento Leer.
LEER
Leer
(
ID
,
EXPRESIÓN
)
NOTA: ID debe ser de tipo fichero
donde ID es la variable controladora y EXPRESIÓN indica el número de caracteres a
leer dentro de ID.
Se puede escribir datos en el fichero utilizando la función Escribir.
ESCRIBIR
Escribir
ID
(
,
EXPRESIÓN
)
NOTA: ID debe ser de tipo fichero
donde ID es la variable controladora y EXPRESIÓN indica el número de carácteres a
escribir dentro de ID.
Otras operaciones con ficheros
Función FinFichero
Esta función lógica sirve para comprobar si se ha alcanzado el final del fichero.
Devuelve verdadero sólo si se ha alcanzado el fin de fichero.
FINFICHERO
FinFichero
(
ID
)
NOTA: ID debe ser de tipo fichero
donde ID es la variable controladora.
Esta función es posible con ficheros uniformes, no uniformes y de texto.
Función Tamaño
Esta función devuelve un entero con el tamaño de un fichero en bytes para los ficheros
no uniformes y para los uniformes su tamaño en número de componentes del tipo base.
TAMAÑO
Tamaño
(
NOTA: ID debe ser de tipo fichero
donde ID es la variable controladora.
ID
)
Procedimiento IRA
Este procedimiento permite situar el cursor en una posición cualquiera del fichero
uniforme o no uniforme.
IRA
IRA
ID
(
EXPRESIÓN
,
)
NOTA: ID debe ser de tipo fichero
donde ID es la variable controladora y EXPRESIÓN indica donde colocar el cursor. Los
valores que puede tomar Pos están comprendidos entre 1 y Tamaño(F) + 1 en bytes o
registros, según sea el fichero. Cuando el cursor se sitúa en esta última posición sólo se
puede hacer un acceso de escritura.
Función Posición
Esta función devuelve un valor entero entre 1 y Tamaño(F) + 1. Indicando la posición
actual del cursor, en bytes o registros, según sea el fichero.
POSICIÓN
Posición
ID_fichero
(
)
donde ID es la variable controladora
Esta función es posible con ficheros uniformes y no uniformes.
Función Renombrar
Esta función lógica devuelve verdadero si el cambio de nombre se realiza con éxito.
RENOMBRAR
Renombrar
(
NOM_ACTUAL
,
NOM_RISTRA
CADENA_CARACTERES
ID
NOTA: ID debe ser de tipo ristra
NOM_NUEVO
)
donde NOM_ACTUAL y NOM_NUEVO son ristras conteniendo, respectivamente, el nombre
actual y el nuevo nombre que se quiere dar al fichero.
Esta función debe realizarse con el fichero cerrado.
La función devolverá falso si existe un fichero con el nombre nuevo que se le quiera dar
al fichero.
Esta función es posible con ficheros uniformes, no uniformes y de texto.
Procedimiento Eliminar
El procedimiento
ELIMINAR
Eliminar
ID
(
)
NOTA: ID debe ser de tipo fichero
elimina el fichero físico cuyo nombre viene dado en la ristra ID
Esta función es posible con ficheros uniformes, no uniformes y de texto
Operaciones específicas de ficheros de texto
Procedimiento LeerLínea
El procedimiento
LEERLÍNEA
LeerLínea
(
ID
,
VARIABLE
)
NOTA: ID debe ser de tipo fichero
donde ID es la variable controladora y VARIABLE una variable de tipo ristra. Este
procedimiento lee una línea completa copiando en VARIABLE el contenido de la misma
sin el carácter fin de línea. Deja el cursor en la primera posición de la siguiente línea.
Si la última línea no tiene carácter de fin de línea y se realiza el procedimiento de
LeerLínea sobre esta línea se producirá un error.
Procedimiento EscribirLínea
El procedimiento
ESCRIBIRLÍNEA
EscribirLínea
ID
(
,
VARIABLE
)
NOTA: ID debe ser de tipo fichero
donde ID es la variable controladora y VARIABLE una variable de tipo ristra.
Este procedimiento escribe el contenido de VARIABLE añadiendo a continuación los
caracteres de fin de línea.
Función FinLínea
La función lógica
FINLINEA
FinLínea
(
ID
)
NOTA: ID debe ser de tipo fichero
donde ID es la variable controladora.
Devuelve verdadero si el cursor se encuentra situado en un fin de línea y falso en caso
contrario.
Procedimiento SaltarLínea
El procedimiento
SALTARLÍNEA
SaltarLínea
(
ID
)
NOTA: ID debe ser de tipo fichero
donde ID es la variable controladora.
Avanza el cursor al comienzo de la siguiente línea.
Procedimiento NuevaLínea
El procedimiento
NUEVALÍNEA
NuevaLínea
(
ID
NOTA: ID debe ser de tipo fichero
donde ID es la variable controladora.
Escribe un fin de línea en el fichero.
)
Ejemplo 2.9.3. El siguiente ejemplo muestra un programa que hace uso de ficheros
algoritmo Copiar_Fichero
variable FicheroTexto Fich_Entrada, Fich_Salida
ristra Línea, NomF_Entrada, NomF_Salida
escribir "Deme el nombre del fichero a copiar"
leer NomF_Entrada
escribir "Deme el nombre del fichero destino"
leer NomF_Salida
Abrir(Fich_Entrada, NomF_Entrada, Lectura)
Abrir(Fich_Salida, NomF_Salida, Escritura)
si Correcto(Fich_Entrada)
si Correcto(Fich_Salida)
mientras no FinFichero(Fich_Entrada) hacer
LeerLínea(Fich_Entrada,Línea)
EscribirLínea(Fich_Salida,Línea)
fin mientras
Cerrar(Fich_Entrada)
Cerrar(Fich_Salida)
si no
escribir "No se puede crear el fichero de salida"
Cerrar(Fich_Entrada)
fin si
si no
escribir "No se puede abrir el fichero de entrada"
fin si
parar
fin algoritmo {Copiar_Fichero}
2.10.- Diferencias entre el pseudolenguaje del proyecto y el
pseudolenguaje especificado en los apuntes de la asignatura
Metodología de la Programación
Las diferencias se pueden clasificar en diferentes tipos, en la especificación del
pseudolenguaje efectuada anteriormente en cada diferencia ha aparecido en superíndice
la palabra diferencia y un número asignado a esa diferencia, ese número corresponde al
tipo de diferencia asociada:
1. Problemas originados por los símbolos del pseudolenguaje que no pertenecen al
código ASCII. Para que puedan escribirse los algoritmos del pseudolenguaje sin
problemas de compatibilidad es conveniente que los caracteres empleados en su
codificación pertenezcan al código estándar ASCII. Además es necesario que los
símbolos aparezcan en los teclados para que sea fácil la codificación de los
algoritmos. La existencia de algunos símbolos que no cumplen esta
característica obliga a hacer pequeños retoques en la gramática original del
pseudolenguaje.
2. Problemas por la ambigüedad de la gramática original del pseudolenguaje.
Aunque para el alumno, los algoritmos escritos en pseudolenguaje pueden
entenderse claramente, el analizador sintáctico encuentra algunas ambigüedades
en la gramática que deben arreglarse.
3. Problemas originados por la flexibilidad de la gramática del pseudolenguaje. El
pseudolenguaje de la asignatura de Metodología de la Programación permite
más símbolos que los permitidos en el pseudolenguaje especificado en este
proyecto, esta flexibilidad se ha restringido ya que entonces el número de
palabras reservadas sería excesivo.
4. Problemas originados al no estar completamente definido en los apuntes de la
asignatura. Hay algunos casos en que los apuntes no llegan a un nivel de detalle
tal que ayuden a la realización del traductor.
5. Problemas originados al no existir un equivalente en C++. Hay algunos casos
en que no existen equivalentes en C++ y se ha tenido que modificar la gramática
de pseudolenguaje de la asignatura de Metodología de la Programación.
Diferencias tipo 1
-
Símbolos del pseudolenguaje no contenidos en el código ASCII. La solución
adoptada es sustituir los símbolos problemáticos por otros parecidos y
compuestos de caracteres ASCII.
Los cambios realizados son los siguientes:
Nombre Símbolo
Símbolo Original
Símbolo en Traductor
Operador Asignación
←
<- (menor < + guión -)
Operador AND
∧
/\ (barra / + barra \ )
Operador OR
∨
\/ (barra \ + barra /)
Operador distinto
≠
#
Operador mayor igual
≥
>=
Operador menor igual
≤
<=
Operador referencia
→
->(guión - + mayor >)
El resto de los operadores del pseudolenguaje permanecen inalterados.
Diferencias tipo 2
-
Comentarios Simples. Los comentarios simples en el pseudolenguaje
desarrollado para este proyecto es mediante doble barra //, mientras que en el
pseudolenguaje de la asignatura de Metodología de Programación es con una
barra /, se ha tomado esta decisión ya que producía ambigüedades con el
símbolo de la división, puesto que era el mismo /.
-
Ristras limitadas. Una ristra limitada en el pseudolenguaje desarrollado para este
proyecto se define como ristra variable[Tamaño], mientras que en el
pseudolenguaje de la asignatura se define como
ristra
[Tamaño],
produciéndose una ambigüedad en el lenguaje al no saber diferenciar cuando se
crea un tipo si lo que se quiere definir es un vector de ristras variables o una
matriz de ristras
Por ejemplo la siguiente instrucción se permite en el pseudolenguaje de los
apuntes:
tipo Elementos es estructura ristra[5][5] fin tipo
pero existe una ambigüedad, porque no se sabe si lo que quiere representar es un
vector de ristras de tamaño variable o bien una matriz de ristras de tamaño
ilimitado.
Para solucionar esta ambigüedad se ha definido las ristras de tamaño variable
como ristra variable[Tamaño] quedando el ejemplo anterior de la siguiente
manera:
Si lo que se pretende es definir una matriz de ristras de tamaño variable:
tipo Elementos es estructura ristra variable[5][5] fin tipo
Si por el contrario lo que se pretende es definir una matriz de ristras de tamaño
ilimitado:
tipo Elementos es estructura ristra[5][5] fin tipo
-
Referencia a un campo en una estructura dinámica. Cuando una variable
puntero es de un tipo compuesto de campos, se refiere en el pseudolenguaje
desarrollado para este proyecto como Q->.NombreCampo, mientras que en los
apuntes de la asignatura Metodología de Programación se refiere como
Q->NombreCampo, se ha tomado esta decisión ya que producía ambigüedades al
ser el siguiente símbolo después del operador de dereferencia un identificador,
no pudiendo ser capaz de distinguir, al no existir limitador de instrucciones, si el
identificador corresponde con una variable de la estructura o un identificador del
programa.
El pseudolenguaje permite llamar a campos dentro de una estructura heterogénea
igual que un identificador del programa.
Por ejemplo si existiera la instrucción:
mes-> <- fecha->mes + mes->fecha->día <- 12
al no existir limitador de sentencias, el traductor no es capaz de saber cual de las
siguientes instrucciones es la correcta:
mes-> <- fecha->mes + mes->fecha->
día <- 12
ó
mes-> <- fecha->mes + mes->
fecha->día <- 12
Por eso se ha tenido que hacer uso del punto, que hace que no existan
ambigüedades, quedando, por ejemplo la instrucción de la siguiente manera:
mes-> <- fecha->.mes + mes->
fecha->.día <- 12
Diferencias tipo 3
-
Operador y y o. En el lenguaje implementado para este proyecto solo se
admitirá como operador AND el símbolo /\ y como operador OR el símbolo
\/. En los apuntes de la asignatura de Metodología de Programación, se admite
los operador ‘y’ y ‘o’, no admitiéndose en este lenguaje.
Diferencias tipo 4
-
Correspondencia entre mayúsculas y minúsculas. En el pseudolenguaje definido
para este proyecto se hace distinción entre mayúsculas y minúsculas.
-
Constantes. En los apuntes de la asignatura de Metodología de Programación no
se especifica cuántos tipos básicos de constantes se permiten, en el
pseudolenguaje desarrollado para este proyecto se permiten declarar cinco tipos
básicos de constantes: constantes enteras, constantes de coma flotante,
constantes de carácter, constantes lógicas y constantes de cadena de caracteres.
-
Secuencias de escape. El pseudolenguaje definido para este proyecto contempla
secuencias de escape, ha parecido útil añadirlas para hacer la interfaz más
amigable con el usuario.
Diferencias tipo 5
-
Ficheros. Operación Abrir y operación Correcto. En C++ la operación Abrir es
un procedimiento (tipo void), mientras que en el pseudolenguaje de la
asignatura Metodología de la Programación es una función, esto ha hecho
necesario modificar la gramática del pseudolenguaje, por lo que se ha añadido la
función Correcto, que sí permite ver si han existido problemas en la apertura.
-
Listas encadenadas. El pseudolenguaje de la asignatura Metodología de la
Programación permitiría la siguiente declaración:
tipo Nodo es estructura
campo ristra Info
campo PLista Siguiente
fin tipo
tipo PLista es puntero<Nodo> fin tipo
en cambio, en el pseudolenguaje para este proyecto la definición la una lista encadenada
se tendría que hacer así:
tipo PLista es puntero<Nodo> fin tipo
tipo Nodo es estructura
campo ristra Info
campo PLista Siguiente
fin tipo
esto es a causa de que C++ no permite en los campos tipos que no hayan sido
declarados.
2.11.- Elementos incluidos en los apuntes de Metodología de la
Programación no traducidos.
En los apuntes de Metodología de la Programación, aparecen ciertos elementos que no
se han implementado, bien por la dificultad que esto generaba, o bien porque no se ha
considerado necesario para el correcto funcionamiento del pseudolenguaje, según los
ejercicios para resolver de la asignatura de Metodología de la Programación.
Los elementos son:
-
Sobrecarga de operadores
-
Sobrecarga de nombres de subprogramas
-
Algoritmos genéricos
Descargar