0% encontró este documento útil (0 votos)
45 vistas9 páginas

Subprogramas - Apunte Teoìrico - RevisioÌn 2021

El documento aborda la importancia de los subprogramas en la programación, destacando la evolución de los problemas computacionales y la necesidad de un diseño modular para facilitar la prueba, mantenimiento y reutilización del código. Se explican conceptos clave como la invocación de funciones y procedimientos, el ámbito de las variables, y el pasaje de parámetros por valor y por referencia. Además, se presentan ejemplos prácticos de implementación de subprogramas en C++ para ilustrar estos conceptos.

Cargado por

mauroserranoeco
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
45 vistas9 páginas

Subprogramas - Apunte Teoìrico - RevisioÌn 2021

El documento aborda la importancia de los subprogramas en la programación, destacando la evolución de los problemas computacionales y la necesidad de un diseño modular para facilitar la prueba, mantenimiento y reutilización del código. Se explican conceptos clave como la invocación de funciones y procedimientos, el ámbito de las variables, y el pasaje de parámetros por valor y por referencia. Además, se presentan ejemplos prácticos de implementación de subprogramas en C++ para ilustrar estos conceptos.

Cargado por

mauroserranoeco
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Ing.

Pablo Damián Méndez


Algoritmos y Estructuras de datos – UTN - FRBA

Subprogramas
Los primeros problemas que se modelizaron utilizando una computadora eran problemas
matemáticos, bastante cortos, donde a lo sumo se debía resolver utilizando un método
numérico iterativo.

Estos problemas, podían encararse utilizando lenguajes de bajo nivel, sea binario o assembler.
Sin embargo, a medida que las computadoras y los lenguajes fueron evolucionando también
fueron evolucionando los problemas que se intentaban resolver. Naturalmente, nadie pensaría
en hacer un sistema bancario o de un hospital en assembler, pero la historia es distinta al tener
lenguajes como C, C++ o Pascal o cualquier otro de alto nivel.

El problema es que a medida que aumenta la envergadura del modelo que se intenta plasmar
en un sistema computacional, aparecen ciertas dificultades:

• Prueba del sistema:


Un sistema de decenas de miles de líneas de código es muy difícil de probar. Aun
identificando el error es difícil identificar la línea que posee la falla que lo genera.
Pensemos el siguiente caso. ¿Una fábrica de automóviles verifica cada componente del
vehículo al salir de la línea de ensamlado? No, realiza la prueba de calidad de cada
componente por separado y luego los ensambla para producir un automóvil. Finalmente
hace una prueba integral de la unidad terminada.

• División de trabajo:
Si se debe confeccionar un modelo, un algoritmo de cientos de miles de líneas de código,
¿cómo hacer para dividir el trabajo? Seguramente no sea una única persona la
involucrada.
¿Cuántas personas trabajan en una fábrica de automóviles? ¿Están todas juntas
trabajando sobre la misma parte de un automóvil?

• Mantenimiento:
Si mi modelo consta de, como hemos dicho, cientos de miles de líneas de código. Ante
la necesidad de un cambio, ¿Cómo puedo saber exactamente qué parte debo actualizar
(mejorar), corregir o reemplazar?

• Reutilización:
Si en mi algoritmo utilicé miles de líneas, no es probable que en una parte esté
intentando resolver un problema que ya he resuelto antes? ¿Aún más, si el problema ya
ha sido resuelto para otro modelo, no sería bueno poder reutilizar la solución de una
forma práctica?

Para todo esto se ideó el diseño descendente o top down. El mismo consta en dividir el problema
grande en subproblemas o módulos. Cada módulo puede descomponerse en submódulos. De
esta manera un programa podría tener la siguiente estructura:

1
Ing. Pablo Damián Méndez
Algoritmos y Estructuras de datos – UTN - FRBA

Programa
principal

Módulo 1 Módulo 2 Módulo 3

Figura 1: Diseño modular. Diagrama de bloques

Cada módulo resuelve una parte del programa principal. Este modelo es sólo didáctico, muy
simple. La descomposición del problema debe ser de los niveles que sean requeridos y cada
rama puede tener distinta cantidad de subniveles.

Un caso muy común que suele darse es un programa muy simple que consiste en un menú y
según la opción elegida u otra. Imaginemos un programa que carga un cierto tipo de dato,
supongamos alumnos de la facultad, teniendo la posibilidad de mostrarlos con algún filtro por
pantalla. Además este sistema tiene también un módulo para hacer reportes. En este caso un
posible diagrama podría ser:

Figura 2: Ejemplo de un caso típico de un diseño modular

2
Ing. Pablo Damián Méndez
Algoritmos y Estructuras de datos – UTN - FRBA

Definición de subprogramas en C++


Las funciones son subprogramas que tienen un tipo asignado. Devuelven un valor a través de
su invocación.

Figura 3: función suma

Los procedimientos no devuelven ningún valor a través de su invocación, esto se indica con la
palabra “void”:

3
Ing. Pablo Damián Méndez
Algoritmos y Estructuras de datos – UTN - FRBA

