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 : MM ENDIF Important?
Author | Message | ||||
Nixie Regular Member Joined: 19/02/2013 Location: AustraliaPosts: 66 |
Sigh... no such thing as a silly question; but.... I can't see if it is mandatory to use ENDIF in my code. Is it mandatory? If not, is there a limit to the number of IF AND THEN statements? Thanks in Advance! Currently code like this: 64 If M=12 And S=10 And Flag=0 Then X=1: Flag=1 65 If M=15 And S=10 And Flag=0 Then X=1: Flag=1 66 If M=18 And S=10 And Flag=0 Then X=1: Flag=1 and 642 If MN=0 And S=30 Then CS$="VE":?@(00,30)" ":?@(00,50)"*" 643 If MN=0 And S=40 Then CS$="W6":?@(00,50)" ":?@(00,70)"*" 644 If MN=0 And S=50 Then CS$="KH":?@(00,70)" ":?@(00,90)"*" So should it be: 64 If M=12 And S=10 And Flag=0 Then X=1: ENDIF: Flag=1 65 If M=15 And S=10 And Flag=0 Then X=1: ENDIF: Flag=1 66 If M=18 And S=10 And Flag=0 Then X=1: ENDIF: Flag=1 and 642 If MN=0 And S=30 Then CS$="VE":ENDIF: ?@(00,30)" ":?@(00,50)"*" 643 If MN=0 And S=40 Then CS$="W6":ENDIF: ?@(00,50)" ":?@(00,70)"*" 644 If MN=0 And S=50 Then CS$="KH":ENDIF: ?@(00,70)" ":?@(00,90)"*" Cheers, Nic. |
||||
kiiid Guru Joined: 11/05/2013 Location: United KingdomPosts: 671 |
Nic, ENDIF makes sense if there are many (or at least two or more) lines of code enclosed in the IF...ENDIF structure. In your case since the operations after THEN end the line, there is no need to have a closing ENDIF. This is a common rule for placing ENDIF in all BASIC dialects. So in short - I don't think there is a need for you to change your current code. In fact placing an ENDIF as in your second example completely changes the logic - flag=1 executes always after the IF and does not depend on its result. I don't know is that what you want Kon http://rittle.org -------------- |
||||
Nixie Regular Member Joined: 19/02/2013 Location: AustraliaPosts: 66 |
Kon many thanks! That is what I wanted to know. I have a couple of old books on a couple varieties of BASIC but they don't even mention ENDIF. Thanks for explaining the aspect of logic change too. Much appreciated! Cheers, Nic. |
||||
mbramwel Regular Member Joined: 10/07/2013 Location: CanadaPosts: 42 |
I could be mistaken but I thought these lines were basically the same: #1 64 If M=12 And S=10 And Flag=0 Then X=1: ENDIF: Flag=1 #2 64 If M=12 And S=10 And Flag=0 Then X=1: Flag=1 I thought I read somewhere that ALL commands on the same line are executed if the "IF" was true otherwise nothing is executed. you would *think* this is another way of rewriting the above lines of code: #1 64 If M=12 And S=10 And Flag=0 Then X=1: ENDIF: Flag=1 #2 64 If M=12 And S=10 And Flag=0 Then X=1: Flag=1 ENDIF But I think Flag = 1 is inside the IF/ENDIF in #1 because the rest of the line is ignored if the *IF* is false. I am not near a mmbasic machine to test. anyone out there know for sure what is the answer? ps: I should load up the Linux mmbasic ! |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6100 |
My choice would be: 64 If M=12 And S=10 And Flag=0 Then X=1: Flag=1: ENDIF
65 If M=15 And S=10 And Flag=0 Then X=1: Flag=1: ENDIF 66 If M=18 And S=10 And Flag=0 Then X=1: Flag=1: ENDIF and 642 If MN=0 And S=30 Then CS$="VE": ?@(00,30)" ":?@(00,50)"*": ENDIF 643 If MN=0 And S=40 Then CS$="W6": ?@(00,50)" ":?@(00,70)"*": ENDIF 644 If MN=0 And S=50 Then CS$="KH": ?@(00,70)" ":?@(00,90)"*": ENDIF This way, all the statements after the condition are acted on. The ENDIF is not required if you only have one statement after the condition and therefore no ":" You might also be able to use ELSEIF to make more readable code which should run a bit faster. Using ELSEIF, once a condition is met, the remaining tests are skipped. This is one example of using ELSEIF: IF rwm>3.10 THEN
w= 17 ELSEIF rwm > 2.98 THEN : w = 12 'W ELSEIF rwm > 2.81 THEN : w = 14 'NW ELSEIF rwm > 2.73 THEN : w = 13 ELSEIF rwm > 2.60 THEN : w = 16 'N ELSEIF rwm > 2.40 THEN : w = 15 ELSEIF rwm > 2.25 THEN : w = 10 'SW ELSEIF rwm > 2.00 THEN : w = 11 ELSEIF rwm > 1.70 THEN : w = 2 'NE ELSEIF rwm > 1.40 THEN : w = 1 ELSEIF rwm > 1.10 THEN : w = 8 'S ELSEIF rwm > 0.90 THEN : w = 9 ELSEIF rwm > 0.70 THEN : w = 6 'SE ELSEIF rwm > 0.50 THEN : w = 7 ELSEIF rwm > 0.40 THEN : w = 4 'E ELSEIF rwm > 0.35 THEN : w = 3 ELSE w = 5 ENDIF Jim VK7JH MMedit  MMBasic Help |
||||
mbramwel Regular Member Joined: 10/07/2013 Location: CanadaPosts: 42 |
I just loaded mmbasic on my pc for a test of how the IF statement works 10 flag=0 20 a=1 30 if a=1 then x=1: flag=1 100 print flag also changed line 30 to: 30 if a=1 then x=1: endif: flag=1 The ENDIF made no difference. The FLAG=1 is only executed if a=1. Adding the ENDIF in the middle did not change the displayed value of FLAG. In essence, the above 2 versions of line 30 are this: 30 if a=1 then x=1: flag=1: endif sorry kiid, I disagree with your statement. I think that is one of the quirks of basic. With a "c" like language, I think your statement would be true because of the required { } around blocks of code. |
||||
kiiid Guru Joined: 11/05/2013 Location: United KingdomPosts: 671 |
That's fine. I only said what is a rule. The exact realisation by Geoff might differ a bit but that is normal. They all do. Normally ENDIF should be expected to terminate the IF structure unconditionally. But I am spending 99% of my programming time writing C code so it is quite possible I am looking from a different angle. At least it is good to have that tested and known. Thanks for making the tests and sharing the results http://rittle.org -------------- |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6100 |
And if you place a ":" after the THEN 30 if a=1 then :x=1: flag=1: endif
The ENDIF does have an effect. Try changing it's location. The single line of code now acts exactly the same as a multiline IF The strange behavior of single line IF's has always caused me grief.... Jim VK7JH MMedit  MMBasic Help |
||||
mbramwel Regular Member Joined: 10/07/2013 Location: CanadaPosts: 42 |
No problem. I spend most of my day in Linux and c-like languages (there seems to be lots of them) and although your comment makes sense in our world, I only read about the If statement structure a few nights ago and thought it odd when I read it. I think Geoff's implementation is probably the same as all other Basics, just not what C/C++/python/perl/php people would expect. But hey! I have only been an expert in mmbasic for 1 week, I am still learning! |
||||
Nixie Regular Member Joined: 19/02/2013 Location: AustraliaPosts: 66 |
Gentlemen! Thanks for your input! From that acorn question I have an oak tree growing! Jim, thanks for the ELSEIF info, beautiful. Your info has nicely solved a little problem that caused splinters in my fingers ( a lot of head scratching!! ) Nic. VK3COW |
||||
MicroBlocks Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
The implementation of MMBasic is different then some other basics where an endif is always the end of a IF/ELSE block. The manual has two descriptions! One for single line and one for multiline IFs The single line version: [code] IF expr THEN statement or IF expr THEN statement ELSE statement Evaluates the expression ‘expr' and performs the THEN statement if it is true or skips to the next line if false. The optional ELSE statement is the reverse of the THEN test. This type of IF statement is all on one line. The ‘THEN statement’ construct can be also replaced with: GOTO linenumber | label’ [/code] As you can see the description limits it to ONE statement, not a block of statements! You don't get an error when you use more then one statement and that can cause some problems. The multiline version: [code] IF expression THEN <statements> [ELSE <statements>] [ELSEIF expression THEN <statements>] ENDIF Multiline IF statement with optional ELSE and ELSEIF cases and ending with ENDIF. Each component is on a separate line. Evaluates 'expression' and performs the statement(s) following THEN if the expression is true or optionally the statement(s) following the ELSE statement if false. The ELSEIF statement (if present) is executed if the previous condition is false and it starts a new IF chain with further ELSE and/or ELSEIF statements as required. One ENDIF is used to terminate the multiline IF. [/code] Here you can have statements, notice the s to signify that more than one statement is possible. The seen behavior is undocumented and can change in the future. Until it is documented it can be seen as a bug or a feature. :) It would be best to only choose one of the two documented styles depending on the needs. This will prevent future upgrades to break your code. Microblocks. Build with logic. |
||||
shoebuckle Senior Member Joined: 21/01/2012 Location: AustraliaPosts: 189 |
TZ is right. Sorry, this is going to be a long story!! Single-line vs multi-line IF format ----------------------------------- The rule is that: - if both the THEN clause and optional ELSE clause each have a single statement following them, you can use EITHER the single-line OR the multi-line IF structure but - if either the THEN or the ELSE needs more than one statement you MUST use the multi-line IF format. Sometimes it would appear that multiple statements in a single-line IF format work, but for the wrong reasons. Don't do it. It will come back to bite you. Let me demonstrate some cases I found. Print "IfTest1"
a=2 b=2: c=3 If a=1 Then b=5: c=9: Else b=8: c=9 Print "a=";a, "b=";b, "c=";c Run this code and you might think that, because the test fails, b becomes 8 and c becomes 9. It doesn't. When the test fails, the whole of the rest of the line is flushed. What you get is: Iftest1
a= 2 b= 2 c= 3 Next is a case where the test passes but the ELSE doesn't do what was intended. Print "IfTest2"
a=1 b=2: c=3 If a=1 Then b=5 Else b=8: c=9 Print "a=";a, "b=";b, "c=";c With this code you might have intended c to remain unchanged as part of the ELSE, but it isn't. What you get is: Iftest2
a= 1 b= 5 c= 9 (Incidentally, I had to remove ": c=9:" from the THEN clause in IfTest1 as you get an error when the test returns true.) The other thing that this shows is that the manual is slightly misleading when describing the single-line IF in that it says that it "skips to the next line if false". The example above shows that the second statement after the ELSE (: c=9) is interpreted as being "on the next line". OK so now let's make the IF statement multi-line and it all works as expected. Print "IfTest3"
a=1 b=2: c=3 If a=1 Then: b=5: c=7: Else: b=8: c=9: endif Print "a=";a, "b=";b, "c=";c Print "IfTest4"
a=2 b=2: c=3 If a=1 Then: b=5: c=7: Else: b=8: c=9: endif Print "a=";a, "b=";b, "c=";c IfTest3 is the true case and sets b to 5 and c to 7 whereas IfTest4 is false and sets b to 8 and c to 9. Multi-statement lines vs multi-line statements ---------------------------------------------- If you are coding for speed, then the multi-statement line (as in IfTest5 below) is about 1% faster than when each statement is coded on its own line (IfTest6). On my MonoMM the times were 3883 and 3924 respectively. (Runs under DOS were inconsistent, depending upon what else the computer was doing. Sometimes IfTest5 was slower than IfTest6.) Print "IfTest5"
Timer=0 For i=1 to 20000 a=2 b=2: c=3 If a=1 Then: b=5: c=7: Else: b=8: c=9: endif Next Print Timer Print "IfTest6"
Timer=0 For i=1 to 20000 a=2 b=2: c=3 If a=1 Then b=5 c=7 Else b=8 c=9 endif Next Print Timer Now for those who like to cram as many statements on a line as possible, you can have multiple statements on a line BEFORE a single-line IF, but not AFTER. Thus the first example below is ok but the second isn't. Print "IfTest7":a=2:b=2:c=3:If a=1 Then b=5 Else c=9
Print "a=";a, "b=";b, "c=";c Print "IfTest7":a=2:b=2:c=3:If a=1 Then b=5 Else c=9: Print "a=";a, "b=";b, "c=";c
Statements AFTER a multi-line IF are ok as in IfTest8. Print "IfTest8"
Timer=0 For i=1 to 20000:a=2:b=2:c=3:If a=1 Then:b=5:c=7:Else:b=8:c=9:endif:Next:Print Timer I hope this clears up the single-line vs multi-line IF question. Cheers, Hugh |
||||
Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3194 |
Part of the confusion comes from Bill Gates who added the multi line IF statement to Microsoft Basic. The original BASIC had just the single line version. I think that the multi line version is good but he could have removed or simplified the single line version and that would have reduced the confusion. In MMBasic the ENDIF command is just a marker, it does not actually do anything if the interpreter runs into it. Take this bit of code: IF <condition> THEN
<statement 1> <statement 2> ELSE <statement 3> <statement 4> ENDIF If the condition is true the interpreter starts executing Statement 1 and when it reached the ELSE it searches for the ENDIF and continues with the code after the ENDIF. If the condition is false the interpreter searches for the ELSE or ENDIF (whichever comes first) and starts executing the code after that (ie, Statement 3). When the interpreter reaches the ENDIF it just skips over it because it actually does nothing. When the ENDIF is executed it should check if it is part of a multi line IF statement and throw an error if it is not but that would have added to the bulk of the interpreter and slowed it down a little so I just left it doing nothing. The result is that you can sprinkle extra ENDIFs around with gay abandon and it will have little effect on your program. Geoff Geoff Graham - http://geoffg.net |
||||
Print this page |