(Consulta) Optimizando programas omitiendo los saltos de líneas

Iniciado por class_OpenGL, 15 Marzo 2016, 23:42 PM

0 Miembros y 1 Visitante están viendo este tema.

class_OpenGL

Hola, muy buenas. Haciendo un código me ha surgido una duda bastante importante a mi parecer. Según tengo entendido, una buena función es aquella que apenas tiene 'return'. Bien, pues yo quiero hacer una función con un diagrama de flujo como el siguiente:

Realizar Operación
Comprobar si ha salido bien
>> Ha salido mal
     Salir del programa
>> Ha salido bien
Realizar Operación 2º
>> Ha salido mal
     Salir del programa
>> Ha salido bien
Realizar Operación 3º
...
Y así sucesivamente hasta que todas las operaciones hayan terminado con éxito. Eso, en C++, sería algo así:

Código (cpp) [Seleccionar]
bool funcion() {
    Realizar_Operacion_1();
    if(Operacion_1_ha_tenido_exito() == false) {
        return false;
    }

    Realizar_Operacion_2();
    if(Operacion_2_ha_tenido_exito() == false) {
        return false;
    }
    Realizar_Operacion_3();
    ...

    return true;
}


Ahora bien, si tenemos en cuenta lo que dije al principio, este programa no sería el mejor porque tiene muchos saltos de línea 'return'. Entonces, otra forma de solucionarlo es así:

Código (cpp) [Seleccionar]
bool funcion() {
    Realizar_Operacion_1();
    if(Operacion_1_ha_tenido_exito() == false) {
        return false;
    } else {
        Realizar_Operacion_2();
        if(Operacion_2_ha_tenido_exito() == false) {
            return false;
        } else {
            Realizar_Operacion_3();
            ...
        }
    }

    return true;
}


Pero este código se hace muy "ancho" cuando hay muchas operaciones a comprobar.

Entonces, lo último que se me ha ocurrido es lo siguiente:
Código (cpp) [Seleccionar]
bool funcion() {
    bool error = false;
   
    Realizar_Operacion_1();
    if(Operacion_1_ha_tenido_exito() == false) {
        error = true;
    }

    if(error == false) {
        Realizar_Operacion_2();
        if(Operacion_2_ha_tenido_exito() == false) {
            error = true;
        }
    }

    if(error == false) {
        Realizar_Operacion_3();
        if(Operacion_3_ha_tenido_exito() == false) {
            error = true;
        }
    }
   
    ...

    return error;
}


Pero no lo veo muy bien, son muchos 'if' que no sé si son necesarios...

Me gustaría saber si saber de algún método mejor para realizar este tipo de diagramas de flujo... Gracias

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

xiruko

Cita de: class_OpenGL en 15 Marzo 2016, 23:42 PM
Según tengo entendido, una buena función es aquella que apenas tiene 'return'.

Y donde has oido eso?

Siguiendo con tu ejemplo, yo no veo nada de malo en hacer algo así:

Código (cpp) [Seleccionar]

bool funcion()
{
   if (!RealizarOperacion1()) return false;
   if (!RealizarOperacion2()) return false;
   if (!RealizarOperacion3()) return false;
   return true;
}


Saludos!

class_OpenGL

Eso me han comentado, por eso no lo he afirmado... En cualquier caso, creo que el problema reside a nivel de ensamblador, donde la instrucción return "trocea" el programa (sinceramente, no lo sé muy bien, y tampoco sé que puede tener de malo :P)

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

xiruko

Bueno por eso te preguntaba que dónde habías oido eso, por curiosidad.

A nivel de ensamblador, la instrucción return no es más que un jump igual que los ifs, whiles, y cualquier otro bucle, solo que return coge la dirección de salto de la pila.

Pero bueno, a ver si algún experto se pasa y comenta.

Saludos!

MAFUS

El que haya un solo return por función es una de las corrientes de estilo de programación y tiene muchos seguidores, yo me incluyo, aunque no la llevo a rajatabla.
Es como otras como no salir de los bucles con break, no usar goto para la lógica, etc.
Yo digo: todos estos estilos tienen su espacio y su momento. Hay que usar el que, en cada momento,  deje más claro el código a la hora de revisarlo.

class_OpenGL

Comprendo... Pero, para que quede claro, escribir un programa como el que he planteado (el que tiene muchos return), en este caso, no estaría mal, ¿no? Gracias!

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

MAFUS

#6
La primera y la tercera me gustan, la tercera me gusta más. La 2 no la haría.

Tambien puedes encadenar ifs:

bool retValue = false;
if ( func1 ())
if ( func2 ())
if ( func3 ())
   retValue = true;

return retValue;


Queda bonito, visible a simple vista y quitas letras de enmedio.

class_OpenGL

Si, pero el problema de encadenar ifs es que no quiero que las operaciones sigan XD. Me quedaré con la tercera forma, aunque resulte un poco tedioso...

Muchas gracias a tod@s por sus respuestas!

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

engel lex

para hoy dia con lo complejo de los compiladores no simplemente convierten pican e codigo y lo pasan a ensamblador...

primero, los satos de linea son irrelevantes, segundo como dice xiruko, a nivel de codigo son igules (aunque los return no son jmp, sino ret, que son casi iguales solo que el ret sabe donde volver, no tiene que indicarsele)

por otro lado el compilador optimiza el código, así que posiblemente a nivel de compilador tus 3 opciones terminen siendo un código ensamblador casi idéntico... dicho esto, lo importante al programar es que sea cómodamente legible pra que pueda revisarse, corregirse y darle mantenimiento facilmente
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.