0

这是一个例子:

while (i < 10)
    {
        int j = 1;
        string k = "hello.";
    }

j 是原始数据类型,k 是对象。根据Do built-in types have default constructors? ,

所以非类类型(包括基本类型、数组类型、引用类型、指针类型和枚举类型)没有构造函数。

根据在循环中声明变量,好的做法还是坏的做法?(2 部分) ,

对于对象(例如 std::string),必须在每次迭代时执行构造函数和析构函数。

但是,while 循环 C/C++ 中的变量声明说,

while(i--)
    {
      int i=100; // gets created every time the loop is entered
      i--;
      printf("%d..",i);
    } // the i in the loop keeps getting destroyed here

我了解到,当调用函数时(例如main()由操作系统调用),所有局部变量都在函数开始时创建并在函数结束时销毁。上面的while循环引用是说原始数据类型i是在while循环块中声明时创建的,并在每次迭代的while循环块结束时销毁。

这是真的吗?#1是否为 while 循环的每次迭代分配了在 while 循环块中声明的原始数据类型?#2我是否错误地认为应该在包含 while 循环块的函数的开头创建 while 循环中的这些声明?

我正在寻找详细的解释,而不仅仅是是或否。

4

3 回答 3

3

程序必须表现得好像每次循环都被重新分配(然后被释放)一样。

程序表现出这种行为的机制完全取决于编译器。在许多情况下,根本不会为变量分配空间,或者它甚至可能根本不存在!(例如j在您的第一个示例中)

如果确实分配了空间,我认为通常会在调用包含循环的函数时保留空间。(并且该空间不一定是专门保留的)

于 2015-06-21T20:08:31.490 回答
3

是的,当您在循环内声明一个变量时,程序的行为就像在每次循环迭代中创建和销毁该变量一样。因此,如果变量具有类类型,则程序的行为就像每次调用其构造函数和析构函数一样。

但是,由于优化,可以删除不可观察的行为,所以第一个循环可以完全优化掉,第二个循环可以优化为类似

while(i--)
    printf("%d..", 99);

因此,可能会发生没有创建实际变量的情况。

于 2015-06-21T20:09:00.023 回答
1

从逻辑上讲,是的,在循环体的每次迭代的循环体开始处创建变量,并在结束时销毁。

在您的第一个示例中,每次迭代都会调用std::string(实际上std::basic_string<char>是什么)的构造函数,析构函数也是如此。std::string类似地j正在1为每次迭代创建和设置。

在第二个示例中,出于同样的原因,i将打印该值。99

编译器在这方面确实有一些余地。如果他们可以检测到重复创建和销毁没有影响,他们可以保持变量处于活动状态,并在每次循环迭代时简单地重新初始化它。他们甚至可以完全消除变量(例如,只重复打印 99,而不创建变量)。但是,不能依赖这些事情,并且程序无法测试它是否发生。

于 2015-06-21T20:09:47.730 回答