C++在for循环中声明int

Yad*_*ada 9 c++

暂时没有使用过C++.我一直依靠我的Java编译器来进行优化.

什么是在C++中进行for循环的最优化方法?或者现在与现代编译器完全相同?在"旧时代",存在差异.

for (int i=1; i<=100; i++)
Run Code Online (Sandbox Code Playgroud)

要么

int i;
for (i=1; i<=100; i++)
Run Code Online (Sandbox Code Playgroud)

要么

int i = 1;
for ( ; i<=100; i++)
Run Code Online (Sandbox Code Playgroud)

在C中它是一样的吗?

编辑: 好的,所以压倒性的共识是使用第一种情况,并让编译器优化它,如果它想.

Jav*_*ier 12

我会说像这样的微不足道的东西可能是由编译器优化的,你不应该担心它们.第一个选项是最易读的,所以你应该使用它.

编辑:添加其他答案所说的,还有不同之处在于,如果在循环初始化程序中声明变量,它将在循环结束后停止存在.

  • 关于编辑,这取决于编译器.我已经看过至少一个编译器(MSVC++ 6.0),其中变量在循环结束后不会停止存在. (2认同)
  • @Jeff标准兼容编译器将限制_i_ for循环的范围,但是有较旧的编译器 - 如MSVC++ 6.0 - 却没有.所以,如果你使用的是较旧的编译器,那么需要注意.但是,根据语言标准,范围仅限于for循环.最近的编译器应该在这方面表现正确. (2认同)

Jon*_*vis 9

差异在于范围.

for(int i = 1; i <= 100; ++i)
Run Code Online (Sandbox Code Playgroud)

通常是优选的,因为那时i的范围仅限于for循环.如果在for循环之前声明它,那么它在for循环结束后继续存在并且可能与其他变量冲突.如果你只是在for循环中使用它,那么就没有理由让它存在的时间长于那个.


小智 5

让我们说原始海报有一个他们真正想要优化的循环 - 每个指令都被计算在内.我们怎样才能 - 凭经验 - 弄清楚他的问题的答案?

gcc至少有一个有用的,如果不常用的开关,'-S'.它转储.c文件的汇编代码版本,可用于回答OP姿势等问题.我写了一个简单的程序:

int main( )
{
    int sum = 0;

    for(int i=1;i<=10;++i)
    {
        sum = sum + i;
    }
    return sum;
}
Run Code Online (Sandbox Code Playgroud)

并运行: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
Run Code Online (Sandbox Code Playgroud)

你不需要成为装配专家来弄清楚发生了什么.movl移动值,addl添加东西,cmpl比较和jle代表'jump if than',$是常量.它将0加载到某个东西 - 必须是'sum',1加入其他东西 - 啊,'我'!跳转到L2我们比较10,跳转到L3进行添加.再次进入L2进行比较.整齐!一个for循环.

将程序更改为:

int main( )
{
    int sum = 0;
    int i=1;
    for( ;i<=10;++i)
    {
        sum = sum + i;
    }
    return sum;
}
Run Code Online (Sandbox Code Playgroud)

重新运行gcc和由此产生的组件将非常相似.有一些东西正在记录行号,所以它们不会相同,但程序集最终是相同的.与最后一个案例相同的结果.因此,即使没有优化,代码也差不多.

为了好玩,请使用'-O3'而不是'-O0'重新运行gcc以启用优化并查看.s文件.

main:
movl    $55, %eax
ret
Run Code Online (Sandbox Code Playgroud)

gcc不仅弄清楚我们正在做一个for循环,而且还意识到它在编译时为我们循环运行了一段时间,清除了'i'和'sum'并硬编码了答案 - 55 !这很快 - 尽管有点做作.

故事的道德启示?花时间确保您的代码干净且设计精良.可读性和可维护性代码.生活在山露和cheetos上的人比我们更聪明,并为我们处理了大部分这些简单的优化问题.玩得开心!