if/else coding style consequences - if-statement

I am a novice programmer and was in lecture one evening, we were studying the "if,else" coding section from my professor and I was curious about an aspect of it. What I was curious about was if we have a bunch of nested if,else's in our program, is it just bad coding style to end an if,else with an "else,if" line of code instead of if "x", else "y"? For example,
if "x"
else if "y"
else if "z"
end
compared to
if "x"
else if "y"
else "z"
end
It would still run the program without an error, but are there consequences later on other than having bad programming style?

Behind the curtain JS dont really have else if, all it is doing is generating another if statement when parsed.
e.g:
if(foo){
} else if (baz){
}
becomes
if (foo){
} else {
if (baz){
}
}
So the reason for using another else if in the end instead of else is when you want to control the else statement as-well and not just pass to that case everything else that don't fit in your first condition... (In order to control the else condition and filter it to the necessary items only)
if you do have a really long statement with a lot of else-if conditions you should consider using switch statement instead.

It all depends on what you are looking to do. The former example makes sure that all IF requirements are met. There would be instances that none of the IFs get hit in this case.
In the latter example however, ELSE "Z" would get hit for sure if all above IFs fail. This would be useful if you are assigning a variable within your IFs - your variable will definitely have a value at the end of the IF statement. If it was as in the first example, the variable will be null and might result in a null error if you try to use it later.
If there are a lot of if-thens, I would checkout the case/switch statement as well, as it is more neater to implement.
Also, remember to comment your code well - especially explaining what all the nested IFs are doing.

Related

basic if statement 3 values in c++

