如何评估此C预处理器?

时间:2015-08-11 12:03:59

标签: c macros c-preprocessor

#include<stdio.h>
#define SQUARE(x) x*x
int main(){
float s=10,u=30,t=2,a;
a=2*(s-u*t)/SQUARE(t); // How is this evaluated ? 
printf("Result %f\n",a);
return 0;
}

编译器显示的输出为-100.000000。但据我说它应该是-25.000000。我该怎么做才能纠正它,我的错误是什么?

4 个答案:

答案 0 :(得分:5)

#define对您定义的字符串执行字面替换。所以表达式:

 a = 2*(s-u*t)/SQUARE(t*t)

将扩展为:

 a = 2*(s-u*t)/t*t

根据运营商的评估顺序,评估为:

a = (2*(s-u*t)/t)*t

不是你想要的。你可能真的想要a = 2*(s-u*t)/(t*t),所以你应该:{/ p>

#define SQUARE(x) (x*x)

甚至更好,正如@Jongware指出的那样,因为x本身可能是一个表达式:

#define SQUARE(x) ((x)*(x))

这样,像[{1}}这样的表达式会正确评估为SQUARE(a+b),而不是((a+b)*(a+b))

同样如评论中所指出的,当您在参数中有副作用时,您需要注意宏表达式结果。例如,(a+b*a+b)做了什么,SQUARE(x++)完成后的价值是多少?在这种情况下,它会给x(x++)*(x++)的值后递增两次,结果可能是未定义的行为(在这种情况下取​​决于后增量的顺序)。

答案 1 :(得分:2)

预处理器是文本替换。所以你的表达成为:

a=2*(s-u*t)/t*t;

*/具有相同的优先级,因此2*(s-u*t)除以t,然后乘以t

答案 2 :(得分:1)

<强>解释

宏函数SQUARE(x) x*x计算给定数字'x'的平方。

第1步:浮动s = 10,u = 30,t = 2,a;这里变量s,u,t,a被声明为浮点类型,变量s,u,t被初始化为10,30,2。

第2步: a = 2 *(s-u * t)/ SQUARE(t);变,

=&GT; a = 2 *(10 - 30 * 2)/ t * t;这里SQUARE(t)被宏替换为t * t。

=&GT; a = 2 *(10 - 30 * 2)/ 2 * 2;

=&GT; a = 2 *(10 - 60)/ 2 * 2;

=&GT; a = 2 *( - 50)/ 2 * 2;

=&GT; a = 2 *( - 25)* 2;

=&GT; a =( - 50)* 2;

=&GT; a = -100;

第3步: printf(“结果=%f”,a);它打印变量'a'的值。

因此,该计划的输出为-100

答案 3 :(得分:0)

#define SQUARE(x) x*x
int main(){
float s=10,u=30,t=2,a;
a=2*(s-u*t)/t*t; // SQUARE(t) is defined as t*t so it is 
                 // what is placed here instead of SQUARE(t)

/t*t==1以来,这可能不是您想要的。

解决方案:

#include<stdio.h>
#define SQUARE(x) ((x)*(x))

然后:

#include<stdio.h>
#define SQUARE(x) x*x
int main(){
float s=10,u=30,t=2,a;
a=2*(s-u*t)/((t)*(t)); // again, exactly as in #define SQUARE(t)