C 局部静态变量在方法中是如何工作的?
下面是我的代码:C 局部静态变量在方法中是如何工作的?,c,function,static,C,Function,Static,下面是我的代码: //main.c int f() { static int x = 0; x += 1; return x; } int main() { f(); printf("%d", f()); } 输出为2 我知道静态变量将保持状态,但由于我调用了两次f(),每次x都首先设置为0(static int x=0;),然后加上1,那么输出应该是1,无论我调用f()多少次?您对f()进行了两次调用,x具有静态存储持续时间,其生存
//main.c
int f()
{
static int x = 0;
x += 1;
return x;
}
int main()
{
f();
printf("%d", f());
}
输出为2
我知道静态变量将保持状态,但由于我调用了两次
f()
,每次x
都首先设置为0(static int x=0;
),然后加上1,那么输出应该是1
,无论我调用f()
多少次?您对f()
进行了两次调用,x具有静态存储持续时间,其生存期是程序的整个执行过程。这就是为什么打印2而不是1。静态
变量不仅持续存在,而且只初始化一次,因此x
不是“每次先设置为0”,它在第二次调用中保持1
,然后递增。的确如此
static int x = 0; // x is initialized once only
与
static int x;
x = 0; // x is set to 0 with every call
每次x设置为0时
不,您正在错误地读取代码。这里的=
并不表示赋值,而是表示初始化,因为它是声明的一部分。变量的初始值显式指定为0。静态变量在程序执行期间只初始化一次。如果它们的声明出现在函数中,则不会改变该行为
此外,静态变量的初始值设定项必须是常量表达式(可以在编译时计算为已知值的表达式)。这意味着实际上,实现不需要引入代码来在函数内部进行任何初始化。该值可以在程序启动时简单地加载到变量的存储器中
“…但是由于我调用了f()
两次,每次x
都设置为0
第一次(static int x=0;
),”
否。x
未在每次调用f
时设置为0
静态
变量仅在第一次调用定义它们的函数时初始化一次
与automatic变量相比,特殊之处在于分配的内存对象一直持续到程序结束
在对函数f
的不同调用之间,x
的对象和值保持不变。因此,x
在每次调用函数时递增一,而不重置为一次初始化的值
// Calls to f() in order
f(); // value of x at the end of the function: 1
f(); // value of x at the end of the function: 2
f(); // value of x at the end of the function: 3
f(); // value of x at the end of the function: 4
// and so on.
因此,当您两次调用f()
时,2
是函数返回时x
的正确值
旁注:
的显式初始化是多余的<默认情况下,代码>静态变量初始化为0
0
- 不应忽略C中函数的参数列表定义/声明。不要写
,而是写intf()
intf(void)
也应编辑为int main()
int main(void)
已过时int main()
2
是正确的:
下面的示例代码以及顶部的语句说明了原因:
首次通话:
static int x = 0; // unlike non-static variables, initialization is executed
// only once on 1st call to function.
// Also unlike non-static, local variables, locally created static
// variables are initialized to 0 automatically
// making the explicit assignment to 0 unnecessary.
// (although still a good habit. :))
...
x++; //x==1
第二次电话:
static x = 0 //skipped
...
x++; //x==2
第三个电话:
static x = 0 //skipped
...
x++; //x==3
等等,直到节目结束
(已替换<代码> x+=1;< /代码>以其惯用的快捷方式:<代码> x++;< /代码>
回答之前:考虑到这个问题已经有8个答案,话题相当基本。您的答案是否添加了一些新的内容,或者以显著的方式改进了一些已经说过的内容?使用intmain(void)
表示法很好,但是请注意C11标准(中的示例3)显示了intmain(){…}
。诚然,它不是规范性的,因为它是一个例子,但…@JonathanLeffler是的,我知道。我也发现了这些例子,并对此感到好奇。我对这个案例进行了讨论,结论是更好地使用intmain(void)
表单。因此,我提出建议。我100%同意“更好”。我在警告“符合标准”。它是合规的代码,但并不能打败现代实践。@JonathanLeffler如何看待Keith关于保证符合未来标准的推理(以防委员会消除这种歧义)?毫无疑问,使用显式int main(void)
形式更好-但目前,int main()
表单也符合标准,即使不是首选符号。类似的注释适用于函数定义的非原型样式。旧风格仍然符合标准;它根本不应该被使用。当您重新编写答案(使用“is Observe”)时,这涉及到我的诡辩(这是小规模的诡辩,不是如何编写好的C代码的哲学中的主要练习),所以一切都很好,尽管我会使用“Observe”而不是“Observe”。