...l'avevo notato anche qualche altra volta, ma non vi avevo dato peso più di tanto; ultimamente mi sono imbattuto nuovamente nel ciclo For...Next da 0 a 255 con variabile di tipo Byte che gira all'infinito:
Public Sub Button1_Click()
Dim j As Byte
For j = 0 To 255
Print j
Next
End
Ho posto la questione nella Mailing List Internazionale, poiché nella mia asinità temevo un bug, ma non è così, e ne è nata un discussione (che tra l'altro non mi attendevo) fra più utenti, che vorrei qui riportare (nel timore di commettere errori di traduzione, riporto i messaggi nella lingua originaria in cui sono stati scritti):
«Just guessing here, but valid values for Byte are 0-255. From
observation I have seen that FOR loops terminate with the loop index
at final value+1. For Byte that would probably be zero (if it just
wraps around from 255 to 0) so there is no reason to terminate the
loop.
Richard»
«Can confirm that with rev5189. Richard's guess sounds logical. "For To" is
inclusive: [0; 255] and that's everything you can represent with Byte width.
You won't ever detect Byte > 255.
Tobias Boege»
« I think all Basics work this way!
Test with any basic:
For ii = 1 to 10
Next
Print ii
What you expect? I think all basic languages gives 11 as result.
Jussi Lahtinen »
«Sinclair BASIC on the QL used to have a FOR loop epilogue which could
be used to handle this sort of thing. A simple FOR loop was
FOR index = start TO stop
Sinclair BASIC on the QL used to have a FOR loop epilogue which could
be used to handle this sort of thing. A simple FOR loop was
FOR index = start TO stop
do some stuff
END FOR index
The NEXT control could be added to create the epilogue so:
FOR byte = 0 TO 254
PRINT index
NEXT index
PRINT index
END FOR index
Would print out the values from 0 to 255. If the loop's initial
conditions would not permit execution, control jumps to after the END
FOR marker.
It also allowed :
FOR index = 0 TO 15, 64, 96, 128 to 254, 255
Very useful, and just one of the many features I miss from SuperBASIC.
richard.j.walker»
« It is the same in almost all languages.
unsigned char i;
for(i=0; i<255; i++){}
and
unsigned int i;
for(i=0; i<4294967295U; i++){}
in C will never terminate.
In Gambas,
Dim i As Integer
For i = 0 To 2147483647
Next
will not terminate either.
You might think that because you say the range 0 To X, you expect to get
each of those values, but the truth is that the For i = 0 To X is actually
interpreted as for(i=0; i<=X; i++) which obviously does not work when X is
the max value of that integer type.
emil.lenngren »
« This same thing is simpler in Gambas:
For ii = 0 to 254
Print ii
Next
Print ii
Jussi Lahtinen »
« Problem with that is that the second "Print ii" statement is executed,
even if the loop is skipped (because of initial conditions). The
SuperBASIC version would print nothing if the initial loop conditions
indicate it should be skipped
The Gambas equivalent would be more like
For ii = 0 to 254
Print ii
Next
If (some test by which we can tell the loop has iterated at least once) Then
Print ii
End If
Also, an EXIT statement in the loop would leave the SuperBASIC FOR
loop, skipping the loop epilogue (the bit between the NEXT and the END
FOR).
A better trivial example of the loop epilogue in action might be:
FOR character = 1 to LEN$(test$)
IF test$(character) == "@" THEN EXIT character
NEXT character
REMark Character not found
character = 0
END FOR character
IF character THEN
PRINT test$(1 TO character-1) & test$(character+1 TO )
ELSE
PRINT "Not found"
END IF
richard.j.walker»
Si, é così. Infatti se tu verifichi il contenuto della variabile indice del ciclo di "For ... Next", all'uscita naturale dal ciclo, ti accorgi che il suo contenuto ha raggiunto lo step successivo al valore massimo del ciclo, cioè:
For i = 0 to n
----- bla bla ------
Next
'Ora i contiene "n+1"
Ma tu hai proprio bisogno di comandare un ciclo "For ... Next", gestito da una variabile di tipo byte, oppure la tua prova è nata da una semplice curiosità?
:ciao:
Ho provato a fare questa cosa con il Basic PDS 7.1 (il successore del QuickBasic 4.5) usando un integer:
DIM i AS INTEGER
FOR i = 0 to 32767
PRINT i
NEXT
In ambiente interpretato, alla fine del ciclo mi da correttamente errore di overflow.
Però non ho provato a compilare il programma per vedere che succede.