Into the following code case 1:
to case 2:
and case 5:
seem to have no code for execution. My question is can't we just omit typing them?
switch(c)
{
case 1:
case 2:
case 3:
a++;
break;
case 5:
default:
b++;
break;
}
Into the following code case 1:
to case 2:
and case 5:
seem to have no code for execution. My question is can't we just omit typing them?
switch(c)
{
case 1:
case 2:
case 3:
a++;
break;
case 5:
default:
b++;
break;
}
They fall through, i.e. if you encounter 1
or 2
it will jump into these cases and since there's no break
just continue with case 3
. So you can not omit those, because otherwise 1
and 2
would jump to default
.
Similarily, case 5
will fall through to default
, meaning that you could omit case 5
.
Essentially, switch
statements can be imagined as goto
-jumps to the appropriate positions. That means, that the program will jump into the appropriate case and continue working from there until it finds break
or return
. This means, that you have to write break
or return
explicitly if you don't want your program to continue execution in the subsequent case
.
My question is can't we just omit typing them?
TL;DR -- In your case, No. They have some meaning.
Quoting C11
, chapter §6.8.4.2, The switch
statement
The integer promotions are performed on the controlling expression. The constant expression in each case label is converted to the promoted type of the controlling expression. If a converted value matches that of the promoted controlling expression, control jumps to the statement following the matched
case
label....
That means, based on the value of c
here, the particular "case" will be executed.
Fine. Wait, now we know where to take the control to start execution, but where to stop, exactly?
You're thinking "before the next case
body?"
Well, not exactly. It does not automatically stop . Usually, we use a break;
statement after each case
block, to "mark" the end of that particular case. In case, the break;
is not present, it will continue to execute the statements from following case
s (if any), as if they are part of the same case
block and it will continue until it reaches the end of switch
body.
Now, to elaborate, in your case, if the value of c
is either 1
, 2
or 3
, it will execute the statement block for case 3
. Notice, there is no break;
statement after case 1:
and case 2:
labels. It is kind of "fall-through" technique.
OTOH, if you remove the case 1:
and case 2:
labels, if c
holds 1
or 2
, the control won't reach the block after case 3:
, it will go to default:
label.
However, case 5:
will fall through to default:
label, making it redundant. This once can be removed.
No, you can't omit them. Basically cases 1
and 2
will fallthrough to 3
. Omitting them would cause the default case to be executed for input values 1
and 2
.
It's a fallthrough case. That means the cases fall down until a break appears. So a++
would be excecuted with c
being 1, 2, 3.
The cases for 1,2 and 3 mean that if c=1,2 or 3 then a++. If c=5 or different then b++ - note that the code only stops if you hit a break so that c=1 gives the same as c=3 for example.
They may be omitted but the result would be different.
Basically what the code does is for c
equal to 1, 2, or 3 a++
gets executed, otherwise, b++
does.
In this case case 5:
should be omitted after all as it will falls in the default:
case.
You can indeed omit a case. This switch statement
switch(c)
{
case 1:
case 2:
case 3:
a++;
break;
case 5:
default:
b++;
break;
}
can be rewritten like
switch(c)
{
case 1:
case 2:
case 3:
a++;
break;
default:
b++;
break;
}
without using label case 5:
. But you may not exclude labels case 1:
and case 2:
With these labels the switch statement can be rewritten using the if-else statement the following way
if ( 1 <= c && c <= 3 )
{
a++;
}
else
{
b++;
}
On the other hand without these case labels the corresponding if-else statement will look like
if ( c == 3 )
{
a++;
}
else
{
b++;
}
As you can see yourself there is a big difference between these two if-else statements.