#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
int n = 12;
int q = (n + 3) / 4;
cout << q;
cout << ' ';
cout << n%4;
cout << ' ';
switch (n % 4) {
case 0: cout << n; cout << ' ';
do { n++; cout << n; cout << ' ';
case 3: n++; cout << n; cout << ' ';
case 2: n++;
case 1: n++; cout <<n; cout << ' ';
} while (--q > 0);
}
cout << n;
}
With the above code, I got the following:
3 0 12 13 14 16 17 18 20 21 22 24 24
I am not familiar with C++ language.
Why does it falls through in the second and third iteration of the while loop?
Does the switch case statement save the initial n%4 value and apply that during the do-while loop?
case labels are just labels.
To make it more clear you may rewrite the switch statement the following way when the expression n % 4
is equal to 0.
goto Label0;
{
Label0: cout << n; cout << ' ';
do { n++; cout << n; cout << ' ';
n++; cout << n; cout << ' ';
n++;
n++; cout <<n; cout << ' ';
} while (--q > 0);
}
So if you will run your program with the modification
#include <iostream>
using namespace std;
int main()
{
int n = 12;
int q = (n + 3) / 4;
cout << q;
cout << ' ';
cout << n%4;
cout << ' ';
goto Label0;
{
Label0: cout << n; cout << ' ';
do { n++; cout << n; cout << ' ';
n++; cout << n; cout << ' ';
n++;
n++; cout <<n; cout << ' ';
} while (--q > 0);
}
cout << n; return 0;
}
you will get the same result.
3 0 12 13 14 16 17 18 20 21 22 24 24
"Switch-cases" always fall through, unless you explicitly break
out of the switch.
The switch-case construct is essentially a glorified bunch of goto
s, but more robust than one constructed manually.
(Your code looks like a slightly mutated version of the legendary "Duff's device", a loop-unrolling construct that has confused generations of C programmers.)
Translated into unstructured "goto code", your switch is logically equivalent to
int x = n % 4;
if (x == 0)
goto zero;
if (x == 1)
goto one;
if (x == 2)
goto two;
if (x == 3)
goto three;
zero:
cout << n << ' ';
loop:
n++;
cout << n << ' ';
three:
n++;
cout << n << ' ';
two:
n++;
one:
n++;
cout << n << ' ';
if (--q > 0)
goto loop;
but the compiler might be able to create more efficient code from the switch than that series of conditionals, by using an actual jump table.
Footnote: gcc actually allows you to use labels as values and jump to them, so you could create exactly such a table yourself;
void* table = { &&zero, &&one, &&two, &&three };
goto *table[n % 4];
zero:
cout << n << ' ';
loop:
n++;
cout << n << ' ';
three:
n++;
cout << n << ' ';
two:
n++;
one:
n++;
cout << n << ' ';
if (--q > 0)
goto loop;
(Not that you should , but you could . A good compiler will compile your switch to something similar to this if it is beneficial, which it knows more about than a mere human.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.