我一直在使用以下代码探索 C 中静态变量的行为:
#include <stdio.h>
int f(int n)
{
static int r = 10;
if (n <= 0)
return 7;
if (n > 2)
return f(n-1) + r; // Important line
else{
r = 17;
return f(n-1) + n;
}
}
int main(void)
{
int n = 4;
printf("%d\n", f(n));
return 0;
}
现在,如果您注意到代码中的“重要行”(return f(n-1) + r
),它会调用函数f 首先,它会更改静态变量,r。
但是,如果我将该行更改为 return r + f(n-1)
,我希望 r 将存储在一个临时寄存器中,并且只有到那时函数 f 会被评估吗?然而,这似乎并没有发生,因为在这两种情况下,函数 f 首先被评估。我什至检查了编译器生成的汇编代码,在这两种情况下它都先调用函数。
但是,如果我将行更改为 return (r+2) + f(n-1)
,那么 (r+2)
会首先求值并存储在临时寄存器中,然后才对函数 f 求值。
如果我再次将行更改为 return f(n-1) + (r+2)
,那么函数 f 将首先被计算。
因此,在程序中使用 return r + f(n-1)
和 return f(n-1) + r
会得到完全相同的输出。
然而,使用 return (r+2) + f(n-1)
和 return f(n-1) + (r+2)
给出 不同的输出。
我不明白为什么静态变量的行为会出现这种差异。根据我的理解,在 return r + f(n-1)
中,显然 r 应该首先被评估,但这并没有发生。谁能解释为什么?为什么这种行为不一致?如果我使用 (r+2)
而不是 r
为什么它会改变?
最佳答案
C 将这些决定留给编译器。
你的期望是没有根据的。
你说的是寄存器,但 C 不需要使用寄存器的机器。
你说的是+
的操作数求值的相对顺序,但是C对此没有要求。编译器可以按照其选择的顺序自由地评估它们。
差异源于您所做的错误假设。您所有的问题都得到了回答:这取决于编译器。
关于c - 关于 C 中局部静态变量的不同行为的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72082395/