简体   繁体   English

如何在 C++ 'for' 循环中放置两个增量语句?

[英]How do I put two increment statements in a C++ 'for' loop?

I would like to increment two variables in a for -loop condition instead of one.我想在for循环条件中增加两个变量而不是一个。

So something like:所以像:

for (int i = 0; i != 5; ++i and ++j) 
    do_something(i, j);

What is the syntax for this?这是什么语法?

A common idiom is to use the comma operator which evaluates both operands, and returns the second operand.一个常见的习惯用法是使用逗号运算符来计算两个操作数,并返回第二个操作数。 Thus:因此:

for(int i = 0; i != 5; ++i,++j) 
    do_something(i,j);

But is it really a comma operator?但它真的是逗号运算符吗?

Now having wrote that, a commenter suggested it was actually some special syntactic sugar in the for statement, and not a comma operator at all.写完之后,一位评论者建议它实际上是 for 语句中的一些特殊语法糖,而根本不是逗号运算符。 I checked that in GCC as follows:我在 GCC 中检查如下:

int i=0;
int a=5;
int x=0;

for(i; i<5; x=i++,a++){
    printf("i=%d a=%d x=%d\n",i,a,x);
}

I was expecting x to pick up the original value of a, so it should have displayed 5,6,7.. for x.我期待 x 获取 a 的原始值,所以它应该为 x 显示 5,6,7..。 What I got was this我得到的是这个

i=0 a=5 x=0
i=1 a=6 x=0
i=2 a=7 x=1
i=3 a=8 x=2
i=4 a=9 x=3

However, if I bracketed the expression to force the parser into really seeing a comma operator, I get this但是,如果我将表达式括起来以强制解析器真正看到逗号运算符,我会得到这个

int main(){
    int i=0;
    int a=5;
    int x=0;

    for(i=0; i<5; x=(i++,a++)){
        printf("i=%d a=%d x=%d\n",i,a,x);
    }
}

i=0 a=5 x=0
i=1 a=6 x=5
i=2 a=7 x=6
i=3 a=8 x=7
i=4 a=9 x=8

Initially I thought that this showed it wasn't behaving as a comma operator at all, but as it turns out, this is simply a precedence issue - the comma operator has the lowest possible precedence , so the expression x=i++,a++ is effectively parsed as (x=i++),a++最初我认为这表明它根本不像逗号运算符,但事实证明,这只是一个优先级问题 - 逗号运算符的优先级最低,因此表达式 x=i++,a++ 是有效的解析为 (x=i++),a++

Thanks for all the comments, it was an interesting learning experience, and I've been using C for many years!感谢所有的评论,这是一次有趣的学习经历,而且我已经使用 C 很多年了!

Try this试试这个

for(int i = 0; i != 5; ++i, ++j)
    do_something(i,j);

Try not to do it!尽量不要这样做!

From http://www.research.att.com/~bs/JSF-AV-rules.pdf :来自http://www.research.att.com/~bs/JSF-AV-rules.pdf

AV Rule 199反病毒规则 199
The increment expression in a for loop will perform no action other than to change a single loop parameter to the next value for the loop.除了将单个循环参数更改为循环的下一个值之外,for 循环中的增量表达式不会执行任何操作。

Rationale: Readability.基本原理:可读性。

for (int i = 0; i != 5; ++i, ++j) 
    do_something(i, j);

I came here to remind myself how to code a second index into the increment clause of a FOR loop, which I knew could be done mainly from observing it in a sample that I incorporated into another project, that written in C++.我来这里是为了提醒自己如何将第二个索引编码到 FOR 循环的 increment 子句中,我知道这主要是通过在我合并到另一个用 C++ 编写的项目中的示例中观察它来完成的。

Today, I am working in C#, but I felt sure that it would obey the same rules in this regard, since the FOR statement is one of the oldest control structures in all of programming.今天,我在使用 C#,但我确信它在这方面会遵守相同的规则,因为 FOR 语句是所有编程中最古老的控制结构之一。 Thankfully, I had recently spent several days precisely documenting the behavior of a FOR loop in one of my older C programs, and I quickly realized that those studies held lessons that applied to today's C# problem, in particular to the behavior of the second index variable.值得庆幸的是,我最近花了几天时间精确地记录了我的一个旧 C 程序中 FOR 循环的行为,我很快意识到这些研究提供了适用于当今 C# 问题的经验教训,特别是第二个索引变量的行为.

