C语言 C中函数内部的静态变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5033627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Static variable inside of a function in C
提问by Vadiklk
What will be printed out? 6 6 or 6 7? And why?
会打印出什么?6 6 还是 6 7?为什么?
void foo()
{
static int x = 5;
x++;
printf("%d", x);
}
int main()
{
foo();
foo();
return 0;
}
回答by
There are two issues here, lifetime and scope.
这里有两个问题,生存期和范围。
The scope of variable is where the variable name can be seen. Here, x is visible only inside function foo().
变量的作用域是可以看到变量名的地方。这里,x 仅在函数 foo() 内可见。
The lifetime of a variable is the period over which it exists. If x were defined without the keyword static, the lifetime would be from the entry into foo() to the return from foo(); so it would be re-initialized to 5 on every call.
变量的生命周期是它存在的时间段。如果定义 x 时没有关键字 static,则生命周期将从进入 foo() 到从 foo() 返回;所以它会在每次调用时重新初始化为 5。
The keyword static acts to extend the lifetime of a variable to the lifetime of the programme; e.g. initialization occurs once and once only and then the variable retains its value - whatever it has come to be - over all future calls to foo().
关键字 static 用于将变量的生命周期延长到程序的生命周期;例如,初始化只发生一次,然后变量保留它的值——不管它变成了什么——在以后对 foo() 的所有调用中。
回答by Nitesh Borad
Output: 6 7
输出:6 7
Reason: static variable is initialised only once (unlike auto variable) and further definition of static variable would be bypassed during runtime. And if it is not initialised manually, it is initialised by value 0 automatically. So,
原因:静态变量仅初始化一次(与自动变量不同),并且在运行时将绕过静态变量的进一步定义。如果不是手动初始化,它会自动初始化为值 0。所以,
void foo() {
static int x = 5; // assigns value of 5 only once
x++;
printf("%d", x);
}
int main() {
foo(); // x = 6
foo(); // x = 7
return 0;
}
回答by Chaim Geretz
6 7
6 7
compiler arranges that static variable initialization does not happen each time the function is entered
编译器安排每次进入函数时不进行静态变量初始化
回答by Richard J. Ross III
That is the same as having the following program:
这与具有以下程序相同:
static int x = 5;
void foo()
{
x++;
printf("%d", x);
}
int main()
{
foo();
foo();
return 0;
}
All that the static keyword does in that program is it tells the compiler (essentially) 'hey, I have a variable here that I don't want anyone else accessing, don't tell anyone else it exists'.
static 关键字在该程序中所做的一切就是告诉编译器(基本上)'嘿,我这里有一个变量,我不希望其他人访问它,不要告诉其他人它存在'。
Inside a method, the static keyword tells the compiler the same as above, but also, 'don't tell anyone that this exists outside of this function, it should only be accessible inside this function'.
在方法内部,static 关键字告诉编译器与上述相同,但“不要告诉任何人它存在于此函数之外,它应该只能在此函数内部访问”。
I hope this helps
我希望这有帮助
回答by Donotalo
A static variable inside a function has a lifespan as long as your program runs. It won't be allocated every time your function is called and deallocated when your function returns.
只要程序运行,函数内的静态变量就有生命周期。不会在每次调用您的函数时分配它,并在您的函数返回时解除分配。
回答by Ivan
Output: 6,7
输出:6,7
Reason
原因
The declaration of xis inside foobut the x=5initialization takes place outside of foo!
的声明在x内部,foo但x=5初始化发生在foo!
What we need to understand here is that
这里我们需要明白的是
static int x = 5;
is not the same as
不一样
static int x;
x = 5;
Other answers have used the important words here, scope and lifetime, and pointed out that the scope of xis from the point of its declaration in the function footo the end of the function foo. For example I checked by moving the declaration to the end of the function, and that makes xundeclared at the x++;statement.
其他答案在这里使用了重要的词,范围和生命周期,并指出范围x是从它在函数中声明的点到函数foo结束foo。例如,我通过将声明移到函数末尾来进行检查,这使得x在x++;语句中未声明。
So the static int x(scope) part of the statement actually applies where you read it, somewhere INSIDEthe function and only from there onwards, not above it inside the function.
因此,static int x语句的(范围)部分实际上适用于您阅读它的地方,在函数内部的某个地方,并且仅从那里开始,而不是在函数内部的上方。
However the x = 5(lifetime) part of the statement is initialization of the variableand happening OUTSIDEof the function as part of the program loading. Variable xis born with a value of 5when the program loads.
然而,x = 5声明(寿命)的部分是变量的初始化和将发生的OUTSIDE功能作为程序加载的一部分。变量x与5程序加载时的值一起生成。
I read this in one of the comments: "Also, this doesn't address the really confusing part, which is the fact that the initializer is skipped on subsequent calls." It is skipped on all calls. Initialization of the variable is outside of the function code proper.
我在其中一条评论中读到了这一点:“此外,这并没有解决真正令人困惑的部分,即在后续调用中跳过初始化程序这一事实。”它在所有调用中都被跳过。变量的初始化在适当的函数代码之外。
The value of 5 is theoretically set regardless of whether or not foo is called at all, although a compiler might optimize the function away if you don't call it anywhere. The value of 5 should be in the variable before foo is ever called.
无论 foo 是否被调用,理论上都会设置 5 的值,尽管如果您不在任何地方调用它,编译器可能会优化该函数。在调用 foo 之前,5 的值应该在变量中。
Inside of foo, the statement static int x = 5;is unlikely to be generating any code at all.
在 内部foo,该语句static int x = 5;根本不可能生成任何代码。
I found the address xuses when I put a function foointo a program of mine, and then (correctly) guessed that the same location would be used if I ran the program again. The partial screen capture below shows that xhas the value 5even before the first call to foo.
我发现x当我将一个函数foo放入我的程序时使用的地址,然后(正确地)猜测如果我再次运行该程序将使用相同的位置。部分屏幕捕获如下图的是x具有价值5,甚至在第一次调用之前foo。
回答by Javed
Vadiklk,
瓦迪克,
Why ...? Reason is that static variable is initialized only once, and maintains its value throughout the program. means, you can use static variable between function calls. also it can be used to count "how many times a function is called"
为什么 ...?原因是静态变量只初始化一次,并在整个程序中保持其值。意味着,您可以在函数调用之间使用静态变量。也可以用来计算“一个函数被调用了多少次”
main()
{
static int var = 5;
printf("%d ",var--);
if(var)
main();
}
and answer is 5 4 3 2 1 and not 5 5 5 5 5 5 .... (infinite loop) as you are expecting. again, reason is static variable is initialized once, when next time main() is called it will not be initialize to 5 because it is already initialized in the program.So we can change the value but can not reinitialized. Thats how static variable works.
答案是 5 4 3 2 1 而不是 5 5 5 5 5 5 ....(无限循环),正如您所期望的。再次,原因是静态变量初始化一次,下次调用main()时不会初始化为5,因为它已经在程序中初始化了。所以我们可以更改值但不能重新初始化。这就是静态变量的工作原理。
or you can consider as per storage: static variables are stored on Data Section of a program and variables which are stored in Data Section are initialized once. and before initialization they are kept in BSS section.
或者您可以按照存储考虑:静态变量存储在程序的数据段中,存储在数据段中的变量被初始化一次。在初始化之前,它们保存在 BSS 部分。
In turn Auto(local) variables are stored on Stack and all the variables on stack reinitialized all time when function is called as new FAR(function activation record) is created for that.
反过来,自动(本地)变量存储在堆栈中,并且当函数被调用时,堆栈上的所有变量都会重新初始化,因为为此创建了新的 FAR(函数激活记录)。
okay for more understanding, do the above example without "static" and let you know what will be the output. That make you to understand the difference between these two.
好的,为了更多的理解,在没有“静态”的情况下做上面的例子,让你知道输出是什么。这使您了解这两者之间的区别。
Thanks Javed
谢谢贾维德
回答by Jerry Coffin
The output will be 6 7. A static variable (whether inside a function or not) is initialized exactly once, before any function in that translation unit executes. After that, it retains its value until modified.
输出将为6 7. 静态变量(无论是否在函数内部)在该翻译单元中的任何函数执行之前只初始化一次。之后,它会保留其值直到被修改。
回答by Ken Wayne VanderLinde
You will get 6 7 printed as, as is easily tested, and here's the reason: When foois first called, the static variable x is initialized to 5. Then it is incremented to 6 and printed.
您将得到 6 7 打印为,这很容易测试,原因如下:foo第一次调用时,静态变量 x 被初始化为 5。然后它会增加到 6 并打印。
Now for the next call to foo. The program skips the static variable initialization, and instead uses the value 6 which was assigned to x the last time around. The execution proceeds as normal, giving you the value 7.
现在进行下一次调用foo. 程序跳过静态变量初始化,而是使用上次分配给 x 的值 6。执行正常进行,为您提供值 7。
回答by mouviciel
6 7
x is a global variable that is visible only from foo(). 5 is its initial value, as stored in the .data section of the code. Any subsequent modification overwrite previous value. There is no assignment code generated in the function body.
x 是一个全局变量,只能从 foo() 中看到。5 是它的初始值,存储在代码的 .data 部分。任何后续修改都会覆盖以前的值。函数体中没有生成赋值代码。


