如何在 C 中“#define”多个值然后“#if”它们

How to "#define" multiple values then "#if" them in C

下面的代码不起作用,但演示了我想做什么

#define TESTINGMACRO 2 | 3

#if TESTINGMACRO & 1 //Should be inactive
#endif

#if TESTINGMACRO & 2 //Should be active
#endif

#if TESTINGMACRO & 3 //Should be active
#endif

另一种选择:

#define TESTINGMACRO 2, 3

#if TESTINGMACRO == 1 //Should be inactive
#endif

#if TESTINGMACRO == 2 //Should be active
#endif

#if TESTINGMACRO == 3 //Should be active
#endif

我知道枚举或数组也可以,但是一些预处理器块包含可能无法构建的#includes。使用预处理器代码可以测试文件的其余部分。

我也知道我可以执行以下操作,但这将是一个大文件,因此单个中央宏会更干净:

#define TESTINGMACRO2
#define TESTINGMACRO3

#ifdef TESTINGMACRO1 //Should be inactive
#endif

#ifdef TESTINGMACRO2 //Should be active
#endif

#ifdef TESTINGMACRO3 //Should be active
#endif

编辑:仅供参考,在第一个场景中,所有预处理器块在实践中都处于活动状态。这样做 2 | 3 也将激活 & 1。第二个代码片段也是如此。这不是我想要的,只有 2 和 3 应该在 2|3 时处于活动状态。

Edit2:我最后做了:

#define BIT(n)  (1<<n)

#define TESTINGMACRO  ( BIT(2) | BIT(3) )

#if TESTINGMACRO & BIT(1) //Inactive
#endif

#if TESTINGMACRO & BIT(2) //Active
#endif

#if TESTINGMACRO & BIT(3) //Active
#endif

在格式方面,这最接近我的原作,而且在我看来非常易读。感谢大家的帮助

#define TESTINGMACRO1
#define TESTINGMACRO2
#define TESTINGMACRO3

#ifdef TESTINGMACRO1 //Should be inactive
#endif

#ifdef TESTINGMACRO2 //Should be active
#endif

#ifdef TESTINGMACRO3 //Should be active
#endif

就去做吧。没有更好的方法。这真是大家所期待的。

虽然你没有工作的真正原因真的很简单。

#define TESTINGMACRO 2 | 3

不正确,因为运算符的优先级。应该是

#define TESTINGMACRO (2 | 3)

正如 Konrad Rudolph 指出的那样,3 不是一个位,您可能想要 4。有些人建议 (1 << n) 来获取位,但我通常使用十六进制常量。 0x04、0x08、0x10 很容易阅读。

理论上,在您 运行 遇到麻烦之前,您只能有 15 位(带符号),但实际上它可以用于 32 位,因为您几乎再也不会遇到 16 位主机编译器了。

可以使用位域——但是您需要正确地使用它:

  • 将值定义为两个不同的幂。而不是 1, 2, 3, …,使用 1 << 0, 1 << 1, 1 << 2, … (aka. 1, 2, 4 …).

  • 通过添加括号修复运算符优先级。请记住,宏是通过 文本替换 .

    展开的
#define TESTINGMACRO ((1 << 1) | (1 << 2))

#if TESTINGMACRO & (1 << 0) //Should be inactive
#endif

#if TESTINGMACRO & (1 << 1) //Should be active
#endif

#if TESTINGMACRO & (1 << 2) //Should be active
#endif

也就是说,我通常建议改用单独的功能宏,这样生成的代码更具可读性。

您的方法的主要问题是您使用的值设置了公共位。每个值应对应一个位。然后你可以检查那个位。您还有一个优先级问题,因为 & 的优先级高于 |

因此,您想要的值不是 1、2 和 3,而是 1、2 和 4(或等效地,1<<01<<11<<2)。

#define TESTINGMACRO ((1<<1) | (1<<2))

#if TESTINGMACRO & (1<<0) //Should be inactive
#endif

#if TESTINGMACRO & (1<<1) //Should be active
#endif

#if TESTINGMACRO & (1<<2) //Should be active
#endif