【问题标题】:switch statement perplexingswitch 语句令人困惑
【发布时间】:2016-02-15 05:49:01
【问题描述】:

我知道这已经被讨论过了,我已经阅读了我能找到的关于 switch 的所有问题和答案。我的问题不是关于 Duff 设备的语法或功能,而是关于 switch,这恰好很好地说明了这个问题。

    {
    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);
    }

我理解这样做,n 的值随着每次迭代而递减。我也明白,宽松的编译器规则允许其他情况跳入 do 循环(很奇怪,但我理解)

但是由于 switch 语句是 (count % 8) 的函数,并且没有任何变化或作用于 count 的值,为什么 count 首先会发生变化以在 switch 内产生不同的模余数?

假设 (count % 8) 在第一遍产生 7。在处理案例 7 后:count 的值保持不变,因此 (count % 8) 的值应该保持不变,因此案例 6:不应该为真,任何其他情况也不应该是没有默认值的 n 应该递减,并且do 循环的下一次迭代应该以 count 的值不变开始。所以看起来循环会结束到 0,count 永远不会改变,所以它只会执行 case 7,每次通过都使所有其他代码毫无意义。

但如果这是真的,那么 Duff 的设备将无法工作,因为它显然依赖于 int(n + 7)/8 来为每个 count 值产生 8 次重复 n 值,并且与 (count % 8) 配对意味着count 确实在递减以产生一个在 7 和 0 之间递减模余数的循环。

从我的新手的角度来看,这似乎需要一个 --count 在那个循环的某个地方。所以我的结论是我不明白 switch 是如何工作的。我会很感激任何解释。

【问题讨论】:

    标签: switch-statement duffs-device


    【解决方案1】:

    在对各种版本进行了一些测试之后,我可以肯定地说 count 没有改变值,只有 n 改变了值。当然,这意味着在 do:while 中简单地连续执行 8 次赋值,原始代码在没有 switch 的情况下可以完全一样地工作,这让我想知道在这种情况下,除了纯粹的混淆之外,switch 的重点是什么.

    就开关的工作方式而言,我通过测试发现它基本上按我的预期工作,只是它执行每个案例而不考虑值,除非您在每个案例中都包含一个中断。进一步的证据表明 count 没有改变,因此 Duff 的代码中没有中断,再加上 count 的值不变,进一步支持了切换完全没有意义的断言。

    这将产生完全相同的结果;

    {
    //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);
    
    }   
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-17
      • 2016-08-31
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-02
      相关资源
      最近更新 更多