在一行中初始化C中的所有变量和未初始化的值

时间:2017-01-29 07:37:17

标签: c side-effects variable-initialization

在C语言中,是

int x, y, z = 0;

与此相同?

int x = 0;
int y = 0;
int z = 0;

此外,如果我只是说int a;a的值似乎为零,即使它未初始化,但未定义,如What will be the value of uninitialized variable?

中所述

4 个答案:

答案 0 :(得分:4)

两者不等同。

int x, y, z = 0;

在此行中xy将具有不确定的值,而z初始化为零。

然而,您可以将其保留在“一行”中以获得一些冗长的代价:

int x = 0, y = x, z = y;

现在所有三个都使用相同的值(您给出的x)初始化。要用另一个变量初始化一个变量,所需的只是先前定义的初始化程序。即使它在同一条线上也能正常工作。以上内容还允许您非常轻松地更改所有变量的初始值。

或者,如果您发现以前的样式很难看,您可以将其分为两行:

int x, y, z;
x = y = z = 0;

但它现在是分配,而不是初始化。

  

另外,如果我只说int a;,似乎a的值即使未初始化也为零,但未定义,如未初始化变量的值是什么? / p>

“不确定值”并不意味着“非零”。零没有任何东西使它成为变量初始值的无效候选者。一些“有用的”编译器在调试版本中初始化变量。如果你不注意编译器警告,它可以隐藏阴险的bug。

答案 1 :(得分:4)

此:

int x, y, z = 0;

不同
int x = 0, y = 0, z = 0;

int x = 0;
int y = 0;
int z = 0;

在第一种情况下,只有z将被初始化,而在后两种情况下 - 所有三种情况。

如果未初始化值,则其值是不确定的,并且读取未初始化的变量是未定义的行为 - 并且在读取它之后看起来具有值0的事实是undefined behavior的结果。

答案 2 :(得分:2)

这样的陈述
 int x, y, z = 0;

仅初始化最后一个变量z; xy仍未初始化。

可能相当于

int x = 0;
int y = 0;
int z = 0;

将是

int x, y, z;
x = y = z = 0;

那就是说,

  

另外,如果我只是说int a;,即使它未初始化,似乎a的值为零

这取决于,如果变量具有静态存储持续时间,则它将隐式初始化为0.

答案 3 :(得分:0)

你的第一个问题的答案是" no",只会分配明确初始化的变量。其他人可能有任何价值,(包括零)。

回答你的第二个(更有趣的)问题(可能应该提出一个单独的问题):

术语" 联合"只是意味着在实例化时没有明确赋值;该值是当时在相关存储器位置中发生的任何值。一些环境在执行开始时将堆栈填充为零,因此在简单的示例中可能为零。然而,由于堆栈在执行期间被搅乱,并且包含从先前执行的代码遗留的不同值,因此它不会一直存在。

例如,在下文中,a中的fn()可能不会为每次通话(或可能是任何通话)为零,并且会在通话之间发生变化:

void fn()
{
    static int i = 1 ;
    volatile int a ;
    printf( "Call %d: a = %d\n", i, a ) ;
    i++ ;
    a = i ;
}

int main()
{
    for( int i = 0; i < 10; i++ )
    {
        fn() ;
    }
}

在我的测试中(在ideone.com上)输出以下内容:

Call 1: a = 134513970
Call 2: a = 2
Call 3: a = 3
Call 4: a = 4
Call 5: a = 5
Call 6: a = 6
Call 7: a = 7
Call 8: a = 8
Call 9: a = 9
Call 10: a = 10

正如您在第二次及以后的调用中所看到的,它包含上一次调用中该位置留下的内容,因为相同的堆栈位置被重用。不同的调用模式 - 例如在fn()之前或之后插入函数调用将在其他函数重用该堆栈区域时产生不同且不太可预测的结果。例如,当我按如下方式修改循环体时:

        rand() ;
        fn() ;

结果是:

Call 1: a = 1433091188
Call 2: a = 1433091188
Call 3: a = 1433091188
Call 4: a = 1433091188
Call 5: a = 1433091188
Call 6: a = 1433091188
Call 7: a = 1433091188
Call 8: a = 1433091188
Call 9: a = 1433091188
Call 10: a = 1433091188