Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


Programación Modular: Conceptos y Aplicaciones, Monografías, Ensayos de Programación Java

Programación modular en el ámbito del lenguaje de programacion de c ++.

Tipo: Monografías, Ensayos

2019/2020

Subido el 21/06/2020

joan-santomas
joan-santomas 🇩🇴

1 documento

1 / 17

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
Subprograma
principal
Módulo I Módulo II
Módulo I.I Módulo I.II Módulo II.I
1
Introducción
La programación modular está presente desde los primeros tiempos de la programación
como disciplina. De hecho existía programación modular antes de existiera programación
estructurada para poder abordar problemas complejos.
Cuando se requieren resolver problemas más complejos, en los que el número de
instrucciones aumenta, existen técnicas que permiten resolverla de forma eficiente estos
problemas, facilitando al programador la construcción de la solución.
Se puede definir a la programación modular como aquella que usa el concepto de dividir
un problema complejo en sus problemas más pequeños, hasta que estos sean fáciles de
tratar y resolver por separado. Así la solución de los su problemas en conjunto dan como
resultado la solución del problema completo (López Román, 2003).
La programación modular permite:
a) Dividir la complejidad de un problema convirtiendo problemas complejos en un
conjunto de problemas más simples y por tanto más sencillos de implementar.
b) Reutilizar el código de un programa en cualquier momento de la ejecución del
mismo.
Evidentemente la división de un problema en módulos no tiene por qué ser ni única ni
obligatoria, pero si es claramente aconsejable a la hora de abordar un problema para lo
cual que se aplican diversos conceptos y técnicas entre las que se encuentran el diseño
descendente, el proceso de modularización y el paso de parámetros, por mencionar
algunos. A continuación se abordaran cada uno de ellos.
Diseño descendente.
Es una técnica que permite diseñar la solución de un problema con base en la
modularización o segmentación dándole un enfoque de arriba hacia abajo (Top Down
Design). Esta solución permite dividir el problema en módulos que se estructuran e
integran jerárquicamente (ver figura 1), como si fuera el organigrama de una empresa
(López Román, 2003).
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff

Vista previa parcial del texto

¡Descarga Programación Modular: Conceptos y Aplicaciones y más Monografías, Ensayos en PDF de Programación Java solo en Docsity!

Subprograma principal Módulo I Módulo II Módulo I.I Módulo I.II^ Módulo II.I 1

Introducción

La programación modular está presente desde los primeros tiempos de la programación como disciplina. De hecho existía programación modular antes de existiera programación estructurada para poder abordar problemas complejos. Cuando se requieren resolver problemas más complejos, en los que el número de instrucciones aumenta, existen técnicas que permiten resolverla de forma eficiente estos problemas, facilitando al programador la construcción de la solución. Se puede definir a la programación modular como aquella que usa el concepto de dividir un problema complejo en sus problemas más pequeños, hasta que estos sean fáciles de tratar y resolver por separado. Así la solución de los su problemas en conjunto dan como resultado la solución del problema completo (López Román, 2003). La programación modular permite: a) Dividir la complejidad de un problema convirtiendo problemas complejos en un conjunto de problemas más simples y por tanto más sencillos de implementar. b) Reutilizar el código de un programa en cualquier momento de la ejecución del mismo. Evidentemente la división de un problema en módulos no tiene por qué ser ni única ni obligatoria, pero si es claramente aconsejable a la hora de abordar un problema para lo cual que se aplican diversos conceptos y técnicas entre las que se encuentran el diseño descendente, el proceso de modularización y el paso de parámetros, por mencionar algunos. A continuación se abordaran cada uno de ellos. Diseño descendente. Es una técnica que permite diseñar la solución de un problema con base en la modularización o segmentación dándole un enfoque de arriba hacia abajo (Top Down Design). Esta solución permite dividir el problema en módulos que se estructuran e integran jerárquicamente (ver figura 1), como si fuera el organigrama de una empresa (López Román, 2003).

