简体   繁体   English

"C++ 在 for 循环中声明 int"

[英]C++ Declaring int in the for loop

Haven't used C++ in a while.好久没用C++了。 I've been depending on my Java compiler to do optimization.我一直依靠我的 Java 编译器来进行优化。

What's is the most optimized way to do a for loop in C++?在 C++ 中执行 for 循环的最优化方法是什么? Or it is all the same now with moderm compilers?或者现代编译器现在都一样了吗? In the 'old days' there was a difference.在“旧时代”,情况有所不同。

for (int i=1; i<=100; i++)

I'd say that trivial things like this are probably optimized by the compiler, and you shouldn't worry about them. 我会说像这样的微不足道的东西可能是由编译器优化的,你不应该担心它们。 The first option is the most readable, so you should use that. 第一个选项是最易读的,所以你应该使用它。

EDIT: Adding what other answers said, there is also the difference that if you declare the variable in the loop initializer, it will stop to exist after the loop ends. 编辑:添加其他答案所说的,还有不同之处在于,如果在循环初始化程序中声明变量,它将在循环结束后停止存在。

The difference is scope. 差异在于范围。

for(int i = 1; i <= 100; ++i)

is generally preferable because then the scope of i is restricted to the for loop. 通常是优选的,因为那时i的范围仅限于for循环。 If you declare it before the for loop, then it continues to exist after the for loop has finished and could clash with other variables. 如果在for循环之前声明它,那么它在for循环结束后继续存在并且可能与其他变量冲突。 If you're only using it in the for loop, there's no reason to let it exist longer than that. 如果你只是在for循环中使用它,那么就没有理由让它存在的时间长于那个。

Let's say the original poster had a loop they really wanted optimized - every instruction counted. 让我们说原始海报有一个他们真正想要优化的循环 - 每个指令都被计算在内。 How can we figure out - empirically - the answer to his question? 我们怎样才能 - 凭经验 - 弄清楚他的问题的答案?

gcc at least has a useful, if uncommonly used switch, '-S'. gcc至少有一个有用的,如果不常用的开关,'-S'。 It dumps the assembly code version of the .c file and can be used to answer questions like the OP poses. 它转储.c文件的汇编代码版本,可用于回答OP姿势等问题。 I wrote a simple program: 我写了一个简单的程序:

int main( )
{
    int sum = 0;

    for(int i=1;i<=10;++i)
    {
        sum = sum + i;
    }
    return sum;
}

And ran: gcc -O0 -std=c99 -S main.c , creating the assembly version of the main program. 并运行: gcc -O0 -std=c99 -S main.c ,创建主程序的汇编版本。 Here's the contents of main.s (with some of the fluff removed): 这是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

You don't need to be an assembly expert to figure out what's going on. 你不需要成为装配专家来弄清楚发生了什么。 movl moves values, addl adds things, cmpl compares and jle stands for 'jump if less than', $ is for constants. movl移动值,addl添加东西,cmpl比较和jle代表'jump if than',$是常量。 It's loading 0 into something - that must be 'sum', 1 into something else - ah, 'i'! 它将0加载到某个东西 - 必须是'sum',1加入其他东西 - 啊,'我'! A jump to L2 where we do the compare to 10, jump to L3 to do the add. 跳转到L2我们比较10,跳转到L3进行添加。 Fall through to L2 for the compare again. 再次进入L2进行比较。 Neat! 整齐! A for loop. 一个for循环。

Change the program to: 将程序更改为:

int main( )
{
    int sum = 0;
    int i=1;
    for( ;i<=10;++i)
    {
        sum = sum + i;
    }
    return sum;
}

Rerun gcc and the resultant assembly will be very similar. 重新运行gcc和由此产生的组件将非常相似。 There's some stuff going on with recording line numbers, so they won't be identical, but the assembly ends up being the same. 有一些东西正在记录行号,所以它们不会完全相同,但程序集最终是相同的。 Same result with the last case. 与最后一个案例相同的结果。 So, even without optimization, the code's just about the same. 因此,即使没有优化,代码也差不多。

