for ( init ; cond ; update ) for bodyThe semicolons in the for header are not the usual semicolons that end statements.
These semicolons are separators, that let you know where init, cond, update are located.
What if you wanted to use a for loop to print? the following:
1 10 2 9 3 8 4 7 5 6Furthermore, you want to do this by initializing two int variables, call them first and second, to 0 and 10 respectively.
You want to keep printing as long as first < second and after each iteration, you increment first and decrement second.
This is what you'd need to do:
For the same reason, you can't write update as i++ ; j--. Again, the semicolon confuses the compiler.
The solution? Use the comma operator.
Personally, I don't think the comma operator is a great idea, and I suspect it was invented just for the for loop.
expr1, expr2You can have two or more expressions separated by commas. The entire thing is also an expression.
Now think about whether this is a good idea or not.
int j = 2, k = 4 ; int x ; // Assignment statement with comma operator x = j + 1, k ;Recall the semantics of an assignment statement. Evaluate the RHS, then take the value and put it in the box on the LHS.
In this case, we evaluate j + 1 to 3, and then evaluate k to 4. The final result of this comma expression is 4 which is the evaluated value of the rightmost expression.
Thus, x is assigned to 4.
Here's the problem. Why did we bother writing j + 1? It never gets used. So why is it there?
If we don't do this, it makes little sense to have the comma operator.
The following makes a little more sense:
x = j++, k ;At the very least, j is updated. Even here, it makes more sense to write the code without the comma operator.
j++ ; x = k ;
for ( int first = 0, second = 10 ; first < second ; first++, second-- ) { System.out.println( first + " " + second ) ; }The comma operator is used only in the update. The init is a declaration. We're allowed to have a declaration in init. This prevents us from declaring variables of two different types.
We could use the comma operator in init provided we didn't declare variables. For example,
int first, second ; for ( first = 0, second = 10 ; first < second ; first++, second-- ) { System.out.println( first + " " + second ) ; }In this case, we could have variables of different types in the init, separated by comma operators.
In the example above, we actually have two assignment statements (which are also expressions), separated by commas, not a declaration. This distinction is subtle, so I hope you noticed it.
foo.bar( x, y + 3, 10 ) ;The commas separate the arguments. It evaluates the arguments, but the result is not a single value passed to bar().
public void foo( int x, int y, double z ) ;These commas separate parameters. The parameters aren't even expressions!
int x = 3, y = x, z ;Again, commas used to separate the variables.