OB OB
OB OB

Reputation: 3345

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?

Upvotes: 71

Views: 44210

Answers (15)

Bill K
Bill K

Reputation: 62759

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.

Upvotes: 4

Bill
Bill

Reputation: 4585

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.

Upvotes: 0

Azhar
Azhar

Reputation: 20670

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.

Upvotes: 0

sandy101
sandy101

Reputation: 3427

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 .

Upvotes: 1

qrdl
qrdl

Reputation: 34948

Summarising my initial post and comments - there are several advantages of switch statement over if/else statement:

  1. Cleaner code. Code with multiple chained if/else if ... looks messy and is difficult to maintain - switch gives cleaner structure.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

Upvotes: 178

JustJeff
JustJeff

Reputation: 12980

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 =)

Upvotes: 3

Joseph Paterson
Joseph Paterson

Reputation: 1493

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;
}

Upvotes: 15

KHWP
KHWP

Reputation: 1211

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.

Upvotes: 0

dfa
dfa

Reputation: 116304

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

Upvotes: 17

Carl Manaster
Carl Manaster

Reputation: 40326

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.

Upvotes: 4

hugoware
hugoware

Reputation: 36397

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...
}

Upvotes: 7

Randolpho
Randolpho

Reputation: 56381

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.

Upvotes: 4

Eric Petroelje
Eric Petroelje

Reputation: 60498

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 || ... )

Upvotes: 10

Eric H.
Eric H.

Reputation: 2574

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"?

Upvotes: 32

Erix
Erix

Reputation: 7105

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.

Upvotes: 0

Related Questions