For the unwary, following is a summary of my observations.对于粗心的人,以下是我的观察摘要。 Everything I saw happening today, by carefully observing variables in the Locals window, confirmed my expectation that a C# FOR statement behaves exactly like a C or C++ FOR statement.通过仔细观察 Locals 窗口中的变量,我今天看到的一切证实了我的预期,即 C# FOR 语句的行为与 C 或 C++ FOR 语句完全一样。

  1. The first time a FOR loop executes, the increment clause (the 3rd of its three) is skipped. FOR 循环第一次执行时,会跳过 increment 子句(三个子句中的第三个)。 In Visual C and C++, the increment is generated as three machine instructions in the middle of the block that implements the loop, so that the initial pass runs the initialization code once only, then jumps over the increment block to execute the termination test.在 Visual C 和 C++ 中,增量作为三个机器指令生成在实现循环的块中间,因此初始 pass 只运行一次初始化代码,然后跳过增量块执行终止测试。 This implements the feature that a FOR loop executes zero or more times, depending on the state of its index and limit variables.这实现了 FOR 循环执行零次或多次的功能,具体取决于其索引和限制变量的状态。
  2. If the body of the loop executes, its last statement is a jump to the first of the three increment instructions that were skipped by the first iteration.如果循环体执行,它的最后一条语句是跳转到第一次迭代跳过的三个增量指令中的第一个。 After these execute, control falls naturally into the limit test code that implements the middle clause.这些执行后,控制自然落入实现中间子句的极限测试代码。 The outcome of that test determines whether the body of the FOR loop executes, or whether control transfers to the next instruction past the jump at the bottom of its scope.该测试的结果决定了 FOR 循环体是否执行,或者控制是否转移到下一条指令,越过其作用域底部的跳转。
  3. Since control transfers from the bottom of the FOR loop block to the increment block, the index variable is incremented before the test is executed.由于控制从 FOR 循环块的底部转移到增量块,索引变量在执行测试之前被增加。 Not only does this behavior explain why you must code your limit clauses the way you learned, but it affects any secondary increment that you add, via the comma operator, because it becomes part of the third clause.这种行为不仅解释了为什么您必须按照您所学的方式对限制子句进行编码,而且它会影响您通过逗号运算符添加的任何二级增量,因为它成为第三个子句的一部分。 Hence, it is not changed on the first iteration, but it is on the last iteration, which never executes the body.因此,它在第一次迭代时没有改变,但在最后一次迭代时发生了变化,它从不执行主体。

If either of your index variables remains in scope when the loop ends, their value will be one higher than the threshold that stops the loop, in the case of the true index variable.如果您的任一索引变量在循环结束时仍在作用域内,则在真正的索引变量的情况下,它们的值将比停止循环的阈值高一个。 Likewise, if, for example, the second variable is initialized to zero before the loop is entered, its value at the end will be the iteration count, assuming that it is an increment (++), not a decrement, and that nothing in the body of the loop changes its value.同样,例如,如果在进入循环之前将第二个变量初始化为零,则其最后的值将是迭代计数,假设它是增量 (++),而不是减量,并且循环体改变它的值。

I agree with squelart.我同意尖叫。 Incrementing two variables is bug prone, especially if you only test for one of them.增加两个变量很容易出错,尤其是当您只测试其中一个时。

This is the readable way to do this:这是执行此操作的可读方式:

int j = 0;
for(int i = 0; i < 5; ++i) {
    do_something(i, j);
    ++j;
}

For loops are meant for cases where your loop runs on one increasing/decreasing variable. For循环适用于循环在一个递增/递减变量上运行的情况。 For any other variable, change it in the loop.对于任何其他变量,请在循环中更改它。

If you need j to be tied to i , why not leave the original variable as is and add i ?如果您需要将j绑定到i ,为什么不保留原始变量并添加i

for(int i = 0; i < 5; ++i) {
    do_something(i,a+i);
}

If your logic is more complex (for example, you need to actually monitor more than one variable), I'd use a while loop.如果您的逻辑更复杂(例如,您需要实际监控多个变量),我会使用while循环。

int main(){
    int i=0;
    int a=0;
    for(i;i<5;i++,a++){
        printf("%d %d\n",a,i);
    } 
}

Use Maths.使用数学。 If the two operations mathematically depend on the loop iteration, why not do the math?如果这两个操作在数学上依赖于循环迭代,为什么不进行数学计算呢?

int i, j;//That have some meaningful values in them?
for( int counter = 0; counter < count_max; ++counter )
    do_something (counter+i, counter+j);

Or, more specifically referring to the OP's example:或者,更具体地说,是指 OP 的示例:

for(int i = 0; i != 5; ++i)
    do_something(i, j+i);

Especially if you're passing into a function by value, then you should get something that does exactly what you want.特别是如果您按值传递给函数,那么您应该得到一些完全符合您要求的东西。

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

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