2010-04-09 10 views
8

In Delphi, consideranoQual è la variabile Loop dopo un ciclo For in Delphi?

var 
    i: integer; 

begin 

    for i := 0 to N do 
    begin 
    { Code } 
    end; 

Si potrebbe pensare che i = N dopo il ciclo for, ma fa il compilatore garanzia Delphi questo? Si può ipotizzare che la variabile loop sia uguale al suo ultimo valore all'interno del ciclo, dopo un ciclo Delphi if?

Aggiornamento

Dopo aver provato un paio di cicli semplici, ho il sospetto che i è in realtà pari a uno più l'ultimo valore della i all'interno del ciclo dopo il ciclo ... ma si può contare su questo ?

+0

Sei sicuro che N sia incluso dopo il ciclo 'for'? Vorrei controllare prima questo - perché ho il sospetto che potrebbe non esserlo. – LBushkin

+0

@LBushkin: dipende da come viene dichiarato N. Ma nell'esempio di codice precedente uso solo * N * come "segnaposto" per qualunque possa essere l'ultimo valore della variabile di loop. –

+0

@LBushkin, puoi essere assolutamente certo che 'N' sarà nell'ambito dopo il ciclo perché era ovviamente in ambito prima del ciclo (altrimenti il ​​codice non sarebbe stato compilato). L'ambito in Delphi non cambia in mid-function; inizia all'inizio di una funzione e termina alla fine. –

risposta

23

No, Delphi non garantisce alcun valore. Al di fuori del ciclo, la variabile non è definita e IIRC the Language Guide lo dichiara in modo esplicito, ovvero le nuove implementazioni del compilatore sono libere di modificare qualsiasi valore che la variabile possa avere al di fuori del ciclo a causa dell'implementazione effettiva.

+5

Questo è corretto. La variabile è specificatamente documentata per non essere definita dopo il completamento del ciclo. Se hai bisogno di una variabile definita dopo il ciclo, usa while o repeat –

+3

A seconda di come la variabile loop viene usata all'interno del loop, il compilatore può persino eliminarlo completamente e semplicemente utilizzare un puntatore per scorrere gli elementi di un array, ad esempio . –

+0

+1 da quando Nick ha detto che hai ragione! –

6

vorrei suggerire che l'utilizzo di un ciclo while è più chiara se è necessario utilizzare l'indice del ciclo dopo il ciclo:

i := 0; 
while i <= N 
begin 
    { Code } 
    i := i + 1; 
end; 

Dopodiché ciclo termina, si sa che i sarà N + 1 (o superiore , se N potrebbe essere stato inferiore a zero).

+0

Sì, questo è un ottimo metodo. Dopotutto, ogni ciclo for può essere scritto come un ciclo while in questo modo, ma senza alcuna "magia del compilatore". –

+2

Si potrebbe usare 'Inc (i)' invece di 'i: = i + 1', ma IIRC il compilatore li tratterà ugualmente. –

7

Il compilatore emette un avviso se si utilizza la variabile di ciclo dopo il ciclo, quindi è necessario considerarlo non definito.

2

È anche documented che la variabile di ciclo da un ciclo for non è definita al di fuori del ciclo.

In pratica: ciò che si ottiene dalla variabile varia in base alle impostazioni del compilatore e alla complessità del codice. Ho visto cambiamenti nel codice spingere il compilatore in un diverso percorso di ottimizzazione, modificando quindi il valore di questa variabile indefinita.

--jeroen

1

Come molte persone ha dichiarato, la variabile I si suppone essere non definito dopo il ciclo. Nell'uso del mondo reale, sarà definito sull'ultimo valore che aveva prima di "spezzare", o su N + 1 se il ciclo è eseguito a termine. Questo comportamento non può essere invocato, poiché è chiaramente specificato che non è pensato per funzionare.

Inoltre, a volte, I non viene assegnato. Ho riscontrato questo comportamento principalmente con l'ottimizzazione attivata.

Per il codice come questo

I := 1234; 
For I := 0 to List.Count - 1 do 
begin 
    //some code 
end; 
//Here, I = 1234 if List.Count = 0 

Quindi ... Se si vuole conoscere il valore di I dopo il ciclo, è meglio la pratica per assegnarlo ad un'altra variabile prima di uscire dal giro.

1

MAI MAI fare affidamento sul valore della variabile for, dopo il ciclo.

Controllare l'output del compilatore. Il compilatore Delphi ti avvisa di questo. Fidati del tuo compilatore.

  1. MAI nascondere i suggerimenti e gli avvisi del compilatore con {$ Warnings off}!
  2. Impara a trattare le informazioni come avvertenze e gli avvisi come errori!
  3. Ottimizza il codice finché non hai suggerimenti e avvisi ZERO (senza violare la regola 1).
+0

Beh, questo è forse un po 'troppo "severo". Ad esempio, in molti casi l'avvertenza "il valore di ritorno della funzione ... potrebbe essere indefinito" è irrilevante. –

+0

È molto raro che il compilatore dice che qualcosa potrebbe essere indefinito quando ciò non è possibile. Gli unici casi che ho visto riguardano due condizionali che assegnano risultati e intrinsecamente uno di loro deve essere eseguito.Ritengo che valga la pena di aggiungere un po 'di codice in più per eliminare gli avvisi * ALL * anche quando so che sono innocui. –

+1

Questo capita spesso se si alza un'eccezione all'interno della funzione, o se si mescola il metodo 'Exit (ReturnValue)' con il metodo 'result: =' della vecchia scuola. –