How Do while inside switch statement works in c - c++

I have a code snippet where a do while statement is inside switch condition of case0, by default the case value is case1 but it seems executing case0. The output of the program print is 6. How is this possible, can someone explain the flow of code here. Thanks in advance for your answers.
int main()
{
int a = 1, t =0,n=2;
switch(a)
{
case 0:
do
{
t++;
case 4:t++;
case 3:t++;
case 2:t++;
case 1:t++;
}while(--n>0);
printf("%d",t);
}
return(0);
}

Since a is 1 in the beginning, case 1 will be executed. Then the loop condition is satisfied, thus it will loop again and execute t++; and all other cases until it tests the loop condition again and breaks the loop.
To get out of the switch, use the break command before every case.

Switch cases are similar to labels for goto.
You start at case 1, which is inside the loop – effectively using that as your starting point – and then execute the loop normally while "falling through" the cases as you go.
Here is the equivalent using goto:
int main()
{
int a = 1, t =0,n=2;
if (a == 0)
goto case_0;
if (a == 1)
goto case_1;
if (a == 2)
goto case_2;
if (a == 3)
goto case_3;
if (a == 4)
goto case_4;
case_0:
do {
t++;
case_4:
t++;
case_3:
t++;
case_2:
t++;
case_1:
t++;
} while (--n > 0);
printf("%d",t);
}
(The actual generated code might use a jump table rather than a series of conditionals, but the behaviour is the same.)

This is known at Duff's device.
case are mostly only label.

Related

C++ if statement notation - Is this equivalent?

I'm 99% sure this won't work but that remaining 1% is bothering me
int x;
//is this if statement
if(x == 1, 5, 7)
{
//do something here
}
//equivalent to this if statement
if((x == 1) || (x == 5) || (x == 7))
{
//do something here
}
No it's totally not equivalent.
if(x == 1, 5, 7)
calls the comma operator, which will effectively end up in the last value because of , has the lowest precedence:
if(7)
since unfolding with parenthesis should look like
if(((x == 1), 5), 7)
while
if((x == 1) || (x == 2) || (x == 7))
checks if x equals either 1, 2 or 7.
They are not equal. When you write it like
if(x == 1, 5, 7)
{
//do something here
}
it basically translates into
if(7)
{
//do something here
}
which will always be true in case the number in the condition block is a non-zero number.
Example 1:
int main()
{
int x=10;
if(x==1,5,7)
cout<<"hello"<<endl;
return 0;
}
Here, the output is "hello", because 7 is treated as a true boolean variable.
Example 2:
int main()
{
int x=10;
if(x==1,5,0)
cout<<"hello"<<endl;
return 0;
}
Here, there is no output because 0 is considered as a false boolean variable.
Regarding a faster solution discussed in the comment section of the OP, here's a 'fast' solution:
If you have a large number of constant comparisons to perform, a switch statement is faster than individual if(x == 1) statements as it is compiled to a branch-table (a kind of hashtable directly within program code, giving it O(1) lookup), however it's possible that existing compilers will already optimize if(x==1||x==2||x==3...) to a branch-table too.
bool xIsInSet = false;
switch( x ) {
case 0: case 1: case 2: case 3:
case 4: case 5: case 6: case 7: // add a case for each literal comparison
xIsInSet = true; // no `break` needed, there's only 1 case.
}
if( xIsInSet ) {
// do stuff
}
This can be inlined to a lambda which is invoked immediately to eliminate xIsInSet:
if( [&x]() -> bool {
switch(x) { case 0: case 1: case 2: case 3: return true; }
return false; }()
) {
// do stuff
}
Unfortunately C++11's variadic templates don't let us dynamically add case statements, and hacking it using a preprocessor #define is possible - if you don't mind using a metaprogramming library. A better alternative might be an inline #include of a file generated by your build script. What would be even neater would be a way to somehow #include the standard-output from another program (e.g. if we could do #include '.\generateCasesFor.sh 1 2 5 10 12', alas not yet).

switch-case statement without break