2 1.1 Módulo. Es un segmento, rutina, subrutina, subalgoritmo o procedimiento que puede ser definido dentro de un algoritmo mayor con el propósito de ejecutar una tarea específica, pudiendo ser llamado o invocado desde el módulo principal cuando se requiera. Este enfoque de segmentación o modularización es útil:  Cuando existe un grupo de instrucciones o una tarea específica que debe ejecutarse en más de una ocasión.  Cuando un problema es complejo o extenso, entonces la solución se “divide” o “segmenta” en módulos que ejecutan “partes” o tareas específicas. Dicha solución se organiza y divide en partes más pequeñas que sean fácilmente manejables y que, lógicamente, puedan ser separadas; así cada una de estas partes se dedica a ejecutar una determinada tarea, lo que redundará en una mayor concentración, entendimiento y capacidad de solución a la hora de diseñar la lógica de cada una de estas. Diseño descendente con pseudocódigo. Cuando el enfoque de diseño descendente se utiliza de manera conjunta con la técnica del pseudocódigo, se logra una herramienta de diseño de algoritmos (programas) muy poderosa. A continuación se explica el procedimiento para hacerlo:

  1. Se tiene un problema ya analizado.
  2. Se diseña la estructura general del algoritmo utilizando el diseño descendente, es decir, se definen los módulos que integrarán el algoritmo.
  3. Se toma cada módulo y se diseña su lógica utilizando pseudocódigo. La llamada de un módulo en pseudocódigo se hace siguiendo la siguiente sintaxis: Llamar NombreModulo Donde: Llamar : identifica la acción de llamar o invocar a un módulo NombreModulo : es el nombre del módulo que se está llamando Formato general de un algoritmo con módulos: Parte 1. Se tiene el encabezado del algoritmo. Es obligatorio. Parte 2. Se tiene una parte de declaraciones globales, donde se pueden declarar  Constantes  Tipos  Variables

Problema en términos de la

solución general

Módulos más pequeños

Módulos que ejecuten

Tareas o funciones

específicas

Modularización funcional. Los bloques de código independientes del programa principal que se han definido como módulos tienen siempre una connotación funcional. Esto quiere decir que estos segmentos realizan alguna tarea específica por lo que cuando se definen estos subprogramas, lo que se hace es identificar actividades concretas y desarrollar el subprograma para resolverlas. Una ventaja al dar solución a los problemas mediante la modularización es que se pueden “encapsular” las distintas tareas que se quiere realice el programa, logrando así colocar como una unidad todas las instrucciones relevantes para una sección específica del programa, lo que también permite que cuando existe la necesidad de realizar algún cambio en dichas instrucciones se tenga claridad a donde dirigirse para hacer ese cambio y no haya necesidad de analizar de manera completa todo el desarrollo, lo que hace que los programas sean fáciles de probar y mantener. Lo anterior permite que si se logra tener un programa que resuelva una tarea específica y este proceso está suficientemente probado, entonces una vez que está programado, es posible usarlo tantas veces como sea necesario con la única condición de conocer los datos que lo alimentan y los resultados que arroja. Por otro lado, esta condición evita que se repita el código muchas veces y que si se comete un error de programación en este segmento del código solo se tenga que corregir una vez. Estos bloques de código o subprogramas reciben distintas denominaciones en los diferentes lenguajes, por ejemplo en los no orientados a objetos la división tradicional distingue entre:  Subprogramas, subrutinas o procedimientos, si pueden devolver más de un valor.  Funciones, si devuelven un único valor a través de su identificador. La estructura del programa en función de sus módulos se puede representar con los denominados diagramas de estructura, que son herramientas típicas del diseño estructurado y forman parte de una completa metodología de trabajo. Estos diagramas son una representación en forma de árbol jerárquico de la estructura del software, donde los diferentes módulos se representan como cajas rectangulares. La relación de invocaciones de unos módulos a otros se representan en estos diagramas por medio de flechas y el sentido de las flechas representa el orden de invocación de los módulos.

Cohesión y acoplamiento.

Los módulos deben cumplir dos características básicas para ser candidatos a una buena división del problema.

Algoritmo GLOBALES num: Entero Módulo principal num ← 0 Llamar resultado Escribir num Fin Módulo principal Módulo resultado num ← El resultado al escribir Fin Módulo resultado el valor de num sería 1 Todos los módulos reconocen la variable num como global y la pueden cambiar Declaración de num como variable global Otro aspecto que destaca al usar modularidad es el acoplamiento que mide el grado de relación de un módulo con los demás. Con un menor acoplamiento el módulo es más sencillo de diseñar, programar, probar y mantener. En el diseño estructurado, se logra bajo acoplamiento reduciendo las interacciones entre procedimientos o funciones, reduciendo la cantidad y complejidad de los parámetros y disminuyendo al mínimo los parámetros por referencia.

Alcance de las variables.

Cuando se consideran varios módulos de software y no un solo programa principal, se pueden declarar variables tanto en el contexto global del algoritmo, como de manera local en cada módulo a lo que se le conoce como alcance de las variables, en otras palabras esto permite identificar la zona del programa donde una variable es accesible “conocida”. Desde este punto de vista, las variables pueden ser de dos tipos: locales o globales. Variables globales. Son las que son accesibles desde cualquier punto del programa y se pueden usar desde cualquier módulo o subprograma, esto lleva a considerar que la variable puede usarse en cualquier parte del programa y su valor se puede alterar incontroladamente, y si posteriormente es necesario usar la variable en otra parte del programa con su valor original, se tendrá un error. El punto donde se da el error es fácil de localizar, pero no lo es tanto el origen del mismo. Este tipo de efectos colaterales produce errores cuyo origen es difícil de trazar y localizar: La programación modular sugiere que se evite el uso de variables globales (ver figura 6). 4.1 Variables locales.

