lunes, 11 de junio de 2012

Programación Estructurada



¿Qué es la programación estructurada?

La programación estructurada es un estilo con el cual él se busca que el programador elabore programas sencillos y fáciles de entender. Un programa estructurado está compuesto de segmentos, los cuales puedan estar constituidos por unas pocas instrucciones o por una página o más de codificación. Cada segmento tiene solamente una entrada y una salida, estos segmentos, asumiendo que no poseen lazos infinitos y no tienen instrucciones que jamás se ejecuten, se denominan programas propios.

Una característica importante en un programa estructurado es que puede ser leído en secuencia, desde el comienzo hasta el final sin perder la continuidad de la tarea que cumple el programa, lo contrario de lo que ocurre con otros estilos de programación. Esto es importante debido a que, es mucho más fácil comprender completamente el trabajo que realiza una función determinada, si todas las instrucciones que influyen en su acción están físicamente contiguas y encerradas por un bloque. La facilidad de lectura, de comienzo a fin, es una consecuencia de utilizar solamente tres estructuras de control y de eliminar la instrucción de desvío de flujo de control, excepto en circunstancias muy especiales tales como la simulación de una estructura lógica de control en un lenguaje de programación que no la posea.

Estructuras básicas de control

Estructura secuencial    
 
Normalmente un programa, o una parte del mismo, consisten en una secuencia de instrucciones que se tienen que ejecutar una detrás de otra para realizar una operación. Esto se denomina una estructura secuencial y se compone de un grupo de acciones que se han de realizar todas y en el orden en que están escritas, sin posibilidad de omitir ninguna de ellas.

Por ejemplo, calcular la suma y el producto de dos números:

El problema es muy simple, lo primero que se tiene que hacer es leer dos números A y B. Después, sumarlos, luego multiplicarlos y por último, mostrar los resultados en la pantalla de la computadora. Estas acciones se deben ejecutar en este orden y secuencialmente.

Y el programa en pseudocódigo sería:

Inicio
      Leer A y B
      SUMA = A + B
      PRODUCTO = A * B
      Mostrar SUMA, PRODUCTO
Fin

Se ve que la estructura secuencial expresa perfectamente la solución al problema.


Estructura condicional 
  
Cuando se está construyendo un programa, es normal tener que seleccionar un conjunto de instrucciones entre varias posibles, dependiendo de que se cumpla o no una determinada condición.

Esto se denomina estructura condicional que presenta las variantes:

Estructura condicional simple

En este tipo, si la condición se cumple, se ejecutan un conjunto de acciones, pero si no se cumple no se realiza ninguna acción.

El pseudocódigo de esta estructura es el siguiente:

Si condición
  Entonces
      Acción-1
      Acción-2
      ..........
      Acción-n
Fin_si

Por ejemplo, el problema a resolver consiste en leer por teclado un número, que se denominará NUM, y si es mayor que 20 visualizarlo en la pantalla.

Inicio
    Leer un número (NUM)
    Si NUM > 20
        Entonces
            Mostrar NUM
    Fin_si
Fin

En el ejemplo se señala que si, y sólo si, el valor NUM es mayor que 20 se debe mostrar este valor; pero si no se cumple la condición no se hace nada.

Estructura condicional doble

En este tipo se ejecutará un bloque de instrucciones u otro, dependiendo de que la condición sea cierta o falsa.

El pseudocódigo de esta variante es:

Si condición
  Entonces
      Acción-1
      Acción-2
      .....
      Acción-n
  Si no
      Acción-A
      Acción-B
      .....
      Acción-Z
Fin_si

Por ejemplo: seleccionar y visualizar el mayor de dos números leídos.

Inicio
  Leer A y B
  Si A > B
      Entonces
        Mostrar "El Mayor es:" A
      Si no
        Mostrar "El Mayor es:" B
  Fin_si
Fin

El problema es sencillo: primero se leen los dos números A y B. Si A es mayor que B entonces se visualiza en la pantalla el texto "El Mayor es:" y a continuación el valor de A. Y en caso contrario, es decir, si A no es mayor que B, se visualiza el texto "El Mayor es:" seguido del valor de B. El programa así diseñado es ilustrativo, pero no es totalmente correcto debido a que ambos números pueden ser iguales, y no contempla esta opción, que se comentará posteriormente.

Estructura condicional múltiple

En este caso, dependiendo del valor que tome la variable numérica que controla la condición, se ejecutará una de las n acciones posibles definidas en la estructura.

El pseudocódigo de esta variante es el siguiente:

Según condición
  = 1 Acción-1
  = 2 Acción-2
  .....
  = n Acción-n
Fin_según

Por ejemplo: leer desde el teclado un valor numérico, denominado NUM-CARTA, asociado a una carta de una baraja (del 1 al 12), y mostrar en pantalla el nombre de la carta asociado a ese número.

Inicio
  Leer NUM-CARTA
  Según NUM-CARTA
      = 1 Mostrar "As"
      = 2 Mostrar "Dos"
      ..........
      = 12 Mostrar "Rey"
  Fin_según
Fin

