Can some one please explain the nesting of case
statements into another. I'm referring to the Duffs Device where all other case
statements are inside the do-while
loop associated with case 0
. I cant get my head around it. It seems to me that it should act like a nested if
. But then i'm definitely missing something. Please explain.
问题:
回答1:
In a switch-case
construct, the switch
body is just a normal or compound statement which can contain any other valid c statements. It may also contain case
or default
labels.
And the control jumps to appropriate case label depending on controlling expression value, the statements in the switch body are executed one after another just like any other scope {
}
unless a break
is encountered.
For example, consider the following simple test program:
#include<stdio.h>
int main()
{
int i = 6;//5,10;
switch(6)
{
case 10:
printf("\nIn case 10");
case 11:
printf("\nIn case 11");
case 12:
printf("\nIn case 12");
break;
case 5:
printf("\nIn case 5");
break;
case 6:
printf("\nIn case 6");
default:
printf("\nIn Default");
}
return 0;
}
Consider 3 values for the controlling expression i
in the switch
statement:
5
6
10
The resultant outputs are as follows:
Scenario 1: i = 6
In case 6
In Default
Scenario 2: i = 10
In case 10
In case 11
In case 12
Scenario 3: i = 5
In case 5
Notice that, in each of the above scenarios, once a matching case
label is encountered the statements are executed sequentially until a break
is encountered, Thereby leading to conclusion which is the first statement in the answer.
回答2:
The easiest way to understand Duff's device is to separate its two logical components, the switch
and the do/while
loop, from each other. Here is a logically equivalent implementation, where the two statements are no longer nested:
void copy(int* to, int* from, int count) {
int n = (count + 7) / 8;
switch(count % 8) {
case 0: goto case_0;
case 1: goto case_1;
case 2: goto case_2;
case 3: goto case_3;
case 4: goto case_4;
case 5: goto case_5;
case 6: goto case_6;
case 7: goto case_7;
}
do {
case_0: *to++ = *from++;
case_7: *to++ = *from++;
case_6: *to++ = *from++;
case_5: *to++ = *from++;
case_4: *to++ = *from++;
case_3: *to++ = *from++;
case_2: *to++ = *from++;
case_1: *to++ = *from++;
} while (--n);
}
Note the labels inside the loop: they are normal C labels, not case
labels.
The only difference between this code and Duff's device is that Duff's code exploits the ability of using case
labels inside a do/while
loop, as long as the loop itself starts and ends inside the switch
statement, eliminating the need for "regular" labels and gotos.