需要解释这个C程序的输出吗 #包括 #定义F1(X)((X>0)?X:-(X)) #是否定义F2(X)(X>0)?X:-X int main(){ INTA=5,b=10; printf(“F1=%d,F2=%d\n”,F1(a-b),F2(a-b)); 返回0; }
输出为:需要解释这个C程序的输出吗 #包括 #定义F1(X)((X>0)?X:-(X)) #是否定义F2(X)(X>0)?X:-X int main(){ INTA=5,b=10; printf(“F1=%d,F2=%d\n”,F1(a-b),F2(a-b)); 返回0; },c,C,输出为:F1=5,F2=-15 当然,我认为F1和F2的输出应该是相同的。括号与输出有什么关系?此程序简单演示了为什么在表达式中使用宏参数时总是需要将它们括起来。它还说明了一个更广泛的观点,即为什么在一般情况下需要非常小心地使用宏 我认为F1和F2的输出应该是相同的 如果F1和F2是函数,而不是宏,那么输出实际上是相同的。但是,宏是简单的文本替换,因此使用和不使用X括号时得到的两个表达式是不同的: F1: F2: 注意,由于缺少括号,F2将一元减应用于a,而不是(a-b) 这仍然是宏的一种相对简
F1=5,F2=-15
当然,我认为F1和F2的输出应该是相同的。括号与输出有什么关系?此程序简单演示了为什么在表达式中使用宏参数时总是需要将它们括起来。它还说明了一个更广泛的观点,即为什么在一般情况下需要非常小心地使用宏 我认为F1和F2的输出应该是相同的 如果
F1
和F2
是函数,而不是宏,那么输出实际上是相同的。但是,宏是简单的文本替换,因此使用和不使用X
括号时得到的两个表达式是不同的:
F1:
F2:
注意,由于缺少括号,F2
将一元减应用于a
,而不是(a-b)
这仍然是宏的一种相对简单的用法。想象一下,如果用带有副作用的表达式替换
X
,会出现什么问题,如F2(a++,b-)
,使用宏时要小心:
(a-b > 0) ? a-b : -a-b
转向:
F1(a-b), F2(a-b)
#定义F1(X)((X>0)?X:-(X))
#是否定义F2(X)(X>0)?X:-X
int main(){
INTA=5,b=10;
printf(“F1=%d,F2=%d\n”,
((a-b>0)?a-b:-(a-b)),
(a-b>0)?a-b:-a-b);//<参见此处
返回0;
}
在宏中,如果希望表达式作为参数,则应将它们放在括号中(exp)在使用宏时,请小心括号
()
。宏替换后,看起来是这样的
#define F1(X) ((X > 0) ? X : -(X))
#define F2(X) (X > 0) ? X : -X
int main(){
int a=5, b=10;
printf("F1=%d, F2=%d\n",
((a-b > 0) ? a-b : -(a-b)),
(a-b > 0) ? a-b : -a-b ); // < see here
return 0;
}
现在计算
printf("F1=%d, F2=%d\n", ((a-b > 0) ? a-b : -(a-b)), (a-b > 0) ? a-b : -a-b);
及
函数和文本替换之间的区别。非常有启发性。宏是按文本替换的,你自己做替换,你就会明白为什么括号会有影响。
-(5-10)
与-5-10
@stark这是一个非常有用的答案……这不是一个答案,而是一个注释。如果您意识到宏只是文本替换,那么您可以自己回答这个问题。任何初级C语言的书都涉及到宏括号的问题,所以我建议读一本。在那之后,答案是微不足道的。
#define F1(X) ((X > 0) ? X : -(X))
#define F2(X) (X > 0) ? X : -X
int main(){
int a=5, b=10;
printf("F1=%d, F2=%d\n",
((a-b > 0) ? a-b : -(a-b)),
(a-b > 0) ? a-b : -a-b ); // < see here
return 0;
}
printf("F1=%d, F2=%d\n", ((a-b > 0) ? a-b : -(a-b)), (a-b > 0) ? a-b : -a-b);
F1 => ((a-b > 0) ? a-b : -(a-b))
=> ((5-10 >0) ? 5-10 : -(5-10))
=> ((-5>0 ) false so it prints -(5-10) which is 5
F2 => (a-b > 0) ? a-b : -a-b
=> (5-10 >0) ? 5-19 : -5-10
=> -5>0 false so it prints -15