Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么函数中的非静态变量被初始化为0,为什么变为静态变量?_C_Variables_Gcc_Static_Non Static - Fatal编程技术网

C 为什么函数中的非静态变量被初始化为0,为什么变为静态变量?

C 为什么函数中的非静态变量被初始化为0,为什么变为静态变量?,c,variables,gcc,static,non-static,C,Variables,Gcc,Static,Non Static,我正在尝试运行以下C代码 #include <stdio.h> void myFunc() { static int a; int b; a++; b = b + 2; printf("a:%d, b:%d\n",a,b); } int main(void) { myFunc(); myFunc(); return 0; } 我知道a是静态的,将被零初始化,但非静态的b似乎也被零初始化。此外,看起来b实际上正在转

我正在尝试运行以下C代码

#include <stdio.h>

void myFunc() {
    static int a;
    int b;
    a++;
    b = b + 2;
    printf("a:%d, b:%d\n",a,b);
}

int main(void)  {
    myFunc();
    myFunc();
    return 0;
}
我知道a是静态的,将被零初始化,但非静态的b似乎也被零初始化。此外,看起来b实际上正在转换为静态变量,因为它的值在第二次调用myFunc时被保留

我假设这与我的编译器/操作系统有关,因为使用GCC4.1.2在线使用codepad编译

a:1, b:2
a:2, b:2
尽管出于某种原因初始化b时仍然为零,但在后续调用myFunc时不会保留b的值


1为什么非静态变量被初始化为零?我是不是一直很幸运,编译器给它分配了一个零的内存块

2为什么gcc似乎在gcc 4中将b转换为静态变量,而不是gcc 5

编辑:

为了更好地说明这个问题,如果我再向myFunc添加(比如)6个调用,结果输出是:

a:1, b:2
a:2, b:4
a:3, b:6
a:4, b:8
a:5, b:10
a:6, b:12
a:7, b:14
a:8, b:16
非静态变量b未初始化为零。在您的实验中,恰好b中的不确定垃圾值为零。零和任何其他值一样是垃圾

变量b未转换为静态变量。它不会在调用之间保留其值。在您的实验中,第二次函数调用中的不确定垃圾值b恰好与第一次调用中的最后一个值相同。该值与任何其他值一样都是垃圾


虽然你观察到的意外行为有相当简单和确定的潜在原因,但它是脆弱的。这些都不适用于实际代码。

未定义的行为是未定义的…请尝试在对myFunc的两次调用之间添加另一个不同的函数,并在该函数中创建新变量。。。看看会发生什么。但是,就像@John3136所说的…@Al-Kenny:你如何区分一个真正零初始化变量和一个恰好垃圾值为0的垃圾变量之间的区别?那么,如何判断一个变量在调用静态变量和一个垃圾变量之间真正保留了它的值,而垃圾变量恰好与它以前的值完全意外地匹配?为什么非静态变量被初始化为零?这是不确定的。编译器看到的代码类似于int b;b=b+2;printfb:%d\n,b;并且可以用putsb:2:替换它,或者销毁硬盘。两者都可以,因为这是未定义的行为。内存位置在堆栈上。由于您是从同一父函数调用它们,因此每次都使用相同的堆栈内存,并且在调用之间没有任何内容被覆盖。再次运行myFunc似乎会显示与您所说相反的结果。如果我修改主代码块以调用myFunc 8次,就会得到输出:a:1,b:2a:2,b:4a:3,b:6a:4,b:8a:5,b:10a:6,b:12a:7,b:14a:8,b:16@keaek尝试在调用myFunc之间调用其他函数。您看到这一点的原因是因为没有其他东西在使用堆栈的这一部分,所以它仍然保留了上次调用留下的内容。@Barmar清除了一些内容。如果我添加函数void print_something{printfsomething\n;}并在调用myFunc之间调用它,我会得到类似于a:1、b:2 something a:2、b:2 something a:3、b:2 something a:4、b:2 something a:5、b:2的结果something@keaek:它并没有真正地对抗它。这仅仅意味着你们继续在无风无声的超洁净实验室条件下,故意地、成功地、无意义地平衡埃菲尔铁塔顶端的上翻。只要试着在通话之间给其他人打电话,它就会崩溃。
a:1, b:2
a:2, b:4
a:3, b:6
a:4, b:8
a:5, b:10
a:6, b:12
a:7, b:14
a:8, b:16