Jump to content

"For...Next" adds 1 to the $i variable


 Share

Recommended Posts

Hi all,

I notice a while ago strange behaviour, check this example:

;Example 1
For $i = 1 To 5
    ConsoleWrite("Count > " & $i & @LF)
Next
MsgBox(0, "", "$i = " & $i & " ?!!") ; 6 ?!!!

;Example 2
For $j = 5 To 1 Step -1
    ConsoleWrite("Count down > " & $j & @LF)
Next
MsgBox(0,"", "$j = " & $j & " ?!!") ; 0 ?!!!

Is this normal? the $i should be 5 at the end (after the loop is done), and $j should be 1 :P

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

I don't think that's bad...Try to look at it this way:

$a=1
While $a<=5
    ConsoleWrite("Count > " & $a & @LF)
    $a+=1
WEnd
MsgBox(0, "", "$i = " & $a & " ?!!") ; 6 ?!!!

This does exactly the same. The variable $a is declared and set to 1 (For $a=1) then it enters the loop. Is $a<=5? yes, then... $a=2 . . . $a=4. Is $a<=5? yes, then...$a=5. Is $a<=5? yes, then $a=6. Is $a <=5? no, then exit loop.

Sorry if that was confusing, but that's how it is in my head :"> and my awful english skills just make it harder to comunicate :P

Link to comment
Share on other sites

Try to look at it this way:

It's not the same, here you add every time 1 to the $a, so naturaly it will grow at the end to the 6, but with For...Next it should not happend, this is how the loop is work (should work):

$a = 0
While 1
    $a += 1
    ConsoleWrite("Count > " & $a & @LF)
    If $a = 5 Then ExitLoop
WEnd
MsgBox(0, "", "$i = " & $a & " ?!!") ; 6 ?!!!

I am confused! :P

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

Indeed, Nahuel got the point of this.

This is a common behaviour for loops where the test is made at the begining, For-Next and While-Wend are doing the test at the begining which is not the case for Do-Until.

Do-Until does the test at the end of the loop. If you run this example:

$i = 1
Do
    ConsoleWrite("Count > " & $i & @LF)
    $i+=1
Until $i=5
MsgBox(0, "", "$i = " & $i & "    :)") ; 5 :)

you will see that the value is the expected one :P

edit: just to add something: this is the way the For-Next works:

$i=1 then 1<=5 ? yes -> execute

$i=2 then 2<=5 ? yes -> execute

...

$i=5 then 5<=5 ? yes -> execute

$i=6 then 6<=5 ? no -> quit

edit2: and YES, inside the For loop the counter is incremented by "step"

Help quote:

For...To...Step...Next

--------------------------------------------------------------------------------

Loop based on an expression.

For <variable> = <start> To <stop> [step <stepval>]

statements

...

Next

Parameters

variable The variable used for the count.

start The initial numeric value of the variable.

stop The final numeric value of the variable.

stepval [optional] The numeric value (possibly fractional) that the count is increased by each loop. Default is 1.

Remarks

The Variable will be created automatically with a LOCAL scope, even when MustDeclareVars is on.

For...Next statements may be nested. The For loop terminates when the value of variable exceeds the stop threshold. If stepVal or stop is a variable, its value is only read the first time the loop executes.

A For loop will execute zero times if:

start > stop and step > 0, or

start < stop and step is negative

Edited by enaiman

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

I don't think that's bad...Try to look at it this way:

$a=1
While $a<=5
    ConsoleWrite("Count > " & $a & @LF)
    $a+=1
WEnd
MsgBox(0, "", "$i = " & $a & " ?!!") ; 6 ?!!!

This does exactly the same. The variable $a is declared and set to 1 (For $a=1) then it enters the loop. Is $a<=5? yes, then... $a=2 . . . $a=4. Is $a<=5? yes, then...$a=5. Is $a<=5? yes, then $a=6. Is $a <=5? no, then exit loop.

Sorry if that was confusing, but that's how it is in my head :"> and my awful english skills just make it harder to comunicate :P

Not confusing and I think your explanation is correct. However I agree a bit with MsCreator because although I know the for/next loops do this, it would make more sense to me if the logic was like -

$a = 0
Do
       $a +=1
       consolewrite('$a = ' & $a & @LF)
    
    
until $a = 5

msgbox(0,'$a','= ' & $a)

EDIT:Sorry enaiman, you beat me to it.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

It's not the same, here you add every time 1 to the $a, so naturaly it will grow at the end to the 6, but with For...Next it should not happend, this is how the loop is work (should work):

$a = 0
While 1
    $a += 1
    ConsoleWrite("Count > " & $a & @LF)
    If $a = 5 Then ExitLoop
WEnd
MsgBox(0, "", "$i = " & $a & " ?!!") ; 6 ?!!!

I am confused! :P

Yeah, but there you are testing the counter variable inside the loop.

-edit-

@enaiman: Exactly. I was going to give the example of Do.. Until for a loop that tests the variable after executing the code inside ;)

Edited by Nahuel
Link to comment
Share on other sites

lol - no worries about who posted first or last :P

Important is to help OP to get the meaning ;)

Edit: lol - I wonder how much confusion these C+ things could bring here: "i++" or "++i" ... just kidding around :)

Edited by enaiman

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

This misunderstanding of the way different looping structures are evaluated is a common source of off by 1 errors in programs. It is not good practice to use the value of a loop variable outside the loop. If you need to use the value of the loop counter outside the loop it should be copied to another variable, declared before the loop started, within the loop and that variable used instead

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Link to comment
Share on other sites

...Is this normal?...

Yes.

Think about what the "Next" line is doing and it might make more sense to you.

"Next" increments the 5 to a 6 and then points to the "For" line.

The "For" line evaluates the start/stop/step and seeing that $i = 6...

...the "For" line then points to the line after the matching "Next" line.

($i still equals 6 at that point)

The same is true for your "count down" loop.

Clear as mud?

[size="1"][font="Arial"].[u].[/u][/font][/size]

Link to comment
Share on other sites

Thanks to all for the explanations/descriptions ( :P ), but i think that the loop must end when the $i = 5, not $i > 5, so when the loop executed 5 times, it must exit immediately, without adding 1 more value.

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

Maybe if it the syntax was:

I am not looking for a solution or anything here, it's just was a strange behaviour for me.

but seriously, the "next" line has nothing to evaluate, it just increments the variable... like it should.

I understand what you mean, and thanks for the effort (by explanations :P ).

And by the way, i never had to use the variable that generated by the For..Next loop, i discover this behaviour only when i build an example for report about "documentation bug" here.

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...