switch without breaks

E

Evie

I understand that when a switch statement is used without breaks, the
code continues executing even after a matching case is found. Why,
though, are subsequent cases not evaluated?

I wrote a program to demonstrate how a switch without breaks behaves
vs. how I expected it to behave. The code includes:
(1) a switch statement with breaks
(2) the if/else statements that have the same results as (1)
(3) a switch statement without breaks
(4) the if/else/goto statements that have the same results as (3)
(5) the if statements that I thought would have the same results as (3)

Below is the code, followed by the output of the program when it's
called with "-b".

#include <stdio.h>

main(int argc, char **argv)
{
int c;

c = getopt(argc, argv, "abcd");
if(c == EOF) {
fprintf(stderr, "ERROR: At least one option must be
used.\n");
exit(1);
}

printf("\n1. Using switch with breaks:\n");
switch(c) {
case 'a':
printf("option a!\n");
break;
case 'b':
printf("option b!\n");
break;
case 'c':
printf("option c!\n");
break;
case 'd':
printf("option d!\n");
break;
default:
printf("wrong option!\n");
}

printf("\n2. Using if/else:\n");
if( c == 'a' ) {
printf("option a!\n");

} else if( c == 'b' ) {
printf("option b!\n");

} else if( c == 'c' ) {
printf("option c!\n");

} else if( c == 'd' ) {
printf("option d!\n");

} else {
printf("wrong option!\n");
}

printf("\n3. Using switch without breaks:\n");
switch(c) {
case 'a':
printf("option a!\n");
case 'b':
printf("option b!\n");
case 'c':
printf("option c!\n");
case 'd':
printf("option d!\n");
default:
printf("wrong option!\n");
}


printf("\n4. Using if/else/goto:\n");
if( c == 'a' ) {
goto a;
} else if( c == 'b') {
goto b;
} else if( c == 'c') {
goto c;
} else if( c == 'd') {
goto d;
}

a: printf("option a!\n");

b: printf("option b!\n");

c: printf("option c!\n");

d: printf("option d!\n");

printf("wrong option!\n");

printf("\n5. Using if:\n");
if( c == 'a' ) {
printf("option a!\n");
}
if( c == 'b' ) {
printf("option b!\n");
}
if( c == 'c' ) {
printf("option c!\n");
}
if( c == 'd' ) {
printf("option d!\n");
}
printf("wrong option!\n");
}

=====================

1. Using switch with breaks:
option b!

2. Using if/else:
option b!

3. Using switch without breaks:
option b!
option c!
option d!
wrong option!

4. Using if/else/goto:
option b!
option c!
option d!
wrong option!

5. Using if:
option b!
wrong option!
 
M

Mike Wahler

Evie said:
I understand that when a switch statement is used without breaks, the
code continues executing even after a matching case is found. Why,
though, are subsequent cases not evaluated?

Because the evaluation only happens in the 'switch' term,
and it only happens once.

int main(void)
{
int x = 2;

switch(x) /* evaluate 'x' */
/* if x == 1, goto case 1 */
/* if x == 2, goto case 2 */
/* any other value, goto default */
{
case 1:
case 2: /* execution will jump to here. */
/* 'x' will not be evaluated again */

default:
}

return 0;
}


-Mike
 
C

Christopher Benson-Manica

Evie said:
I understand that when a switch statement is used without breaks, the
code continues executing even after a matching case is found. Why,
though, are subsequent cases not evaluated?
(3) a switch statement without breaks
(4) the if/else/goto statements that have the same results as (3)
(5) the if statements that I thought would have the same results as (3)

These should tell you everything you wanted to know about switch -
as you can see, it's essentially a glorified goto. That's why 4 and
not 5 duplicated the effects of a switch without breaks. What would
be the point of checking subsequent cases anyway?
 
R

Richard Tobin

Evie said:
I understand that when a switch statement is used without breaks, the
code continues executing even after a matching case is found. Why,
though, are subsequent cases not evaluated?

Your model of switch statements is wrong. The cases aren't tests
which are checked as they are encountered, they are labels indicating
where to start processing. A switch behaves just like your version 4:
printf("\n4. Using if/else/goto:\n");
if( c == 'a' ) {
goto a;
} else if( c == 'b') {
goto b;
} else if( c == 'c') {
goto c;
} else if( c == 'd') {
goto d;
}

so it's not surprising that it produces the same output!

-- Richard
 
M

Michael Mair

Evie said:
I understand that when a switch statement is used without breaks, the
code continues executing even after a matching case is found. Why,
though, are subsequent cases not evaluated?

Because
a) case labels are just that -- labels
b) the numbers for the cases have to be compile time constants.
I wrote a program to demonstrate how a switch without breaks behaves
vs. how I expected it to behave. The code includes:
(1) a switch statement with breaks
(2) the if/else statements that have the same results as (1)
(3) a switch statement without breaks
(4) the if/else/goto statements that have the same results as (3)