I am new and beginner in programming and dont quiet understand how to post my question here. Hope this works.
Anyways, im starting from basic and just learnt the "if" statement. But when i tried to create my own version its not working. My program below is showing all three cout results even if i enter only one option(attack or run or hide). It was working fine when there was just one "if" statement. I tried the "else if" too but then it only printed out the result "you have attacked" no matter what i chose. :( I used the search bar for similar questions that might have already been answered but didnt find much that could help me.
If there are similar questions then i'd appreciate if you could point me towards it, although i'd really be grateful if you could point out what my mistakes are specifically.
Thnx~
#include <iostream>
#include <string>
using namespace std;
int main(){
cout<<"Welcome to the jungle!!!"<<endl;
cout<<"--------"<<endl;
cout<<"Enemies approaches! \n Choose your next move! \n";
cout<<"Attack / Run / Hide \n\n\n";
string choice;
cin>>choice;
if(choice=="Attack"||"attack")
{
cout<<"You have attacked!"<<endl;
}
if(choice=="Run"||"run")
{
cout<<"You start running!"<<endl;
}
if(choice=="Hide"||"hide")
{
cout<<"You hide in a cave!"<<endl;
}
return 0;
}
if(choice=="Attack"||"attack")
does not mean "if choice contains "Attack", or choice contains "attack", do the thing".
It means "if choice contains "Attack", or "attack" is true, do the thing".
In pseudo-code, you expect:
if choice is the string "Attack"
or choice is the string "attack"
do a thing
but the or splits the statement into halves, and the second half doesn't mention the variable choice at all. It breaks down more like
if choice is the string "Attack"
or the string "attack" on its own is somehow true, whatever that might mean
do a thing
Since "attack" is a pointer to a char array, being true means it is not NULL, which is always the case, so this branch is always entered.
To express what you mean, write instead:
if(choice=="Attack"||choice=="attack")
Welcome to C/C++ world.
As you have already read in tutorials or book, the content inside the parens of an if has to be a boolean value. Now, a lot of stuff can be converted automatically to bool and as a condition for an if.
In particular, anything that can be converted to an int will, in turn, have a bool value attached to it. Pointers are of such kind.
If the value is different from 0 then the result will be -> true
0 otherwise.
Writing if(choice=="Attack"||"attack") you are telling the compiler to execute the content of the if either if the content of choice is equal to the string Attack or if the the pointer to the underlying const char* attack is not zero.
attack is a valid string which mean its value is not zero which in turn means you are getting a true out of it.
Same goes for all the others ifs. The second part of all you ifs are true cause they are not null pointers.
Change the all the ifs as the following: if(choice=="Attack"||choice=="attack") and the problem will be fixed.
You must use
if(choice=="Attack"||choice=="attack")
{
cout<<"You have attacked!"<<endl;
}
OR( || ) is a boolean operator.
So Anything other than 0 gives an impression of 1 in boolean. Thus the syntax in if code is always executed. This is the reason for in the else if case first statement is always executed (and further statements are skipped).
Also, using namespace std; is a bad practice since it makes our code confined to just one std library. instead you must use std:cout;

Is it preferred to use else or else-if for the final branch of a conditional

What's preferred
if n > 0
# do something
elsif n == 0
# do something
elsif n < 0
# do something
end
or
if n > 0
# do something
elsif n == 0
# do something
else
# do something
end
I was using else for awhile. I recently switched to doing elsif. My conclusions are the first option adds readability at the cost of more typing, but could confuse some people if they expect an else. I don't have enough experience to know if the first option would create more readability or more confusion and if there are other pros/cons I've missed.
For my specific example, where the scope of else is comparable to the previous conditions and what it does catch can be expressed as a simple condition, is using else preferable for the final branch? Also, would a different conditional influence the answer? I wrote the code in Ruby but I assume the answer is language agnostic. If it isn't, I would also like to know why.
You should know every execution path through your conditional logic regardless. That being said, a simple else for the remaining case is usually the most clear. If you only have an else if it makes the next guy scratch his head and wonder if you are missing something. If it makes you feel better to say "else what" then put an inline comment in else # n < 0
edit after your edit:
For my specific example, where the scope of else is comparable to the previous conditions and what it does catch can be expressed as a simple condition, is using else preferable for the final branch? Also, would a different conditional influence the answer? I wrote the code in Ruby but I assume the answer is language agnostic. If it isn't, I would also like to know why.
Yes, else is still preferable. I can't think of any scenario that changes this answer. Having the else implies completeness in your logic. Not having the else will be distracting - others (or you at a later date) will have to spend more time scrutinizing the code to double check to make sure all conditions are being handled. In fact the coding standard I abide by, the Embedded C Coding Standard by BARR Group says this:
"Any if statement with an else if clause shall end with an else clause. ... This is the equivalent of requiring a default case in every switch."
This echos MISRA rule 14.10
All if ... else if constructs shall be terminated with an else clause.
*All of my examples pertain to C, but as you said in the post, this is someone agnostic to the language being used.
I always prefer the plain else - it makes it obvious to anyone that your intention is "if all else fails, do this" (no pun intended).
In your example you only have 3 possible states, but what about if there were more?
If you want the final conditional statement to be a catch-all, then you should use just else. If you would like, for clarity, you could do something like this:
else # n < 0
# do something
(Note the n < 0 is just a comment). A couple reasons for this:
Depending on the language/compiler, there could be a speed improvement
Less likely to make a programming mistake. Your example above is fairly simple, but imagine a situation in which there is a fourth option that you did not consider at the time of programming? In that case, no action would be taken, when you probably meant for it to fall into the else statement.
else creates a catch-all, with only elsifs none of the choices might be executed. Each specific situation needs its own solution, so I would use what is necessary.
else clarifies that it is the only branch of the program at that point. If the execution makes it there, no matter what it should go through the else. If that's your intention, use else, not elseif because although you can make the exact same program using elseif as the last statement, it sort of linguistically implies that it will only conditionally execute that block of code.

use of "else if" in c++

I have two questions -
(I)
code-fragment-1
if(<condition-statement>){
}
else if(<condition-statement-2>){
//statements-1
}
//statements-2
code-fragment-2
if(<condition-statement>){
}
else{
if(<condition-statement-2>){
//statements-1
}
//statements-2
}
Are the above two code fragments same?
(II) when are else ifs (in C++) used?
The only difference is in example 1 your Statement2 will get executed regardless of the conditions you check. In example 2, Statement2 will only get executed if your if condition is false. Other than that, they're basically the same.
No, in the first case you execute the else block only if the <condition-statement> is not verified AND only if <condition-statement-2> is verified.
In the second case you execute the else block simply if the <codition-statement> is not verified.
In this case are equivalent until you does not have any //statements-2.
About the question : when is the else if (in c++) used ?
Is used basically under the same conditions of all other languages​​ that have this construct.
else is executed as alternative to the related if, else-if is executed as alternative but with an 'attached' if to be verified, otherwise is not executed.
So they are not logically equivalent.
the syntax of an if is really
if(condition) statement;
What the {} really do is allow you to group together multiple statements. In your second example you only have one statement(the if) inside your {}s, so yes, both examples are the same, except //statements-2 always gets run when !=true
In your first code sample, statement-2 is executed unconditionally. In the second it is conditional. Not the same.
'else if' is generally to be preferred, because you can keep inserting or appending more of them indefinitely, or append an 'else', whereas with the other form you have to endlessly mess around with braces to get the same effect, and you risk altering the semantics, as indeed you have done in your second sample.

Another way to use continue keyword in C++

Recently we found a "good way" to comment out lines of code by using continue:
for(int i=0; i<MAX_NUM; i++){
....
.... //--> about 30 lines of code
continue;
....//--> there is about 30 lines of code after continue
....
}
I scratch my head by asking why the previous developer put the continue keyword inside the intensive loop. Most probably is he/she feel it's easier to put a "continue" keyword instead of removing all the unwanted code...
It trigger me another question, by looking at below scenario:
Scenario A:
for(int i=0; i<MAX_NUM; i++){
....
if(bFlag)
continue;
....//--> there is about 100 lines of code after continue
....
}
Scenario B:
for(int i=0; i<MAX_NUM; i++){
....
if(!bFlag){
....//--> there is about 100 lines of code after continue
....
}
}
Which do you think is the best? Why?
How about break keyword?
Using continue in this case reduces nesting greatly and often makes code more readable.
For example:
for(...) {
if( condition1 ) {
Object* pointer = getObject();
if( pointer != 0 ) {
ObjectProperty* property = pointer->GetProperty();
if( property != 0 ) {
///blahblahblah...
}
}
}
becomes just
for(...) {
if( !condition1 ) {
continue;
}
Object* pointer = getObject();
if( pointer == 0 ) {
continue;
}
ObjectProperty* property = pointer->GetProperty();
if( property == 0 ) {
continue;
}
///blahblahblah...
}
You see - code becomes linear instead of nested.
You might also find answers to this closely related question helpful.
For your first question, it may be a way of skipping the code without commenting it out or deleting it. I wouldn't recommend doing this. If you don't want your code to be executed, don't precede it with a continue/break/return, as this will raise confusion when you/others are reviewing the code and may be seen as a bug.
As for your second question, they are basically identical (depends on assembly output) performance wise, and greatly depends on design. It depends on the way you want the readers of the code to "translate" it into english, as most do when reading back code.
So, the first example may read "Do blah, blah, blah. If (expression), continue on to the next iteration."
While the second may read "Do blah, blah, blah. If (expression), do blah, blah, blah"
So, using continue of an if statement may undermine the importance of the code that follows it.
In my opinion, I would prefer the continue if I could, because it would reduce nesting.
I hate comment out unused code. What I did is that,
I remove them completely and then check-in into version control.
Who still need to comment out unused code after the invention of source code control?
That "comment" use of continue is about as abusive as a goto :-). It's so easy to put an #if 0/#endif or /*...*/, and many editors will then colour-code the commented code so it's immediately obvious that it's not in use. (I sometimes like e.g. #ifdef USE_OLD_VERSION_WITH_LINEAR_SEARCH so I know what's left there, given it's immediately obvious to me that I'd never have such a stupid macro name if I actually expected someone to define it during the compile... guess I'd have to explain that to the team if I shared the code in that state though.) Other answers point out source control systems allow you to simply remove the commented code, and while that's my practice before commit - there's often a "working" stage where you want it around for maximally convenient cross-reference, copy-paste etc..
For scenarios: practically, it doesn't matter which one you use unless your project has a consistent approach that you need to fit in with, so I suggest using whichever seems more readable/expressive in the circumstances. In longer code blocks, a single continue may be less visible and hence less intuitive, while a group of them - or many scattered throughout the loop - are harder to miss. Overly nested code can get ugly too. So choose either if unsure then change it if the alternative starts to look appealing.
They communicate subtly different information to the reader too: continue means "hey, rule out all these circumstances and then look at the code below", whereas the if block means you have to "push" a context but still have them all in your mind as you try to understand the rest of the loop internals (here, only to find the if immediately followed by the loop termination, so all that mental effort was wasted. Countering this, continue statements tend to trigger a mental check to ensure all necessary steps have been completed before the next loop iteration - that it's all just as valid as whatever follows might be, and if someone say adds an extra increment or debug statement at the bottom of the loop then they have to know there are continue statements they may also want to handle.
You may even decide which to use based on how trivial the test is, much as some programmers will use early return statements for exceptional error conditions but will use a "result" variable and structured programming for anticipated flows. It can all get messy - programming has to be at least as complex as the problems - your job is to make it minimally messier / more-complex than that.
To be productive, it's important to remember "Don't sweat the small stuff", but in IT it can be a right pain learning what's small :-).
Aside: you may find it useful to do some background reading on the pros/cons of structured programming, which involves single entry/exit points, gotos etc..
I agree with other answerers that the first use of continue is BAD. Unused code should be removed (should you still need it later, you can always find it from your SCM - you do use an SCM, right? :-)
For the second, some answers have emphasized readability, but I miss one important thing: IMO the first move should be to extract that 100 lines of code into one or more separate methods. After that, the loop becomes much shorter and simpler, and the flow of execution becomes obvious. If I can extract the code into a single method, I personally prefer an if:
for(int i=0; i<MAX_NUM; i++){
....
if(!bFlag){
doIntricateCalculation(...);
}
}
But a continue would be almost equally fine to me. In fact, if there are multiple continues / returns / breaks within that 100 lines of code, it is impossible to extract it into a single method, so then the refactoring might end up with a series of continues and method calls:
for(int i=0; i<MAX_NUM; i++){
....
if(bFlag){
continue;
}
SomeClass* someObject = doIntricateCalculation(...);
if(!someObject){
continue;
}
SomeOtherClass* otherObject = doAnotherIntricateCalculation(someObject);
if(!otherObject){
continue;
}
// blah blah
}
continue is useful in a high complexity for loop. It's bad practice to use it to comment out the remaining code of a loop even for temporary debugging since people tends to forget...
Think on readability first, which is what is going to make your code more maintainable. Using a continue statement is clear to the user: under this condition there is nothing else I can/want to do with this element, forget about it and try the next one. On the other hand, the if is only telling that the next block of code does not apply to those for which the condition is not met, but if the block is big enough, you might not know whether there is actually any further code that will apply to this particular element.
I tend to prefer the continue over the if for this particular reason. It more explicitly states the intent.

Why Switch/Case and not If/Else If?

This question in mainly pointed at C/C++, but I guess other languages are relevant as well.
I can't understand why is switch/case still being used instead of if/else if. It seems to me much like using goto's, and results in the same sort of messy code, while the same results could be acheived with if/else if's in a much more organized manner.
Still, I see these blocks around quite often. A common place to find them is near a message-loop (WndProc...), whereas these are among the places when they raise the heaviest havoc: variables are shared along the entire block, even when not propriate (and can't be initialized inside it). Extra attention has to be put on not dropping break's, and so on...
Personally, I avoid using them, and I wonder wether I'm missing something?
Are they more efficient than if/else's?
Are they carried on by tradition?
Summarising my initial post and comments - there are several advantages of switch statement over if/else statement:
Cleaner code. Code with multiple chained if/else if ... looks messy and is difficult to maintain - switch gives cleaner structure.
Performance. For dense case values compiler generates jump table, for sparse - binary search or series of if/else, so in worst case switch is as fast as if/else, but typically faster. Although some compilers can similarly optimise if/else.
Test order doesn't matter. To speed up series of if/else tests one needs to put more likely cases first. With switch/case programmer doesn't need to think about this.
Default can be anywhere. With if/else default case must be at the very end - after last else. In switch - default can be anywhere, wherever programmer finds it more appropriate.
Common code. If you need to execute common code for several cases, you may omit break and the execution will "fall through" - something you cannot achieve with if/else. (There is a good practice to place a special comment /* FALLTHROUGH */ for such cases - lint recognises it and doesn't complain, without this comment it does complain as it is common error to forgot break).
Thanks to all commenters.
Well, one reason is clarity....
if you have a switch/case, then the expression can't change....
i.e.
switch (foo[bar][baz]) {
case 'a':
...
break;
case 'b':
...
break;
}
whereas with if/else, if you write by mistake (or intent):
if (foo[bar][baz] == 'a') {
....
}
else if (foo[bar][baz+1] == 'b') {
....
}
people reading your code will wonder "were the foo expressions supposed to be the same", or "why are they different"?
please remember that case/select provides additional flexibility:
condition is evaluated once
is flexible enough to build things like the Duff's device
fallthrough (aka case without break)
as well as it executes much faster (via jump/lookup table) * historically
Also remember that switch statements allows the flow of control to continue, which allows you to nicely combine conditions while allowing you to add additional code for certain conditions, such as in the following piece of code:
switch (dayOfWeek)
{
case MONDAY:
garfieldUnhappy = true;
case TUESDAY:
case WEDNESDAY:
case THURSDAY:
case FRIDAY:
weekDay = true;
break;
case SATURDAY:
weekendJustStarted = true;
case SUNDAY:
weekendDay = true;
break;
}
Using if/else statements here instead would not be anywhere as nice.
if (dayOfWeek == MONDAY)
{
garfieldUnhappy = true;
}
if (dayOfWeek == SATURDAY)
{
weekendJustStarted = true;
}
if (dayOfWeek == MONDAY || dayOfWeek == TUESDAY || dayOfWeek == WEDNESDAY
|| dayOfWeek == THURSDAY || dayOfWeek == FRIDAY)
{
weekDay = true;
}
else if (dayOfWeek == SATURDAY || dayOfWeek == SUNDAY)
{
weekendDay = true;
}
If there are lots of cases, the switch statement seems cleaner.
It's also nice when you have multiple values for which you want the same behavior - just using multiple "case" statements that fall through to a single implementation is much easier to read than a if( this || that || someotherthing || ... )
It might also depend on your language -- For example, some languages switch only works with numeric types, so it saves you some typing when you're working with an enumerated value, numeric constants... etc...
If (day == DAYOFWEEK_MONDAY) {
//...
}
else if (day == DAYOFWEEK_TUESDAY) {
//...
}
//etc...
Or slightly easier to read...
switch (day) {
case DAYOFWEEK_MONDAY :
//...
case DAYOFWEEK_TUESDAY :
//...
//etc...
}
Switch/case is usually optimized more efficiently than if/else if/else, but is occasionally (depending on language and compiler) translated to simple if/else if/else statements.
I personally think switch statements makes code more readable than a bunch of if statements; provided that you follow a few simple rules. Rules you should probably follow even for your if/else if/else situations, but that's again my opinion.
Those rules:
Never, ever, have more than one line on your switch block. Call a method or function and do your work there.
Always check for break/ case fallthrough.
Bubble up exceptions.
Clarity. As I said here, a clue that else if is problematic is
the frequency with which ELSE IF is
used in a far more constrained way
than is allowed by the syntax. It is a
sledgehammer of flexibility,
permitting entirely unrelated
conditions to be tested. But it is
routinely used to swat the flies of
CASE, comparing the same expression
with alternate values...
This reduces the readability of the
code. Since the structure permits a
universe of conditional complexity,
the reader needs to keep more
possibilities in mind when parsing
ELSE IF than when parsing CASE.
Actually a switch statement implies that you are working off of something that is more or less an enum which gives you an instant clue what's going on.
That said, a switch on an enum in any OO language could probably be coded better--and a series of if/else's on the same "enum" style value would be at least as bad and even worse at conveying meaning.
addressing the concern that everything inside the switch has equivalent scope, you can always throw your case logic into another { } block, like so ..
switch( thing ) {
case ONETHING: {
int x; // local to the case!
...
}
break;
case ANOTHERTHING: {
int x; // a different x than the other one
}
break;
}
.. now I'm not saying that's pretty. Just putting it out there as something that's possible if you absolutely have to isolate something in one case from another.
one other thought on the scope issue - it seems like a good practice to only put one switch inside a function, and not a lot else. Under those circumstances, variable scope isn't as much of a concern, since that way you're generally only dealing with one case of execution on any given invocation of the function.
ok, one last thought on switches: if a function contains more than a couple of switches, it's probably time to refactor your code. If a function contains nested switches, it's probably a clue to rethink your design a bit =)
switch case is mainly used to have the choice to made in the programming .This is not related the conditional statement as :
if your program only require the choice to make then why you use the if/else block and increase the programming effort plus it reduce the execution speed of the program .
Switch statements can be optimized for speed, but can take up more memory if the case values are spread out over large numbers of values.
if/else are generally slow, as each value needs to be checked.
A Smalltalker might reject both switch and if-then-else's and might write something like:-
shortToLongDaysMap := Dictionary new.
shortToLongDaysMap
at: 'Mon' put: 'Monday';
at: 'Tue' put: 'Tuesday';
at: 'Wed' put: 'Wednesday'
etc etc.
longForm := shortToLongDaysMap at: shortForm ifAbsent: [shortForm]
This is a trivial example but I hope you can see how this technique scales for large numbers of cases.
Note the second argument to at:IfAbsent: is similar to the default clause of a case statement.
The main reason behind this is Maintainability and readability. Its easy to make code more readable and maintainable with Switch/case statement then if/else. Because you have many if/else then code become so much messy like nest and its very hard to maintain it.
And some how execution time is another reason.
Pretty sure they compile to the same things as if/else if, but I find the switch/case easier to read when there are more than 2 or 3 elses.