C ++:在迭代中重用的浮点值

时间:2010-07-21 08:52:29

标签: c++

让我们看一下我无意中写的以下代码:

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以获得预期的输出。

9 个答案:

答案 0 :(得分:6)

由于newNum未显式初始化,因此它将具有随机值(由分配给它的内存块中包含的垃圾数据确定),至少在第一次迭代时。

在后续迭代中,可能重用其早期值(因为编译器可能会将其重复分配到同一内存位置 - 这完全取决于编译器的判断)。从输出来看,这就是实际发生的事情:在第一次迭代中newNum的值为0(纯粹偶然),然后分别为1,3,6和10。

因此,要获得所需的输出,请在循环内显式初始化变量:

float newNum = 0.0;

答案 1 :(得分:2)

  

C ++必须分配一些默认值   值(huhm,必须为0)

这是你假设中的错误。 C ++不会尝试分配默认值,您必须显式初始化所有内容。

每次循环时,它很可能会在内存中分配相同的位置,因此(在这个简单的情况下)newNum似乎会从每次迭代持续到下一次迭代。

在一个更复杂的场景中,分配给newNum的内存将处于一个基本上随机的状态,你可能会发现奇怪的行为。

http://www.cplusplus.com/doc/tutorial/variables/

答案 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会为每次迭代创建一个新变量?

变量是一块内存。在这个变量中分配在堆栈上。您没有对它进行初始化,并且每次迭代它恰好都放在相同的内存地址上,这就是它存储先前值的原因。当然,你不应该依赖这种行为。如果希望值在迭代中保持不变,请在循环外声明它。

  

顺便说一句,在Java中,由于newNum未初始化,这段代码将无法编译

顺便说一下,在C ++中,普通编译器会给你一个警告,即变量未初始化(例如:“警告C4700:未初始化的局部变量'f'使用过”)。在调试版本中你会得到crt调试错误(例如:“运行时检查失败#3 - 正在使用变量'f'而没有被初始化”)。

  

这可能更好

否定。你需要不时地使用未初始化的变量(通常是 - 在没有“标准”赋值运算符的情况下初始化它们 - 例如通过指针/引用传入函数),并强迫我初始化它们中的每一个都将浪费我的时间。