运行C代码时输出错误

可能重复:
在C中调用函数之前的参数评估顺序

对于下面的代码,我预计输出为20和76,而75和21将作为输出。请解释为什么会这样。

#include unsigned func(unsigned n) { unsigned int a =1 ; static unsigned int b=2; a+=b; b+=a; { unsigned int a=3; a+=b; b+=a; } //printf("%d %d ",a,b); return (n+a+b); } int main() { printf("%d %d\n",func(4),func(5)); return 0; } 

你期望在func(5)之前func(5)但编译器会发生相反的情况。 C标准未指定function参数的评估顺序。 因此,编译器可以自由选择首先调用哪个函数。 因此,在不同的运行中,您可能会观察到不同的函数调用顺序,尽管使用相同的编译器不太可能发生这种情况。

func(4)和func(5)的评估顺序不是由C标准定义的。

表达式的评估顺序是unspecified behaviour因此func(4)func(5)可以按照您应该的不同顺序调用

您可能想要访问它以获取更多信息

C ++中编译器和评估的参数顺序

在C中调用函数之前的参数评估顺序

参数以相反的顺序被压入堆栈。 在您的编译器实现中, func(5)func(4)之前被调用。

评估顺序可能是原因。 因为,

 //printf("%d %d\n",func(4),func(5)); printf("%d \n",func(4)); printf("%d \n",func(5)); 

版画

 20 76 

func(5)首先被执行:

执行func(5)后的变量值:

 a = 3 b = 13 func(5) = 21 

因为,b是静态的,执行func(4)后的值:

 a = 14 b = 57 func(4) = 75 

代码很简单,并且记住static变量将在函数调用之间保留它们的值。

在您的程序中,由于您的编译器(因此编译器特定,未由标准定义):

func(5)首先执行,:返回21 ..解释:

  unsigned func(unsigned n) /*first with 5*/ { unsigned int a =1 ; static unsigned int b=2; a+=b; b+=a; // a = 3, b = 5 { unsigned int a=3; a+=b; b+=a; // a = 8, b = 13 } //printf("%d %d ",a,b); return (n+a+b); // 5 + 3 + 13 = 21. } 

接下来执行func(4),

说明:

  unsigned func(unsigned n) /*first with 5*/ { unsigned int a =1 ; static unsigned int b=2; a+=b; b+=a; // a = 14, b = 27 { unsigned int a=3; a+=b; b+=a; // a = 30, b = 57 } //printf("%d %d ",a,b); return (n+a+b); // 4 + 57 + 14 = 75(which is printed first). } 

因此输出。

对于这种称为“function副作用”的术语是众所周知的。 您在函数内部更改变量,调用函数并依赖于使用变量的语句,期望它已经更改。 通常这应该避免,并不是一个好方法。

在这种情况下更好的替代方案是调用函数并存储返回值,然后在printf中使用它们或进行两个不同的printf调用。

副作用