Why this isn't an infinite loop? How is it working? - c

Trying this code and the output as per my book is -10 to -1. How this is being printed is really baffling me.
#include <stdio.h>
void main()
{
int var = -10;
for(; var; printf("%d\n ", var++));
}

Let's go through this step by step:
The int var variable is initialised to -10. So far, so good.
Now we get to the interesting part of this: the for loop. We have a powerful construct with the following form:
for (/* initialisation-statement */ ; /* condition */ ; /* iteration-statement */)
/* statement or block of code */
With your code, we have nothing for the initialisation statement (int var = -10 could go here), var for the condition, and printf("%d\n ", var++) for the iteration statement.
In case you're not familiar with how for loops, here's a more primitive (but still equivalent) form:
{
/* initialisation-statement */;
startloop:
if (/* condition */) {
/* statement or block of code */
/* iteration-statement */;
goto startloop;
}
}
Putting for(int var = -10; var; printf("%d\n ", var++)); into this, we get:
{
int var = -10;
startloop:
if (var) {
;
printf("%d\n ", var++);
goto startloop;
}
}
When the printf("%d\n ", var++); statement is executed, it prints the value of var++ to stdout. The postfix version of the ++ operator increments the value, but evaluates to the original value.
Because var controls the loop, it will keep the loop going as long as it evaluates to true (non-zero). Since var is incrementing from -10, it will end up reaching 0 and ending the loop.
SIDE NOTE: void main() is not standard. Use int main(void) or int main(int argc, char *argv[]) instead.

It is working for below reasons
The var in the if condition serves as a boolean expression, its value is evaluated and any non-zero value serves as true and a zero value serves as false.
var++ in printf("%d\n ", var++) is postfix operator applied on var. It takes the current value and then increments var by one.
Eventually var reaches zero (Read it along with the first point)

Here you have your code a little bit formatted. Note that the following code does exactly the same thing as yours:
#include <stdio.h>
int main()
{
int var;
for (var=-10; var!=0 ;var++) {
printf("%d\n ", var);
}
return 0;
}
The condition var!=0 will be evaluated in your code as well automatically. In C everything !=0 is true and 0 is false.

Generally in programming, every integer (to a boolean) except for a 0 is interpreted as the boolean true.
Only a 0 is interpreted as false, so the loop breaks at var = 0 and 0 doesn't get printed.
Also: If you would put any positive integer in var and run the same loop, the loop would count up infinite times because it never hits 0, except if you'd wait to get to an overflow. That is, when you add 1 to 2,147,483,647 (increment) and get a -2,147,483,648. Since then var is negative again but still counting up, eventually you reach 0 and the loop will break.

first, var++ means var = var + 1;
which means that the loop goes from -10 to -1.
therefore printf("%d\n ", var++) will increment var by one and print the var.
the diff between var++ and ++var is that in var++ the printf happened first and than the +1 because of that you see output from -10 to -1.
second, 0 in C means false. then var become 0 the loop stops.
also the loop can be for(int var = -10;var;printf("%d\n ", var++)) ; which is the same as for(;var;printf("%d\n ", var++)) ;

Related

++i and i++ in while loop in C

I am using a program to detect the boundary of each data type, which is like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
/*first while loop using a++ dosesn't give us a right answer*/
int a = 0;
while (a++ > 0);
printf("int max first = %d\n", a-1);
/*second while loop using ++a performs well*/
int b = 0;
while (++b > 0);
printf("int max second = %d\n", b-1);
system("pause");
return 0;
}
After I compile this propram and excute it, it returns:
int max first = 0
int max second = 2147483647
So I try to debug it, and I find out that in the first part, after a++ becomes 1, then it just stop autoincrement and jump the while loop,while in second part it runs well, why is this happening?
The pre-increment operator (e.g. ++b) is done first, and the value of the expression is the incremented value.
That is
int b = 0;
while (++b > 0) ...
will increment b first and then check its value using the larger-than comparison. Since in the very first iteration ++b will make b equal to 1 the condition will be 1 > 0 which is true.
Now the post-increment operator does the increment after the old value is used.
So for example a++ will return the old value of a and then do the increment.
So with
int a = 0;
while (a++ > 0) ...
the very first iteration a++ will return 0 which means you have the condition 0 > 0 which is false and the loop will never even iterate once. But the value of a will still be incremented, so afterwards it will be equal to 1 (when the loop have already ended).
This behavior of the pre- and post-operators should be part of any decent book, tutorial or class.
after a++ becomes 1, then it just stop autoincrement and jump the
while loop
This happens because of the post and pre increment operators and the ; in while loop working together.
a will be incremented by 1 after the condition a++ > 0 is evaluated. Thus, the condition fails. The ; at the end of the while statement results in an empty loop and the next print statement will be executed even if the condition on which the while loop is based returns true.
This is exactly what happens in the second while loop - the pre increment operator will increment b before the condition is checked inside while (++b > 0);. The empty while loop keeps on adding one to the value of b until there is an overflow.
At this point, strictly speaking, you have invoked undefined behaviour because the operation has resulted in overflowing a signed integer.
Let me rewrite the main function you wrote - so that it becomes easier to understand.
int main()
{
/*first while loop*/
int a = 0;
while (a > 0){ a = a + 1; }
printf("int max first = %d\n", a-1);
/*second while loop*/
int b = 0;
b = b + 1;
while (b > 0){ b = b + 1; }
printf("int max second = %d\n", b-1);
system("pause");
return 0;
}
Some observations regarding what happened here:
Because at the beginning of the first while loop - the value of a is 0 - which is not greater than 0; the loop gets skipped at the beginning. As a result, the first printf outputs 0.
At the beginning of the second while loop, before evaluating the loop control condition; the loop control variable b gets incremented by 1, resulting the value of b becoming 1; which is greater than 0. For this reason, the second loop is executed.
While executing the second loop, the value of b keeps incrementing by 1 until the value of b overflows. At this point, the program encounters undefined behaviour - and exits the while loop if the program doesn't crash or keeps executing the loop indefinitely (in which case, at some stage the OS will terminate the program; or ask the user to terminate it - as the program will become non-responsive).
You mentioned that you wanted to measure the limit of int values; I hope this reference and this reference will help you in some way.

