Programación lógica
MODULO 4
Subalgoritmos
Dividir el problema en subproblemas más pequeños de menor complejidad.
Cada uno de los algoritmos que resuelven estos subproblemas se denominan
subalgoritmos o subprogramas. Cada uno de estos subalgoritmos puede ser
visto como una unidad más pequeña del algoritmo principal que se encarga
de resolver una tarea específica. Al asignar un nombre a esta división o
conjunto de acciones, se la puede invocar desde diferentes secciones del
algoritmo principal por medio del nombre que lo identifica.
Algunas de las ventajas de la utilización de subalgoritmos son:
Una vez implementado un subalgoritmo, si se tuviese que modificar, es
más fácil y rápido efectuar el cambio en el subalgoritmo, en
comparación con si el cambio tuviese que realizarse en el algoritmo
principal.
Se pueden construir librerías propias del usuario con los subalgoritmos
que se desarrollan.
La verificación del correcto funcionamiento de un algoritmo es más
fácil.
Desarrollar programas gradualmente con subalgoritmos permite
probar estos módulos aisladamente antes de integrarlos en el
algoritmo principal.
El diseño de un programa con subalgoritmos hace más sencillo trabajar
en ambientes colaborativos, donde distintos programadores
desarrollan los subalgoritmos y luego se unen en el programa principal.
Funciones y procedimientos
Los subalgoritmos se clasifican en dos, funciones o procedimientos.
Funciones: Una función es un subalgoritmo que retorna un valor al
algoritmo que lo haya invocado.
El programador también puede definir sus propias funciones. La sintaxis
utilizada para definir una función en un algoritmo es la siguiente:
<tipo de dato> funcion <nombre función>(lista de parámetros)
var
Declaración de variables locales
inicio
<acciones> //cuerpo de la función
devolver(<expresión>)
fin-funcion
La definición de una función comienza indicando el tipo de dato del valor que
devolverá la función. A continuación, se define el nombre o identificador de
la función utilizando la palabra reservada funcion. Posteriormente, entre
paréntesis, se coloca la lista de parámetros indicando el tipo de dato y
nombre o identificador de las variables. Los parámetros se separan con coma.
Se pueden definir también variables locales a la función en la sección var. A
continuación, el cuerpo de acciones de la función debe delimitarse con las
palabras reservadas inicio y finfuncion. En la última sección del cuerpo de la
función debe indicarse el valor que se retornará utilizando la sintaxis
devolver(). Para llamar a la función, se debe invocar su nombre con la lista de
parámetros que esta requiere:
nombre_funcion(lista de parámetros actuales)
Procedimiento: Un procedimiento es un subalgoritmo que realiza una
tarea, pero no retorna ningún valor al algoritmo que lo haya invocado.
El programador también puede definir sus propios procedimientos utilizando
la siguiente sintaxis de pseudocódigo:
procedimiento <nombre procedimiento> (lista de parámetros)
var
Declaración de variables locales
inicio
<acciones> //cuerpo del procedimiento
fin-procedimiento
La definición de un procedimiento comienza con la palabra reservada
procedimiento y a continuación el nombre o identificador del procedimiento.
Posteriormente, entre paréntesis, se coloca la lista de parámetros indicando
el tipo de dato y nombre o identificador de las variables. Los parámetros se
separan con coma. Se pueden definir también variables locales al
procedimiento en la sección var. Seguidamente, el cuerpo de acciones del
procedimiento debe delimitarse con las palabras reservadas inicio y fin-
procedimiento. Para llamar al procedimiento, se debe invocar su nombre con
la lista de parámetros que este requiere:
nombre_procedimiento(lista de parámetros actuales)
También se puede utilizar la sintaxis llamar_a para invocar a un
procedimiento:
llamar-a nombre_procedimiento(lista de parámetros actuales)
Declaración de procedimiento: La declaración de un procedimiento no indica
a la computadora que ejecute las instrucciones dadas, sino que indica a la
computadora cuáles son estas instrucciones y dónde están localizadas cuando
sea necesario.
Ámbito de variables
Una variable local es aquella que se define en un subprograma o
subalgoritmo. Estas variables son visibles y existen dentro del subalgoritmo;
fuera de él la variable no existe y no puede ser utilizada. A esto se lo
denomina ámbito de una variable. Se puede declarar más de una variable
local con el mismo nombre siempre y cuando tengan distinto ámbito, es decir,
pertenezcan a distintos módulos o subalgoritmos. Los parámetros de una
función o procedimiento son variables locales.
Una variable global es aquella que está definida en el algoritmo principal y su
ámbito es abierto a todo el programa, incluidos los subalgoritmos. Es decir,
desde un subalgoritmo se puede utilizar una variable global. No puede existir
más de una variable global con el mismo nombre.
Paso de parámetros
Un subalgoritmo puede requerir de información de entrada para poder
realizar su tarea, y está la puede obtener por medio de un paso de
parámetros. Cuando un programa invoca un subalgoritmo, le puede enviar
información por medio de parámetros.
Los parámetros definidos en la cabecera del subalgoritmo se denominan
parámetros formales, y los parámetros que se envían cuando se invoca al
subalgoritmo se denominan parámetros actuales. Cuando se invoca a un
subalgoritmo, los parámetros formales toman el valor de los parámetros
actuales.
El paso de parámetros se clasifica en paso por valor y paso por referencia.
Paso de parámetros: por valor
Cuando se pasan por valor, los parámetros formales de un subalgoritmo
reciben el valor de los parámetros actuales. Cualquier modificación sobre los
parámetros formales no afecta a los parámetros actuales. Cuando el
subalgoritmo finalice, el parámetro actual en la sección del algoritmo que
invocó al subprograma tendrá el mismo valor original sin importar lo que se
realice en el subprograma.
Los valores iniciales se proporcionan copiando los valores correspondientes
en la lista de parámetros actuales.
Paso de parámetros: por referencia
Cuando se utiliza el paso de parámetros por referencia, los parámetros
formales de un subalgoritmo reciben las referencias (dirección de memoria)
de los parámetros actuales. Cualquier modificación que se haga sobre estos
últimos tendrá impacto sobre las referencias y, en consecuencia, sobre los
parámetros actuales en el caso de que sean variables, ya que ambos tipos de
parámetros (actuales y formales) hacen referencia a la misma dirección de
memoria. Cuando finaliza el subalgoritmo, la variable que representa al
parámetro actual del algoritmo que invocó el subprograma tendrá el mismo
valor que el parámetro formal del subprograma.
Se produce el paso de la dirección del parámetro actual. En realidad, se pasa
la posición de memoria. Es decir que una variable pasada por referencia
puede ser modificada dentro del subprograma y producir un efecto en el
programa de llamada. Utilizaremos la palabra reservada var para indicar este
tipo de paso.
Registros
Un registro es una estructura compuesta por diversos tipos de datos que se
agrupan en una misma variable. La utilización de un registro es apropiada
cuando se desea manejar datos relacionados sin importar sus tipos, bajo una
misma unidad. La ventaja en la utilización de un registro en lugar de distintas
variables simples es la de poder acceder mediante un único identificador a la
colección completa de datos. En lugar de tener distintas variables separadas,
con una única variable de tipo registro se accede a la información.
La composición de un registro debe definirse en la sección tipo del algoritmo
y también debe indicarse un nombre a la estructura o tipo de dato definida.
Dentro de la sección delimitada por las palabras reservadas inicio y fin, se
declaran los elementos que componen el registro, que pueden ser de tipo
primitivos (entero, real, lógico, cadena, carácter) o compuestos (array o
incluso otro registro). Los elementos que componen un registro se
denominan campos.
En la sección var, se declaran las variables que se utilizarán en el algoritmo,
por lo tanto, si se utilizará el tipo de dato del registro definido, se deben
indicar las variables que utilizarán dicho tipo de dato.
Algoritmo declaracion_registro
tipo
registro: nombre_registro
inicio
<tipo de dato>: <nombre de variable, nombre de variable, etc.>
<tipo de dato>: <nombre de variable, nombre de variable, etc.>
fin-registro
var
nombre_registro: nombre_variable
inicio
< sentencia ejecutable n>
Fin
Acceso a los campos de un registro
Para acceder a los elementos o campos de un registro, se utiliza el nombre o
identificador de la variable de tipo registro y el operador punto (.), seguido
del nombre del campo al que queremos acceder.
Arreglo de registros
Si se desea manipular una lista de elementos cuyo tipo de dato es de un
registro definido, entonces se puede utilizar un arreglo de registros. En este
caso, cada posición del arreglo corresponde a un registro.
Algoritmo arreglo_de_registros
tipo
registro: reg_alumno
inicio
cadena: nombre, apellido
entero: nota1, nota2, nota3
real: promedio
fin-registro
array[1…10] de reg_alumno: vector
var
vector: listado_alumnos
inicio
<…>
Fin
Si se deseara acceder al campo promedio del tercer registro del arreglo
listado_alumnos, se utilizaría la siguiente sintaxis:
listado_alumnos[3].promedio
Registros (struct, C++)
Un registro es una agrupación de datos, los cuales no necesariamente son del
mismo tipo. Se definen con la palabra “struct”.
Para acceder a cada uno de los datos que forman el registro, tanto si
queremos leer su valor como si queremos cambiarlo, se debe indicar el
nombre de la variable y el del dato (o campo) separados por un punto.
Se puede realizar un array de struct y también colocar struct dentro de otros
struct.