How to put two increment statements in a C ++ loop for a loop?

I would like to increase two variables in for -loop state instead of one.

So something like:

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

What is the syntax for this?

+64
c ++ for-loop comma-operator
Aug 05 '09 at 9:40
source share
8 answers

A common idiom is the use of an operator that evaluates both operands and returns the second operand. In this way:

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

But is this a comma operator?

Now, having written this, the commentator suggested that in fact it was some kind of special syntactic sugar in the for statement, and not as a comma operator. I checked this in GCC as follows:

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

I expected x to take the original value of a, so it should have displayed 5,6,7 .. for x. I got it

 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 make the parser really see the 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=%da=%dx=%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 

At first, I thought that it showed that it does not behave like a comma operator at all, but as it turns out, this is just a priority problem - the comma operator has the lowest possible priority , therefore the expression x = i ++, a ++ is effectively parsed as ( x = i ++), a ++

Thanks for all the comments, it was an interesting learning experience and I have been using C for many years!

+113
Aug 05 '09 at 9:44
source share
— -

try it

 for(int i = 0; i != 5; ++i, ++j) do_something(i,j); 
+51
Aug 05 '09 at 9:42
source share

Try not to do this!

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

AV rule 199
An increment expression in a for loop will not do anything except change one loop for the next value for the loop.

Rationale: readability.

+4
Aug 05 '09 at 9:53
source share
 for (int i = 0; i != 5; ++i, ++j) do_something(i, j); 
+3
Aug 05 '09 at 9:42
source share

I came here to remind myself how to encode the second index into the increment clause of the FOR loop, which, as I knew, can be made mainly from observing it in a sample that I included in another C ++ project.

Today I work in C #, but I was sure that he would obey the same rules in this regard, since the FOR statement is one of the oldest control structures in all programming. Fortunately, I recently spent several days accurately documenting the behavior of the FOR loop in one of my old C programs, and I quickly realized that there were lessons in these studies that applied to the current C # problem, in particular, the behavior of the second index variable.

For careless, below is a summary of my observations. Everything that I saw today, carefully observing the variables in the Locales window, confirmed my expectation that the C # FOR operator behaves exactly the same as the C or C ++ FOR operator.

  • The first time the FOR loop is executed, the increment clause (the third of its three) is skipped. In Visual C and C ++, an increment is generated as three machine instructions in the middle of a block that implements a loop, so that the initial pass runs only the initialization code once, then jumps through the increment block to complete the completion test. This implements a function in which the FOR loop executes zero or more times, depending on the state of its index and limit variables.
  • If the loop body is executed, its last statement is the transition to the first of the three increment instructions that were skipped by the first iteration. After their implementation, the control naturally falls into the test restriction code, which implements the middle sentence. The result of this test determines whether the body of the FOR loop is executing, or if control passes to the next command after the transition at the bottom of the scope.
  • Since control transfers from the bottom of the FOR loop to the increment block, the index variable is incremented before the test runs. Not only does this behavior explain why you should encode your limit sentences in the way you learned, but it affects any additional increment that you add through the comma operator, because it becomes part of the third sentence. Therefore, it does not change at the first iteration, but is at the last iteration, which the body never performs.

If any of your index variables remains in scope when the cycle ends, their value will be one higher than the threshold that stops the cycle, in the case of a true index variable. Similarly, if, for example, the second variable is initialized to zero before the loop is entered, its value at the end will be an iteration counter, assuming that it is an increment (++) and not a decrement, and that nothing in the body of the loop changes its value.

+2
Jun 10 '16 at 5:01
source share

I agree with compliance. Increasing two variables is due to an error, especially if you are checking only one of them.

This is a readable way to do this:

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

For are intended for cases when your cycle works on one increasing / decreasing variable. For any other variable, change it in a loop.

If you need to bind j to i , why not leave the original variable as it is and add i ?

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

If your logic is more complex (for example, you need to control more than one variable), I would use a while .

+1
Aug 05 '09 at 10:38
source share
 int main(){ int i=0; int a=0; for(i;i<5;i++,a++){ printf("%d %d\n",a,i); } } 
0
Aug 05 '09 at 9:43
source share

Use math. If the two operations are mathematically dependent on the iteration of the loop, 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 example:

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

Especially if you go to a function by value, then you should get what does exactly what you want.

0
Jun 11 '15 at 13:17
source share



All Articles