Why no output when index value is 0

Change the value of index from o to 1. loop is printing value. Why it is not printing any value when index is assigned to 0?
Currently i = 0 - No Output
Make i = 1 - infinite loop
#include<stdio.h>
int main()
{
for(int i = 0;i++;i<100)
{
printf("Mahesh\n");
}
}
enter code here
C for loop structure:
for ( init; condition; increment )
You have actually added i++ in the place of condition and i<100 in the place of increment.
Flow Control of for loop in C:
init step is executed first and only once.
Condition is evaluated next and if it is True, the body of the loop is executed. If False, the body of the loop doesn't execute and the flow jumps to the next statement after the for loop.
After the body of the loop executes once, the flow control jumps to increment statement and then condition is evaluated again.
Body of loop, Condition and increment steps are repeated in the same order till the condition becomes False after which the for loop terminates.
Your loop is:
for(int i = 0;i++;i<100)
In this, you have i++ as the condition. Now, in this i is evaluated first followed ++. Since, i is 0, it leads to the loop exiting as the condition evaluates to False. But, if you change i to 1, the condition (i.e. i) evaluates to True and it enters the loop.
If you have not done this deliberately, you need the loop like below:
for (int i = 0; i < 100; i++)
The syntax for a for loop in C is as follows:
for ( init; condition; increment ) {
statement(s);
}
-init: initialising the index variable with the value you would like to start the iteration at.
-condition: the condition for the iteration to continue until met
-incremenet: indicating how much you want the program to incremenet your index by
Hence in your example is should be:
for(int i = 0; i < 100; i++){
//yourcode
}
Hope that helps
The parameters of for loop are:
for(initialization; Condition; Next iteration initialization){
//code
}
The initialization(s) can be more than one separated by commas.
The condition will continue if have 1 (or the value TRUE which means the same thing as 1) or will break if the condition is not met i.e the value 0 (or FALSE). You can have multiple conditions as well by the use of && or || or commas.
The third parameter is what you want to do in the next iteration. It can have multiple commands too. I suggest you run the following code and change it to observe the results:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,j;
for( i=0,j=0;i<10 || j<5;i++,j++)
printf("%d\t%d\n",i,j);
return 0;
}
#include<stdio.h>
int main()
{
int i = 0;
// Postfix Increment Operator
for (i = 0; i++; i<100) // Condition is false, Because the i is Zero
{
printf("Mahesh");
}
printf("%d", i); // i outputs One here
// Prefix Increment Operator
for (i = 0; ++i; i<100) // Condition is True, Because the i is One
{
printf("Mahesh");
}
}

Incrementing of variable inside a loop

