Cascading if
I might teach this indentation pattern for if
when there’s more than two arms, as an alternative to actually nesting them. (The parse tree is still nested, but the indentation level isn’t.)
if (expr == 1) {
…
} else {
if (expr == 2) {
…
} else {
if (expr == 3) {
…
} else {
…
}
}
}
⇒
if (expr == 1) {
…
} else if (expr == 2) {
…
} else if (expr == 3) {
…
} else {
…
}
switch
/ case
I like to introduce switch
as an alternative to “chained” if
statements:
if (expr == 1) {
…
} else if (expr == 2) {
…
} else if (expr == 3) {
…
} else {
…
}
⇒
switch (expr) {
case 1:
…
break;
case 2:
…
break;
case 3:
…
break;
default:
…
}
that has the advantages:
- Communicates the design intent – this is the most important
- Only evaluates
expr
once (doesn’t matter ifexpr
is a variable)
Note: Having to use break
(in C/C++/Arduino, but lots of other languages too) is a gotcha and an annoyance though.
Note: It took me decades to get straight that switch
goes on the outside and case
is the thing that goes inside. Then I made the mnemonic that there are a number of different cases, and I haven’t gotten confused since. (It’s so direct and obvious that it’s barely a mnemonic, but I needed it.) I think if I’d thought more about mechanical switches I could have used that as mnemonic too.
The else
is optional
In a chained if
, the else
is optional. In a switch
/case
, the default
is optional.
if (expr == 1) {
…
} else if (expr == 2) {
…
} else if (expr == 3) {
…
}
switch (expr) {
case 1:
…
break;
case 2:
…
break;
case 3:
…
break;
}
Optional break
The break
comes in handy when two (or more) cases share the same code:
if (expr == 1) {
// executed when expr is 1
} else if (expr == 2 || expr == 3) {
// executed when expr is 2 or 3
}
switch (expr) {
case 1:
// executed when expr is 1
break;
case 2:
case 3:
// executed when expr is 2 or 3
break;
}