Pregunta

[EDITAR] Vaya, hubo un error en el código, y ahora todas las respuestas a la pregunta parecen extrañas, pero básicamente el ciclo for solía ser, for (i = 0; i < 15; i ++ ) También edité para aclarar la pregunta. [/ EDIT]

Estoy tratando de hacer un bucle for, que verifica una matriz de 16 elementos, por lo que realiza un bucle de 0 a 15. Luego uso la variable i más tarde, sin embargo a veces i == 16, lo que causa problemas al estar fuera de los límites .

Tengo una solución, pero no parece elegante, lo que me hace pensar que me falta algo. Intenté los bucles while, pero nunca consigo que ningún bucle vaya de 0 a 15, y nunca termine en un valor mayor que 15.

¿Hay alguna forma de hacer que un bucle funcione y verificar los 16 elementos de la matriz, sin que nunca sea mayor que 15 al final del bucle?

int i;

for(i=0; i<16; i++)
{
    someClass.someMethod(i);

    if(someClass.Test())
    {
        break;
    }
}



if (i == 16)
{
    i = 15;
}
¿Fue útil?

Solución

Sugiero usar alguna otra variable que no sea i después de que finalice su ciclo. El criterio para usar un bucle for en lugar de un bucle while es que sepa de antemano exactamente cuántas veces se ejecutará un bucle for. Si ya sabe esto, simplemente configure alguna otra variable para el valor final de su ciclo y úsela en lugar de darle a <=> un doble propósito.

int j = 15;

for(int i=0; i <= j; i++)
{
    someClass.array[i];
}

// continue on using j, which value hasn't changed

Otros consejos

Bueno, para empezar, su código de muestra se repite de 0 a 14. Pero si se repite de 0 a 15, naturalmente tengo que tener 16 antes de que el bucle pueda finalizar. Lo que sucede es que se convierte en 16, LUEGO su ciclo se da cuenta de que está fuera de los límites y se rompe. Si quiere que termine a los 15, honestamente, lo más fácil es disminuirlo justo después del final del ciclo.

i se incrementa en la última comprobación para que sea 16, que no es menor que 15, por lo que el ciclo sale con i siendo 16.

Quizás sea útil saber eso:

for (before; check; after) { body } 

es lo mismo que:

before 
while(check) { 
  body 
  after 
} 

Si piensa en su ciclo for en ese término, quizás descubra fácilmente por qué yo, en la salida, es 16.

Parece haber algunas fallas fundamentales en su enfoque.

  1. No deberías usar una variable de índice fuera del alcance del bucle.
  2. Debe usar una variable o función para determinar el límite del bucle.
  3. Sería mejor usar iteradores en lugar de índices numéricos.
  4. Los algoritmos genéricos pueden eliminar la necesidad de bucles.

Solo mis $ 0.02.

Entonces, si está comprobando una matriz de 16 elementos, normalmente haría esto:

for(i=0; i<16; i++)

Cómo funciona, si comienza con la primera declaración de tres:

i=0

Luego realiza su verificación, en la segunda declaración:

i < 16 // True here, since 0 < 16

Eso sucede antes de tu ciclo. Luego ejecuta el bloque de su ciclo con ese conjunto:

someClass.array[i]; //0

Finalmente, hace la declaración final:

i++

Luego repite las declaraciones segunda y tercera, en una secuencia.

Antes de la última ejecución, i == 14, entonces hace i ++, configurando i en 15, y ejecuta el bloque. Finalmente, hace i ++, configurando:

i==16

En este punto, la condición ya no es verdadera:

i < 16 // False, since i==16

En este punto, su bloque no se ejecuta, pero todavía estoy configurado en 16.

Debes haberte perdido algo.

En este ciclo ni siquiera llegaría a 15, tendrías que decir i < = 15, tan pronto como i = 14 se ejecutaría una vez y saldría bajo fianza.

El bucle for es equivalente al siguiente bucle while:

i = 0;
while(i < 16) {
    someClass.array[i];

    i++;
} // while

i necesita alcanzar 16 para salir del ciclo correctamente.

Técnicamente, hay formas de escribir el ciclo de modo que i tenga 15 años al salir del ciclo, pero no debe hacerlo:

int i = 0;
while (1) {
    someclass.someMethod(i);
    if (i < 15) {
        i++;
    } else {
        break;
    }
}

Sí, hace lo que pides. Pero el flujo es horrible.