Invocación de subprogramas
Bien, hasta ahora se hemos visto la definición de funciones y procedimientos. La cuestión
pendiente es cómo hacer que se ejecute, formalmente cómo invocarla. Por ejemplo, desde el
main podríamos llamar a la función suma como se muestra en la línea resaltada en rojo del
siguiente código:

Figura 5: Invocación de funciones

En la invocación se realiza una asignación del valor devuelto por la función a una variable del
mismo tipo. Esto es sólo posible con funciones, no con procedimientos ya que estos no
devuelven ningún valor. La asignación del valor de una función también puede ser externa de
salida, es decir que la sentencia “cout << nombrefuncion(parámetros);” es válida.

Op1 y op2 son los parámetros actuales de la función, osea las variables que son pasadas por
parámetro desde la invocación. Mirando la definición de la función en la figura 3 vemos que x
e y son los parámetros formales.

Ámbito de las variables (scope)


Otra clasificación a tener en cuenta es la que se realiza según el ámbito o alcance de las variables.
Las variables declaradas fuera de cualquier subprograma (incluso fuera del subprograma main)
son variables globales y su uso es universal, pueden ser llamadas desde cualquier lugar del
archivo .cpp. No obstante, tener en cuenta que en esta materia está prohibido el uso de
variables globales dentro de un subprograma. Esto es así porque en realidad, utilizar una
variable global en un subprograma rompe su independencia con su contexto y el valor devuelto
puede variar según el estado de una variable externa.

Debemos tener en cuenta que cualquier variable global ocupa espacio en memoria durante toda
la ejecución del programa.

Las variables declaradas en el subprogramas, ya sean los parámetros formales o variables


declaradas internamente, son variables locales del subprograma donde están declaradas. Sólo
pueden ser utilizadas dentro del mismo y sólo ocupan espacio en memoria durante la ejecución
del subprograma.

4
Ing. Pablo Damián Méndez
Algoritmos y Estructuras de datos – UTN - FRBA

Pasaje de parámetros por valor vs pasaje de parámetros por referencia

Cuando una variable se pasa por valor, el parámetro formal tendrá una copia del valor del
parámetro actual (en una dirección de memoria distinta al del parámetro formal). Por este
motivo, los cambios que se realicen sobre el parámetro formal, no serán reflejados sobre el
parámetro actual, ya que la dirección de memoria sobre la que se trabaja es distinta.

Figura 6: pasaje por valor

Cuando una variable se pasa por referencia, el parámetro formal será, en realidad, una
referencia al parámetro actual. Dicho en otras palabras, tanto el parámetro formal como el
parámetro actual están alojados en la misma dirección de memoria. Por lo tanto, los cambios
realizados sobre el parámetro formal, impactarán en el parámetro actual.

Figura 7: pasaje por referencia

El mecanismo del pasaje por valor y por referencia puede verificarse con una prueba muy
simple (se recomienda su implementación a los estudiantes):

5
Ing. Pablo Damián Méndez
Algoritmos y Estructuras de datos – UTN - FRBA

Ejemplos:
1) Escriba una función que calcule la potencia de un número.

6
Ing. Pablo Damián Méndez
Algoritmos y Estructuras de datos – UTN - FRBA

2) Escriba un subprograma que calcule la intersección de dos rectas.

Implementación 1:

La invocación del subprograma sería:

Implementación 2:

Esta implementación debería ser invocada de la siguiente manera:

7
Ing. Pablo Damián Méndez
Algoritmos y Estructuras de datos – UTN - FRBA

Analizando ambas soluciones vemos que el subprograma de la segunda implementación es más


independiente que el de la primera, ya que no se encarga de imprimir él mismo, sino que
devuelve de alguna forma el resultado, dejando al programa que lo invoca que determine qué
hacer con la información devuelta.

3) Escriba un programa que permita al usuario:


• Leer tres números.
• Obtener el promedio.
• Obtener el mayor de ellos.
• Salir del programa.

Planifiquemos un poco. Este problema podríamos dividirlo en las siguientes partes: necesitamos
algo que muestre las opciones, una parte que lea tres números, otra que pueda calcular el
promedio de tres números y finalmente otra que calcule el promedio de tres valores también.

Entonces podríamos realizar los siguientes módulos:

- mayorvalor: que recibirá 3 números y devolverá cuál es el mayor.

- promedio: que también recibirá 3 números y devolverá el promedio de ellos.

- Un módulo para mostrar las opciones (no necesitaría parámetros).

- Otro módulo para hacer la lectura de valores: es importante que modifique los valores de los
parámetros actuales de la invocación, por lo tanto el pasaje tendría que ser por referencia.

- Finalmente el módulo principal o función main: Implementaremos un menú de opciones donde


solamente le permitiremos al usuario que ingrese las opciones solicitadas. En caso que aprete
otro caractér el programa no hará nada y se quedará “esperando” que aprete un caratér
correcto.

8
Ing. Pablo Damián Méndez
Algoritmos y Estructuras de datos – UTN - FRBA

Y Finalmente los ensamblamos en un módulo principal:

También podría gustarte