我知道之前已经被删除了,我已经阅读了我能找到的关于开关的每个问题和答案。我的问题不是关于Duff设备的语法或功能,而是关于切换一般这恰好说明了这个问题。
{
int n = (count + 7) / 8;
switch(count % 8) {
case 0: do { *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 > 0);
}
我理解do while,n的值随着每次迭代而递减。我也明白,松散的编译器规则允许其他情况跳转到do循环内部(很奇怪但我明白了)
但是由于switch语句是(count%8)的函数,并且没有任何改变或对count的值起作用,为什么计数首先会改变以在switch中产生不同的模余数?
假设(计数%8)在第一次传球时产生7。在处理案例7之后:count的值保持不变,因此(count%8)的值应该保持不变,因此案例6:不应该是true,也不应该是任何其他情况和没有默认n应该减少,并且do循环的下一次迭代应该以count的值不变为开始。所以似乎循环会降低到0,计数永远不会改变,所以它只会在每次传递时执行情况7,使所有其他代码无意义。
但如果这是真的那么Duff的设备将无法工作,因为它明显依赖于int(n + 7)/ 8来产生8个重复值,每个值为n,并与(count%8)配对意味着count确实在递减,以产生一个在7和0之间减少模数余数的循环。
从我的新手角度来看,似乎这个工作需要在某个地方的循环中使用--count。所以我的结论是我不明白交换机是如何工作的。我很感激任何解释。
答案 0 :(得分:0)
在对各种版本进行一些测试后,我可以肯定地说,计数不会改变值,只有n才会改变值。当然,这意味着原始代码在没有切换的情况下完全相同,只需在do:中连续执行8次赋值,这让我想知道在这种情况下开关的重点是什么,而不是纯混淆。
至于交换机是如何工作的,我通过测试发现它基本上按照我的预期工作,除了它执行每种情况而不管值,除非你在每种情况下都包含一个中断。进一步的证据表明,计数没有改变,因为Duff代码中没有中断,再加上计数的不变值,进一步支持了断言完全没有意义的断言。
这会产生完全相同的结果;
{
//integer division by 8 produces 8 iterations of the same value
int n = (count + 7) / 8;
do {
*to++ = *from++; //therefore since the loop will be 1/8th
*to++ = *from++;
*to++ = *from++; //the value of count you need to perform
*to++ = *from++;
*to++ = *from++; //8 assignments per iteration of n
*to++ = *from++;
*to++ = *from++; //this produces the same result without
*to++ = *from++;
*to++ = *from++; //the switch
} while(--n > 0);
}