Cómo formular algoritmos con refinamiento descendente paso a paso: Estudio de caso 3 (estructuras de control anidadas)

Trabajemos otro problema completo. Volveremos a formular el algoritmo utilizando seudocódigo y refinamiento descendente paso a paso, y escribiremos el programa en C para calculadoras CASIO fx-9860G Series. Hemos visto que las estructuras de control pueden ser apiladas una encima de otra (en secuencia), de la misma forma que un niño apila bloques. En este estudio de caso veremos la única otra forma estructurada que en C pueden conectarse estructuras de control, es decir mediante el anidar una estructura de control dentro de otra.

Considere el siguiente enunciado de problema:

Una universidad ofrece un curso que prepara alumnos para el examen estatal de licenciatura para corredores de bienes raíces. El año pasado, varios de los alumnos que terminaron este curso hicieron el examen de licenciatura. Naturalmente, la universidad desea saber qué tan bien salieron sus alumnos en el examen. Se le ha pedido a usted que escriba un programa para resumir los resultados. Se le ha dado una lista de estos cinco alumnos. A continuación de cada nombre se ha escrito un 1 si el alumno pasó el examen y un 2 si no lo pasó.

Su programa deberá analizar los resultados del examen, como sigue:

  1. Introducir cada resultado de prueba (es decir, 1 o 2). Desplegar en pantalla el mensaje "introducir resultado" cada vez que el programa solicite otro resultado de prueba.
  2. Contar el número de resultados de prueba de cada tipo.
  3. Desplegar un resumen de los resultados de prueba, indicando el número de alumnos que pasaron y el número de alumnos que reprobaron.
  4. Si más de 4 alumnos pasaron el examen, imprima el mensaje "aumente la colegiatura".


Después de leer de forma cuidadosa el enunciado del problema, hacemos las siguientes observaciones:


  1. El programa debe procesar 5 resultados de prueba. Se utilizará un ciclo controlado por contador.
  2. Cada resultado de prueba es un número ya sea 1 ó 2. Cada vez que el programa lea un resultado de prueba, el programa debe determinar si el número es 1 ó 2. Probaremos buscando un 1 en nuestro algoritmo. Si el número no es un 1, supondremos que se trata de 2. (Con un ejercicio más adelante analizaremos las consecuencias de esta suposición).
  3. Se utilizarán dos contadores uno para contar el número de estudiantes o alumnos que pasaron el examen y uno para contar el número de alumnos que reprobaron el examen.
  4. Después que el programa haya procesado todos los resultados, debe decidir si más de 4 alumnos pasaron el examen.

Procedamos con refinamiento descendente paso a paso. Empezamos con una representación general en seudocódigo:

Analice los resultados de examen y decida si debe aumentarse la colegiatura

De nuevo, es importante enfatizar que lo general es una representación completa del programa, pero es probable que se requerirán varios refinamientos, antes de que el seudocódigo pueda ser convertido naturalmente en un programa C para la calculadora. Nuestro primer refinamiento es:

Inicializar variables
Introduzca las cinco notas de examen, cuente los aprobados y los reprobados 
Imprima un resumen de los resultados de examen, decida si debe aumentarse la colegiatura

Aquí, también, aunque tenemos una representación completa de la totalidad del programa, se requiere de aún más refinamiento. Debemos ahora fijar ciertas variables específicas. Se requieren de contadores para registrar los aprobados y los reprobados, un contador se utilizará para controlar el proceso del ciclo, y se necesita una variable para almacenar la entrada del usuario. El enunciado en seudocódigo.

Inicializar variables

puede ser refinado como sigue:

Inicializar aprobados a cero 
Inicializar reprobados a cero 
Inicializar alumnos a uno

Note que sólo los contadores y los totales se inicializan. El enunciado en seudocódigo

Introduzca las cinco notas de examen, cuente los aprobados y los reprobados

requiere de un ciclo que introduzca en lo sucesivo el resultado de cada examen. Aquí se sabe por anticipado que existirán precisamente cinco resultados de exámenes, por lo que es apropiado utilizar un ciclo controlado por contador. Dentro del ciclo (es decir, anidado dentro del ciclo) una estructura de doble selección determinara si cada resultado de examen es un aprobado o un reprobado, e incrementará de forma correspondiente los contadores apropiados. Por lo tanto, el refinamiento del enunciado precedente en seudocódigo es

While el contador de alumnos sea menor o igual a cinco 
    Introduzca el resultado del siguiente examen

    if el alumno aprobó
        Añada uno a aprobados 
    else 
        Añada uno a reprobados

    Añada uno a contador de alumnos

Note la utilización de líneas en blanco para destacar la estructura de control if / else, a fin de mejorar la legibilidad del programa. El enunciado en seudocódigo

