我非常清楚静态局部变量的概念:全局生命周期,本地范围。同样,我理解当程序流进入并离开变量的上下文时,自动变量会自动分配/解除分配。
#include <stdio.h>
void test_var(void){
static unsigned foo = 0;
unsigned bar = 0;
printf(" %u %u\n", foo++, bar++);
}
int main(void){
printf("Foo Bar\n");
printf("--- ---\n");
for(unsigned x = 0; x < 10; x++){
test_var();
}
return 0;
}
因此,前面的示例按预期运行并打印以下输出:
Foo Bar
--- ---
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
令我困惑的是变量在未初始化时的行为方式:
#include <stdio.h>
void test_var(void){
static unsigned foo; /* not initialized */
unsigned bar; /* not initialized */
printf(" %u %u\n", foo++, bar++);
}
int main(void){
printf("Foo Bar\n");
printf("--- ---\n");
for(unsigned x = 0; x < 3; x++){
test_var();
}
return 0;
}
输出:
Foo Bar
--- ---
0 2
1 3
2 4
3 5
4 6
5 7
6 8
7 9
8 10
9 11
因此静态变量的行为符合预期 - 获得默认值0
并通过函数调用持续存在;但自动变量似乎也会持续存在 - 虽然持有垃圾值,但每次调用都会增加。
这是因为 C标准中的行为未定义,还是标准中有一组规则可以解释这一点?
答案 0 :(得分:1)
C标准表示对象的生命周期是保证存储的时间(参见例如ISO / IEC 9899:TC3的6.2.4)。静态和全局变量的生命周期贯穿整个程序,为此,标准保证了上述行为。在程序启动之前初始化这些值。对于自动,对象处于一个恒定的地址,但只能保证它们的使用寿命。因此,虽然多条函数调用中条形似乎仍然存在,但您无法保证它。 这也是为什么你应该总是初始化你的变量,在使用之前你永远不知道哪个变量在同一个地方。
我稍微调整了程序以打印静态和局部变量的地址:
#include <stdio.h>
void test_var(void){
static unsigned foo; /* not initialized */
unsigned bar; /* not initialized */
printf(" %u %u\t%p\t %p\n", foo++, bar++, &foo, &bar);
}
int main() {
printf("Foo Bar\n");
printf("--- ---\n");
for(unsigned x = 0; x < 3; x++){
test_var();
}
return 0;
}
这在我的计算机上产生了以下输出:
Foo Bar
--- ---
0 33616 0x1067c 0xbee894fc
1 33617 0x1067c 0xbee894fc
2 33618 0x1067c 0xbee894fc
这表明在我的机器上,静态foo
和自动bar
在每次调用时都处于相同的相应地址,但这是巧合而且C标准不保证{{{ 1}}将始终位于同一地址。