For fun, rerun gcc with '-O3' instead of '-O0' to enable optimization and look at the .s file. 为了好玩,请使用'-O3'而不是'-O0'重新运行gcc以启用优化并查看.s文件。

main:
movl    $55, %eax
ret

gcc not only figured out we were doing a for loop, but also realized it was to be run a constant number of times did the loop for us at compile time, chucked out 'i' and 'sum' and hard coded the answer - 55! gcc不仅弄清楚我们正在做一个for循环,而且还意识到它在编译时为我们循环运行了一段时间,清除了'i'和'sum'并硬编码了答案 - 55 ! That's FAST - albeit a bit contrived. 这很快 - 尽管有点做作。

Moral of the story? 故事的道德启示? Spend your time on ensuring your code is clean and well designed. 花时间确保您的代码干净且设计精良。 Code for readability and maintainability. 可读性和可维护性代码。 The guys that live on mountain dew and cheetos are way smarter than us and have taken care of most of these simple optimization problems for us. 生活在山露和cheetos上的人比我们更聪明,并为我们处理了大部分这些简单的优化问题。 Have fun! 玩得开心!

It's the same. 一样的。 The compiler will optimize these to the same thing. 编译器会将这些优化为同样的东西。

Even if they weren't the same, the difference compared to the actual body of your loop would be negligible. 即使它们不相同,与循环的实际主体相比的差异也可以忽略不计。 You shouldn't worry about micro-optimizations like this. 你不应该担心像这样的微优化。 And you shouldn't make micro-optimizations unless you are performance profiling to see if it actually makes a difference. 除非你进行性能分析以确定它是否真的有所作为,否则你不应该进行微观优化。

It's the same in term of speed. 速度方面也是如此。 Compiler will optimize if you do not have a later use of i. 如果您以后没有使用i,编译器将进行优化。

In terms of style - I'd put the definition in the loop construct, as it reduces the risk that you'll conflict if you define another i later. 在风格方面 - 我将定义放在循环结构中,因为它可以降低您在以后定义另一个时会发生冲突的风险。

Don't worry about micro-optimizations, let the compiler do it. 不要担心微优化,让编译器去做。 Pick whichever is most readable. 选择最具可读性的。 Note that declaring a variable within a for initialization statement scopes the variable to the for statement (C++03 § 6.5.3 1 ), though the exact behavior of compilers may vary (some let you pick). 请注意,在for initial语句中声明变量会将变量范围限定for语句(C ++ 03§6.5.31 ),尽管编译器的确切行为可能会有所不同(有些for您选择)。 If code outside the loop uses the variable, declare it outside the loop. 如果循环外的代码使用变量,则在循环外声明它。 If the variable is truly local to the loop, declare it in the initializer. 如果变量对循环是真正的本地变量,则在初始化程序中声明它。

It has already been mentioned that the main difference between the two is scope. 已经提到两者之间的主要区别在于范围。 Make sure you understand how your compiler handles the scope of an int declared as 确保您了解编译器如何处理声明为的int的范围

for (int i = 1; ...;...)

I know that when using MSVC++6, i is still in scope outside the loop, just as if it were declared before the loop. 我知道当使用MSVC ++ 6时,我仍然在循环之外的范围内,就像它在循环之前声明一样。 This behavior is different from VS2005, and I'd have to check, but I think the last version of gcc that I used. 这种行为与VS2005不同,我必须检查,但我认为我使用的最后一个版本的gcc。 In both of those compilers, that variable was only in scope inside the loop. 在这两个编译器中,该变量仅在循环内的范围内。

for(int i = 1; i <= 100; ++i)

这是最容易阅读的,但ANSI C / C89除外,它是无效的。

A c++ for loop is literally a packaged while loop. C++ for 循环实际上是一个打包的 while 循环。

   for (int i=1; i<=100; i++){
   some foobar ; }

Is precisely the same as this to the compiler.与编译器完全相同。

{ int i=1 ;
while (i<=100){
some foobar ;
i++ ; }
}

这都一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM