使用函数与宏时,为什么会得到不同的结果?

我正在使用DevCPP IDE,我发现在用c编程时,

返回的值:

float f(float x) { return 1/(1+x*x); } 

和f(x)返回的值如果定义为:

 #define f(x) 1/(1+x*x) 

是不同的。

为什么我在这些情况下会得到不同的结果?

编辑:

这是我的代码,我得到了exception:

 main() { int i; float a=0, b=1, h, n=12, s1, s2=0; h=(ba)/n; //step length s1=f(a)+f(b); for(i=1;i<=n-1;i++) { s2+=f(a+(i*h)); } s1=(s1+2*s2)*h/2; printf("sum: %f", s1); getch(); } 

输出1:0.693581(使用MACRO)

输出2:0.785109(使用function)

这里有很多种可能性。 这里有几个。

在函数版本中,参数显式地键入为float 。 这意味着如果你打电话

 f(1); 

然后将1转换为float 1.0f作为参数。 然后,当计算1 / (1 + x * x) ,它评估为1 / 2.0f ,其为0.5f 。 但是,在宏版本中, f(1)将使用整数除法计算为1 / 2 ,得到值0。

其次,在函数版本中,参数仅计算一次。 这意味着

 int x = 0; f(x++); 

x增加到1 ,然后传入值0 。 结果将是1.0f 。 但是,在宏版本中,代码扩展为

 1 / (1 + x++ * x++) 

这会导致未定义的行为,因为x++的评估之间没有序列点。 这个表达式可以评估任何东西 ,或者它可能会彻底崩溃程序。

最后,函数版本遵循运算符优先级而宏不支持。 例如,在函数版本中,调用

 f(1 - 1) 

将调用f(0) ,评估为1.0f 。 在宏版本中,这扩展为

  1 / (1 + 1 - 1 * 1 - 1) = 1 / (1 + 1 - 1 - 1) = 1 / 0 

由于被零除错误,这会导致未定义的行为。

避免这种情况的简单方法是不使用宏来定义函数 。 回到Bad Old Days这是一个标准的做法,但是现在C有inline函数和编译器更聪明,你应该更喜欢函数到宏。 它们更安全,更易于使用,更难以搞定。 它们也是类型感知的,并且不会多次评估参数。

希望这可以帮助!

 #define f(x) 1/(1+x*x) 

应定义为

 #define f(x) 1/(1+(x)*(x)) 

试试这个:

 #define f(x) (1/(1+x*x)) 

#define基本上将代码放在#define ‘名称所在的位置,因此将应用操作顺序和优先顺序。