According to this book I am reading:
Q What happens if I omit a break in a switch-case statement?
A The break statement enables program execution to exit the switch construct.
Without it, execution continues evaluating the following case statements.
Suppose if I have codes looking like
switch (option}{
case 1:
do A;
case 2:
do B;
default:
do C;
break;
}
Does this mean if I choose case 1, the A and C are done. If I choose case 2, B and C are done. If i choose neither, then only C is done.
if so, what happens if we omit the break after do C.
I assume these are bad programming practice, but I am curious what would happen to get a deeper understanding how it all works. Thanks
You execute everything starting from the selected case up until you see a break or the switch statement ends. So it might be that only C is executed, or B and then C, or A and B and C, but never A and C
If you don't include break in any of case then all the case below will be executed and until it sees break.
And if you don't include break in default then it will cause no effect as there are not any case below this 'Default' case.
And not using break generally considered as a bad practice but some time it may also come handy because of its fall-through nature.For example:
case optionA:
//optionA needs to do its own thing, and also B's thing.
//Fall-through to optionB afterwards.
//Its behaviour is a superset of B's.
case optionB:
// optionB needs to do its own thing
// Its behaviour is a subset of A's.
break;
case optionC:
// optionC is quite independent so it does its own thing.
break;
The break acts like a goto command. Or, as a better example, it is like when using return in a void function. Since it is at the end, it makes no difference whether it is there or not. Although, I do like to include it.
switch (option}{
case 1:
do A;
case 2:
do B;
case 2:
do C;
break;
default:
do C;
}
if your option is 1 it executes everything til it finds the break keyword...
that mean break end the excution of the switch --> case
Output :A then B then C
so it is recommended to put break after each case
like :
switch (option}{
case 1:
do A;
break;
case 2:
do B;
break;
do C;
break;
default:
do D;
}
if your option is 1 the Output will be : just A ...
note: default doesn't need a break;
I've seen in many comments and answers that it's a bad practice to omit break lines. I personally find it very useful in some cases.
Let's just take a very simple example. It's probably not the best one, just take it as an illustration:
- on bad login, you need to log the failed attempt.
- for the third bad attempt, you want to log and do some further stuff (alert admin, block account, ...).
Since the action is the same for first and second try, no need to break between these two and rewrite the same commands a second time.
Now the third time, you want to do other things AND also log. Just do the other things first, then let it run (no break) through the log action of the first and second attempts:
switch (badCount) {
case 3: //only for 3
alertAdmin();
blockAccount();
case 2: //for 2 AND 3
case 1: //for 1 AND 2 and 3
errorLog();
badCount++;
}
Imho, if it was soooo bad practice to have common code for different cases, the C structure would simply NOT allow it.
The key is execution control is transferred to the statement for the matching case.
E.g.
1. switch(x) {
2. case 1:
3. do_step1;
4. case 2:
5. do_step2;
6. default:
7. do_default;
8. }
Treat lines 2, 4, 6, as "Labels" for the goto calls. On x = 1, the control will be transferred to line 3 & execution of line 3, 5 & 7 will occur.
Try yourself - Run the code using ideone available here.
#include <stdio.h>
void doA(int *i){
printf("doA i = %d\n", *i);
*i = 3;
}
void doB(int *i){
printf("doB i = %d\n", *i);
*i = 4;
}
void doC(int *i){
printf("doC i = %d\n", *i);
*i = 5;
}
int main(void) {
int i = 1;
switch(i){
case 1:
doA(&i);
case 2:
doB(&i);
default:
doC(&i);
break;
}
return 0;
}
Output:
doA i = 1
doB i = 3
doC i = 4
Note:
It will execute all the options from the selected case until it sees a break or the switch statement ends. So it might be that only C is executed, or B and then C, or A and B and C, but never A and C
If you change the value of the variable analysed in switch inside the handle function (e.g doA), it does not affect the flow as describe above
Without break statements, each time a match occurs in the switch, the statements for that case and SUBSEQUENT CASES execute until a break statement or the end of the switch is encountered.

Using a switch in a do..while loop, in C++

