这个问题在这里已有答案:
在C中,声明循环外的所有变量与 aside from the scope 中的某些变量之间有什么区别吗?比另一个快一点吗?例如:
int i;
for(i = 0; i < len; i++)
{
int j;
for(j = i; j < len; j++)
{
…
VS
int i, j;
for(i = 0; i < len; i++)
{
for(j = i; j < len; j++)
{
…
从概念上讲,我遇到了一个问题,因为在第一个例子中,每次迭代都会重新声明相同的变量,这不是很低效吗?
4 回答
仅限于该循环内的变量范围是一种很好的做法 . 从分配的角度来看,在外部循环和内部循环中声明变量没有区别 .
当您看到反汇编代码时,您应该为这两种情况获得相同的代码 . 您将确切地找到分配变量存储的位置 . 它在循环外部分配 .
在现代C(AKA C99或C11)中有更好的选择
那就是直接在
for
-statement中声明循环变量 .在你的简单情况下,任何级别都没有区别,这将全部编译为相同的二进制文件 .
在更复杂的情况下,可能有一个,因为您将为同一个目的“重新使用”相同的变量 . 您可以轻松地将事物混合在一起,并将之前使用的旧值排放到以后的值,而您不期望它 .
轻微的违规行为:
int
在大多数情况下不是适用于"length"或类似的循环索引的类型 . 指数不应为负数,类型的宽度应该是这样的,您可以捕获任何对象的大小 . 为此目的,现代C有size_t
.要使用gcc具有该功能,您必须添加开关
-std=c99
或使用可执行文件名称c99
. clang和POSIX机器上的许多其他编译器默认符合C99 .在循环(块)内声明的变量只能被该块访问,即它对于该特定块是本地的(从它的声明点到块的末尾是可见的,除了这个范围之外你无法访问它) .
在代码中
j
是一个局部变量,具有块范围 . 在for(i = 0; i < len; i++)
结束后,您无法在程序中进一步访问j
. 对j
的所有修改都将保留在此范围内 .如果你没有将变量的范围放入帐户中,那么在循环的情况下,在任何级别声明变量都没有区别(但这两个代码在这里是不同的) .
限制范围时,可以使编译器更容易优化代码(例如,确定应在寄存器中使用哪些变量) . 一个好的编译器不应该浪费时间在优化条件下在循环开始时“重新声明”变量 .