Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I was wondering the if if-else statements, is like a switch statement that does have a break statement.

if( boolean_expression_1 )
  statement_1
else if( boolean_expression_2 )
  statement_2
else 
  default_statement

Is the same as:

switch( controlling_expression )
{
case: ( boolean_expression_1 )
{
     statement_1
     break;
}
case: ( boolean_expression_2 )
{
     statement_2
     break;
}
default:
{
     default_statement
}
share|improve this question
    
Changed the question to what I really meant, WHICH was the OPPOSITE of what I origanally asked. Edited example to match intended question. I know some of you ansewered whether the two statements were Seemingly the same, and other's responded whether they were Literally the same. I appreciate the both, as it gives an angle of thougt of preseseved similiarities and also what they are ( different / alike ) deep down –  Chris Okyen Oct 22 '12 at 20:26
    
If you find these types of constructs interesting, I'd highly recommend taking a look at pattern matching conditionals and guards. The concepts are very similar but can be wonderfully expressive. I'm familiar with them in F# but on the JVM, I believe Scala supports them. –  Steve Evers Oct 23 '12 at 6:08

5 Answers 5

I was wondering the if if-else statements, is like a switch statement that does not have a break statement.

That's backwards. Kind of.

An if, else if, ... else sequence in which all of the tests are all simple equality tests on the same variable of the form (variable == value) or ((variable == value1) || (variable == value2) ...) can be converted to a switch statement on that variable. The (variable == value) tests become case value:, and the body of the if (or else if) becomes the body of the case, but you need to add a break statement at the end of the case body. The ((variable == value1) || (variable == value2) ...) tests become a sequence of cases of the form case value1: case value2: ... case valuen: An if sequence with more complex tests is in general distinct from a switch statement.

If every case in a switch statement ends with break, that switch statement can always be rewritten as an if, else if, ... sequence. This conversion from a switch to an if sequence is also possible when fall through is limited to things such as case A: case B: ... case N: do_something(); break; Fall through in which a non-empty body falls through to another non-empty body is not directly convertible to an if sequence.

share|improve this answer
    
Thanks. if-else statements are percieved/seemingly switch ( ... ) statements with a break at every end of each case body. Multiple if statements alone without an else pair, are percieved/seemingly switch( ... ) statements with No breaks at the end of each case body. I would describe how it be percieved, adding the details of nesting, but that'd be out of scope/more to chew for the chunk of this question. –  Chris Okyen Oct 22 '12 at 20:39

Although thinking about an if-else block as being like a switch statement without a break might be a helpful abstraction for a new programmer, it is not a perfect comparison.

Switch is probably closer related to "goto". Granted, Java doesn't have Goto, but the language was built upon ideas from other languages like C that did. The "case" and "default" labels are not really any different than any other jump target for a goto statement, so the expected behavior would be to continue executing the next line of code within the block (the entire switch statement is the block). This is explained further in one of the answers on a related question: Why do we have to use break in switch So we end up with the case that you need a break statement to tell your program you're done executing this block. You could use break in other types of statements such as a for or while loop similarly.

In languages such as java that use short-circuiting, in an if-elseif-else block, if the condition for the first case of the if statement is true, the else if and else block conditions will not be evaluated. After an if it is expected that you will either find a block of code enclosed braces {} or a single statement. By definition, else means "otherwise" or that the previous condition was not true, it would be a bit contradictory to let the code fall through.

share|improve this answer
    
"Although thinking about an 'if-else' block as being like a 'switch-statement' without a break might be a helpful abstraction for a new programmer, it is not a perfect comparison." - Don't you mean "thinking about an 'if-else' block as being like a 'switch-statement' with a break...?" –  Chris Okyen Oct 4 '12 at 20:00
    
Contradictory is right! –  Chris Okyen Oct 22 '12 at 21:15

Programming languages often provide many different constructs which allow you to express similar logic using different syntax.

if/else statements do not "fall through" to each another unconditionally; the else keyword prevents any further else-if conditions being evaluated just as a break at the end of a case-block gets you out of a switch, however creating a set of standalone ifs (without using else) will cause each if condition to be evaluated on its own.

Coversely, removing the break keyword from the end of your case blocks will cause the flow of execution to unconditionally keep falling through to the next case until either a break/return/goto is encountered or the end of the switch block has been reached.

There are (rarely) situations where switch-case fallthrough is considered to be useful; however its more common, and usually more idiomatic to want each case block to be treated on its own.

if-else and switch-case are both constructs which allow you to express selection (decision making) in a programming language; sometimes the choice between the two is down to personal style, other times there are compelling reasons to choose one over the other - A similar choice exists when choosing for-vs-while to express repetition.

share|improve this answer
    
Thanks. One example of a situations where switch-case fall through is considered to be useful is when if you want one case to do something and possibly allow something further to happen after a true outcome for that case if the next case is true also... switch ( i ) case: A { break; } case: B { .... } case: C { .... break } So if B occurs and then allows the possibility of C occurring... –  Chris Okyen Sep 21 '12 at 22:18

The answer is no - the if-statement is not like a switch-statement without a break. Let us begin with this part of your question:

if boolean_expression_1 was true, would it check if boolean_expression_2 is true?

We can find the answer with this program. The trick is, that we call a method as our boolean_expression and use System.out.println() to see, if the method gets executed. This way we know if the expression was evaluated. Here is the program:

public class IfElseExample {

    private static boolean booleanExpression1() {
        System.out.println("Expression 1 is being evaluated.");
        return true;
    }

    private static boolean booleanExpression2() {
        System.out.println("Expression 2 is being evaluated.");
        return true;
    }

    public static void main(String[] args) {
        if (booleanExpression1()) 
            System.out.println("Statement 1 is executed");
        else if (booleanExpression2()) 
            System.out.println("Statement 2 is executed");
        else
            System.out.println("Default statement is executed");
    }

}

You will see, that the second boolean expression is not evaluated. This behavior probably becomes more understandable if you put in some brackets (which is a good habit in most cases):

    if (booleanExpression1()) { 
        System.out.println("Statement 1 is executed");
    } else {
        if (booleanExpression2()) {
            System.out.println("Statement 2 is executed");
        } else {
            System.out.println("Default statement is executed");
        }
    }

This is the way, the compiler views your original if-chain. As you can see now, the second "if" is a single statement of its own and as such it is not on the same level as the first if-statement. If you chain more if-statements those get nested even deeper.

You also asked, why the switch-statement needs a break statement. This is because the switch-statement is not implemented internally with a chain of if-statement (neither is the if-statement based upon switch-statements). You might expect that

        switch(controllingExpression()) {
            case 42: System.out.println("A");
                        case 43: System.out.println("B");
            default : System.out.println("z");
        }

gets translated by the compiler into something like:

if (controllingExpression() == 42) {
    System.out.println("A");
} else if (controllingExpression() == 43) {
    System.out.println("B");
} else {
    System.out.println("z");
}

This is not the case. Instead it uses a hidden skip-statement:

int x = numberOfStatementsToSkipFor(controllingExpression());
skip x // hidden skip the next x statements byte code instruction
System.out.println("A");
System.out.println("B");
System.out.println("z");

The method numberOfStatementsToSkipFor() returns 0 for 42, 1 for 43 and 2 for everything else. Now it becomes clear why this program might produce

A
B
z

or

B
z

or just

z

but never

A
B

without the 'z'. But clearly it would be nice if we could do this. And we can by using break which gets translated into another skip statement. So if you put break into all case-branches

switch(controllingExpression()) {
    case 42: {
        System.out.println("A");
        break;
    }
    case 43: {
        System.out.println("B");
        break;
    }
    default : System.out.println("z");
}

the compiler will produce this:

int x = numberOfStatementsToSkip(controllingExpression());
skip x; // hidden skip the next x statements byte code instruction
System.out.println("A");
skip 3; //"B" + skip + "z"
System.out.println("B");
skip 1;
System.out.println("z");
share|improve this answer
    
Thanks I understood everything up to the 'int x = numberOfStatementsToSkipFor(controllingExpression());' code chunk that described how the it will skip the next x number of bytecode instructions if you have a switch statement as you showed. Does the compiler turn the switch statement to code that tells it to skip X # of bytecode and the JVM does so? –  Chris Okyen Sep 24 '12 at 19:38
    
Also I do not understand how this skip proces works... I know some M6800 asm, is it like jumping the pointer to the call stack X amount... Don't all the statements of the 2 cases adn the default get called so why would they be skipped. How does it know to skip them. And why did you put skip only the statements ( or actions ) called due to the cases being true... Isn't the switch { and case: code and default: and } code need to be skipped op code or is that not real "opcode" but just logic put into higher level programming languages like C and Java and Pascal? –  Chris Okyen Sep 24 '12 at 19:43
    
@ChrisOkyen I was trying to illustrate the basic concept. The actual realization in the JVM is described here: artima.com/underthehood/flowP.html –  scarfridge Sep 25 '12 at 9:56

To answer the edited question (with the breaks)

They would evaluate the statements the same, if and only if the conditions to enter each block is the same.

To answer the subjective question, of

gives an angle of thought of preserved similarities and also what they are ( different / alike ) deep down

Comparing the two distracts you from what each was designed to quickly express.

A switch syntactically centralizes the comparison so that you can follow the flow based on its cases.

While an if describes a single condition to enter a block.

Basically the code just "reads" differently.

For example, you have a word in your head and you want to look it up in the dictionary.

A switch would read like: hold the starting letter in your head, and then thumb through the alphabet, then give up if it doesn't start with that letter.

While a bunch of if-else blocks would read like: does word start with letter? repeated many times, then give up.

If you are trying to explain how a switch works to a new programmer (who is familiar with if blocks, it might be easier to explain it as:

if( boolean_expression_1 ) {
  statement_1;
  return;
}

if( boolean_expression_2 ) {
  statement_2;
  return;
}

default_statement;
return;

Now the preceding example breaks what is typically taught in schools, but return early and return often is sometimes easier to read, and just as fast in a stack based vm.

There should be optimizations for switches on primitives, so the choice of which to control block to use should be based on what you are comparing.

Remember that lengthy switch and if statements tend to become very verbose, hard to maintain, and also degrade in performance as more conditions would have to be checked.

You might want to consider a Hash of anonymous classes/functions or a command pattern, instead of lengthy control blocks with many conditions.

Hashes and command pattern allows the code to perform faster, and improves the maintainability of the code.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.