A simple programm that reads strings, and responds using a switch;
in this do-while loop containing a switch, I am able to run case 1-4 with no issues, but once i hit the default case, the programme simply loops the default case over and over again the code is as follows;
do { switch ( switchstring (entry, input) )
/*the switchstring function is one 1 wrote to convert a given entry(string),
into an input(integer)*/
{
case 1:
//code
repeat = 2;
break;
case 2:
//code
repeat = 2;
break;
case 3:
//code
repeat = 2;
break;
case 4:
//code
repeat = 2;
break;
default:
//code
repeat = 1;
break;}} while(repeat == 1);
the 2nd question is regarding my switchstring() function; is there a way to change the switch function such that it reads;
case (insert string):
i.e. so that I can remove the entire switchstring() function
thanks in advance!
Show us how switchstring (entry, input) works.
The problem you are facing is because, in default you do the following:
repeat = 1;
Which makes while(repeat == 1) always true. And then switchstring (entry, input) always return something that makes your switch block always go the the default case again.
When no case will be true in switch, then it will go in default case of switch and you are specifying repeat=1; in default. After that while condition will be checked and it will be true because repeat is 1, again it will go to do and check condition, your switch function will return something and it will go to default.
To solve 2nd question regarding your switchstring() function, you have to show your code what you are doing in that function, So that i can give you best suggestion.

Switch case to break an outer loop? [duplicate]

This question already has answers here:
How to break out of a loop from inside a switch?
(20 answers)
Closed 9 years ago.
This isn't a specific problem that I actually am trying to implement, but it ocurred to me that I do not know how to do this, so I will give a simple example to illustrate:
Suppose we have a while loop containing a switch statement, for instance:
while(some_cond){
switch(some_var){
case 1:
foo();
break;
case 2:
bar();
break;
}
}
what would we do if we wanted to break out of the while loop in case 1, say?
We can't do break; break;, since the second will never happen.
We also can't do break *un*conditionally in the while loop, since this would happen in any case.
Do we have no choice but to if (some_var == 1) break; in the while loop, or else append && !flag) to the while condition, and set flag = 1?
Various options, in approximate order of tastefulness:
Move the loop into a separate function. Use return to stop looping.
Replace while(1) with while(looping) and set to false to stop looping. Use continue if you need to skip the rest of the current iteration.
Use goto to jump past the end of the loop. How bad can it be?
Surround the loop with a try block, and throw something to stop looping.
You can use goto (don't go too wild with goto though).
while ( ... ) {
switch( ... ) {
case ...:
goto exit_loop;
}
}
exit_loop: ;
Have your while use a variable modified within your loop.
bool shoulEnterLoop = true;
while(shoulEnterLoop ){
switch(some_var){
case 1:
if ( !foo() )
shoulEnterLoop = false;
break;
case 2:
bar();
break;
}
}

Changing switch variable inside a case

In the following code:
int i = 0;
switch(i)
{
case 0:
cout << "In 0" << endl;
i = 1;
break;
case 1:
cout << "In 1" << endl;
break;
}
What will happen? Will it invoke undefined behavior?
No undefined behavior. But the value of i is only tested when the code reaches switch (i). So case 1: will be skipped (by the break; statement).
The switch keyword does not mean "run code whenever the value of i is 0 / 1". It means, check what i is RIGHT NOW and run code based on that. It doesn't care what happens to i in the future.
In fact, it's sometimes useful to do:
for( step = 0; !cancelled; ++step ) {
switch (step)
{
case 0:
//start processing;
break;
case 1:
// more processing;
break;
case 19:
// all done
return;
}
}
And changing the control variable inside a case block is extremely common when building a finite state machine (although not required, because you could set next_state inside the case, and do the assignment state = next_state afterward).
You break out of this switch statement after you set it to 1 which is defined behavior so it will never enter case 1.
There's no issue here. The expression in the switch condition is evaluated when it is reached. It doesn't have to be a variable and if it is the variable can be subsequently modified without any effect on the behaviour of the switch statement.
Your output would be :
"In 0"
even if you assign the value i = 1 it wont be reflected because switch does not operate in iteration, it is one time selection as break would make it go out of the switch statement.