让我们看一下我无意中写的以下代码:
void test (){
for (int i = 1; i <=5; ++i){
float newNum;
newNum +=i;
cout << newNum << " ";
}
}
现在,这就是我脑子里发生的事情: 我一直认为 float newNum 会为每次迭代创建一个新变量 newNum ,因为该行被放入循环中。由于 float newNum 不会抛出编译错误,因此C ++必须分配一些默认值(huhm,必须为0)。然后我预计输出为“1 2 3 4 5”。印刷的是“1 3 6 10 15”。
请帮助我知道我期望 float newNum 会为每次迭代创建一个新变量有什么问题?
顺便说一句,在Java中,由于 newNum 没有初始化,这段代码将无法编译,这对我来说可能更好,因为我知道我需要将其设置为0以获得预期的输出。
答案 0 :(得分:6)
由于newNum
未显式初始化,因此它将具有随机值(由分配给它的内存块中包含的垃圾数据确定),至少在第一次迭代时。
在后续迭代中,可能重用其早期值(因为编译器可能会将其重复分配到同一内存位置 - 这完全取决于编译器的判断)。从输出来看,这就是实际发生的事情:在第一次迭代中newNum
的值为0(纯粹偶然),然后分别为1,3,6和10。
因此,要获得所需的输出,请在循环内显式初始化变量:
float newNum = 0.0;
答案 1 :(得分:2)
C ++必须分配一些默认值 值(huhm,必须为0)
这是你假设中的错误。 C ++不会尝试分配默认值,您必须显式初始化所有内容。
每次循环时,它很可能会在内存中分配相同的位置,因此(在这个简单的情况下)newNum似乎会从每次迭代持续到下一次迭代。
在一个更复杂的场景中,分配给newNum的内存将处于一个基本上随机的状态,你可能会发现奇怪的行为。
答案 2 :(得分:1)
您正在创建的浮动根本没有初始化。看起来你很幸运,第一次传球结果是零,虽然它可能有任何价值。
在循环的每次迭代中,都会创建一个新浮点数,但它使用与最后一个相同的内存位,因此最终得到了您的旧值。
要获得所需的效果,您需要在每次传递时初始化浮点数。
float newNum = 0.0;
答案 3 :(得分:0)
在代码中使用垃圾值会调用C ++中的未定义行为。未定义的行为意味着任何事情都可能发生,即代码的行为未定义。
float newNum; //uninitialized (may contain some garbage value)
newNum +=i; // same as newNum=newNum+i
^^^^^
Whoa!!
所以最好试试这个
float newNum=0; //initialize the variable
for (int i = 1; i <=5; ++i){
newNum +=i;
cout << newNum << " ";
}
答案 4 :(得分:0)
你所表达的想法中的错误是“C ++必须分配一些默认值”。它不会。 newNum包含dump。
答案 5 :(得分:0)
自上个月以来,我没有做太多的C ++,但是:
为每次迭代新分配的浮点值 。不过,我对初始的零值感到有些惊讶。问题是,在每次迭代之后,浮点值超出范围,下一步(重新输入循环范围)首先重新分配浮动内存,这通常会返回刚刚释放的相同内存块。
(我在等待任何抨击:-P)
答案 6 :(得分:0)
您正在使用未初始化的自动堆栈变量。在每次循环迭代中,它位于堆栈上的相同位置,因此事件虽然它具有未定义的值,但在您的情况下它将是前一次迭代的值。
还要注意,在第一次迭代中,它可能具有任何价值,而不仅仅是0.0
。
答案 7 :(得分:0)
您可能已在调试版本中获得了预期的答案但未发布,因为调试版本有时会将变量初始化为0。我认为这是未定义的行为 - 因为C ++不会为你自动初始化变量,每次循环它都会创建一个新变量,但它会保持使用与刚刚发布的相同的内存,并且不会擦除之前的值。正如其他人所说,你可能最终完全废话。
使用未初始化的变量不是编译错误,但通常应该有关于它的警告。总是很好地打开警告并尝试删除所有这些警告,因为它们之间隐藏着更糟糕的东西。
答案 8 :(得分:0)
C ++必须分配一些默认值(huhm,必须为0)。
C ++不会在没有默认构造函数的情况下初始化东西(它可能会在调试版本中将其设置为0xcccccccc) - 因为作为任何适当的工具,编译器“认为”如果你还没有提供初始化那么它就是什么你自找的。 float没有默认构造函数,因此它是未知值。
然后我预计输出为“1 2 3 4 5”。印刷的是“1 3 6 10 15”。
请帮助我知道我的期望是什么,浮动newNum会为每次迭代创建一个新变量?
变量是一块内存。在这个变量中分配在堆栈上。您没有对它进行初始化,并且每次迭代它恰好都放在相同的内存地址上,这就是它存储先前值的原因。当然,你不应该依赖这种行为。如果希望值在迭代中保持不变,请在循环外声明它。
顺便说一下,在C ++中,普通编译器会给你一个警告,即变量未初始化(例如:“警告C4700:未初始化的局部变量'f'使用过”)。在调试版本中你会得到crt调试错误(例如:“运行时检查失败#3 - 正在使用变量'f'而没有被初始化”)。顺便说一句,在Java中,由于newNum未初始化,这段代码将无法编译
这可能更好
否定。你需要不时地使用未初始化的变量(通常是 - 在没有“标准”赋值运算符的情况下初始化它们 - 例如通过指针/引用传入函数),并强迫我初始化它们中的每一个都将浪费我的时间。