这两个带有递归函数和静态变量的C程序谁有不同的输出?
Who do these two C programs with a recursive function and static variable have different outputs?
此代码输出为 125
#include<stdio.h>
int func(int a)
{
static int num = 2;
if(a==0) return 1;
num++;
return num*func(--a);
}
int main()
{
printf("%d", func(3));
}
虽然此代码给出的输出为 60
#include<stdio.h>
int func(int a)
{
static int num = 2;
if(a==0) return 1;
return (++num)*func(--a);
}
int main()
{
printf("%d", func(3));
}
在第一个代码中,我在 return 语句之前增加了 num
,在第二个代码中,我在 return 语句中预先增加了 num
。
第一个代码似乎评估为 5*5*5,而第二个代码评估为 3*4*5。为什么会这样?
在第二个程序的这一行:
return (++num)*func(--a);
num
的值作为副作用递增, 和 对 func
的函数调用也会修改 num
。
这个表达式的各个操作数的计算是未排序的,这意味着要么先计算num
,要么调用func
首先.
对func
的调用确实引入了一个序列点。因此,如果首先评估 ++num
,则在实际调用 func
之前应用递增 num
的副作用。另一方面,如果首先评估对 func
的调用,则 num
将在函数调用内部被修改,然后 num
的读取和更新将看到更新后的值。但是,不能保证其中一个会先发生。
所以这里没有未定义的行为,但是由于子表达式的未排序计算,结果是 未指定。
第一个程序有类似的问题,即使 num
没有在同一语句中递增:
return num*func(--a);
和以前一样,如果先计算 num
,那么就会看到当前值。如果首先评估函数调用,则将读取 num
的更新值。
要从程序中获得确定性行为,您需要将静态变量的当前值复制到 non-static 变量,并使用该值乘以函数结果。
int func(int a)
{
static int num = 2;
if(a==0) return 1;
int num_tmp = ++num;
return num_tmp*func(--a);
}
此代码输出为 125
#include<stdio.h>
int func(int a)
{
static int num = 2;
if(a==0) return 1;
num++;
return num*func(--a);
}
int main()
{
printf("%d", func(3));
}
虽然此代码给出的输出为 60
#include<stdio.h>
int func(int a)
{
static int num = 2;
if(a==0) return 1;
return (++num)*func(--a);
}
int main()
{
printf("%d", func(3));
}
在第一个代码中,我在 return 语句之前增加了 num
,在第二个代码中,我在 return 语句中预先增加了 num
。
第一个代码似乎评估为 5*5*5,而第二个代码评估为 3*4*5。为什么会这样?
在第二个程序的这一行:
return (++num)*func(--a);
num
的值作为副作用递增, 和 对 func
的函数调用也会修改 num
。
这个表达式的各个操作数的计算是未排序的,这意味着要么先计算num
,要么调用func
首先.
对func
的调用确实引入了一个序列点。因此,如果首先评估 ++num
,则在实际调用 func
之前应用递增 num
的副作用。另一方面,如果首先评估对 func
的调用,则 num
将在函数调用内部被修改,然后 num
的读取和更新将看到更新后的值。但是,不能保证其中一个会先发生。
所以这里没有未定义的行为,但是由于子表达式的未排序计算,结果是 未指定。
第一个程序有类似的问题,即使 num
没有在同一语句中递增:
return num*func(--a);
和以前一样,如果先计算 num
,那么就会看到当前值。如果首先评估函数调用,则将读取 num
的更新值。
要从程序中获得确定性行为,您需要将静态变量的当前值复制到 non-static 变量,并使用该值乘以函数结果。
int func(int a)
{
static int num = 2;
if(a==0) return 1;
int num_tmp = ++num;
return num_tmp*func(--a);
}