What will be the output of the program?
#include<stdio.h>
void main()
{
int i = 0;
while(i < 10)
{
i++;
printf("%d\n",i);
}
}
Will the output start from 0 or from 1 as I my professor taught me that the value of the variable is incremented only at the end of the loop while using i++ unlike in ++i?
The side effect of incrementing using either the prefix ++ or the postfix ++ occurs before the statement i++; completes. The fact that the statement is in a loop doesn't change that.
Your professor is correct. The first time printf is called in the loop, i will have the value 1 because the previous statement incremented the value.
Had you instead had the following code:
while(i < 10)
{
printf("%d\n",i++);
}
Then 0 would be printed on the first iteration. In this case, the value of i is incremented, but the postfix ++ operator means that the old value of i is passed to the printf call.
will start from 1 since the line i++ ends before you enter the next line which prints, the ++i compared to i++ is different when you increment it while doing something else in the same line/command.
for example: if you use
printf("%d",i++);
it would print 0 before incrementing i but if you put it like this:
printf("%d",++i);
it will first increment i (from 0 to 1) and then print i(which is 1 the first time it's printed).
Your code will print 1 as first value.
i++ increments the value at the end of the statement, and vice versa ++i increments the value before the statement. This is usually used when assigning variables:
i = 5;
int a = ++i; // a=6, i=6
i = 5;
int b = i++; // b=5, i=6

Why we can't compare a int variable with int return type function in c?

I tried to compare int variable with the function in two ways:
storing the int function return value in a variable then comparing with another
in value.
Directly comparing the int variable and the function call.
Here I got the answer for the first one but not for the second one.
Why does this happen?
My code:
#include < stdio.h >
int count = 0;
int countDigits(int);
int main() {
int i;
int result = countDigits(435);
for (i = 0; i < result; i++) {
printf("id %d\n", 3);
}
for (i = 0; i < countDigits(435); i++) {
printf("i =%d\n", i);
}
}
int countDigits(int n) {
if (n == 0) {
return count;
} else {
countDigits(n / 10);
count++;
}
}
We can.
It's just that your function has a logical error. Debug it, and you will be fine.
Enabling compiler warnings would have helped you. For example with GCC and Wall flag, you get:
prog.c: In function 'countDigits':
prog.c:32:1: warning: control reaches end of non-void
function [-Wreturn-type]
}
^
Tip: Think of what your function does if n us different than zero.
count is a global variable.
The function countDigits(n) adds the number of decimal digits in n to count and
If n is zero it returns 1.
If n is non-zero the return value is undefined.
Since countDigits(435) has an undefined value, anything can happen and no further analysis is necessary.
Let's assume that this obvious error is corrected by inserting return count; after count++;. In this case, the function returns the incremented count.
So we have this nice sequence:
Set result to countDigits(435).
countDigits(435) adds 3 to count and returns 3.
Set i to 0 and compare to countDigits(435).
countDigits(435) adds 3 to count and returns 6. 0 is less than 6, so the for loop continues.
Now i is 1, and we compare it to countDigits(435).
countDigits(435) adds 3 to count and returns 9. 1 is less than 9, so the for loop continues.
Now i is 2, and we compare it to countDigits(435).
countDigits(435) adds 3 to count and returns 12. 2 is less than 12, so the for loop continues.
... And so on.
Morality:
Beware of side effects. Never use and modify global variables unless you have a good reason to.
When you must use side effects, keep them prominent in your mind.
It is possible to compare a variable directly with the output of a function. However, your function countDigits has several problems.
Not all code paths return a value - you're missing a return statement in the else block. This alone makes the output of the function undefined.
It's not algorithmically correct. Have you tried debugging it? Just start with printing the output for different inputs and you'll see.
Modifying and returning a global variable count inside that function is a really bad practice - it should be local to the function. When it's global, every call to the function modifies a [possibly] already modified variable.
Others have already addressed the problem here with globals, so I will not go into details about that. Instead, here is a solution without globals:
int countDigits(int n) {
int count = 0;
while(n>0) {
n/=10;
count++;
}
return count;
}
I guess you could be philosophical about whether 0 has 0 or 1 digit, but your code implied that you wanted it to be 0. If you want it to be 1 instead, just change the first row to int count = 1.

Interchanging statements in for loop

This is the line of code in C.
The condition of loop here is ++i.
So how does compiler decide which condition to consider because here other two appear as conditions?
char i=0;
for(i<=5&&i>-1;++i;i>0)
printf("%d",i);
output
1234..127-128-127....-2-1
The for statement works like this:
for (X; Y; Z)
{
...
}
translates to
X;
while (Y)
{
...
Z;
}
So your code changes from:
char i=0;
for(i<=5&&i>-1;++i;i>0)
printf("%d",i);
to:
char i = 0;
i<=5 && i>-1; // X
while (++i) // Y
{
printf("%d", i);
i > 0; // Z
}
As you can see, lines marked with X and Z are completely useless. Therefore:
char i = 0;
while (++i)
printf("%d", i);
This means it will print from 1 up to whenever result of ++i is zero.
If char in your compiler is signed, then the behavior is left to implementation, even though most likely it will overflow to a negative value and work its way up to zero.
If char is positive, this will print positive values up to where it overflows back to 0.
It doesn't. It runs the first part and i gets set to any side effect of this, then it terminates when the second part is false, in this case when i is 0, then on every loop it runs the 3rd part.
SO the compiler essentially rewrites this as:
char i=0;
i<=5&&i>-1;
do {
printf("%d",i);
i>0;
} while ( (++i) != 0)
hint: remember char is signed and twos complement, so i will go 1,2,3....128, -127,-126.... 0
the loop termination condition here is ++i. There is no mystery about it. The loop will stop when i hits 0 (because the it will be 'false')

Resources