我有以下C ++代码:
#include <iostream>
using namespace std;
#include <stdio.h>
int main (int argc , char ** argv)
{
int i1;
int i2;
double d1;
double d2;
printf("i1: %d, i2: %d, d1: %f, d2: %f \n", i1, i2, d1, d2);
}
输出
i1:4195872,i2:0,d1:0.000000,d2:0.000000
每次我运行程序时,我都得到相同的输出。现在让我们说我使用以下代码:
#include <iostream>
using namespace std;
#include <stdio.h>
int main (int argc , char ** argv)
{
int i1;
int i2;
double d1;
double d2;
cout << "i1: " << i1;
cout << " i2: " << i2;
cout << " d1: " << d1;
cout << " d2: " << d2;
}
现在我得到以下输出:
i1:4196144 i2:0 d1:6.95294e-310 d2:0
当我重新运行程序时,d1的值略有变化,其他值保持不变。
为什么以这种方式初始化值?为什么没有随机初始化或初始化为零?
答案 0 :(得分:2)
您的程序具有未定义的行为,这意味着您获得的输出是完全随机的(因为您正在获取输出)。
在C ++中,非类类型的局部变量不会自动初始化。读取未初始化变量的值是未定义的。
答案 1 :(得分:1)
答案 2 :(得分:1)
为什么以这种方式初始化值?
基本类型和自动存储持续时间的默认初始化变量具有不确定的值。
为什么没有随机初始化或初始化为零?
因为标准没有这么说,并且编译器实现者选择不这样做。随机化和零初始化都可能比不执行任何操作都慢,因此选择似乎是合乎逻辑的。
标准所说的是,读取不确定的值具有未定义的行为(除少数选择情况外,请参阅标准报价)。
现行标准草案:
[dcl.init](12)如果没有为对象指定初始值设定项,则默认初始化该对象。当获得具有自动或动态存储持续时间的对象的存储时,该对象具有不确定的值,并且如果没有对该对象执行初始化,则该对象保留不确定的值,直到该值被替换([expr.ass])。 [注意:具有静态或线程存储持续时间的对象是零初始化的,请参见[basic.start.static]。 - 结束注释]如果评估产生不确定的值,则行为是未定义的,除非在以下情况下:
(12.1)如果通过以下评估产生无符号窄字符类型或std :: byte类型([cstddef.syn])的不确定值:
- (12.1.1)条件表达式的第二个或第三个操作数
- (12.1.2)逗号表达式的右操作数,
- (12.1.3)强制转换或转换([conv.integral],[expr.type.conv],[expr.static.cast],[expr.cast])的操作数为无符号窄字符类型或std :: byte类型([cstddef.syn])或
- (12.1.4)废弃值表达式,
然后操作的结果是一个不确定的值。
- (12.2)如果通过评估一个简单赋值运算符的右操作数产生无符号窄字符类型或std :: byte类型的不确定值,该操作符的第一个操作数是无符号窄字符类型或std的左值:: byte类型,一个不确定的值替换左操作数引用的对象的值。
- (12.3)如果在初始化无符号窄字符类型的对象时通过初始化表达式的计算产生无符号窄字符类型的不确定值,则该对象被初始化为不确定的值。
- (12.4)如果在初始化std :: byte类型的对象时通过初始化表达式的计算产生无符号窄字符类型或std :: byte类型的不确定值,则该对象被初始化为不确定的价值。