En primer lugar, se lee un número de la carta y, a continuación, dependiendo del valor de la variable NUM-CARTA se mostrará el nombre de la carta. Las estructuras condicionales múltiples derivan de las estructuras condicionales dobles de tipo anidado, es decir, cuando la parte "si no" de una estructura condicional doble se transforma en otra estructura condicional.

Así, el ejemplo de seleccionar y visualizar el mayor de dos números dados debería quedar programado, teniendo en cuenta que pueden ser iguales, como sigue:

Inicio
  Leer A y B
  Si A > B
      Entonces
        Mostrar "El Mayor es:" A
  Si no
  Si A < B
Entonces
        Mostrar "El Mayor es:" B
  Si no
        Mostrar "A y B son iguales"
  Fin_si
Fin

El programa lee dos números A y B, si A es mayor que B muestra A como el mayor, si no pregunta si A es menor que B y en caso afirmativo muestra B como el mayor. Pero si no se cumplen ninguna de las dos condiciones quiere decir que ambos números son iguales.

Transformado en una "estructura condicional múltiple" sería de la forma:

Inicio
  Leer A y B
  Según Comparación (A,B)
      = 1 Mostrar "El Mayor es:" A
      =-1 Mostrar "El Mayor es:" B
      = 0 Mostrar "A y B son iguales"
  Fin_según
Fin

En este caso, se compara A con B mediante la función Comparación (A,B) que devuelve el valor 1,-1,0 según sea el resultado de comparar A con B. Si el resultado de la comparación es igual a 1 quiere decir que A > B, si es -1 indica que A < B y si es 0, señala que A y B son iguales.

Estructura repetitiva    
    
En un programa es normal tener que ejecutar repetidamente un conjunto de instrucciones, dependiendo de que sea cierta o no una condición. La condición se conoce como "condición de salida" y la instrucción se denomina "repetitiva" o "de bucle".

Existen tres versiones:
- Estructura tipo Mientras.
- Estructura tipo Hasta.
- Estructura tipo Para.

Estructura tipo Mientras

En este tipo, el bloque de instrucciones (acciones) se repetirá mientras que la condición sea cierta. La condición se evalúa al comienzo de la estructura. Esto implica que el bloque de instrucciones puede no ejecutarse ninguna vez si la condición de salida es inicialmente falsa.

El pseudocódigo de esta estructura es de la forma:

Mientras Condición
  Acción-1
  Acción-2
  ..........
  Acción-n
Fin_mientras

Por ejemplo: una empresa tienen grabados los datos personales de sus empleados. Se desea imprimir el nombre de aquellos empleados mayores de 55 años.

Inicio
  Leer Empleado
  Mientras Haya-Empleado
      Si Empleado-Edad > 55
        Entonces
            Mostrar Empleado
      Fin_si
      Leer Empleado
  Fin_mientras
Fin

En primer lugar, se leen los datos de un empleado, a continuación se evalúa la condición de salida (Haya-Empleado), preguntando si existen empleados. Si la condición es cierta, porque realmente se han leído los datos de un empleado, entonces se comprueba, con una estructura condicional simple, si la edad del empleado es mayor de 55 años, si lo es se muestra el nombre del empleado. Después se vuelve a leer otro empleado y se retorna a la evaluación de la condición salida del bucle, cuya finalización se realiza cuando no existan más empleado. Obsérvese que si en la primer lectura no hay empleados, el bucle Mientras no se realizará nunca, ya que se comprueba la condición al principio de la estructura Mientras y, sólo si es cierta, se entra en ello.

 Estructura tipo Hasta

En este tipo, el bloque de acciones se repetirá hasta que la condición sea cierta. Dicha condición se evalúa al final de la estructura. Esto implica que el bloque de instrucciones se ejecutará al menos una vez, aunque la condición de salida ya sea cierta al entrar en dicha estructura.

La diferencia fundamental entre ambas estructuras repetitivas es que, en el primer tipo (tipo Mientras), las acciones del bucle no se realizan nunca si la condición de salida del mismo es inicialmente falsa.

Por el contrario, las acciones del bucle, en el segundo tipo (tipo Hasta), se realizarán al menos una vez, ya que la condición se evalúa después de haber sido realizadas dichas acciones.
El pseudocódigo para esta estructura es:

Repetir
  Acción-1
  Acción-2
  ......
  Acción-n
Hasta Condición de Fin_repetir

Por ejemplo: "Visualizar la tabla de multiplicar del número 4".

Inicio
  CONT = 0
  Repetir
      CONT = CONT + 1
      PROD = CONT * 4
      Mostrar PROD
  Hasta CONT = 10
Fin

Para resolver este problema se necesitan dos variables: CONT, que es un contador que almacena cuantos números se han visualizado (es la variable que contiene la condición de salida del bucle); y PROD, que almacena el valor del número a mostrar y que corresponde a los números de la tabla.

Estructura tipo Para

Si el número de repeticiones del bucle (iteraciones) es fijo o se conoce de antemano, se puede utilizar una estructura tipo "Para", en lugar de una estructura tipo "Mientras". La estructura "Para" indica que las acciones del bucle se realizan un número específico de veces y que la estructura controla automáticamente el número de repeticiones.

