为什么打印32767
(或其他随机数)?什么是std::cout
打印?为什么不是NULL
(或0
)?
int main()
{
int a;
std::cout << a;
}
答案 0 :(得分:14)
这是因为具有自动存储持续时间的变量在C ++中不会自动初始化为零。在C ++中,您不需要支付您不需要的费用,并且自动初始化变量需要花费时间(将内存位置设置为零最终会减少到机器内容,然后转换为控制物理位的电信号)。
变量被保留为内存位置,并且发生了一些垃圾在该内存位置。那个垃圾是由cout
打印出来的。
正如@dwcanillas指出的那样,它是未定义的行为。相关:What happens to a declared, uninitialized variable in C? Does it have a value?
从C ++标准(强调我的):
8.5初始值设定项[dcl.init]
7)默认初始化T类型的对象意味着:
- 如果T是(可能是cv限定的)类类型(第9条),那么构造函数是 考虑。列举了适用的构造函数(13.3.1.3),并且是最好的 通过重载决策(13.3)选择一个初始化器()。该 使用空参数列表调用如此选择的构造函数以初始化&gt;&gt;对象。
- 如果T是数组类型,则每个元素都是默认初始化的。
- 否则,不执行初始化。
12)如果没有为对象指定初始化程序,则默认初始化对象。当获得具有自动或动态存储持续时间的对象的存储时,该对象具有不确定的值,并且如果没有对该对象执行初始化,则该对象保留不确定的值,直到该值被替换(5.18)。 [注意:具有静态或线程存储持续时间的对象是零初始化的,请参见3.6.2。 - 结束注释] 如果评估产生不确定的值,则行为未定义,但以下情况除外:
- 如果通过以下评估产生无符号窄字符类型(3.9.1)的不确定值:
- 条件表达式的第二个或第三个操作数(5.16),
- 逗号表达式(5.19)的右操作数,
- 强制转换或转换为无符号窄字符类型(4.7,5.2.3,5.2.9,5.4)或
的操作数- 废弃值表达式(第5条)
...
答案 1 :(得分:6)
这是未定义的行为。您正在打印占据a
内存的任何内容,在这种情况下恰好是32767
。
答案 2 :(得分:1)
C ++ 14(N3936)涵盖了这种行为[dcl.init] / 12:
如果没有为对象指定初始值设定项,则默认初始化该对象。当获得具有自动或动态存储持续时间的对象的存储时,该对象具有不确定值,并且如果没有对该对象执行初始化,则该对象保留不确定的值,直到替换该值。
[...]如果评估产生了不确定的值,行为未定义,除非在以下情况下:
并且任何“以下情况”都不包含您的代码,这些情况涵盖了允许传播unsigned char
个不确定值的几种情况。
答案 3 :(得分:0)
因为&#34; a&#34;不是全局/静态的。它是一个自动变量,在运行时进行初始化。如果它是全局的,那么在编译时就会发生初始化为零。即
•静态变量在编译时初始化,因为它们的地址已知且已修复。将它们初始化为0不会产生运行时成本。
•自动变量可以针对不同的调用具有不同的地址,并且每次调用函数时都必须在运行时初始化,从而产生可能不需要的运行时成本。如果您确实需要初始化,请提出请求。