Jas*_*ank 0 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;
}
Run Code Online (Sandbox Code Playgroud)
这打印:
max = 2
0
1
2
...
Run Code Online (Sandbox Code Playgroud)
并继续直到终止,当它应该打印简单:
max = 2
0
1
Run Code Online (Sandbox Code Playgroud)
并退出.
如果我这样做,它的工作原理:
#define TWO 2
Run Code Online (Sandbox Code Playgroud)
我认为这是宏的定义的一个问题...但是,如果我使用原始的#define执行以下操作,它似乎工作:
...
int count = TWO;
for (i = 0; i < count; i++) {
...
Run Code Online (Sandbox Code Playgroud)
谁能解释一下这里发生了什么?
Jam*_*lis 11
问题是令牌TWO
被您定义宏的令牌所取代,因此:
i < TWO
Run Code Online (Sandbox Code Playgroud)
成为这个:
i < (SIXTEEN % 8 == 0)? (SIXTEEN / 8) : ((SIXTEEN / 8) + 1)
Run Code Online (Sandbox Code Playgroud)
由于运算符优先级,因此读为:
(i < (SIXTEEN % 8 == 0))
? (SIXTEEN / 8)
: ((SIXTEEN / 8) + 1)
Run Code Online (Sandbox Code Playgroud)
您需要额外的括号,以便当TWO
替换为替换列表时,您将获得所需的结果:
#define TWO ((SIXTEEN % 8 == 0)? (SIXTEEN / 8) : ((SIXTEEN / 8) + 1))
^ ^
Run Code Online (Sandbox Code Playgroud)
使用宏时,最好尽可能使用括号来确保结果符合您的预期.