Las variables locales sólo existen en un ámbito determinado del programa, por ejemplo en un subprograma o en un bloque de sentencias. Solo pueden ser utilizadas en el módulo donde fueron definidas Entonces si son analizados los conceptos de variables globales y locales, es posible resumir que cuando se usan variables locales, éstas son independientes de las globales y de las de otros módulos. Parámetros. Entre los módulos que componen la estructura completa de un problema, se establece una serie de comunicaciones a través de determinadas interfaces (llamadas a los módulos) que permiten el paso de información de un módulo a otro así como la trasferencia del control de la ejecución del programa. Un método puede aceptar información para usarla en su cuerpo de sentencias. Esta información es suministrada en forma de literales, variables pasadas al método a través de su cabecera y cada uno de estos elementos de información se denomina parámetro. De manera más formal se puede definir un parámetro como un valor que se pasa al método cuando éste es invocado. La lista de parámetros en la cabecera (al inicio) de un método especifica los tipos de los valores que se pasan y los nombres por los cuales el método se referirá a los parámetros en la definición del método.  En la definición del método los nombres de los parámetros aceptados se denominan parámetros formales.  En las invocaciones al método desde algún punto del programa, los valores que se pasan al método se denominan parámetros actuales (reales). Algoritmo LOCALES num:Entero Módulo principal num ← 0 Llamar resultado Escribir num Fin Módulo principal Módulo resultado num: Entero num ← Fin Módulo resultado . El resultado al escribir el valor de num sería 0 Al momento de declarar num dentro de un módulo, es una variable local y solo tiene efecto dentro de ese módulo Declaración de num como variable global

Para efectos prácticos si se realiza una modificación de ese valor dentro del módulo, la modificación se mantiene al salir del mismo y la diferencia con el paso por valor, es que el que el módulo maneja una copia del valor original, y las modificaciones realizadas dentro del método no afectan a la variable externa. Explicación: Se define a la variable X en el módulo principal, la cual tiene su contenido en la memoria, y se le coloca 0. Contenido X Cuando se llama al Módulo Cambiar, se conecta X y Y vía parámetro por referencia, lo que hace que sean sinónimos, es decir, que Y utilice la misma dirección de memoria que X. Contenido X Y Cuando Y se le colca 1 ¿qué le pasa a X? Contenido X Y A X le pasa lo mismo que le sucede a Y; es decir, a Y se le coloca 1 e indirectamente le sucede lo mismo a X, porque manejan el mismo contenido en la memoria (López Román, 2003).

Funciones definidas por el usuario.

Cuando existe un cálculo que será usado de manera repetida a lo largo del programa en distintos momentos se implementan funciones que el usuario define. Una función es muy parecida a los módulos, con la diferencia de que sólo devuelve un valor de un tipo de dato simple. El nombre de la función puede estar seguido por uno o más parámetros encerrados entre paréntesis, a continuación se detallan como son definidas: 0 1 0

Sintaxis: Función Nom_Función (Parámetros): Tipo de dato Declaraciones Acción 1 ….. Acción N Fin Función Nom_Función Donde: Función : Indica que se está definiendo una función. Declaraciones : se pueden definir constantes y variables. Nom_Función : Es el nombre de la función que será manejada como cualquier variable de tipo simple. Parámetros : Es la lista de variables de entrada que sirven como base para hacer los cálculos en la función. Tipo de dato : Es el tipo de dato que regresa la función. Para llamar una función se indica el nombre de la función y entre paréntesis el parámetro o parámetros que se envían (ver Anexo II). Nom_Función (lista de parámetro(s))

Módulos de programa en C.

En C la técnica de programación modular se implementa mediante la utilización de funciones. Una función permite agrupar un conjunto de instrucciones en un bloque que típicamente realizara una tarea elemental. Por lo general en C, los programas se escriben combinando nuevas funciones que el programador diseña, con funciones “preempacadas”, disponibles en la biblioteca estándar de C (Deitel & Deitel, 2004). Como se indicó anteriormente para dar solución a un problema particular es necesario identificar previamente las tareas elementales que debe realizar el problema, y posteriormente estas se implementarán como funciones. Las funciones permiten modularizar un programa y se invocan mediante una llamada de función que específica el nombre de la misma y proporciona

