如何在 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<<0
、1<<1
和 1<<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
下面的代码不起作用,但演示了我想做什么
#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<<0
、1<<1
和 1<<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