为什么全局变量与此函数中的局部变量不同?
Why global variable is different from local variable in this function?
这里我有一个名为 max(a,b)
的函数来获取两个中的最大值。
而且我发现变量a
和b
使用printf()
执行后的值是不一样的
printf("maxab()=%d after max: a=%d b=%d \n",max(a++,b++),a,b);
当a
和b
为Global variables
和Local 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是原来的值,为什么第三个输出的是a+1和b+1?为什么当a和b是全局变量时,打印出来的a和b的值只有在我们先执行max(a++,b++)
时才会改变?为什么 a 和 b 是局部变量并不重要?
谢谢!
(在 windows 10 上使用 gcc 5.3.0)
据我所知,它与变量的范围无关。 C 没有指定函数参数求值的确切顺序。所以,这是未指定的行为。
表达式 printf(... max(a++,b++),a,b);
是 undefined 行为 Why are these constructs (using ++) undefined behavior?.
a++
的评估与 a
的评估没有先后顺序,b++
和 b
也是如此。在调用函数之前有一个序列点并不重要,因为子表达式可以在此之前以任何顺序求值。
未定义的行为 = 始终是错误。意味着该程序可以有任何类型的行为,打印任何内容,崩溃和烧毁等。
它是未定义行为的原因是,C11 6.5/2:
If a side effect on a scalar object is unsequenced relative to either
a different side effect on the same scalar object or a value
computation using the value of the same scalar object, the behavior is
undefined.
(a
是标量对象 - 不是数组或结构等。a++
会导致更新变量的副作用。这与 [= 的值计算相关是无序的13=] 在同一表达式的其他地方。)
不要与 未指定的行为 混淆,这意味着该程序将确定性地运行,但您不知道以哪种方式运行。例如,函数参数的求值顺序是未指定的行为:
int func (void)
{
static int x=0;
x++;
return x;
}
printf("%d %d", func(), func());
这可能会打印 1 2
或 2 1
,我们无法知道或假设哪个适用。编译器不需要对此进行记录,也不必在整个程序中保持一致。它可以在一种情况下选择一个订单,在另一种情况下选择另一个订单。
依赖未指定行为的代码是不好的,但不会像包含未定义行为的代码那样表现得完全不稳定。
这里我有一个名为 max(a,b)
的函数来获取两个中的最大值。
而且我发现变量a
和b
使用printf()
执行后的值是不一样的
printf("maxab()=%d after max: a=%d b=%d \n",max(a++,b++),a,b);
当a
和b
为Global variables
和Local 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是原来的值,为什么第三个输出的是a+1和b+1?为什么当a和b是全局变量时,打印出来的a和b的值只有在我们先执行max(a++,b++)
时才会改变?为什么 a 和 b 是局部变量并不重要?
谢谢! (在 windows 10 上使用 gcc 5.3.0)
据我所知,它与变量的范围无关。 C 没有指定函数参数求值的确切顺序。所以,这是未指定的行为。
表达式 printf(... max(a++,b++),a,b);
是 undefined 行为 Why are these constructs (using ++) undefined behavior?.
a++
的评估与 a
的评估没有先后顺序,b++
和 b
也是如此。在调用函数之前有一个序列点并不重要,因为子表达式可以在此之前以任何顺序求值。
未定义的行为 = 始终是错误。意味着该程序可以有任何类型的行为,打印任何内容,崩溃和烧毁等。
它是未定义行为的原因是,C11 6.5/2:
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.
(a
是标量对象 - 不是数组或结构等。a++
会导致更新变量的副作用。这与 [= 的值计算相关是无序的13=] 在同一表达式的其他地方。)
不要与 未指定的行为 混淆,这意味着该程序将确定性地运行,但您不知道以哪种方式运行。例如,函数参数的求值顺序是未指定的行为:
int func (void)
{
static int x=0;
x++;
return x;
}
printf("%d %d", func(), func());
这可能会打印 1 2
或 2 1
,我们无法知道或假设哪个适用。编译器不需要对此进行记录,也不必在整个程序中保持一致。它可以在一种情况下选择一个订单,在另一种情况下选择另一个订单。
依赖未指定行为的代码是不好的,但不会像包含未定义行为的代码那样表现得完全不稳定。