#include <stdio.h> main() { float x, y; printf("Cantidad a calcular el impuesto"); scanf("%f", &x); printf("Cantidad con IVA incluido %.2f \n", cal_imp(x)); return 0; } Invocación de la función Definición o cuerpo de la función Prototipo o cabecera de la función float cal_imp (float); float cal_imp (float i) { return (i*1.16); }  Se pueden trasferir un conjunto de datos distinto cada vez que se llama a la función (entorno de ejecución de una función), obteniendo resultados diferentes en cada uno de los casos. La estructura de una función en C se divide en:Cabecera o prototipo de la función: Se define el nombre de la función y el modo en el que se va a realizar la trasferencia de información con dicha función (argumentos de entrada y tipo de dato de salida).  Cuerpo de la función : Se encuentra encerrado entre llaves y está formado por dos partes, la primera contiene la declaración de las variables que se van a emplear en la función y la segunda un conjunto de instrucciones que realizan la tarea para la cual se diseñó la función, empleando los datos en los argumentos formales de la cabecera. La declaración de variables (si existe) en el cuerpo de la función debe proceder siempre a las instrucciones del mismo. El control de la ejecución de programa se pasará automáticamente a la función invocadora una vez que se haya terminado de ejecutar las instrucciones que forman el cuerpo de la función invocada. Finalmente las funciones se utilizan normalmente en un programa, escribiendo el nombre de la función seguido por un paréntesis izquierdo y a continuación por el argumento (o una lista de argumentos separados por comas) de la función, seguida por un paréntesis derecho (ver figura 8).

Prototipo de la función. Un prototipo de función le indica al compilador el tipo de dato que regresa la función, el número de parámetros que la función espera recibir, los tipos de dichos parámetros, y el orden en el cual se esperan dichos parámetros. El compilador utiliza los prototipos de funciones para verificar las llamadas de función. Cuerpo de la función. El formato de una definición de función como se ha mostrado en el ejemplo anterior es: tipo_de_valor_de_regreso nombre_la_función (lista de parámetros) { Declaraciones Enunciados } Donde: tipo_de_valor_de_regreso : El tipo de valor de regreso el valor que una función devolverá. nombre_de_la_función : Es cualquier identificador valido. lista_de_parámetros : lista separada por comas que contiene las declaraciones de los parámetros recibidas por la función al ser llamada. Declaraciones y Enunciados : Forman el cuerpo de la función. El cuerpo de la función también se conoce como un bloque. Un bloque es un enunciado compuesto que incluye declaraciones. Las variables pueden ser declaras en cualquier bloque y los bloques pueden estar anidados. Bajo ninguna circunstancia puede ser defina una función en el interior de otra función.

evita efectos colaterales accidentales que obstaculizan de forma importante el desarrolla de sistemas correctos y confiables de software. La llamada por referencia debe ser utilizada solo en funciones llamadas confiables, que necesitan modificar la variable original (Deitel & Deitel, 2004). Al realizar llamadas por valor se realiza una copia del valor de la variable y esta copia se pasa a la función llamada. De tal forma que los cambios a la copia de la función llamada no afectan el valor contenido en la variable original (ver anexo III). En C, todas las llamadas son llamadas por valor. Sin embargo es posible simular la llamada por referencia mediante la utilización de operadores de dirección y de indirección (Deitel & Deitel, 2004). Llamadas por referencia. En muchos casos cuando se requiere modificar una o más variables del llamador o bien es necesario pasar un objeto de datos grande y evitar así la sobrecarga de pasar un objeto en llamada por valor, C permite “simular” las llamadas por referencia. Es frecuente emplear apuntadores y el operador de indirección^4 para simular las llamadas por referencia^5 (Deitel & Deitel, 2004). C implementa esta funcionalidad con el uso de referencias. Una referencia es un alias a una localización de memoria, es decir permite referirse a la misma zona de almacenamiento que otro valor. El paso de valores por referencia permite tener parámetros que se refieran a las mismas posiciones de memoria que los parámetros reales usados en al llamada. Por esta razón, toda modificación que se realice sobre los parámetros formales pasados por referencia se aplicará a los parámetros reales. Para indicar que un determinado parámetro se pasa por referencia, el nombre del parámetro debe ir precedido del símbolo &. Al simular estas llamadas lo que se hace es pasar a la función las direcciones de los argumentos mediante el operador de dirección “&” a la variable que modificara el valor (ver anexo IV). Diferencias entre paso por valor y paso por referencia.  En el paso por valor se realiza una copia del valor del parámetro en el momento de la llamada. Para datos de gran tamaño esto puede representar un problema de eficiencia.

 En los parámetros pasados por valor, si se hacen cambios a los parámetros formales, los parámetros originales no son modificados.  En los parámetros pasados por referencia, la llamada debe usar como parámetros reales valores de otra forma no podrán ser modificados.  En el paso por referencia lo que se copia es una dirección aunque el parámetro en cuestión se refiera a un tipo estructurado (Fatos, Martin Prat, Vazquez, Gómez, & Molinero, 2006)