Please explain this behaviour of switch statement [duplicate] - c

This question already has answers here:
Switch function in C does all the cases
(6 answers)
Closed 3 years ago.
Output:
case0
case1
case2
casedef
I understand that the default case is running because there is no break statement executing inside of the switch statement.
But I don't understand why case 1 and 2 are running when 0!= 1 and 0!=2
Also if I write switch(1) instead of switch(0) then only case 1 and 2 run which is understandable since 1!=0 and 1=1, 1=2 (in boolean? because non zero number denotes truth, but I am not sure, please correct me)
int main(){
switch(0){
case 0: printf("case0\n");
case 1: printf("case1\n");
case 2 : printf("case2\n");
default : printf("casedef\n");
}
}

Switch cases "fall through" to cases that are under them. You're seeing the mentioned behavior because cases for 1, 2 and default are all underneath 0. When you're switching on 1, you see 2 and the default because they're both underneath 1.
If you want to avoid falling through, you need to explicitly break out of the switch at the end of each case:
int main(){
switch(0){
case 0: printf("case0\n"); break;
case 1: printf("case1\n"); break;
case 2 : printf("case2\n"); break;
default : printf("casedef\n"); break;
}
}

Related

When we don't use 'break' statement in switch statements,why is 'deafult' evaluated before other cases that is below 'default'?

Yesterday I saw the below code. As you can see it hasn't got any break I predicted that it would print "354" because I thought the default part would be finally evaluated (after checking all the cases.)
But that isn't practically correct as it printed "345". Can somebody explain the reason?
int main ()
{
int a = 2;
switch (2*a-1)
{
case 1: printf ("1");
case 2: printf("2");
case 3: printf("3");
default: printf("4");
case 5: printf("5");
}
}
Since 2*a-1 is 3, the code jumped to the case 3 label and kept running from there. The other labels were ignored because no code ever jumped to them. The default label is only jumped to if the value in the switch doesn't match any of the case labels.

Working with mathematical operations received as input

Let's say I'd like to receive two mathematical operations from a user (e.g. + - %) and calculate numbers accordingly. Let's also say I can use one if/else statement to determine precedence (and that all operations have different precedences).
I have several ideas in mind for implementation, and would like feedback regarding which is considered "better" coding (clearer, more efficient, etc.).
I could do something like this:
if (firstOperator >= secondOperator){
switch (firstOperator){
case '+':
switch (secondOperator)
// insert all 6 possible cases
case '-':
switch (secondOperator)
// insert all 5 possible cases
...
...
}
else{
// same idea as above
}
Or I could simply hard-code all options by creating one switch for every option of firstOperation, and nest a second switch in each of those cases for all possible secondOperation.
The two approaches are different, and I have one or two more. I would have thought that the first is more "correct" and elegant, but it actually results in more lines of code than the "brute-force" all-out second option.
I would love to hear any input regarding this kind of coding.
Note: I'm talking about only very basic C programming (i.e. without using other data structures like stacks, etc. Just the basic if/else, switch, loops, etc.
Here's how I would have done it, but it depends on your first and second operations being independently handled (which I think should be possible if what you are doing is an expression evaluator). In my example, I assume there is a queue holding the arguments that were parsed in the order they were parsed.
if (firstOperator >= secondOperator) {
handle(firstOperator);
handle(secondOperator);
} else {
// Assuming something like 1 + 2 * 3, with 1 2 3 in the queue:
//
// tmp = dequeueArg() makes the queue: 2 3
// handle('*') makes the queue: 6
// pushFront(tmp) makes the queue: 1 6
// handle('+') makes the queue: 7
//
int tmp = dequeueArg();
handle(secondOperator);
pushFront(tmp);
handle(firstOperator);
}
void handle(Op operator)
{
int x = dequeueArg();
int y = dequeueArg();
switch (operator) {
case '+': pushFront(x+y); break;
case '-': pushFront(x-y); break;
case '*': pushFront(x*y); break;
case '/': pushFront(x/y); break; // Maybe check for 0
case '%': pushFront(x%y); break; // Maybe check for 0
case '&': pushFront(x&y); break;
etc...
}
}
What I wrote here probably will not work as a general infix parser with precedence. It's more an example of how to not use O(N^2) nested case statements.

switch case in c, default before case

I was trying this :
#include<stdio.h>
int main() {
int i = 2;
switch(i) {
default:{
printf("Hi\n");}
case 1:
printf("Hi1\n");
case 2:
printf("Hi2\n");
}
}
output is "Hi2" as expected, however if i = 3,
#include<stdio.h>
int main() {
int i = 3;
switch(i) {
default:{
printf("Hi\n");}
case 1:
printf("Hi1\n");
case 2:
printf("Hi2\n");
}
}
Output is
"Hi"
"Hi1"
"Hi2"
How does program enter other cases which do not match? I know putting break in default would solve this.
Why this behavior? Is there anything mentioned in C specification for this?
In C (and many other languages) the cases are simply labels that get 'jumped' to. Once execution starts in a selected case, it flows just like normal. If you want execution to 'stop' at the end of a case 'block' you have to use the break statement (or some other flow control statement):
switch(i) {
default:{
printf("Hi\n");}
break;
case 1:
printf("Hi1\n");
break;
case 2:
printf("Hi2\n");
break;
}
}
For whatever it's worth, in my opinion this is was an unfortunate decision made by the language designers since falling through to the next case after execution one or more statements in a case are executed is very, very rarely desired. However, that's the way the language works.
C# addresses this by making it so falling out of a case is illegal - some sort of explicit flow control (a break or a goto) is required at the end of a sequence of of statements in a case (unless it's the last case in the switch).
This is because the code steps through each instruction unless explicitly stated not to.
In a switch() { }, you must be explicit.
Think about the instructions backed by this C. It would be a jump table. Without break, there would be no jump beneath each branch to go after the switch case.
Complementing #alex, try this.
#include<stdio.h>
int main() {
int i = 2;
switch(i) {
default:{
printf("Hi\n");}
case 2:
printf("Hi2\n");
case 1:
printf("Hi1\n");
}
}

