Domanda

[EDIT] Supplica che ci sia stato un errore nel codice, e ora tutte le risposte alla domanda sembrano bizzarre, ma sostanzialmente il ciclo for era, per (i = 0; i < 15; i ++ ). Ho anche modificato per rendere la domanda più chiara. [/ EDIT]

Sto cercando di creare un ciclo for, che controlla un array di 16 elementi, quindi passa da 0 a 15. Quindi uso la variabile i in un secondo momento, tuttavia a volte i == 16, che causa problemi essendo fuori dai limiti .

Ho una soluzione ma non sembra elegante, il che mi fa pensare che mi manchi qualcosa. Ho provato mentre i loop, ma non riesco mai a far passare alcun loop da 0 a 15 e non finiscono mai con un valore maggiore di 15.

Esiste un modo per far andare un ciclo e controllare tutti i 16 elementi dell'array, pur non essendo mai maggiore di 15 alla fine del ciclo?

int i;

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

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



if (i == 16)
{
    i = 15;
}
È stato utile?

Soluzione

Suggerisco di utilizzare qualche altra variabile diversa da i al termine del ciclo. Il criterio per utilizzare un ciclo for anziché un ciclo while è sapere in anticipo esattamente quante volte verrà eseguito un ciclo for. Se lo sai già, imposta semplicemente un'altra variabile sul valore finale del tuo loop e usalo invece di dare a <=> un duplice scopo.

int j = 15;

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

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

Altri suggerimenti

Bene, per cominciare, il tuo codice di esempio passa da 0 a 14. Ma se fai un ciclo da 0 a 15, naturalmente devo essere 16 prima il ciclo può finire. Quello che succede è che diventa 16, ALLORA il tuo loop nota che è fuori dai limiti e scoppia. Se vuoi che finisca alle 15, onestamente la cosa più semplice da fare è solo diminuire dopo la fine del ciclo.

I sull'ultimo controllo viene incrementato per essere 16, che non è inferiore a 15, quindi il ciclo termina con i che sono 16.

Forse è utile sapere che:

for (before; check; after) { body } 

è uguale a:

before 
while(check) { 
  body 
  after 
} 

Se pensi al tuo ciclo for in quel termine, forse scoprirai facilmente perché io, all'uscita, ho 16.

Sembra che ci siano alcuni difetti fondamentali nel tuo approccio.

  1. Non dovresti davvero usare una variabile indice al di fuori dell'ambito del ciclo.
  2. Dovresti usare una variabile o una funzione per determinare il limite del loop.
  3. Sarebbe meglio usare iteratori invece di indici numerici.
  4. Gli algoritmi generici possono rimuovere la necessità di loop.

Solo i miei $ 0,02.

Quindi - se stai controllando un array di 16 elementi, normalmente dovresti farlo:

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

Come funziona, inizia con la prima affermazione di tre:

i=0

Quindi controlla, nella seconda affermazione:

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

Succede prima del tuo loop. Quindi esegue il blocco del tuo ciclo con quel set:

someClass.array[i]; //0

Infine, fa la dichiarazione finale:

i++

Quindi ripete la seconda e la terza istruzione, in una sequenza.

Prima dell'ultima corsa, i == 14, quindi esegue i ++, impostando i su 15 ed esegue il blocco. Infine, fa i ++, impostazione:

i==16

A questo punto, la condizione non è più vera:

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

A questo punto, il blocco non viene eseguito, ma i è ancora impostato su 16.

Devi aver perso qualcosa.

In questo ciclo non avrebbe nemmeno colpito 15, avresti bisogno di dire i < = 15, non appena i = 14 sarebbe stato eseguito una volta e salvato su cauzione.

Il ciclo for equivale al seguente while ciclo:

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

    i++;
} // while

i deve raggiungere i 16 anni per uscire correttamente dal ciclo.

Tecnicamente ci sono modi per scrivere il ciclo in modo tale che i sia 15 all'uscita dal ciclo, ma non dovresti farlo:

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

