在 C 语言中,是
int x, y, z = 0;
和这个一样吗?
int x = 0;
int y = 0;
int z = 0;
另外,如果我只是说,即使未初始化,它int a;
的值似乎也为零,但不是未定义的,如未初始化变量的值是什么?a
在 C 语言中,是
int x, y, z = 0;
和这个一样吗?
int x = 0;
int y = 0;
int z = 0;
另外,如果我只是说,即使未初始化,它int a;
的值似乎也为零,但不是未定义的,如未初始化变量的值是什么?a
不,两者不相等。
int x, y, z = 0;
在这一行中x
,并且y
将具有不确定的值,而z
将其初始化为零。
但是,您可以以一些冗长的价格将其保留在“一行”中:
int x = 0, y = x, z = y;
现在所有三个都用相同的值初始化(你给的那个x
)。要使用另一个变量初始化一个变量,只需要预先定义初始化程序即可。即使它在同一条线上,它也可以工作。以上还允许您很容易地更改所有变量的初始值。
或者,如果您发现以前的样式丑陋,可以将其分为两行:
int x, y, z;
x = y = z = 0;
但现在是赋值,而不是初始化。
另外,如果我只是说,即使未初始化,它
int a;
的值似乎也为零,但不是未定义的,如未初始化变量的值是什么?a
“不确定值”并不意味着“非零”。零并没有使它成为变量初始值的无效候选者。一些“有用的”编译器在调试版本中对变量进行零初始化。如果您不注意编译器警告,它可以隐藏险恶的错误。
这个:
int x, y, z = 0;
不一样
int x = 0, y = 0, z = 0;
或者
int x = 0;
int y = 0;
int z = 0;
仅在第一种情况下z
将被初始化,而在后两种情况下 - 所有三种情况。
如果 value 未初始化,则它的值是不确定的,读取未初始化的变量是未定义的行为 - 读取它之后它似乎具有值 0 的事实是未定义行为的结果。
像这样的声明
int x, y, z = 0;
只初始化最后一个变量,z
;x
并y
保持未初始化。
一个可能的等价物
int x = 0;
int y = 0;
int z = 0;
将会
int x, y, z;
x = y = z = 0;
也就是说,
另外,如果我只是说,即使未初始化
int a;
,它的值似乎也为零a
这取决于,如果变量具有静态存储持续时间,它将隐式初始化为 0。
您的第一个问题的答案是“否”,只会分配显式初始化的变量。其他的可能有任何值,(包括零)。
要回答您的第二个(更有趣的)问题(可能值得一个单独的问题):
术语“统一化”仅表示在实例化时没有明确分配值;该值是当时在关联的内存位置中发生的任何事情。某些环境在执行开始时将堆栈填充为零,因此在简单的示例中可能为零。然而,这并不总是正确的,因为堆栈在执行期间被搅动,并且包含以前执行的代码留下的不同值。
例如在下面,对于每个调用(或任何调用),a
in很可能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