c - 奇怪的宏定义问题

标签 c macros c-preprocessor

我想在编译时根据另一个宏的值定义一个宏。然而这段代码没有按预期执行:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIXTEEN 16
#define TWO (SIXTEEN % 8 == 0)? (SIXTEEN / 8) : ((SIXTEEN / 8) + 1)

int main();

int main() {
    printf("max = %d\n", TWO);
    int i;
    for (i = 0; i < TWO; i++) {
        printf("%d\n", i);
    }
    return 0;
}

这打印:

max = 2
0
1
2
...

并继续直到终止,当它应该简单地打印时:

max = 2
0
1

并退出。

如果我改为这样做,它会起作用:

#define TWO 2

我认为这是宏定义的问题...但是,如果我对原始的#define 执行以下操作,它似乎可以工作:

...
int count = TWO;
for (i = 0; i < count; i++) {
...

谁能解释一下这是怎么回事?

最佳答案

问题是标记 TWO 被您用来定义宏的标记所替换,因此:

i < TWO

变成这样:

i < (SIXTEEN % 8 == 0)? (SIXTEEN / 8) : ((SIXTEEN / 8) + 1) 

由于运算符的优先级,这被读作:

(i < (SIXTEEN % 8 == 0))
    ? (SIXTEEN / 8) 
    : ((SIXTEEN / 8) + 1) 

你需要额外的括号,这样当 TWO 被它的替换列表替换时,你会得到你想要的结果:

#define TWO ((SIXTEEN % 8 == 0)? (SIXTEEN / 8) : ((SIXTEEN / 8) + 1))
            ^                                                       ^

使用宏时,最好尽可能使用括号,以确保结果符合您的预期。

关于c - 奇怪的宏定义问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4455307/

相关文章:

c - 在 Linux 上获取有关网络接口(interface)更改的通知

c - c中的空闲内存

c - linux __user 宏的含义是什么?

c - 是否可以使用预处理器(宏)将 C 字符串文字转换为大写?

c++ - 可行的语言是否需要预处理器?

c# - .NET 的 C 代码解析器

macros - Racket Macro 如何将省略号传递给 Helper 函数?

c++ - 预处理器计数器宏

c++ - C++ constexpr函数来测试预处理器宏

c - 从堆栈和堆中获取二维数组的函数