任何人都可以弄清楚这种方法(在C中)是做什么的吗?试图理解这个任务

时间:2010-11-18 02:26:11

标签: c methods

void* memorycopy (void *des, const void *src, size_t count)
{

  size_t n = (count + 7) / 8;
  char* destination = (char *) des;
  char* source = (char *) src;

  switch (count % 8)
  {
      case 0:  do{  *destination++ = *source++;
      case 7:  *destination++ = *source++;
      case 6:  *destination++ = *source++;
      case 5:  *destination++ = *source++;
      case 4:  *destination++ = *source++;
      case 3:  *destination++ = *source++;
      case 2:  *destination++ = *source++;
      case 1:  *destination++ = *source++;

    } while (--n > 0);
  }

  return des;
}




void tworegistervarswap (int *x, int *y)
{
  if (x != y)
  {
    *x = *x ^ *y;
    *y = *x ^ *y;
    *x = *x ^ *y;
  }
}



int bigintegeraverage (int x, int y)
{
  return (x & y) + ((x ^ y) >> 1);
}

4 个答案:

答案 0 :(得分:3)

switch的恐怖是Duff's device(创造性展开的循环,但除此之外它只是将来源复制到目的地)。

tworegisterswap使用按位XOR交换xy指向的值。

bigintegeraverage是一种偷偷摸摸的方式,以潜在的非便携方式获得两个整数的平均值,但没有溢出的可能性。 (有关详细信息,请参阅Aggregate Magic Algorithms。)

答案 1 :(得分:1)

它被称为Duff的设备。它使用switch语句在C中实现状态机。在这种特殊情况下,它每8次memcopy迭代执行一个分支。

请阅读此内容以获取更多信息:http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html

第二个函数交换两个整数。

第三个只计算两个数的平均值,因为sum可以写为

a + b = (a ^ b) + ((a & b) << 1); // the AND here represents carry

并使用((a ^ b) >> 1) + (a & b)代替(a + b >> 1),我们可以避免可能的溢出。

答案 2 :(得分:1)

请参阅Tom Duff on Duff's Device

  

设备的要点是直接在C中表示一般循环展开。已经发布说“只使用memcpy”的人已经错过了这一点,那些使用各种依赖于机器的memcpy实现作为支持批评它的人也是如此。实际上,消息中的示例不能作为memcpy实现,任何计算机也不可能具有实现它的类似memcpy的习惯用法。 more

答案 3 :(得分:0)

这实际上是3个功能。

memorycopy() ......好吧,其他人可以解决这个问题:P

tworegistervarswap()似乎指向了两个int s,如果它们不匹配,那么它会对它们进行一些调整(XOR)。它在不使用临时变量的情况下交换值。

bigintegeraverage()需要两个int并根据它们返回均值(感谢Steve Jessop),同时使用位摆弄(AND,XOR和RIGHT SHIFT)。