About switch case in C, why it does not print out? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Code before the first ‘case’ in a switch-statement
I have the following set of code in C:
void isFindValue(int value1, int value2)
{
switch (value1)
{
case 1:
printf("value1 is found!\n");
break;
case 2:
printf("value1 is found!\n");
break;
case 3:
switch(value2)
{
printf("aaaaaaaaaaaaa\n");
case 6:
printf("bbbbbbbbbbbb\n");
printf("value2 is found!\n");
break;
}
default:
break;
}
if I call the function as is isFindValue(3,6); the printf of bbbbbbbbbbbb show up, but aaaaaaaaaaaaa does not, why this will happen? should we not do something before the case?
Because switch () works using labels. It jumps to the label of which the condition is satisfied. So when reaching
switch(value2) {
printf("aaaaaaaaaaaaa\n");
case 6:
the control flow immediately jumps to the label case 6: so that it skips the call to printf().
The solution would be placing it correctly, outside of the inner switch:
case 3:
printf("aaaaa\n");
switch (value2) {
etc.
"aaaaaaaaaaaaa" is not showing up because it is misplaced (it's not contained in a label so it is unreachable). You need to move it up to before the second switch statement:
case 3:
printf("aaaaaaaaaaaaa\n");
switch(value2)
{
// body
}
The call to the printf function in the statement :
printf("aaaaaaaaaaaaa\n");
cannot be reached because it is before the first case statement of the second switch.
see Code before the first 'case' in a switch-statement
"aaaaaaaaaaaaa\n" is not being printed within any case. Your code is not properly structured.
Try moving the statement out of the switch block like this:
printf("aaaaaaaaaaaaa\n");
switch(value2)
{
case 6:
printf("bbbbbbbbbbbb\n");
printf("value2 is found!\n");
break;
}
break;
switch always look for case and that's why aaaaaaaaaaaa was skipped. It will execute the statement of related case block.

is it possible to do an OR in a case statement?

I want to do something like:
case someenumvalue || someotherenumvalue:
// do some stuff
break;
Is this legal in C?
The variable that I am doing a switch on is an enumerated list data struct.
You can rely on the fact that case statements will fall-through without a break:
case SOME_ENUM_VALUE: // fall-through
case SOME_OTHER_ENUM_VALUE:
doSomeStuff();
break;
You can also use this in a more complicated case, where both values require shared work, but one (or more) of them additionally requires specific work:
case SOME_ENUM_VALUE:
doSpecificStuff();
// fall-through to shared code
case SOME_OTHER_ENUM_VALUE:
doStuffForBothValues();
break;
Yes, you can simply skip the break in the first case to achieve the fall-through effect:
switch (expr) {
case someenumvalue: // no "break" here means fall-through semantic
case someotherenumvalue:
// do some stuff
break;
default:
// do some other stuff
break;
}
Many programmers get into the trap of fall-through inadvertently by forgetting to insert the break. This caused me some headaches in the past, especially in situations when I did not have access to a debugger.
you need:
case someenumvalue:
case someotherenumvalue :
do some stuff
break;
You can use fallthrough to get that effect:
case someenumvalue:
case someotherenumvalue :
do some stuff
break;
A case statement like a goto -- your program will execute everything after it (including other case statements) until you get to the end of the switch block or a break.
As others have specificied, yes you can logically OR things together by using a fall through:
case someenumvalue: //case somenumvalue
case someotherenumvalue : //or case someothernumvalue
do some stuff
break;
But to directly answer your question, yes you can do a logical, or bit-wise or on them as well (it's just a case for the result of the operation), just be careful that you're getting what you'd expect:
enum
{
somenumvalue1 = 0,
somenumvalue2 = 1,
somenumvalue3 = 2
};
int main()
{
int val = somenumvalue2; //this is 1
switch(val) {
case somenumvalue1: //the case for 0
printf("1 %d\n", mval);
break;
case somenumvalue2 || somenumvalue3: //the case for (1||2) == (1), NOT the
printf("2 %d\n", mval); //case for "1" or "2"
break;
case somenumvalue3: //the case for 2
printf("3 %d\n", mval);
break;
}
return 0;
}
If you choose to do the second implementation keep in mind that since you're ||'ing things, you'll either get a 1 or 0, and that's it, as the case.

Resources