为什么这个C ++代码不应该工作?

时间:2014-02-11 09:56:42

标签: c++ debugging loops

我正在使用Robert Lafore的书(OOP with C ++)学习C ++。 在本书中,我遇到了这个例子:

#include <iostream>
#include <conio.h>

using namespace std;

void main ()
{
    int numb;

    for ( numb = 1 ; numb <= 10 ; numb++ )
    {
        cout << setw(4) << numb;
        int cube = numb*numb*numb;
        cout << setw(6) << cube << endl;
    }

    getch();
}

变量'cube'已在循环体内声明为int'。

int cube = numb*numb*numb;

由于循环迭代10次,变量'cube'也会被声明10次。无论迭代次数如何,'cube'都可以在循环体内访问。所以,当我们进入第二次迭代的循环体时,'cube'已经知道了(因为它已经在第一次迭代中声明了),而'cube'的另一个声明应该给出“重新定义”的错误。但相反,它成功构建并调试没有问题。为什么呢?

7 个答案:

答案 0 :(得分:15)

自动变量(例如cube)的范围是声明它的块。声明cube的块是for循环的主体。在每次迭代结束时,cube变量超出范围,下一次迭代开始,然后cube再次引入范围。从逻辑上讲,没有冲突,因为在同一范围内不存在两个标识符cube - 实际上,只有一个cube声明。

可能值得区分变量的声明和由于该声明而创建的对象。只有一个声明int cube = ...;。可以多次访问这段代码并不重要;它仍然只有一个声明。语言规则说你不能在同一范围内声明两个具有相同名称的变量,但这没关系,因为你只声明了一次。这是一个完全静态的规则,您的编译器可以分析它。

由于您的for循环,您的声明达到了10次,这意味着将创建10个int个对象。由于变量的范围,它们不会同时存在。这不是程序的静态属性。编译器通常不能事先知道将达到一行代码的次数。

答案 1 :(得分:8)

当您第二次进入循环时,第一个cube已超出范围,所以一切正常。

同一范围内的两个cubes会出现问题:

{
    int cube = 0;
    int cube = 1;
}

答案 2 :(得分:6)

您已发现“自动存储持续时间”。

变量cube在循环内声明。特别是,在循环的块范围内。在循环结束时,这个变量将被销毁,就像在任何块作用域中声明的任何变量一样,无论是函数,循环,if / else块,还是只能在任何地方声明的原始块作用域使用{}的代码,即:

int main(){

    //Beginning of block
    {
        int cube = 1;
        //cube exists and is declared here
    }//End of block

    //cube is gone here

    return 0;
}

事实上,循环的每次迭代都会有一个全新的cube变量。

答案 3 :(得分:5)

变量cube仅在for循环的主体内部使用。我不确定说它被声明十次是正确的(声明,在你的情况下实际上是定义,是源代码的语法和静态文本部分)。

在C ++中,您可以(并且经常)拥有包含局部变量的块。 cube的范围从声明开始,到结束时结束(括号{ ... })。

如果已定义变量的类型具有构造函数,则在定义点处调用它。如果该类型具有析构函数,则在块的末尾从概念上调用它(比喻,在结束}之前....)。

答案 4 :(得分:2)

变量将在循环的每次迭代中声明,然后当块({...})结束时它将超出范围,即它将不再存在。然后在下一次迭代中,它将再次声明,这不是重新声明,因为它不存在。它被称为“局部变量”,在这种情况下是块的本地变量。

答案 5 :(得分:1)

由于cube在循环体内定义,其范围将是该体。因此,在每次迭代完成后,cube将超出范围,在下一次迭代中,将创建一个全新的cube。这就是理论上发生的事情。尽管编译器优化了此代码并且只创建了一个变量,但可能会发生这种情况。无论哪种方式,代码都是完全有效的,并且将作为例外工作。

答案 6 :(得分:0)

在每次迭代中声明并定义变量'cube'。 “cube”的范围随着迭代而消失,每个循环中都会出现新的声明和定义。