2012-04-25 35 views
6

Estoy trabajando en algunos deberes y quería saber si hay algo así como demasiados bucles anidados. ¿Hay inconvenientes en anidar varios bucles while? Si es así, ¿cómo podría uno refactorizar el fragmento de código que tengo a continuación?¿Hay problemas con la anidación de muchos ciclos while?

A continuación se muestra un código para leer un archivo una línea a la vez, analizar los campos delimitados por algunos delimitadores definidos y eliminar el espacio en blanco inicial antes de imprimir en la consola.

// Read the file one line at a time 
while (fgets(lineStr, MAXLINELENGTH, fp) != NULL) 
{ 
    charPtr = strtok(lineStr, DELIMITERS); 

    // Loop until line is parsed 
    while (charPtr != NULL) 
    { 
     // Skip past leading whitespace 
     while (isspace(*charPtr)) 
      charPtr++; 

     puts(charPtr); 
     charPtr = strtok(NULL, DELIMITERS); 
    } 
} 
+6

No, no hay problema en los bucles anidados. – pmg

+1

Aunque, es posible que desee encapsular algunos de ellos en métodos que reflejen lo que están haciendo; el último se convierte en 'skipSpaces()', o algo así. –

+0

si la entrada puede contener caracteres negativos (* con valores mayores que 127 *) es posible que desee convertir el argumento a 'isspace' para evitar un comportamiento indefinido:' isspace ((char sin signo) * charPtr) ' – pmg

Respuesta

6

Esto es realmente un tema bastante subjetivo. En mi opinión, no hay nada fundamentalmente erróneo en tres bucles while anidados, pero está llegando al límite de aceptabilidad. Si agregara uno o dos niveles más de anidación, en mi opinión, cruzaría el límite de lo que es razonable esperar que el lector comprenda. El cerebro humano solo puede manejar tanta complejidad en cualquier punto del tiempo.

Algunas personas podrían argumentar, en contra de mi opinión, que no debería haber más de un nivel de anidación en una función, y que las funciones no deberían contener más de 10 líneas de código. El argumento contrario es que dicha política puede dar como resultado un código disjunto más fragmentado. Mi regla de oro es que si no se puede pensar en un buen nombre de función para un fragmento de código, entonces tal vez ese trozo de código no esté destinado a funcionar solo como una función.

En cuanto a las formas en que puede romper esta función, hay un par de opciones obvias.

  1. Extraiga el cuerpo del while más externo en una función separada. Esa función extraída procesaría una sola línea. Sería fácil de nombrar y claro para leer.
  2. Extraiga el lazo while que omite espacios en blanco en una función separada. Eso sería fácil de nombrar y haría que tu código sea más fácil de leer. Quitaría el comentario de espacio en blanco porque el nombre de la función extraída lo haría innecesario. Probablemente valga la pena hacerlo

Si aplicó estas ideas, entonces su código podría ser un poco como esto:

char* skipWhitespace(char* str) 
{ 
    while (isspace(*str)) 
     str++; 
    return str; 
} 

void parseLine(char *lineStr) 
{ 
    charPtr = strtok(lineStr, DELIMITERS); 
    while (charPtr != NULL) 
    { 
     charPtr = skipWhitespace(charPtr); 
     puts(charPtr); 
     charPtr = strtok(NULL, DELIMITERS); 
    } 
} 
...... 
while (fgets(lineStr, MAXLINELENGTH, fp) != NULL) 
    parseLine(lineStr); 

Tenga en cuenta que la refactorización y la denominación de métodos extraídos hace que los comentarios un poco superfluo y me los quitó. Otra buena regla empírica es que si necesita comentar un código demasiado, entonces quizás todavía no esté bien factorizado.

En última instancia, realmente no hay reglas duras y rápidas, y todo se reduce a juicio y preferencia personal. En mi opinión, el código en la pregunta es muy claro y legible, pero la versión refactorizada es un poco más clara, en mi opinión.

Descargo de responsabilidad: No hago ningún comentario sobre la corrección o no del código. Simplemente ignoré ese aspecto.

+1

Me gusta su regla empírica 'sin nombre, sin función'. Obviamente solo es una guía, pero trae a casa un buen punto: si no puedes describir lo que haría la función, ¡probablemente no necesites que sea una función! – corsiKa

+0

Gracias por el código refactorizado. Tendrá que preguntar al profesor si prefiere que el código sea como es o si prefiere que los bucles anidados individuales se refactoricen en sus propias funciones. Me gusta la idea de no tener comentarios porque el nombre de la función es lo suficientemente claro como para transmitir la idea. – Peter

+0

¿Cuál prefieres? Al menos debe tener una opinión y estar preparado para discutir de una manera u otra cuando vaya a su prof. –

3

La única desventaja real es la legibilidad, para la cual no existen realmente reglas estrictas sobre ... aunque más de 3 nidos generalmente irritarán a cualquier otra persona con la que estés trabajando. Como dijo otro cartel, a veces es mejor romper el nido moviendo el lazo a otra función, pero lo que tienes aquí es perfectamente legible para mí, y esa es la única métrica real que existe; opinión subjetiva pura :)

0

Como se mencionó anteriormente, esto es relativamente subjetivo. Sin embargo, la forma que anida los bucles puede tener un impacto directo en el rendimiento de su código.Considere la programación de con memoria caché. Es decir, desea organizar el código de tal forma que el procesador pueda realizar una precarga (es decir, predecir) el siguiente bloque de datos en la memoria caché antes de que lo necesite. Esto permitirá más visitas de caché y tiempos de acceso a la memoria más rápidos.

Tenga en cuenta que esto no es particularmente importante para su ejemplo, sin embargo, si está haciendo muchos accesos a la memoria, esto puede significar un aumento o disminución significativa del rendimiento. Si está atravesando una matriz multidimensional en forma de columna en una arquitectura de fila mayor, es posible tener muchas fallas de caché (tenga en cuenta que una falta de caché es muy costosa en términos de tiempo real).

Por lo tanto, anidar los bucles no es necesariamente malo, pero definitivamente puede tener efectos notables en el rendimiento, especialmente después de un número arbitrario n bucles.

Cuestiones relacionadas