我正在阅读Stroustrup的书,他建议我们保留变量 内部循环,仅在循环范围内。这很容易做到 对于一个变量,但对于更多变量,有更多选项可以做到, 但我不确定是否值得。你们有没有打扰过这个?
例如:
for (double d; is >> d;) {}
最好将变量d保留在循环范围内而不是这样做:
double d;
for (;is >> d;) {}
答案 0 :(得分:3)
一般来说,范围越小越好。
此规则有三个主要原因:
正在阅读代码的人不会分心,试图了解变量的生命将在何处结束。使用局部变量,您可以跳过代码段,确保在跳过的部分中没有任何您感兴趣的内容。相反,如果您使用非本地变量并在以后重复使用,则必须检查中间的任何代码是否正在使用该变量。
在维护程序时,您可以自由更改代码,而不必担心随后的代码可能会停止工作,因为它依赖于变量。假设你有一个循环,并且正在使用非本地变量,然后通过调用函数来改变该循环......风险在于原始循环之后的代码取决于索引的值。
今天的编译器非常聪明,但有时即使对于变量保持长寿命,它也会让人感到困惑。因此,寄存器分配可能会受此影响,编译后的代码效率会降低。
如果在一个函数中你想要做一个需要一些本地的处理步骤,但这个步骤取决于很多上下文,并且不容易将它分解出一个函数(因为你需要传递很多参数)然后只为本地人打开一个块:
... code before ...
{
int local1, local2;
... processing here ...
}
... code after ...
这是非常易读的,可以保持尽可能小的范围。
答案 1 :(得分:1)
将变量保持在尽可能小的范围内是值得的,并且可以避免名称冲突,阴影等问题。但是很难提供完整的一般指导,因为代码就像你的例子:
for (double d; is >> d;)
不太可能在野外发现。我做过类似的事情:
for (string s; getline(is, s); )
并且有一个版本使用"如果"这很方便:
if (MyThing* t = dynamic_cast<MyThing*>(o))
这使您可以访问条件框内的t
,但不能访问外部,这有点不错,因为无论如何它都在外面。
答案 2 :(得分:0)
通常你应该始终将这些变量保留在循环范围内。
答案 3 :(得分:0)
如果你把它放在外面,就像第二个选项一样,这意味着你可以在循环后访问该值。因此,有时您需要这样做。
由于后来的访问是外部声明的优点,所以当你使用外部声明时暗示你想要这个,这也暗示了那些不真实的东西是坏的,所以如果你以后不使用这些值,不要在外面宣布他们。
答案 4 :(得分:0)
有几点要说明:
我认为第2点是最重要的 - 如果我能在短片代码中看到变量如何用于它的生命周期,那真的很有帮助。
答案 5 :(得分:0)
如果你想在循环外使用循环变量,那么在外面定义它,否则将这些变量保存在循环的范围内。
答案 6 :(得分:0)
我使用过的一个有趣的习惯用法,特别是在迭代器的上下文中,是对需要绑定到for作用域的多个值使用逗号运算符:
for(vector<int>::iterator iter = foo.begin(), end = foo.end(); iter != end; ++iter)
我使用这种技术来避免重复类型定义,但它同样适用于允许更漂亮的范围捕获。
使用C ++ 11自动语义,这变得更加漂亮:
for(auto iter = foo.begin(), end = foo.end(); iter != end; ++iter)
至于性能,即使是最简单的编译器(例如,tccp)也可以正确地优化变量重用(在嵌入式系统中很重要,或者在没有优化的情况下)。