C语言中的##运算符

18

## 在 C 语言中是什么意思?

示例:

typedef struct
{
    unsigned int bit0:1;
    unsigned int bit1:1;
    unsigned int bit2:1;
    unsigned int bit3:1;
    unsigned int bit4:1;
    unsigned int bit5:1;
    unsigned int bit6:1;
    unsigned int bit7:1;
} _io_reg;

#define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->bit##bt

(除了 ## 部分,我知道所有的内容都是做什么的。)


http://symbolhound.com/?q=C+%23%23 - mu is too short
7个回答

17

它是预处理器宏的一部分,用于字符串连接

(在这个上下文中,"字符串"指的当然是预处理器标记,或者是"源代码字符串",而不是C字符串。)


16

它被称为粘贴运算符; 它将bt中的文本与bit中的文本连接起来。因此,例如,如果您的宏调用是

REGISTER_BIT(x, 4)

它会扩展为

((volatile _io_reg*)&x)->bit4

如果没有这个,你无法在宏体中直接将宏参数放在文本旁边,因为那样文本会和参数名字相连并成为同一令牌,导致变为不同的名称。


1
最好的澄清,谢谢 :) - user2948075

9
运算符 ## 连接两个参数,它们之间不留空格:
#define glue(a,b) a ## b
glue(c,out) << "test";

3

这是宏定义的一部分。

它允许您在宏内连接字符串。

在您的情况下,您可以像这样使用 7 到 0 的 bt

REGISTER_BIT(myreg, 0)

并且它将被转换为:

((volatile _io_reg*)&myreg)->bit0

如果没有这个,您必须将宏的bit部分定义为宏的参数之一:

#define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->bt

使用场景如下:

REGISTER_BIT(myreg, bit0)

这更加繁琐。

这还可以让你创建新的名称。

假设你有这些宏:

#define AAA_POS 1
#define AAA_MASK (1 << AAA_POS)
#define BBB_POS 2
#define BBB_MASK (1 << BBB_POS)

如果你想从一个位向量中提取AAA,可以这样写宏:

#define EXTRACT(bv, field) ((bv & field##_MASK) >> field##_POS)

然后你可以像这样使用它:
EXTRACT(my_bitvector, AAA)

3

2
我知道这很老旧,但是你的旧链接可能没有指向你最初想要的地方。这正是为什么不建议使用像这样的链接,即没有任何其他关于其内容的真实信息。 - ryyker

1

这不是C语言的结构,而是预处理器特性。在这种情况下,它旨在评估bt变量并将其与bit前缀连接起来。如果没有哈希符号,你会得到bitbt,显然这是行不通的。


我认为“评估bt变量”不是正确的说法...在预处理器的上下文中,“替换令牌”或类似的术语是通常使用的术语。预处理器对值一无所知;它所看到的只是字符串标记(有几个例外)。 - Kerrek SB

0
这是来自 ffmpeg 的一个示例,它注册了音频和视频滤镜的宏:
#define REGISTER_FILTER(X, x, y)                                        \
    {                                                                   \
        extern AVFilter ff_##y##_##x;                                   \
        if (CONFIG_##X##_FILTER)                                        \
            avfilter_register(&ff_##y##_##x);                           \
    }

使用方法如下:

REGISTER_FILTER(AECHO,aecho,af);
REGISTER_FILTER(VFLIP,vflip,vf);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接