来自Zed Shaw,艰难地学习C ,在练习23中,他谈到了Duff的设备。这是Duff的设备供参考:
int duffs_device(char *from, char *to, 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);
}
}
return count;
}
他要求读者:
“创建一组宏,让你可以像这样创建任何长度的设备。例如,如果你想要32个case语句并且不想写出所有这些语句怎么办?你能做一个放置的宏吗?一次减少8个?“
这真让我难过,我觉得我只需要朝着正确的方向轻推。任何帮助将不胜感激!
答案 0 :(得分:6)
这样的事情:
#define LAYDUFF(x, y) \
case ((0 ## x ## y) + 1) : *to++ = *from++
#define SEVEN_AT_ONCE(x) \
LAYDUFF(x,6); \
LAYDUFF(x,5); \
LAYDUFF(x,4); \
LAYDUFF(x,3); \
LAYDUFF(x,2); \
LAYDUFF(x,1); \
LAYDUFF(x,0)
#define EIGHT_AT_ONCE(x) \
LAYDUFF(x,7); \
SEVEN_AT_ONCE(x)
int duffs_device(char *from, char *to, int count)
{
{
int n = (count + 31) / 32;
switch(count % 32) {
case 0: do { *to++ = *from++;
SEVEN_AT_ONCE(3);
EIGHT_AT_ONCE(2);
EIGHT_AT_ONCE(1);
EIGHT_AT_ONCE(0);
} while(--n > 0);
}
}
return count;
}
将扩展为
case ((036) + 1) : *to++ = *from++; // = 31
...
case ((000) + 1) : *to++ = *from++; // = 1
更新:
或者,您可以重写第一个宏:
#define LAYDUFF(x, y) \
case (8 * x + y + 1) : *to++ = *from++
基本相同,只是它不使用八进制数。