Sì, fa quello che chiedi. Ma il flusso è orribile.

Non puoi realizzarlo con le strutture di loop integrate e, come ha detto Bill The Lizard, probabilmente non vorrai davvero riutilizzare la variabile for-loop.

Ma, se vuoi davvero, ecco un modo per farlo. Il trucco è mettere la condizione del loop nel mezzo del loop:

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

Il problema chiave da capire qui è che ci sono 17 risposte diverse alla domanda " Quale valore di i fa sì che il test abbia successo? " ;. O posso essere in {0, 1, ..., 15} o nessun valore di i fa sì che il test abbia esito positivo, il che è indicato da i == 16 in questo caso. Quindi, se sono limitato a soli 16 valori, non è possibile rispondere alla domanda.

Esistono casi legittimi in cui non si desidera superare l'ultimo valore valido. Ad esempio, se avevi 256 valori e per qualche motivo hai solo un byte con cui contare. Oppure, come mi è capitato di recente, vuoi esaminare solo tutti gli elementi di un array e l'ultima aggiunta al tuo iteratore ti porta ben oltre la fine dell'array. In questi casi è necessario srotolamento in loop .

Tuttavia, per questo problema sarebbe più pulito usare una bandiera:

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

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

Quindi è chiaro se il test è mai riuscito.

Se il tuo ciclo termina natuaralmente, piuttosto che con una pausa, i sarà essere 16. Non c'è modo di evitarlo. Il tuo codice è perfettamente accettabile se quello che vuoi è che io finisca come 15 o meno:

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

Tutto ciò che cambia someClass.Test() da 16 a 15 dopo il corpo del loop farà:

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

e così via.

Tuttavia, ciò presuppone che i == 15 verrà utilizzato per qualcosa di significativo come post-condizione rispetto a quel ciclo. Trovo che raramente sia così, le persone tendono a reinizializzarlo prima di riutilizzarlo (come un altro per loop).

Inoltre, ciò che stai facendo rende molto difficile (impossibile, anche) capire come post-condizione, se il tuo ciclo è terminato normalmente o se è terminato prematuramente perché <=> è tornato vero per <=>. Questo significa che usare i per prendere ulteriori decisioni è pieno di pericoli.

La mia domanda sarebbe: Perché pensi di dover lasciare <=> come 15 o meno?

  

Sto cercando di creare un ciclo for, quello   controlla un array di 16 elementi, quindi passa in loop   da 0 a 15. Uso quindi l'i   variabile in seguito, tuttavia a volte i ==   16, che causa problemi essendo fuori   dei limiti.

Devi verificare il caso in cui il tuo ciclo for non si sia interrotto, perché queste informazioni determinano se qualunque cosa tu voglia fare con i è valida.

Ci sono un paio di modi per farlo. Uno è di tenerne traccia in un bool, come & Quot; foundClass & Quot; oppure " test <<>> superato ;. L'impostazione predefinita è false, quindi impostarla su true durante l'interruzione. Racchiudere in seguito eventuali usi di i nella funzione tra & Quot; if (foundClass) {} & Quot; blocchi.

Un altro è semplicemente quello che hai fatto. Anche se il tuo fallback non sembra affatto giusto. Se stai impostando i su 15, stai mentendo al tuo codice e gli stai dicendo che someClass.Test () è riuscito per i == 15, il che non è vero. Evita di impostare il valore su qualcosa che non va, in modo che il tuo codice non si verifichi più tardi. È molto meglio mettere un controllo dei limiti intorno all'utilizzo effettivo di io più avanti nel codice.

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

se dici di avere un array con 16 elementi, non devi definirlo, usa l'array per ottenere quelle informazioni (NON DUPLICARE INFORMAZIONI)

in seguito, se si desidera ottenere nuovamente l'ultimo indice, utilizzare l'array per ottenere tali informazioni.

for(int i = 0; i < myArray.length; ++i){
       myArray[i].somemethod();
}
// lastindex = myArray.length-1;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top