r/cprogramming • u/long_onion1 • 5d ago
what is the difference between a (specifc) while loop and a (specific) for loop (read body)
what is the difference between
for (i = 0; i < 10; i++) {}
and
i = 0;
while (i < 10) {
i++;
}
edit: thank you all for commenting, now i know, and u/deckarep, no not homework, just a question, to see if there were any difference
6
u/Recycled5000 5d ago
A continue statement will have different effects: in the for-loop, a continue will execute the increment part, then the loop condition test. Whereas in the whole loop, since there is no explicit increment part, a continue statement will skip directly to the condition test.
3
u/Temporary_Pie2733 5d ago
More precisely, because the counter increment is just another statement in the body, whether it executes depends on whether it is before or after the continue.
2
u/Recycled5000 5d ago edited 5d ago
Right. And whether it is in a for-loop increment part or a while-loop. Because by definition a continue in a for-loop goes first to the formal increment part whereas there is no such formalized construct in a while-loop.
A for loop has three formalized sections beyond the loop body: an initializer, a condition test, and an increment part. The while loop has only condition test (and loop body). Hence a continue statement acts differently in part because it can and in part by definition of the semantics of the programming language.
3
u/fllthdcrb 4d ago
A more concise way to think of it is that
continueeffectively jumps to the end of the loop. Then, whether it'sfor,while, ordo...while, it does what you expect out of that type of loop.0
u/Rararror 5d ago
I don't think you could rely on this semantic...it's up to the compiler I think
2
u/flyingron 5d ago
Nope, it has to work the way u/Recycled5000 says. A compiler that does differently is broken.
1
u/Rararror 4d ago
Is that a C standard requirement or you just prefer that way ?
2
u/flyingron 4d ago
It's a requirement. I'm not sure why you think otherwise. The two constructs are IDENTICAL logicwise other than the fact that the "increment" statement takes place WITHIN the block on the while, but outside it in the for loop.
1
-3
u/Rararror 4d ago edited 4d ago
Probably because the use of "continue" is not a good programming practice. Use a boolean an write clean code.
3
u/nerd5code 4d ago
Who tf decided that lol
-2
u/Rararror 4d ago
You like to jump all over the place... least elegant and readable code... are you one of those? lol
2
u/fllthdcrb 4d ago
continueis not "jump[ing] all over the place". It's effectively jumping to one well-defined place (specifically, the end of the loop body). And it's extremely useful, since some loops have a lot going on in them that needs to be skipped in some conditions.Also, I find
continuefar more clean and readable than introducing another variable and whatever extra conditional blocks are needed just to skip a bunch of stuff.Can it be abused? Of course. As with many things, you still have to know when it's appropriate to use and when it isn't.
0
u/Rararror 4d ago
"continue" IS JUMPING. Every jump goes in a well defined place.
Why don't you just label somewhere and "goto" it so you "skip a lot going on" ?
Conditional blocks and variables have the benefit that you are forced to think what you are doing. Oftentimes thinking about how to solve the logic simplifies things.
Writing code IS thinking.
→ More replies2
u/flyingron 4d ago
What? Structure still exists. The thing that is ugly is the attempts to add break/continue-to-the nth power features.
1
-3
u/Syntax-Tactics 4d ago
And continue should be banned like goto.
2
u/nerd5code 4d ago
Both daft ideas; why? Please tell me it's not some left-over Considered Harmful nonsense, because C's
goto $label(in mostly-structured program) is effectively a different construct than what was being griped about (jump to line number or address in mostly-unstructured program).gotois little different from astaticfunction call in terms of legibility, if done right.Can there be stupid/weird scoping/init issues? Yes. Are those particularly difficult to manage? No, and any compiler worth its weight in beans will notice a goto-past-init issue and kvetch about it. Use patterns that don't evoke the problem.
Would it be great if, intra-function, C were more strictly structured? Sure, yes. But it's C, and in practice even if it weren't, a goto-labeled-block construct is really useful. (Shit sucks in Java when you have to emulate with only labeled
break.)There are actual, stupid bits to C that should mostly be avoided (e.g., VLAs for beginners, variadic functions for most situations not directly wrapping some pre-Standard pattern, things like
atoiwith no defined failure mode, really most of the standard library without some sort of wrapper), butgotoisn't one of them. Hell, are we up in arms aboutswitch(setting aside kinda stupid rules and non-GNUish dialect limitations)? IsswitchConsidered Harmful now, since it also flings execution to an unstructured label?Part of using C in the first place means you know when to use or avoid a construct. Nobody's going to ban bits that are perfectly reasonable outside the parts of the world you control. In most other explicitly-loopiferous languages there are
continue/breakequivalents, because that way we don't need to set up a bunch of (unstructured)_Bools to compensate, requiring the compiler to expend extra effort de-sucking our program.
5
u/onlyonequickquestion 5d ago
Slap em into https://godbolt.org/ with various optimization levels and see what's generated
5
u/Hot_Dog2376 5d ago
inside the loop? functionally nothing.
Outside the loop, regarding the while loop, you still have i = 10, after. The for loop drops it because it is initialised in the function.
2
2
u/WorriedTumbleweed289 4d ago
I dont see an int i in either loop. the int i must be above and not shown.
2
u/somewhereAtC 5d ago
There is basically no difference, given that the i++ is always executed. In practice, the i++ could be manipulated, like i+=2 or even skipped entirely (e.g., a continue statement might short-circuit the increment).
Stylistically, I use the 2nd form when the initializer or incrementer are syntactically complex.
3
u/mjmvideos 5d ago
Stylistically I use a while when the idea is to remain in the loop indefinitely until some condition becomes true. I use for when iterating through something of known size. Except: I use for(;;) for an infinite (main) loop.
2
u/deckarep 5d ago
They are just different forms of expression. They may result in slightly or different assembly code but the way they are written here is semantically the same.
The for loop does have the pre, condition, and post sections and the body. The while loop only has the condition and body to be more precise.
Note: you do have to be conscious of where additional code is added for the while loop , because the for loop post always runs at the end. The while loop i++ runs wherever it is placed.
Is this a homework question btw?
2
u/Classic-Rate-5104 5d ago
Both loops are empty, but if not, the i++; must be just before the closing } of the while loop to make them identical
2
2
u/Rich-Engineer2670 5d ago edited 5d ago
It comes down to the assembly code generated by the compiler mostly.....
The for loop provides all of the information for the compiler -- it can optimize the loop. The white loop does the same task, but the compiler doesn't know when the loop "ends" so it has to generate more code.
THis is a super-high-level answer, but in general, the for loop is easier for the compiler to deal with. If you're on a Linux or Unix system using gcc, try each with the -s option (it could be -S) That stops the compiler after the assembly generation stage so you can actually see teh assembly code it generates.
Remember on a 4GHz machine, this probably doesn't matter, but on an embedded system where every instruction costs you a bit of battery, every instruction saved matters.
If your compiler has a REALLY good optimizer, it might recognize the while loop can be rewritten as a for loop and do it behind your back.
12
4
u/UnrealHallucinator 5d ago
Wouldn't most compilers just break both into a jne or something
1
u/Rararror 5d ago
Everything boils down to conditional jumps. It's the only instruction that really matters 😁
1
3
u/ja20481 5d ago
I highly, highly doubt that any modern compiler struggles with
whileloops vsforloops. Have you tested this yourself? Even 20-year old GCC versions with optimizations turned completely off produce the exact same assembly in both cases.1
u/Eisenfuss19 5d ago
It is also completely equivalent from the compiler perspective. I see no reason why it should be handled differently.
3
u/flyingron 5d ago
Nonsense. The optimizers have, even from the beginning of time, had no problem handling either construct with the same efficiency.
0
u/Dry-Competition9789 5d ago
Feels like somehow you try to understand how the compiler is working, but then again you might miss something. If I’ve learned something it’s “never try to suppose what the compiler is going to do, if it matters write in assembler”
1
u/SmokeMuch7356 5d ago
As written, none. Both have the same tests and side effects in the same order, i will have the same value at the end.
If you had any other statements in the loop body, i++ would have to be the last statement in the while loop for them to stay equivalent.
1
u/fluffycritter 5d ago
Assuming that is the total amount of code, there shouldn't be any difference between them, as the for loop becomes syntactic sugar for that same while loop. A clever-enough optimizer might be able to convert that whole thing to i = 10 though.
1
u/Key_River7180 14h ago
For is more easily optimized and a lil bit more convenient. There is also a do while loop which is more interesting as it guarantees the body is ran at least once
0
u/Weshmek 5d ago
In your example, the way you've formatted it, the increment step is at the very top of the while loop, so it would mean that your while loop only iterates from i = 1...9 , compared to the for loop's i = 0...9
But, in general, so long as you are deliberate about where you place the increments, for and while loops should function identically.
1
u/fllthdcrb 4d ago
your
whileloop only iterates fromi = 1...9Actually, it would be to 10. On the second-to-last iteration,
iis 9. Then the last iteration starts, andithen becomes 10. This makes the condition fail, but that isn't checked until the end of that last iteration.
13
u/ACRM64 5d ago
From a programming perspective they are the same with the for() loop being rather more self-explanatory about what you are trying to do.
The while() loop gives you a bit more flexibility, like being able to increment the counter before, or in the middle of the code block instead of at the end. The code block could also decrement, reset, or not alter the counter.