No puede lograr esto con las estructuras de bucle incorporadas, y como dijo Bill The Lizard, probablemente no quiera reutilizar la variable for-loop.

Pero, si realmente quieres, aquí hay una manera de hacerlo. El truco es poner la condición del bucle en el medio del bucle:

int i = 0;
while (true)
{
    someclass.array[i];
    if (i == 15)
        break;
    ++i;
}

La cuestión clave a entender aquí es que hay 17 respuestas diferentes a la pregunta & "; ¿Qué valor de i hace que la prueba tenga éxito? &" ;. O puedo estar en {0, 1, ..., 15}, o ningún valor de i hace que la prueba tenga éxito, lo que se denota por i == 16 en este caso. Entonces, si estoy restringido a solo 16 valores, la pregunta no puede ser respondida.

Hay casos legítimos en los que no desea pasar el último valor válido. Por ejemplo, si tenía 256 valores y por alguna razón solo tiene un byte para contar. O, como me ocurrió recientemente, desea examinar solo cada elemento i-ésimo de una matriz, y la última adición a su iterador lo lleva mucho más allá del final de la matriz. En estos casos, es necesario desenrollar el bucle .

Sin embargo, para este problema sería más limpio usar una bandera:

bool flag = false;
for (int i = 0; i < 15; ++i) 
{
    someClass.someMethod(i);

    if (someClass.Test())
    {
        flag = true;
        break;
    }
}

Entonces está claro si la prueba alguna vez tuvo éxito o no.

Si su ciclo termina de forma natural, en lugar de con un descanso, i será será 16. No hay forma de evitar esto. Su código es perfectamente aceptable si lo que desea es que termine como 15 o menos:

int i;
for (i=0; i<16; i++) {
    someClass.someMethod(i);
    if (someClass.Test())
        break;
}
if (i == 16)
    i = 15;

Cualquier cosa que cambie someClass.Test() de 16 a 15 después del cuerpo del bucle hará:

if (i == 16) i = 15;
i = (i == 16) ? 15 : i;
i = MAX (15,i); /* where MAX is defined :-) */

y así sucesivamente.

Sin embargo, eso supone que i == 15 se utilizará para algo significativo como una condición posterior con respecto a ese bucle. Creo que rara vez es así, las personas tienden a reiniciarlo antes de volver a usarlo (como otro bucle for).

Además, lo que está haciendo hace que sea muy difícil (imposible, incluso) darse cuenta como una condición posterior, ya sea que su ciclo finalice normalmente o si finalizó prematuramente porque <=> volvió verdadero para <=>. Esto significa que usar i para tomar más decisiones está lleno de peligros.

Mi pregunta sería: ¿Por qué cree que necesita dejar <=> como 15 o menos?

  

Estoy tratando de hacer un bucle for, que   comprueba una matriz de 16 elementos, por lo que se repite   de 0 a 15. Luego uso el i   variable más tarde, sin embargo a veces i ==   16, que causa problemas al estar fuera   de límites.

Debe verificar el caso en el que su ciclo for no se rompió, porque esta información determina si lo que desea hacer con i es válido o no.

Hay un par de formas de hacer esto. Una es hacer un seguimiento de ella en un bool, como & Quot; foundClass & Quot; o " testSucceeded " ;. Predeterminado a falso, luego configúrelo a verdadero en su descanso. Incluya cualquier uso de i más adelante en la función en & Quot; if (foundClass) {} & Quot; bloques.

Otra es simplemente hacer lo que has hecho. Aunque su reserva no se ve bien en absoluto. Si está configurando i a 15, está mintiendo a su código y diciéndole que someClass.Test () tuvo éxito para i == 15, lo cual no es cierto. Evite establecer el valor en algo que está mal solo para que su código no se equivoque más adelante. Es mucho mejor poner controles de límites alrededor del uso real de i más adelante en el código.

for(int i=0; i<17; i++)
{    
  if(i<16)
  {
     someClass.someMethod(i); 
     if(someClass.Test())   
     {        
       break;    
     }
  }
  else if(i==16)
  {
     i=15;
  }
}

si dice que tiene una matriz con 16 elementos, no tiene que definir eso, use la matriz para obtener esa información (NO DUPLICAR LA INFORMACIÓN)

luego, si desea obtener el último índice nuevamente, use la matriz para obtener esa información.

for(int i = 0; i < myArray.length; ++i){
       myArray[i].somemethod();
}
// lastindex = myArray.length-1;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top