我遇到了这段代码:
void function(int nextFoo)
{
static int lastFoo = nextFoo;
if (nextFoo != lastFoo)
{
// is this possible?
}
lastFoo = nextFoo;
}
编码器认为lastFoo
只在第一次运行时设置,最后一行,他是对的吗?我认为(但不知道) if 块中的代码永远不会运行,但找不到验证。
coder 认为 nextFoo 只设置在第一次运行,最后一行,对吗?
是的。static
局部变量只初始化一次(而不是每次输入函数时)。在 C++11 中,这也保证以线程安全的方式发生。根据 C++11 标准的第 6.7/4 段:
[...] 如果在初始化变量时控制同时进入声明,则并发执行应等待初始化完成 [...]
注意,如果static
对象的初始化抛出异常,下次function()
进入时会重新尝试初始化(本例不相关,因为 an 的初始化int
不能抛出)。从上面引用的同一段中:
[...]如果初始化通过抛出异常退出,则初始化未完成,因此将在下次控制进入声明时再次尝试。[...]
当然有可能。静态初始化只发生一次。下次调用该函数时,不再执行初始化。
(事实上,初始化甚至是无种族的 :-)。)
块中的代码可以运行;以下示例打印hello
:
#include <iostream>
using namespace std;
void function(int nextFoo)
{
static int lastFoo=nextFoo;
if (nextFoo!=lastFoo)
{
cout << "hello" << endl;
}
lastFoo=nextFoo;
}
int main()
{
function(1);
function(2);
return 0;
}
简单的答案是 yeslastFoo
只会在这里第一次设置:
static int lastFoo=nextFoo;
但这足以作为一个测试来了解它是如何为你自己工作的。当然在函数结束时lastFoo
会通过最终赋值来设置:
#include <iostream>
void function(int nextFoo)
{
static int lastFoo=nextFoo;
std::cout << "lastFoo: " << lastFoo << std::endl ;
if (nextFoo!=lastFoo)
{
std::cout << "here" << std::endl ;
}
lastFoo=nextFoo;
}
int main()
{
function(10) ;
function(11) ;
}
静态是一个存储类,它告诉编译器该变量不是每次进入和离开函数时都会创建/销毁的自动变量。
来自 K&R C 编程语言(第 2 版)
A4.1 存储类
有两种存储类:自动和静态
...
静态对象可能是块的本地对象或所有块的外部,但在任何一种情况下,在退出和重新进入函数和块时都会保留它们的值。
所以是的,这个if
声明是完全合法的。再次调用该函数时,该变量可能具有不同的值。