我有一段时间没有使用C++了。我一直依赖我的Java编译器来进行优化。
在C++中,做一个for循环最优的方法是什么?或者现代编译器都一样吗?在“旧日子”里是不同的。
for (int i=1; i<=100; i++)
或者
int i;
for (i=1; i<=100; i++)
或
int i = 1;
for ( ; i<=100; i++)
在C语言中是一样的吗?
编辑:好的,压倒性的共识是使用第一个情况,并让编译器如果需要的话进行优化。
我有一段时间没有使用C++了。我一直依赖我的Java编译器来进行优化。
在C++中,做一个for循环最优的方法是什么?或者现代编译器都一样吗?在“旧日子”里是不同的。
for (int i=1; i<=100; i++)
或者
int i;
for (i=1; i<=100; i++)
或
int i = 1;
for ( ; i<=100; i++)
在C语言中是一样的吗?
编辑:好的,压倒性的共识是使用第一个情况,并让编译器如果需要的话进行优化。
我认为像这样的琐碎问题可能已经被编译器优化了,你不必担心。 第一种选项最易读,所以你应该使用它。
编辑:根据其他答案提供的信息,还有一个区别是,如果你在循环初始化中声明变量,它将在循环结束后停止存在。
区别在于作用域。
for(int i = 1; i <= 100; ++i)
通常更好,因为这样i的作用域被限制在for循环内部。如果你在for循环之前声明它,那么它会在for循环结束后继续存在,并可能与其他变量发生冲突。如果你只在for循环中使用它,那么没有理由让它存在更长的时间。
假设原帖作者有一个循环,他非常想要优化 - 每个指令都很重要。我们如何通过实证的方法找到他的问题的答案?
至少gcc有一个有用但不常用的开关'-S'。它会转储.c文件的汇编代码版本,并可用于回答像OP提出的问题。我写了一个简单的程序:
int main( )
{
int sum = 0;
for(int i=1;i<=10;++i)
{
sum = sum + i;
}
return sum;
}
运行命令:gcc -O0 -std=c99 -S main.c
,生成主程序的汇编版本。以下是main.s文件的内容(已删去部分冗余内容):
movl $0, -8(%rbp)
movl $1, -4(%rbp)
jmp .L2
.L3:
movl -4(%rbp), %eax
addl %eax, -8(%rbp)
addl $1, -4(%rbp)
.L2:
cmpl $10, -4(%rbp)
jle .L3
int main( )
{
int sum = 0;
int i=1;
for( ;i<=10;++i)
{
sum = sum + i;
}
return sum;
}
main:
movl $55, %eax
ret
gcc不仅知道我们正在进行一个for循环,而且还意识到它将在编译时运行固定次数的循环,并为我们执行了循环,扔掉了“i”和“sum”,并硬编码了答案-55!那很快-尽管有点牵强。
故事的寓意是什么?花时间确保您的代码清洁且设计良好。编写易读且易于维护的代码。那些靠着山露和奇多饼干生活的家伙比我们聪明得多,并且已经为我们解决了大部分这些简单的优化问题。玩得开心!
这是一样的。编译器会将它们优化为相同的内容。
即使它们不同,与循环实际体的差异也可以忽略不计。您不应该担心微小的优化问题。除非您正在性能分析以查看它是否有影响,否则不应进行微小的优化。
就速度而言,这两种写法没有区别。如果你不会再次使用 i,编译器会进行优化。
就风格而言,我会把定义放在循环结构中,因为这样可以减少后面定义另一个 i 时出现冲突的风险。
for
初始化语句中声明变量将该变量限定于for
语句的范围内(C++03 § 6.5.3 1),尽管编译器的确切行为可能会有所不同(某些编译器可供选择)。如果循环外的代码使用该变量,请在循环外声明它。如果变量真正只在循环中使用,请在初始化程序中声明它。for(int i = 1; i <= 100; ++i)
这是最容易阅读的,除了 ANSI C / C89 不支持。
已经提到两者之间的主要区别是作用域。确保您了解编译器如何处理声明为 int 的变量的作用域。
for (int i = 1; ...;...)
我知道在使用MSVC++6时,变量i在循环外仍然在作用域内,就像它是在循环之前声明的一样。这种行为与VS2005不同,我需要检查一下,但我认为在我使用的最后一个版本的gcc中也是如此。在这两个编译器中,该变量只在循环内部有效。
C++ 的 for 循环本质上就是一个封装好的 while 循环。
for (int i=1; i<=100; i++)
{
some foobar ;
}
对于编译器而言,上述代码与下面的代码完全相同。
{
int i=1 ;
while (i<=100){
some foobar ;
i++ ;
}
}
int i=1;
被包含在一个专用范围内,该范围仅包括它和while循环。都一样。