(macro +1) 和 (1 + macro) 区别的原因

Reason for the difference between (macro +1) and (1 + macro)

一个宏(见下文)到return两个数字中较大的一个加1。但是,加法的效果不存在。

PS: 我也通过在宏中添加过多的括号进行了检查。

#define max(a,b) (a >= b ? a : b);
void main(){
    int result = max(5,10) + 1; //result = 10
}

解决方案: 案例 1:

通过手动替换表达式中的宏(我认为就像预处理器所做的那样),加法正确执行。

result = (5 >= 10 ? 5 : 10) + 1;  // Evaluates correctly to 11.

案例 2: 当操作数的顺序颠倒时,表达式也能正确求值。

result = 1 + max(5,10); //Evaluates correctly to 11.

为什么原始表达式没有按预期工作,而两个解决方案案例却可以?

您错误地将 ; 添加到您的宏中。所以展开其实是

void main(){
    int result = (5 >= 10 ? 5 : 10); + 1;
}

这里你的+1变成了一个什么都不做的单独语句,result被初始化为10

顺便说一下,如果您使用 gcc 或 Clang,则有一个 -E 标志将 运行 实际的预处理器放在您的源代码上。上面的代码是运行ninggcc -E a.c在你的代码上得到的

我还建议使用最大可能级别的警告进行编译。例如。 gcc -Wall -Wextra -Werror a.c提示有问题:

a.c:2:6: error: return type of 'main' is not 'int' [-Werror=main]
    2 | void main(){
      |      ^~~~
a.c: In function 'main':
a.c:3:28: error: statement with no effect [-Werror=unused-value]
    3 |     int result = max(5,10) + 1; //result = 10
      |                            ^
a.c:3:9: error: unused variable 'result' [-Werror=unused-variable]
    3 |     int result = max(5,10) + 1; //result = 10
      |         ^~~~~~
cc1.exe: all warnings being treated as errors

因为你在宏后面加了分号

#define max(a,b) (a >= b ? a : b);
                               ^^^

删除它。

宏应该这样写

#define max(a,b) ( ( a ) >= ( b ) ? ( a ) : ( b ) )

所以在第一种情况下你实际上有

int result = ( 5 >= 10 ? 5 : 10 );
+ 1;

如果你会放置声明

int result = max(5,10) + 1;

在函数 main 之前的文件作用域中,编译器会报错,因为会有语句

+ 1;

并且您不能在文件范围内放置语句。

至于这个说法

result = 1 + max(5,10);

然后扩展为两个语句

result = 1 + ( 5 >= 10 ? 5 : 10 );
;

也就是还有一个无效的空语句。

注意根据C标准,不带参数的函数main应该声明为

int main( void )