Imprima un resumen de los resultados de examen y decida si debe aumentarse la colegiatura

puede ser refinado como sigue:

Imprima el número de aprobados 
Imprima el número de reprobados 
Si cuatro o más estudiantes aprobaron 
    Imprima "Aumentar colegiatura"

La segunda refinación completa es

Inicializar aprobados a cero 
Inicializar reprobados a cero 
Inicializar alumnos a uno

While el contador de alumnos sea menor o igual a cinco 
    Introduzca el resultado del siguiente examen

    if el alumno aprobó
        Añada uno a aprobados 
    else 
        Añada uno a reprobados

    Añada uno a contador de alumnos

Imprima el número de aprobados 
Imprima el número de reprobados 
Si cuatro o más estudiantes aprobaron 
    Imprima "Aumentar colegiatura"

Note que también se utilizan líneas en blanco para destacar la estructura while mejorando la legibilidad del programa.

Este seudocódigo está lo suficiente refinado para su conversión a C para nuestra calculadora. 

El programa C para la calculadora y dos ejecuciones de muestra.

/*****************************************************************/
/*                                                               */
/*   CASIO fx-9860G SDK Library                                  */
/*                                                               */
/*   File name : passfail.c                                 */
/*                                                               */
/*   Copyright (c) 2006 CASIO COMPUTER CO., LTD.                 */
/*                                                               */
/*****************************************************************/
#include "fxlib.h"
#include "inout.h"


//****************************************************************************
//  AddIn_main (Sample program main function)
//
//  param   :   isAppli   : 1 = This application is launched by MAIN MENU.
//                        : 0 = This application is launched by a strip in eACT application.
//
//              OptionNum : Strip number (0~3)
//                         (This parameter is only used when isAppli parameter is 0.)
//
//  retval  :   1 = No error / 0 = Error
//
//****************************************************************************

/*Analizar los resultados de examen*/

int AddIn_main(int isAppli, unsigned short OptionNum)
{
    unsigned int key, paso = 0, fallo = 0, alumno = 1, resultado;
    char sresultado[17], spaso[17], sfallo[17];

    Bdisp_AllClr_DDVRAM();

    /* Procesa 5 alumnos; ciclo controlado por contador */
    while (alumno <= 5){
        locate (1,alumno);
        Print((unsigned char*) "1=paso; 2=fallo: ");
        Scan((unsigned char*) sresultado);
        resultado = atoi(sresultado);
     
        if (resultado == 1)      /* if / else anidado en while */
            paso = paso + 1;
        else
            fallo = fallo + 1;
     
        alumno = alumno + 1;
    }  

    Bdisp_AllClr_DDVRAM();

    locate(1,1);
    sprintf (spaso, "%d", paso);  
    Print((unsigned char*) "Aprobo:  ");
    Print((unsigned char*) spaso);

    locate(1,2);
    sprintf (sfallo, "%d", fallo);
    Print((unsigned char*) "Reprobo: ");
    Print((unsigned char*) sfallo);

    if (paso > 4){
        locate(1,3);
        Print((unsigned char*) "Aumentar colegiatura");
    }

    while(1){
        GetKey(&key);
    }

    return 1;
}

//****************************************************************************
//**************                                              ****************
//**************                 Notice!                      ****************
//**************                                              ****************
//**************  Please do not change the following source.  ****************
//**************                                              ****************
//****************************************************************************


#pragma section _BR_Size
unsigned long BR_Size;
#pragma section


#pragma section _TOP

//****************************************************************************
//  InitializeSystem
//
//  param   :   isAppli   : 1 = Application / 0 = eActivity
//              OptionNum : Option Number (only eActivity)
//
//  retval  :   1 = No error / 0 = Error
//
//****************************************************************************
int InitializeSystem(int isAppli, unsigned short OptionNum)
{
    return INIT_ADDIN_APPLICATION(isAppli, OptionNum);
}

#pragma section







Note que se ha aprovechado una característica de C, que permite que la inicialización sea incorporada en las declaraciones. Esta inicialización ocurre en tiempo de compilación.

Consejo

La inicialización de variables en el mismo momento que son declaradas reducen el tiempo de ejecución de un programa.

Observación

La experiencia ha mostrado que la parte más difícil para resolver un programa en una computadora es desarrollar el algoritmo de su solución. Una vez que se haya especificado el algoritmo correcto, el proceso de producir un programa C operacional por lo regular resulta simple.

Observación

Muchos programadores escriben programas sin jamás utilizar herramientas de desarrollo de programas, como es el seudocódigo. Sienten que su meta final es resolver el problema sobre una computadora, y que la escritura de seudocódigo sólo retarda la producción de los resultados finales.


No hay comentarios:

Publicar un comentario