【问题标题】:duff device not working达夫设备不工作
【发布时间】:2015-05-27 09:15:20
【问题描述】:

我尝试实现 Duff 设备,但它不起作用。它不会复制任何东西。我已经实现了原始版本和更清晰的版本:

void duff_function(int *a, int *b, int length)
{
    int n = (length + 7) / 8;
    switch(length % 8)
    {
        case 0: *a++ = *b++;    // I dereference, copy, and then increment the pointer, * > ++
        case 7: *a++ = *b++;
        case 6: *a++ = *b++;
        case 5: *a++ = *b++;
        case 4: *a++ = *b++;
        case 3: *a++ = *b++;
        case 2: *a++ = *b++;
        case 1: *a++ = *b++;
    }
    while ( --n > 0)
    {
        *a++ = *b++;
        *a++ = *b++;
        *a++ = *b++;
        *a++ = *b++;
        *a++ = *b++;
        *a++ = *b++;
        *a++ = *b++;
        *a++ = *b++;
    }

}

void send(int *to, int *from, int count)
{
        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);
        }  
}

int main()
{
    int a[10] = {21, 34, 12, 64, 13, 9, 56, 54, 90, 1};
    int b[10] = {22};
    for (int i = 0; i < 10; ++i)
    {
       printf("%d, ", a[i]);
    }
    printf("\n");
    duff_function(a, b, 10);
    //send(a, b, 10);

    for(int i = 0; i < 10; ++i)
        printf("%d, ", b[i]);
    printf("\n");
    return 0;
}

输出是:

21, 34, 12, 64, 13, 9, 56, 54, 90, 1, 
22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 

它不会复制任何东西。 在原始版本中,由于某种原因它不会增加指向的指针,但我认为我应该增加它(我在我的函数中这样做)。

编辑 据报道,我的代码中有一个错误: 我已经改了:

send(b, a, 10);

但现在的输出是:

1, 0, 0, 0, 0, 0, 0, 0, 0, 0,

编辑 2 最后编辑以使代码工作:

duff_function(b, a);

【问题讨论】:

  • 原始版本被输出到内存映射I/O端口,这就是它没有增量的原因。将它包含在内存副本中是正确的。
  • “达夫的装置”是开关和循环的奇怪组合。如果你把开关从循环中分离出来,它就不再是达夫的设备了。
  • 我希望你没有将 Duff 的设备用作编程练习以外的任何东西。
  • @onemasse 是的,这只是一个练习。 molbdnilo:如果我把它们分开,我会改变语法,但语义对我来说是一样的。
  • duff 函数有一个 while 循环。该 while 循环复制了 a[] 数组的末尾。这是可能/将导致段错误事件的未定义行为。注意:只需一次调用 memcpy() 即可正确执行所有复制。

标签: c loops duffs-device


【解决方案1】:

您正在从b 复制到a,但您想从a 复制到b

将每个*a++ = *b++; 更改为*b++ = *a++;

你也可以memcpy(b, a, length * sizeof *a);

【讨论】:

  • 我已经修改了我的代码,但它仍然无法正常工作,请参阅我的编辑。
  • 你改错了函数调用,改duff_function调用:ideone.com/Uz5ebm
  • 谢谢,我在这段代码中犯了严重的错误。
【解决方案2】:

这个函数:

void send(int *to, int *from, int count)
{
    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);
    }  
}

包含几个问题。

1) the while statement 
   places the majority of the switch case statements 
   at a different scope level from the first case statement.

2) stepping through the code
   int n = (10+7)%8 = 2
   switch(2)
      (jumping into the center of a do/while loop is 
      a very poor program practice)
      do{
      case 2: *to = *from++;
      case 1: *to = *from++; // which overlays the prior line
      } while( --n >0 ) // on first pass decrement 'n' to 1
      case 7:   overlays prior *to with from[2]
      case 6:   overlays prior *t0 with from[3]
      case 5:   ... from[4]
      case 4:   ... from[5]
      case 3:   ... from[6]
      case 2:   ... from[7]
      case 1"   ... from[8]
         while( --n >0 ) fails, exiting loop

      final result, *to = from[8]

这可能不是你想要做的

【讨论】:

    猜你喜欢
    • 2019-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 2013-08-26
    • 2012-01-13
    • 1970-01-01
    相关资源
    最近更新 更多