See my correction below.

Cheers
Michael
(5) the if statements that I thought would have the same results as (3)

Below is the code, followed by the output of the program when it's
called with "-b".

#include <stdio.h>

main(int argc, char **argv)
{
int c;

c = getopt(argc, argv, "abcd");
if(c == EOF) {
fprintf(stderr, "ERROR: At least one option must be
used.\n");
exit(1);
}

printf("\n1. Using switch with breaks:\n");
switch(c) {
case 'a':
printf("option a!\n");
break;
case 'b':
printf("option b!\n");
break;
case 'c':
printf("option c!\n");
break;
case 'd':
printf("option d!\n");
break;
default:
printf("wrong option!\n");
}

printf("\n2. Using if/else:\n");
if( c == 'a' ) {
printf("option a!\n");

} else if( c == 'b' ) {
printf("option b!\n");

} else if( c == 'c' ) {
printf("option c!\n");

} else if( c == 'd' ) {
printf("option d!\n");

} else {
printf("wrong option!\n");
}

printf("\n3. Using switch without breaks:\n");
switch(c) {
case 'a':
printf("option a!\n");
case 'b':
printf("option b!\n");
case 'c':
printf("option c!\n");
case 'd':
printf("option d!\n");
default:
printf("wrong option!\n");
}


printf("\n4. Using if/else/goto:\n");
if( c == 'a' ) {
goto a;
} else if( c == 'b') {
goto b;
} else if( c == 'c') {
goto c;
} else if( c == 'd') {
goto d;
}

You forgot the default:

goto my_default;
a: printf("option a!\n");

b: printf("option b!\n");

c: printf("option c!\n");

d: printf("option d!\n");

my_default:
 
E

Evie

Michael said:
Because
a) case labels are just that -- labels
b) the numbers for the cases have to be compile time constants.

Reason (b) explains Christopher Benson-Manica's question "What would
be the point of checking subsequent cases anyway?" If the numbers for
the cases could be variables, there would be a point in checking their
values at run time.

Thanks, everyone. I now understand how it works.

- Evie
 
D

Default User

Evie said:
I understand that when a switch statement is used without breaks, the
code continues executing even after a matching case is found. Why,
though, are subsequent cases not evaluated?

One reason is that you can't have multiple values as part of a case. As
others have said, they are just labels.

So:

switch (val)
{
case 1,2,3:
/* do stuff */
}

Is NOT valid. So how do you get one that triggers on any of those three
values?

switch (val)
{
case 1:
case 2:
case 3:
/* do stuff */
}



Brian
 
B

ballpointpenthief

Also,

#include <stdio.h>
#define THIS 1
#define REASON 1
int main(void)
{
int sw;
sw = REASON;
switch(sw)
{
case THIS:
printf("Case 1");
REASON;
case 2:
printf("Case 2");
break;
default:
printf("Default 1");
break;
}
return 0;
}
....and I think two defaults should compile.
 
K

Keith Thompson

ballpointpenthief said:
Also,

#include <stdio.h>
#define THIS 1
#define REASON 1
int main(void)
{
int sw;
sw = REASON;
switch(sw)
{
case THIS:
printf("Case 1");
REASON;
case 2:
printf("Case 2");
break;
default:
printf("Default 1");
break;
}
return 0;
}
...and I think two defaults should compile.

Sorry, I don't understand what point you're making here. Your
"REASON;" is eqivalent to "1;"; it does nothing. The program
will print

Case 1Case 2

because the first case falls through to the second (newlines would be
helpful).

Are you saying that it should be legal to have two "default:" labels
in a single switch statement? Why? What would you expect that to do?
 
B

ballpointpenthief

Whoops, my bad.
I meant to put an example with two equivalent labels.
(and it turns out that that doesn't work.)
 
C

Chuck F.

ballpointpenthief said:
Whoops, my bad.
I meant to put an example with two equivalent labels.
(and it turns out that that doesn't work.)

What, if anything, are you talking about? Include adequate
context. For assistance in doing this on the broken Google Usenet
interface, see my sig. below. Be sure to read the referenced URL
before posting again.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top