Para dicho control hay que definir dentro de la estructura el nombre de una variable, su valor inicial, su valor final y un incremento fijo.

Ello quiere decir que inicialmente el bloque de acciones se ejecuta con el valor inicial de la variable, incrementándose este valor en cada iteración con el valor del incremento y finalizan las iteraciones cuando el valor de la variable sobrepasa su valor final. La evaluación de la condición de salida se realiza al comienzo de cada iteración.

El pseudocódigo de este tipo de estructura es el siguiente:

Para VAR desde V1 hasta V2 incremento V3
  Acción-1
  Acción-2
  .....
  Acción-n
Fin_para

Por ejemplo: "Construir un programa en pseudocódigo estructurado que calcule la suma de los números comprendidos entre 1 y 100, ambos inclusive".

Inicio
  SUMA = 0
  Para NUM desde 1 hasta 100
      SUMA = SUMA + NUM
  Fin_para
  Mostrar SUMA
Fin

En el ejemplo se utiliza la variable SUMA para almacenar la suma de los 100 primeros números y la variable NUM para controlar el bucle. Éste empieza en 1 y llega hasta 100 con incremento 1, y cuando NUM sobrepasa el valor 100, indica que ya se han sumado todos los números, con lo que el bucle tipo "Para" termina y en SUMA se tendrá el valor buscado.

La diferencia fundamental entre los tipos "Mientras" y "Para" radica en que en la estructura "Mientras" hay que realizar, mediante instrucciones, la inicialización de la variable que controla el bucle y su incremento; mientras que en la estructura "Para" esto se hace automáticamente.

Así el ejemplo anterior desarrollado con una estructura del tipo Mientras daría lugar al siguiente código:

Inicio
  SUMA = 0
  NUM = 1
  Mientras NUM <= 100
      SUMA = SUMA + NUM
      NUM = NUM + 1
  Fin_mientras
  Mostrar SUMA
Fin

Programación modular

La programación modular es un paradigma de la programación que consiste en dividir un programa en módulos o subprogramas con el fin de hacerlo más legible y manejable.
Se presenta históricamente como una evolución de la programación estructurada para solucionar problemas de programación más grandes y complejos de lo que ésta puede resolver.

Al aplicar la programación modular, un problema complejo debe ser dividido en varios su problemas más simples, y estos a su vez en otros su problemas más simples. Esto debe hacerse hasta obtener subproblemas lo suficientemente simples como para poder ser resueltos fácilmente con algún lenguaje de programación. Ésta técnica se llama refinamiento sucesivo, divide y vencerás ó análisis descendente (Top-Down).

Un módulo es cada una de las partes de un programa que resuelve uno de los subproblemas en que se divide el problema complejo original. Cada uno de estos módulos tiene una tarea bien definida y algunos necesitan de otros para poder operar. En caso de que un módulo necesite de otro, puede comunicarse con éste mediante una interfaz de comunicación que también debe estar bien definida.

Si bien un módulo puede entenderse como una parte de un programa en cualquiera de sus formas y variados contextos, en la práctica se los suele tomar como sinónimos de procedimientos y funciones. Pero no necesaria ni estrictamente un módulo es una función o un procedimiento, ya que el mismo puede contener muchos de ellos, no debe confundirse el término "modulo" (en el sentido de programación modular) con términos como "función" o "procedimiento", propios del lenguaje que lo soporte.

Siempre la misma: dividir un programa grande en un conjunto de subprogramas o funciones más pequeñas que son llamadas por el programa principal; éstas a su vez llaman a otras funciones más específicas y así sucesivamente. 

Ventajas

La división de un programa en unidades más pequeñas o funciones presenta entre otras las ventajas siguientes:

1.  Modularización. Cada función tiene una misión muy concreta, de modo que nunca tiene un número de líneas excesivo y siempre se mantiene dentro de un tamaño manejable. Además, una misma función (por ejemplo, un producto de matrices, una resolución de un sistema de ecuaciones lineales, ...) puede ser llamada muchas veces en un mismo programa, e incluso puede ser reutilizada por otros programas. Cada función puede ser desarrollada y comprobada por separado.

2.  Ahorro de memoria y tiempo de desarrollo. En la medida en que una misma función es utilizada muchas veces, el número total de líneas de código del programa disminuye, y también lo hace la probabilidad de introducir errores en el programa.

3.  Independencia de datos y ocultamiento de información. Una de las fuentes más comunes de errores en los programas de computador son los efectos colaterales o perturbaciones que se pueden producir entre distintas partes del programa. Es muy frecuente que al hacer una modificación para añadir una funcionalidad o corregir un error, se introduzcan nuevos errores en partes del programa que antes funcionaban correctamente. Una función es capaz de mantener una gran independencia con el resto del programa, manteniendo sus propios datos y definiendo muy claramente la interfaz o comunicación con la función que la ha llamado y con las funciones a las que llama, y no teniendo ninguna posibilidad de acceso a la información que no le compete.

1 comentario:

  1. Genial!!! entendí algunas cositas que no podía hace un buen rato, gracias.

    ResponderEliminar