Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Exiting Nested "FOR . . . NEXT" loops
Page 1 of 3 | |||||
Author | Message | ||||
Andrew_G Guru Joined: 18/10/2016 Location: AustraliaPosts: 840 |
Hi all, Fairly trivial but out of interest I'm looking for a neat way to EXIT nested FOR . . . NEXT loops. I have a set of multiple loops that when a test is true I want to EXIT all of the loops and move on. I could use a GOTO statement. OR (& what I am doing now) is: When the test becomes true set a flag eg "ExitNow" and just before each NEXT statement test the flag and, if true, invoke "EXIT FOR". Then after the dust has settled set ExitNow to FALSE again and carry on. Is there a better way to EXIT all the FORs? Cheers, Andrew Here is an extract of the code, with the old GOTO statements commented out: . . . For dd = 3 to 3 for hh = 1 to 3 for mm = 0 to 59 for ss = 0 to 0 In$ = str$(dd,2,0,"0") + "-04-2022 " +str$(hh,2,0,"0")+":"+Str$(mm,2,0,"0")+":"+str$(ss,2,0,"0") print In$, IsDST(In$), Out$ if IsDST(In$) = 0 and mm > 2 then ExitNow = True: Exit For 'Goto Skip Next ss If ExitNow then Exit For Next mm If ExitNow then Exit For next hh If ExitNow then Exit For Next dd ExitNow = False 'Skip: . . . |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5885 |
One method I used was: Make the outer loop a DO...LOOP and then you can EXIT DO to get out from any level. Not sure if Peter/Geoff will groan but it has worked for me (so far) Jim VK7JH MMedit  MMBasic Help |
||||
Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3165 |
There is no EXIT ALL LOOPS command and your method is the most "sensible" method of achieving this. Jumping straight out of the loop as you suggested will also work as MMBasic is designed to handle such manoeuvres, although it is untidy and will give the GOTO police a heart attack. The only other way that I can think of to do what you want is to set all the looping variables to a value that is greater than their terminating TO value (is, 999). However that is also rather untidy. Geoff Geoff Graham - http://geoffg.net |
||||
Tinine Guru Joined: 30/03/2016 Location: United KingdomPosts: 1646 |
|
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 1773 |
Over use of GOTO gets confusing, however a single instance isn't a problem. Especially if the Label is explanatory. GOTO Nest_Exit or GOTO Exit_All_Loops Edited 2022-10-04 07:56 by phil99 |
||||
Andrew_G Guru Joined: 18/10/2016 Location: AustraliaPosts: 840 |
Thanks folks. I like Jim's idea - if Geoff and Peter have no objections? (It just needs an EXIT DO after the last NEXT, as well as where the test becomes TRUE) Cheers, Andrew Edited 2022-10-04 08:39 by Andrew_G |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5885 |
Or Do LOOP UNTIL 1=1 or replace the outer for-next with the do-loop My concern is I don't know if the stack gets properly cleared. Jim Edited 2022-10-04 08:42 by TassyJim VK7JH MMedit  MMBasic Help |
||||
Andrew_G Guru Joined: 18/10/2016 Location: AustraliaPosts: 840 |
Very cleaver Jim! (that's why you really are a Guru!) Andrew |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9055 |
I do pretty much the same thing as your example: If Y THEN EXIT DO, and I set and clear Y as needed to make loops drop to the next level. Its always worked for me, so I think that is a good a way as any, and pretty much anyone else reading your code will understand why you did that, as I think plenty of people write exits in a similar way and for a similar reason as you just highlighted. Huh? One will always equal one, so how does that work? Is that just another way of forcing an exit cos one will always equal one, so it will exit at that point? Never seen that idea before, so it kinda shorted out my brain a bit! Smoke makes things work. When the smoke gets out, it stops! |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5885 |
Yes. A crude way to make sure that you only do the loop once without wasting a variable. I normally convert the outer FOR NEXT into a DO LOOP so no need for such oddities. Jim VK7JH MMedit  MMBasic Help |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5885 |
I ran this test on a picomite with the RC5 firmware to use the MM.INFO(STACK) function ' OPTION EXPLICIT OPTION DEFAULT INTEGER DIM x,y,z,t, quit DIM stack1, stack2 stack1 = mm.info(stack) x = 0 DO 'for x = 0 to 9 FOR y = 0 TO 9 FOR z = 0 TO 9 t = x*100+y*10+z PRINT t IF t > 200 THEN EXIT DO ' quit = 1 : exit for NEXT z ' if quit = 1 then exit for NEXT y ' if quit = 1 then exit for ' next x INC x LOOP UNTIL x > 9 stack2 = mm.info(stack) PRINT stack1 PRINT stack2, stack1-stack2 ' stack grows downwards There was no obvious difference between the various methods including GOTO, setting a flag and multiple EXIT FOR and DO LOOP as a wrapper or as replacement for the outer FOR NEXT Jim VK7JH MMedit  MMBasic Help |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 3496 |
@Jim I use Do Loop All the time. No need for the 1=1...... probably a remainder of the Arduino world.... Edited 2022-10-05 01:37 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
stanleyella Guru Joined: 25/06/2022 Location: United KingdomPosts: 1639 |
I used to use goto but it is frowned upon now but the easiest way out of a nested for next loop. elegant. |
||||
Mixtel90 Guru Joined: 05/10/2019 Location: United KingdomPosts: 5705 |
Help save GOTO! Don't let it become extinct! Join Friends Of GOTO now - we need your support urgently! (Said with more than a little tongue in cheek and too many exclamation marks) More seriously, I don't see much of a problem with GOTO <label>. In the days of line numbers or, even worse, GOTO <function> it could get extremely confusing, but a simple GOTO to a label can often be the clearest way to write a program. I think rejecting them out of hand is a mistake. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Martin H. Guru Joined: 04/06/2022 Location: GermanyPosts: 890 |
oh the GOTO POLICE what is wrong with Goto? In Assembler you wouldn't gat anywhere without Branches or Jump Statements. Not so elegant(for some Hipsters) but sometimes necessary initialise: 'some Variables LIveLost%=0 Intro: cls:Print "Bla Bla Bla" prepare_Playfield Live%=5 next_Live: LIveLost%=0 If not Live% the goto Intro do something something_else If LIveLost% then inc Live%,-1: goto next_Live loop sub prepare_Playfield end sub sub something end sub sub something_else end sub Edited 2022-10-05 03:48 by Martin H. 'no comment |
||||
stanleyella Guru Joined: 25/06/2022 Location: United KingdomPosts: 1639 |
goto supported in gcbasic and still the most elegant way of exiting nested loops. worst was before labels and goto line numbers. zx basic, remember? |
||||
lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3010 |
Hipster? Me? LOL indeed! Not only inelegant, but in that case, certainly not necessary. I do use GOTO when encountering an unrecoverable error deep in loops. You only really get into trouble with larger programs (though I've seen plenty of beginners fall into places they didn't want to be with GOTOs). I have no problem with a use such as Grogster proposes, though I'd probably use the EXIT DO instead (even though it's just an obfuscated GOTO). PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
stanleyella Guru Joined: 25/06/2022 Location: United KingdomPosts: 1639 |
' OPTION EXPLICIT OPTION DEFAULT INTEGER DIM x,y,z,t, quit DIM stack1, stack2 stack1 = mm.info(stack) x = 0 DO 'for x = 0 to 9 FOR y = 0 TO 9 FOR z = 0 TO 9 t = x*100+y*10+z PRINT t IF t > 200 THEN EXIT DO ' quit = 1 : exit for NEXT z ' if quit = 1 then exit for NEXT y ' if quit = 1 then exit for ' next x INC x LOOP UNTIL x > 9 This got my attention. Please explain mmbasic stack ie push pop and relevance to for next counters. I thought they were ram variables. stack2 = mm.info(stack) PRINT stack1 PRINT stack2, stack1-stack2 ' stack grows downwards There was no obvious difference between the various methods including GOTO, setting a flag and multiple EXIT FOR and DO LOOP as a wrapper or as replacement for the outer FOR NEXT Jim |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5885 |
I use Do Loop All the time. No need for the 1=1...... probably a remainder of the Arduino world.... The 1=1 was to make sure that the loop only passed through the one time. In this instance, the DO LOOP is only a target for the EXIT DO and not really a loop. Normally, I convert the outer FOR NEXT into a DO LOOP so don;'t resort to such crudities. JIm VK7JH MMedit  MMBasic Help |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 3496 |
There is a problem with goto exit a loop. Geoff has apparently fixed it, but in the loop, the return address, and maybe more, is pushed on stack. When you exit with goto, the return address remains on stack. Slowly your stack will fill up, with every goto exit. PicomiteVGA PETSCII ROBOTS |
||||
Page 1 of 3 |
Print this page |