[C con Clase] Duda Teórica

Steven Davidson srd4121 en njit.edu
Mar Ene 17 12:14:13 CET 2012


Hola Guillermo,

2012/1/16 Guillermo Rolando Roig Carralero <grroig en estudiantes.uci.cu>:
> Saludos a todos:
> Mi duda es simple: Sé que para un ciclo que puede detenerse antes de llegar
> al límite que se le ha puesto es recomendado usar "while", ¿pero existe
> algún inconveniente en usar "for" y dentro de este las sentencias "break" o
> "return" para detenerlo?¿Puede esto tener alguna influencia en el
> funcionamiento de un programa simple?
>

La verdad es que ya te han contestado, así que voy a agregar a lo dicho.

Como existen 3 tipos diferentes de bucles en C/C++, es preferible
elegir el más adecuado según el diseño. EL bucle 'for' sirve para
realizar cierta cantidad de iteraciones desde una cota inferior a una
superior. Los bucles 'while' y 'do/while' son más parecidos entre sí,
y se especializan en iterar basándose en una condición. El compilador
puede optimizar cada bucle, según la situación, por lo que es una
buena costumbre elegir correctamente el tipo de bucle que uno quiere y
necesita. Por otro lado, el lenguaje ofrece bastante flexibilidad
acerca del uso del bucle 'for'.

Personalmente, no me gusta usar 'break' para salirme de un bucle. Se
suele usar alguna condición a comprobar para luego salirse del bucle;
esto lo veo como una forma perezosa de resolver el problema. En estos
casos, suelo usar variables booleanas y comprobar su estado en el
bucle. Por ejemplo,

for( int i = 0; i < 100; i++ )
  if( aEnteros[i] < 0 )
    break;
  else
    suma += aEnteros[i];

Si la condición es tan importante como para detener un algoritmo,
entonces debería formar parte de la gestión de este bucle. Esto se
soluciona así,

bool bPositivo = true;

for( int i = 0; i < 100 && bPositivo; i++ )
{
  bPositivo = aEnteros[i] < 0;
  if( !bPositivo )
    suma += aEnteros[i];
}

O incluso,

bool bPositivo = true;

for( int i = 0; i < 100 && bPositivo; i++ )
{
  if( !(bPositivo = aEnteros[i] < 0) )
    suma += aEnteros[i];
}

Pero ya puestos, podríamos incluso escribir esto:

bool bPositivo = true;

for( int i = 0; i < 100 && !(bPositivo = aEnteros[i] < 0); i++ )
  suma += aEnteros[i];

Esto crea un código más limpio y legible. En el caso del bucle 'for',
mucha del código que involucra su gestión queda en la "cabecera" del
bucle, dejando el resto del código del "cuerpo" del bucle para el
algoritmo en sí.

En cuanto a usar 'return', dentro de un bucle, personalmente no tengo
un gran problema con su uso, con tal de que no se abuse de ella.
Típicamente, uso 'return' como discriminante en un programa y para
detectar posibles errores y peligros antes de empezar siquiera el
algoritmo. Por ejemplo,

int suma( int *pEnteros, int nCant )
{
  if( !pEnteros || nCant <= 0 )  return 0;   // Datos entrantes
incoherentes => Salimos de inmediato

  // Algoritmo propiamente dicho

  int nSuma = pEnteros[0];

  for( int i=1; i<nCant; i++ )
    nSuma += pEnteros[i];

  return nSuma;
}

En otros casos, si el algoritmo es sencillito y se puede deducir sin
problemas, entonces también uso 'return' dentro de un bucle para
salirme de toda la función. No es considerado una buen práctica, pero
no creo que descontrole demasiado, especialmente porque se trata de un
'return' y no influye en el resto del código de la función.
Ciertamente, puede descontrolar un poco la corrección del bucle, ya
que no sabríamos a ciencia cierta cuándo terminará. Por lo tanto,
intento rediseñar el algoritmo para que use variables booleanas, y ya
me preocupo de retornar la información correcta después del bucle.


Espero haber aclarado un poco más el tema.

Steven




Más información sobre la lista de distribución Cconclase