Why does the continue statement ignore the increment of the loop counter in the while loop, but not in the for loop?

Why does it tend to get into an infinite loop if I use continue in a while , but it works fine in a for loop?
The increment of the i++ loop counter is ignored in the while if I use it after continue , but it works if it is in the for loop.

If continue ignores subsequent statements, then why doesn't it ignore the third statement of the for loop, which contains the increment i++ counter? Isn't this the third for loop statement following the continue , and should be ignored, given that the third for loop statement is executed after the loop body?

 while(i<10) //causes infinite loop { ... continue i++ ... } for(i=0;i<10;i++) //works fine and exits after 10 iterations { ... continue ... } 
+6
source share
8 answers

Because continue returns to the beginning of the loop. With for post-operation i++ is an integral part of loop control and is performed before the loop body reloads.

With while , i++ is just another expression in the body of the loop (not like something like a = b ), skipped if you continue before you reach it.

+18
source

The reason is that the continue statement will short circuit the statements that follow it in the body of the loop. Since the way you wrote the while contains an increment statement that follows the continue statement, it closes. You can solve this problem by changing the while .

Many text books claim that:

 for (i = 0; i < N; ++i) { /*...*/ } 

is equivalent to:

 i = 0; while (i < N) { /*...*/ ++i; } 

But in fact, this is true:

 j = 0; while ((i = j++) < N) { /*...*/ } 

Or, to be a little more pedantic:

 i = 0; if (i < 10) do { /*...*/ } while (++i, (i < 10)); 

They are more equivalent since now, if the while body has continue , the increment is still happening, as in for . The last alternative only performs the increment after the completion of the iteration, just like for (the first performs the increment before the iteration, deferring storage to i until the end of the iteration).

+10
source

Your increment i will continue, so it will never be executed

 while(i<10) //causes infinite loop { ......... continue i++ ...... } 
+3
source

In any cycle, continue execution at the beginning of the cycle, do not execute any other instructions after the continue statement .

In this case, the definition of the loop cycle is always performed (according to the C standard), whereas I ++; the statement is NOT executed because it comes AFTER the continue statement.

+2
source

Because the third part of for is always executed.

0
source
Operator

continue transfers the control to the end of statements in the current iteration of the loop, that is, skips the execution of statements in the current iteration and proceeds to the next iteration of the loop.

In a while the continue statement causes the control to reach the end of the statements (including the increment statement), thereby causing the loop to continue forever.

In the for loop, the continue statement jumps the control to the end of the statement and emits the increment operator (the for loop, the increment statement is considered to be separate from the records written inside the loop body).

0
source

for the loop, the condition operator and increment are executed, therefore, when the condition is fulfilled, it executes inside the for loop, but if the write continue statement is reached, than it will be reached again in the first line of the for loop, that is, increment and check the condition if it is satisfied, than goes back to execution. For a while loop, it simply checks the condition statement, and if the condition is met, it is executed to execute the statements in the while loop. therefore continue will not execute any line after it. Therefore, your condition is satisfied every time and goes for an infinite loop.

0
source

continue bypasses the rest of the block and starts again at the top of the block if the loop condition is met.

Next question: "What should I do, then?" There are two answers that I can think of.

Example:

 void foo () { size_t i = 0; do { /*...*/ if ( /*...*/ ) { /*...*/ continue; } /*...*/ i++; } while ( /* loop conditional */ ); } 

Solution # 1: Manual Zoom

 void foo () { size_t i = 0; do { /*...*/ if ( /*...*/ ) { /*...*/ i++; continue; } /*...*/ i++; } while ( /* loop conditional */ ); } 

Solution # 2: clearly goto *

 void foo () { size_t i = 0; do { /*...*/ if ( /*...*/ ) { /*...*/ goto foo_next; } /*...*/ foo_next: i++; } while ( /* loop conditional */ ); } 

goto valid in this case, since the increment in two places is technically the same instruction. This solution is especially relevant when iteration-dependent variables are more complex; for example, setting multiple variables or changing a value using an equation or function.

In the case of a single increment or decrement operator, decision No. 1 may be favorable; however, it should be noted that: if the code was changed after such an implementation, you must remember to update both instances of the instruction (which may be subject to errors, especially if changes occur after a long period of time **). Therefore, I highly recommend Decision No. 2.

* Some people think that any use of goto bad practice. I recommend you decide for yourself and leave this: google for "c goto bad"

** Perhaps a comment reminiscent of this need may be sufficient, but if my recommendations have been implemented, the variables depending on each iteration are limited to one statement. And I quote:

There is never a reason to comment on one line

-Linus Torvalds (source: http://yarchive.net/comp/linux/coding_style.html )

0
source

Source: https://habr.com/ru/post/945204/


All Articles