2017-04-05 44 views
0

当在C++中的循环内声明变量时,C++是否会在循环的每次迭代中重新创建变量?我的意思是,它是否为另一个num变量重新分配内存?所以如果循环迭代5次,你会得到5个独立的num变量与他们自己的唯一值吗?在循环开始之前声明一个变量是否是一种更好的做法,即使该变量只能在循环中使用?例如,如果我想将该变量用作计数器或占位符?C++是否会重新创建循环中定义的变量?

// is this better code? 
// int num; 
for (int i = 0; i < 5; i++) { 
    int num; 
    // do stuff with num 
} 

回答

4

是的,如果num是内循环定义,那么它会在每次循环运行时间代表不同的变量。每次控制通过它的定义时,它都会被重新初始化(如果有的话),并且每次迭代结束时,它都会被销毁。

变量通常应该在可能的最窄范围内声明。所以如果num不需要从一次迭代到下一次迭代保留它的值,它通常应该在循环内部定义。如果它确实需要从一次迭代到下一次迭代保持它的值,那么它必须在循环之外定义。

此风格最佳实践有一些例外情况,例如初始化成本高昂时。

4

编译器可能优化内存使用情况,因此变量只在物理上分配一次,然后在每次循环迭代中重用。但是,一般而言,范围规则要求每个循环迭代对变量的不同实例进行操作。在类型复杂的情况下,比如类/结构体,这意味着在每次循环迭代时调用变量的构造函数和析构函数。

0

在你所描述的情况下,C++标准指定了变量的新实例在循环开始时被构造,并在循环结束时被销毁。

究竟发生了什么,当你想到它的本质时,除了重点之外。只要可观察结果符合C++标准的规定,C++实现就可以以任何想要的方式实现它。

在这里,你只是一个普通的花园品种int。正如我所描述的那样,虽然它被正式构建并销毁,但当变量被构建和销毁时,没有任何物质真的发生。 C++不需要在本地范围内新构建的int被初始化为任何特定值。因此,在这种情况下,典型的C++实现将简单地将这个int分配给内存中的某个内存中的某个地方,并将其用于每个循环迭代。但是,如果你用一个更加充实的对象,用一个正式的构造函数替换这个int,你将会看到,在每次循环迭代开始时,对象的构造函数将被乖乖地调用,并且对象的析构函数将会是在循环迭代结束时(或执行线程离开循环的作用域时)乖乖地调用。

2

这是一个新变量。

for (int i = 0; i < 5; i++) { 
    const int num = i; 
    // do stuff with num 
} 

如果它真的是相同的变量,我们如何分配给一个常变量新的东西:你可以很容易的事实,这个编译说服自己的是什么?

至于它是否更有效率,你应该记住C++有一个非常好的优化编译器。没有真正的“成本”与堆栈变量相关联。一个简单的整数赋值显然没有任何副作用,因此编译器重用相同的空间是微不足道的。如果你不需要循环外的变量,最好在循环中声明它。

我建议使用https://gcc.godbolt.org/来查看为几个小函数生成的程序集,这些程序可以进行优化或不进行优化,它会让您感觉到编译器可以轻松优化。