I think both loops are identical:
1) number of additions, subtractions are the same in both cases (50 increments, 50 decrements, 2*50 additions and 100 increments and 100 additions).
2) number of comparison are the same (2*50 and 100 ones).
I would prefer to use the second loop, because its structure is simpler (or even just formula: sum = 100*(100+1)/2).
So then I guess it just boils down to preference. The main thing I learned was that if needed, you CAN have multiple conditions in a for loop (but you can't declare two variables in the for loop for some reason).
As a beginner, reading the second version looks simpler, but I just think the first one is a little cooler... even though they essentially do the same thing.
> As a beginner, reading the second version looks simpler, but I just think the first one is a little cooler...
As you gain experience, you will learn that simple, transparent, easily understandable code is the coolest code.
It is always more programmer-efficient. And, so very often, also more machine-efficient. What is easier for a programmer to read, is also easier for an optimizer to understand.
The optimizer does not have much of a clue about this; the code generated is almost a literal translation of the source code:
int foo()
{
int sum = 0;
int j = 100;
for( int i = 1 ; i<=100/2 && j>100/2 ; ++i )
{
sum += i+j;
j--;
}
return sum ;
/* g++ -std=c++11 -Wall -O3 -fomit-frame-pointer -c -S
__Z3foov:
LFB0:
movl $1, %ecx
movl $100, %edx
xorl %eax, %eax
jmp L2
L10:
cmpl $50, %ecx
jg L4
L2:
subl $1, %edx
addl $101, %eax
addl $1, %ecx
cmpl $50, %edx
jg L10
L4:
rep
ret
*/
}
This, on the other hand, is transparent code; the optimizer can see what is going on; it unrolls the loop, performs constant-folding, and does compile-time computations on constants.
1 2 3 4 5 6 7 8 9 10 11 12 13
int bar()
{
int sum = 0 ;
for( int i = 1 ; i<=100 ; ++i ) sum += i ;
return sum ;
/* g++ -std=c++11 -Wall -O3 -fomit-frame-pointer -c -S
__Z3barv:
LFB1:
movl $5050, %eax // return 5050 ;
ret
*/
}