为什么全局变量与此函数中的局部变量不同?

时间:2017-03-30 06:53:10

标签: c scope function-call

这里我有一个名为max(a,b)的函数来获取两个中的最大数。 我发现使用a的变量bprintf()的值在执行后会有所不同

printf("maxab()=%d after max: a=%d b=%d \n",max(a++,b++),a,b);

abGlobal variablesLocal variables时。以下是我的代码:

#include<stdio.h>

int max(int a,int b)
{

    if(a>b)
    {
        //printf("In func max():%d %d \n",a,b);
        return a;
    }
    else {
        //printf("In func max():%d %d \n",a,b);
        return b;
    }

}
void jubu_test(void)
{
    int a=1;
    int b=2;    
    printf("maxab()=%d after max: a=%d b=%d \n",max(a++,b++),a,b);  //a=2,b=3
}
int c=2;
int d=1;
void quanju_test(void)
{
    printf("maxcd()=%d  c=%d d=%d \n",max(c++,d++),c,d);    //c=2,d=1
    c=2;
    d=1;
    int f=max(c++,d++);
    printf("maxcd()=%d after max: c=%d d=%d \n",f,c,d);     //c=3,d=2
}   
int main(int argc, char** argv)
{
    jubu_test();
    quanju_test();
}

我在计算机上得到的结果是:

maxab()=2 after max: a=2 b=3
maxcd()=2  c=2 d=1
maxcd()=2 after max: c=3 d=2

我的问题是:为什么在第二个输出中a和b是它们的原始值以及为什么第三个输出是+ 1和b + 1?为什么当a和b是全局变量时,打印出的a和b的值只会在我们首先执行max(a++,b++)时发生变化?为什么a和b是局部变量并不重要?

谢谢! (在Windows 10上使用gcc 5.3.0)

2 个答案:

答案 0 :(得分:5)

根据Why are these constructs (using ++) undefined behavior?,表达式printf(... max(a++,b++),a,b);未定义的行为。

a++的评估与a的评估无关,b++b的评估相同。在调用函数之前有一个序列点并不重要,因为可以在此之前以任何顺序评估子表达式。

未定义的行为=总是一个错误。意味着该程序可以有任何行为,打印任何东西,崩溃&amp;烧伤等。

它是未定义行为的原因是,C11 6.5 / 2:

  

如果标量对象的副作用相对于其中任何一个都没有排序   对同一个标量对象或值有不同的副作用   使用相同标量对象的值进行计算,行为是   未定义。

a是一个标量对象 - 不是数组或结构等。a++会导致更新变量的副作用。这与{{1}的值计算无关在同一个表达式的其他地方。)

不要与未指明的行为混淆,这意味着程序将具有确定性,但您无法知道以哪种方式。例如,函数参数的评估顺序是未指定的行为:

a

这可能会打印int func (void) { static int x=0; x++; return x; } printf("%d %d", func(), func()); 1 2,我们无法知道或假设哪个适用。编译器不需要记录这一点,也不必在整个程序中表现一致。它可以在一个案例中选择一个订单,在另一个案例中选择另一个订单。

依赖于未指定行为的代码很糟糕,但不会像包含未定义行为的代码那样完全不正常。

答案 1 :(得分:3)

我相信,它与变量的范围无关。 C没有指定函数参数求值的确切顺序。所以,这是未指明的行为。