在循环外声明循环索引变量有什么好处?

4
我在很多游戏引擎代码中看到了这个。如果你在for循环体中声明它,这是否比那更快?此外,接下来还有许多其他的for循环,每个都使用相同的变量。
int i;
for(i=0; i<count; ++i)
{
}

vs

for(int i=0; i<count; ++i)
{
}

顺便说一下,我从来没有这样做过,只是好奇背后的想法,因为除了性能以外,我不知道为什么有人会这样做。


我非常怀疑汇编代码有任何不同。 - chris
1
Chris是正确的。原因是因为一些编译选项不喜欢在循环体中声明它。两者是相同的,只是编译器的偏好等等。 - FrostyFire
如果循环的作用域在循环外部,您也可以稍后继续循环。类似于 int i; for(i = 0; i < count; i++) { /* do stuff */ if(arr[i].group == 2) break; } /*do stuff */ for(; i < count; i++) { /* do stuff with group 2 */ }。虽然这可能不是最好的设计。 - Alxandr
1
@chris: 当然汇编语言可能不同,用其中一个替换另一个可能会导致程序意义不同:http://liveworkspace.org/code/a67b2d82aafe2bd413bef5a744478510 - Mankarse
@Mankarse,没错。我的意思是如果i只在循环内部使用,那么很可能是相同的。 - chris
5个回答

16

第一种方法可能是C的方式,OLD OLD C的方式,在这种方式中,第二个版本是无效的。使用第二种方式,尽可能紧密地限定变量的范围。


3

原本在K&R C中,如果你有一个如下的for语句:

for (int i = 1; ...

在同一方法(或{}作用域)中,您无法再次说

for (int i = 1; ...

否则会出现“重复符号”错误。

所以如果想要重复使用相同的循环变量,那么就应该在循环外部声明它。

C语言中的这个“特性”早已不存在,但是如果想要从循环中break并保留循环索引,则必须在for语句外部声明循环变量:

int i;
for (i = 1; ...
  do stuff;
  if (something) break;
}

x = y[i];

在K&R C和C89中,for(int i = 1; ...都是语法错误。您必须指的是早期的C ++。 - user4815162342
@user4815162342 - 很多早期的C编译器语法都比较宽松。你不能真正把K&R当作规范来处理,因为它留下了很多需要你填写的内容。 - Hot Licks

2
声明循环索引变量在循环外的好处是什么?
在前一种情况下,你可以在循环外部访问`i`的最后一个值。有些开发人员会说这个值将是`count`的值。但是看看这个例子。
int i;
for(i = 0; i < count; ++i)
{
   if (i == 2)
       break;

   //Loop Logic
}

在这种情况下,i 将会等于 = 2 或者 < 2,但如果计数 > 2 呢。
然而,在后一种情况下,i 在循环结束时就超出了范围。

2

K&R C不接受第二种风格。

第一种风格的优点是,在循环之后可以访问“i”,如果您正在搜索特定索引,则可能非常重要。

第二个优点是范围更紧密,这总是一件好事。您不能混淆“i”。


2
Kernighan和Ritchie。Ritchie设计了C语言(并共同设计了Unix..!)Kernighan编写了一堆Unix实用程序。他们一起编写了有史以来最好的计算机科学书籍之一,《C程序设计语言》。如果所有的计算机书籍都像他们的书那样易于理解、阅读,而且最重要的是简短明了,那该多好啊。 - Graham Perks
谢谢,我以前从未听说过K&R的参考,现在有了更好的理解 :) - Joan Venge

1

至少有一个编译器(MSVC的旧版本)泄露了for(int i = 0; i < max; ++i) { ... }int i的定义,超出了循环的结尾。标准规定其作用域仅限于for循环本身。如果您在多个编译器中编译,其中一个泄漏了定义,而另一个没有,如果您稍后在同一代码体中重新声明变量,则可能会遇到问题。

因此,我可以看到有人决定编写代码,在符合标准和不符合标准的编译器中都会出现相同的错误,方法是将变量声明放在循环外部。

现在,另一个理论是程序员想要在循环结束后访问迭代变量的值。另一个可能性是团队或编码人员认为将变量声明放在自己的一行上是良好的风格。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接