7

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

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

    #include<stdio.h>

    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;
    }
4

8 回答 8

10

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

于 2012-10-25T07:22:21.297 回答
3

C 标准没有定义 func(4) 和 func(5) 的求值顺序。

于 2012-10-25T07:20:05.120 回答
2

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

您可能想访问它以了解更多信息

C++ 中的编译器和参数求值顺序

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

于 2012-10-25T07:20:47.743 回答
1

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

于 2012-10-25T07:19:13.267 回答
1

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

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

印刷

20 
76
于 2012-10-25T07:23:23.240 回答
0

func(5) 首先被执行:

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

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

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

a = 14
b = 57
func(4) = 75
于 2012-10-25T07:25:01.757 回答
0

代码很简单,记住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). 
    }

因此输出。

于 2012-10-25T07:31:48.733 回答
0

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

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

副作用

于 2012-10-25T07:31:57.273 回答