Manual de estilo C / C++

[< anterior]       [indice]       [siguiente >]

4. Sentencias de control


4.1 Comparaciones

  • Cuando se utilicen comparaciones entre una variable y una constante, hay que indicar como primer miembro de la comparación la constante.
    Esto se hace asi para prevenir posibles errores (muy difíciles de identificar) por indicar una asignación en vez de una comparación.

    Así la siguiente sentencia sería poco correcto:
    if (nDato == 10) { ... }
    // si por error se pusiera if (nDato = 10) esto no daría un error de compilación,
    // pero provoca malfuncionamiento (por una alteración del valor de nDato).

    En cambio lo correcto sería realizarlo así:
    if (10 == nDato) { ... }
    // si por error se pusiera if (10 = nDato) daría un error de compilación

  • Se aconseja no hacer comparaciones de igualdad con constantes numéricas de punto flotante.
    Es mejor sustituir estas comparaciones de igualdad por desigualdades y utilizar los valores mínimos definidos para tipo DBL_EPSILON y FLT_EPSILON.

    Por ejemplo, la siguiente sentencia:
    // Comparación errónea de variable en punto flotante.
    if (0.1 == fVariable) { ... }

    Es mejor sustituirlo por
    // Comparación correcta con una variable en punto flotantes.
    if (FLT_EPSILON > fabs(fVariable-0.1)) { ... }

[subir]

4.2 Asignaciones

  • En las asignaciones se debe evitar la conversión explícita de tipos de datos. Se aconseja utilizar la conversión implícita de los datos siempre que sea posible.

  • Se aconseja no hacer asignaciones múltiples.
    Las asignaciones múltiples pueden dar lugar a actuaciones erróneas, se puede entener (de manera errónea) que ciertas variables son equivalentes (en cuyo caso sobrarían) y no da legibilidad al código.

    Por ejemplo, el código siguiente:
    // Asignación múltiple (desaconsejada)
    nXSuperior = nYSuperior = (nAnchoPantalla - nAnchoVentana)/2;

    Quedaría más sencillo y comprensible como:
    // Varias asignaciones, mucho más sencillo,
    nXSuperior = (nAnchoPantalla - nAnchoVentana)/2;
    nYSuperior = nXSuperior;

  • Se debe evitar el uso de expresiones de asignación dentro de expresiones condicionales, ya que dificulta la depuración y legibilidad del código.

    Por ejemplo, el siguiente código:
    // asignación en una comparación (desaconsejada)
    if (0.5*PI <= (fAngulo=asin(fRadio))) {...}

    Sería más correcto como sigue:
    fAngulo = asin(fRadio); // Primero asignación
    if (0.5*PI <= fAngulo) {...} // Despues la comparación

[subir]

4.3 Operador ternario ?

  • Es aconsejable utilizar sentencias if en vez del operador ternario ?.
    Este operador ternario ?, propio de C, no presenta ventajas frente a la sentencia if, que es más conocida, de uso extendido y da lugar a un código más legible.

    El siguiente código:
    // Uso del operador ternario (desaconsejado)
    nValorRetorno = (bStatusCorrecto ? hacerUnaCosa() : hacerOtra());

    Quedaría más sencillo para su lectura como:
    // Uso de sentencia if... else..., más correcta
    if (bStatusCorrecto) nValorRetorno = hacerUnaCosa();
    else nValorRetorno = hacerOtra();

[subir]

4.4 Sentencia for

  • La sentencia for se usará para definir un bucle en el que una variable se incrementa de manera constante en cada iteración y la finalización del bucle se determina mediante una expresión constante.

  • Como contador for se utilizarán preriblemente variables de un solo caracter como i, j, k... y se declarará (C++) este contador en el propio bucle for.
    En el bucle del for no se modificará el valor de esta variable contador.
    Por ejemplo:
    for (int i=0; i<nMaximoVueltas; i++)
     {
       // sentencias que no modifican el valor de i
     }

[subir]

4.5 Sentencias while y do while

  • La sentencia while se usará para definir un bucle en el que la condición de terminación se evalúa al principio del bucle.

  • La sentencia do...while se usará para definir un bucle en el que la condición de terminación se evaluará al final del bucle.

  • Al comenzar un bucle while o do...while la expresión de control debe tener un valor claramente definido, para impedir posibles indeterminaciones o errores de funcionamiento

    Un caso de posible indeterminación sería el siguiente:
    int nVariableCount;
    ...
    // codigo que no modifica nVariableCount
    ...
    // No podriamos saber si se inical el bucle
    while (MAXIMO_CONTADOR < nVariableCount) { ... }

    En cambio sería correcto el siguiente codigo:
    int nVariableCount;
    ...
    // codigo que no modifica nVariableCount
    ...
    nVariableCount = 0; // Inicializamos el contador del bucle
    while (MAXIMO_CONTADOR < nVariableCount) { ... }

[subir]

4.6 Sentencia Switch

  • En las sentencias switch hay que incluir siempre la opción default y el break en todas las ramas.

    Un esqueleto de unasentencia switch:
    // Ejemplo de uso del switch
    switch (nCondicion)
     {
      case 1:
       ...
       break;
      case 2:
       ...
       break;
      ...
      default:
       ...
     }

[subir]

4.7 Sentencia goto

  • En general NO USAR SENTENCIAS GOTO.
    Las sentencias goto y otras sentencias de salto similares que rompen la estructura del código provocan una alteración no lineal en el flujo del programa. Atentan seriamente contra la integridad del código. Aparentemente pueden suponer una solución rápida a problemas puntuales, pero conllevan muchos posibles problemas colaterales, imprevisibles y de dificil determinación.

[subir]

4.8 Sentencias break y continue

  • Se aconseja minimizar el uso de las sentencias break y continue (o no usarlas), a favor de utilizar sentencias else.
    Estas sentencias hacen más ilegible el código.

[subir]

4.9 Sentencias exit y return

  • La sentencia exit finaliza la ejecución de un proceso de manera inmediata, forzando la vuelta al sistema operativo.
    Se desaconseja su utilización en cualquier parte del código, siendo preferible controlar el flujo en el proceso mediante bucles condicionales y devolver el control mediante la sentencia return.

  • La sentencia return se utiliza para salir de una función o procedimiento, volviendo al punto en el cual se llamó a dicha función o precedimiento.
    En el código hay que minimizar la utilización de return, sólo tendría que aparecer una vez en cada función o procedimiento, al final del mismo, de manera que se tenga un sólo punto de entrada a la función y un solo punto de salida de la misma.

[subir]

4.10 Bloques

  • Las sentencias if, else, for, while y do while tienen que estar seguidas siempre por un bloque, aunque este bloque esté vacío.

    Por ejemplo, el siguiente código serí erróneo:
    // while sin bloque, desaconsejable
    while( /* Lo que sea */ );

    Sería correcto ponerlo como sigue:
    // While con bloque vacío, correcto
    while( /* Lo que sea */ )
      {
        // vacio
      }

[subir]


[< anterior]       [indice]       [siguiente >] Oscar Valtueña García - "Manual de estilo C / C++"