0
static const unsigned char BitsSetTable256[256] = 
{
#   define B2(n) n,     n+1,     n+1,     n+2
#   define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)
#   define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)
    B6(0), B6(1), B6(1), B6(2)
};

这段代码在设置位问题中非常有名。我已经了解它将如何在编译时输出查找表。

但我需要更多的直觉..意味着

B2(n),B4(n),B6(n)是什么意思?
以及归结为这个递归宏的基本思想是什么?

编辑我的意思是递归背后的想法

4

3 回答 3

1

这个想法是“将问题递归定义为 2 位值”:00、01、10、11。它们不是递归宏,但确实代表了问题的递归分解技术。将宏排列为级联解决了生成 2^8 值表的问题,方法是先解决 2 位(生成 4 个值)的问题,然后是 4 位(使用 2 位解决方案 4 次),然后对于 6 位(使用 4 位解决方案 4 次),然后针对整个问题(使用 6 位解决方案 4 次)。

2 位为您提供四个值:0、1、2、3。0 设置了 0 位,1 设置了 1 位,2 也只有 1 位设置,3 设置了 2 位。

4 位数字的值使用相同的模式,并为每个值的额外 2 位使用 2 位模式。

它可以“简化”到每个宏 1 位。

#define B1(n) n,     n+1
#define B2(n) B1(n), B1(n+1),
#define B3(n) B2(n), B2(n+1),
#define B4(n) B3(n), B3(n+1),
#define B5(n) B4(n), B4(n+1),
#define B6(n) B5(n), B5(n+1),
#define B7(n) B6(n), B6(n+1),
 B7(0), B7(1)

请记住查找表的目的是howmanybits(x)用 table-lookup替换函数调用howmanybits[x]。所以表中的每个值都应该代表索引 i 的 f(i) 和整个函数 f。

因此,要真正掌握它,请跟踪前几个值。B6(0)以 开头B4(0),以 开头B2(0),依次为 0、1、1、2。f(0)=0,f(1)=1,f(2)=1,f(3)=2。B4(0)继续B2(1)1, 2, 2, 3。 f(4)=1, f(5)=2, f(6)=2, f(7)=3。如果您以二进制表示形式查看这些数字,应该清楚这 8 个结果是正确的。

x  x_2  f(x)
0 0000  0 bits set
1 0001  1
2 0010  1
3 0011  2
4 0100  1
5 0101  2
6 0110  2
7 0111  3
...
于 2013-08-10T07:14:19.437 回答
0

回想一下:在编译程序之前,预处理器会处理宏。“编译”代码时会发生 3 个步骤:

  1. 预处理(处理所有预处理器指令)。
  2. 将 C 源文件编译成目标文件(翻译成机器代码)。
  3. 将所有目标文件和其他库文件链接到一个可执行文件中。

B2(n)将执行以下操作:

n, n + 1, n + 2

...n一些数字在哪里。


Bx宏的全部意义在于递归地构建位表。

于 2013-08-10T06:57:05.130 回答
0

“归结为这个递归宏的基本思想”

B2(n) 将生成:n, n+1, n+1, n+2

自行检查:-

gcc -E file_name.c

于 2013-08-10T06:59:27.443 回答