在一行中初始化C中的所有变量和未初始化的值
Initializing all variables in C in one line and uninitialized value
在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?[=15中所述未定义=]
不,两者不等价。
int x, y, z = 0;
在这一行中 x
和 y
将具有不确定的值,而 z
被初始化为零。
不过,您可以将其保留在 "one line" 中,但要付出一些冗长的代价:
int x = 0, y = x, z = y;
现在所有三个都使用相同的值(您给的值x
)进行了初始化。要用一个变量初始化另一个变量,只需预先定义初始化器即可。即使在同一条线上也能正常工作。上面的内容还可以让您很容易地更改所有变量的初始值。
或者,如果你觉得之前的样式很丑,你可以改成两行:
int x, y, z;
x = y = z = 0;
但现在是赋值,而不是初始化。
Also, if I just say int a;
, it seems that the value of a
is zero even if it is uninitialized, but not undefined as described in What will be the value of uninitialized variable?
"Indeterminate value" 并不意味着 "not-zero"。零并没有使它成为变量初始值的无效候选者。一些 "helpful" 编译器将调试版本中的初始化变量置零。如果您不注意编译器警告,它可能会隐藏严重的错误。
这个:
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.
的结果
像
这样的陈述
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;
也就是说,
Also, if I just say int a;
, it seems that the value of a
is zero even if it is uninitialized
视情况而定,如果变量具有静态存储持续时间,它将隐式初始化为0。
第一个问题的答案是"no",只有显式初始化的变量才会被赋值。其他的可能有任何值,(包括零)。
回答您的第二个(更有趣的)问题(也许值得单独提问):
术语“unitialised”只是意味着在实例化时没有显式赋值;该值是当时恰好位于相关内存位置的任何值。一些环境在执行开始时用零填充堆栈,因此在简单的示例中可能为零。然而,它不会一直如此,因为堆栈在执行期间会被搅动,并且包含以前执行的代码遗留下来的不同值。
例如,在下面的示例中,fn()
中的 a
可能不会在每次调用(或任何调用)中都为零,并且会在调用之间发生变化:
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
在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?[=15中所述未定义=]
不,两者不等价。
int x, y, z = 0;
在这一行中 x
和 y
将具有不确定的值,而 z
被初始化为零。
不过,您可以将其保留在 "one line" 中,但要付出一些冗长的代价:
int x = 0, y = x, z = y;
现在所有三个都使用相同的值(您给的值x
)进行了初始化。要用一个变量初始化另一个变量,只需预先定义初始化器即可。即使在同一条线上也能正常工作。上面的内容还可以让您很容易地更改所有变量的初始值。
或者,如果你觉得之前的样式很丑,你可以改成两行:
int x, y, z;
x = y = z = 0;
但现在是赋值,而不是初始化。
Also, if I just say
int a;
, it seems that the value ofa
is zero even if it is uninitialized, but not undefined as described in What will be the value of uninitialized variable?
"Indeterminate value" 并不意味着 "not-zero"。零并没有使它成为变量初始值的无效候选者。一些 "helpful" 编译器将调试版本中的初始化变量置零。如果您不注意编译器警告,它可能会隐藏严重的错误。
这个:
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.
的结果像
这样的陈述 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;
也就是说,
Also, if I just say
int a;
, it seems that the value ofa
is zero even if it is uninitialized
视情况而定,如果变量具有静态存储持续时间,它将隐式初始化为0。
第一个问题的答案是"no",只有显式初始化的变量才会被赋值。其他的可能有任何值,(包括零)。
回答您的第二个(更有趣的)问题(也许值得单独提问):
术语“unitialised”只是意味着在实例化时没有显式赋值;该值是当时恰好位于相关内存位置的任何值。一些环境在执行开始时用零填充堆栈,因此在简单的示例中可能为零。然而,它不会一直如此,因为堆栈在执行期间会被搅动,并且包含以前执行的代码遗留下来的不同值。
例如,在下面的示例中,fn()
中的 a
可能不会在每次调用(或任何调用)中都为零,并且会在调用之间发生变化:
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