Both while
loops run once (and once only); the difference is that, in the second case (the j
loop) you are printing the 'control variable' inside the loop but, for the first case, you are printing it after the loop condition has evaluated to false
. Also note that, in the first case, the semicolon immediately following the while
statement defines the body of that loop as empty1.
Let's break down the first loop into steps:
On the first test of the condition, i++
evaluates to 1
and then i
is incremented – so the loop runs.
On the second test, i++
evaluates to 2
(so the loop doesn't run) but i
is still (post-)incremented, leaving it with the value of 3
(as shown in the output).
The same thing happens with j
in the second loop but, in that case, as previously mentioned, you are displaying the value in the body of the loop (on its only run), so you see the value after the first (post-)increment.
As noted in the comments, if you add another printf("%d", j);
after the body of the loop (which, in that case, consists of a single statement), you will see that j
, too, has the value 3
when that loop has finished.
1 More precisely, the semicolon (on its own) defines a null statement, which forms the body of the while
loop.
It is often helpful to clarify such 'null loops' by putting the semicolon on a line by itself (some compilers, with full warnings or static analysis enabled, may even suggest you do this):
#include<stdio.h>
int main()
{
int i = 1;
while (i++ <= 1)
; // Body of loop - Null Statement
printf("%d", i); // Loop has finished
int j = 1;
while (j++ <= 1)
printf("%d", j); // Body of loop
// Loop has finished
return 0;
}