Interchanging statements in for loop - c

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')

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.

An example of for loop in C leading to an infinite loop

The following program was cited as going into an infinite loop:
#include<stdio.h>
int main()
{
int n;
for(n = 7; n!=0; n--)
printf("n = %d", n--);
getchar();
return 0;
}
On analyzing, I do find that at one point the value of n does become 0 and right then, the loop should terminate.
Won't it happen such that when it enters the loop for the first time, the value is 7, then it becomes 6, and since that there are 2 post-decrements per iteration?
But, why does that not happen?
Each loop iteration actually decreases n by two, and the comparison n != 0 always sees an odd value for i and hence never terminates.
In particular, just before the iteration in question, n is first decremented to 1 by n-- in the loop header (since this must occur after the end of the previous iteration, just before evaluation of the condition n!=0).
Then, printf("n = %d", n--); is evaluated, printing n = 1, while postdecrementing n to zero. After the end of the loop body, n is decremented again by n-- in the loop header, making it -1, just before the condition n!=0 is evaluated to determine whether the loop should continue.
As a result, n!=0 is true every time it is evaluated (in particular, it is not evaluated at the instant that n is zero, since the n-- in the loop header must first complete)
It's because of the second decrement in the print here:
for(n = 7; n!=0; n--)
printf("n = %d", n--);
That makes the sequence of checks against n go 7, 5, 3, 1, -1, ... There are an even number of values for an int so this will form a cycle upon underflow that leaves out the even numbers, including 0.
Remember that the for loop condition is evaluated just before each loop iteration, and after the decrement in the loop itself. It isn't tested while the loop is running.
try doing this
#include<stdio.h>
int main()
{
int n;
for(n = 7; n>=0; n--)
printf("n = %d", **--n**);
getchar();
return 0;
}

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 this isn't an infinite loop? How is it working?

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++)) ;

What is the output of the following code and how?

I can't understand the logic of the for loop in the function fun:
long fun(char* s)
{
long r=0;
for(;*s; r=(r<<1)|(*s++ - '0'));//explain this
return r;
}
int main()
{
printf("%d ",fun("000001010"));
}
for(;*s; r=(r<<1)|(*s++ - '0'));//explain this
is:
int r=0;
while(*s){
int m=*s-'0';
r=r*2 + m;
++s;
}
As commented above It will parse(convert) your binary string to number
It is more or less equivalent to this:
long r = 0;
for(size_t i=0; i<strlen(s); i++) // Traverse the string
{
r = r<<1; // Shift the long representation
if( s[i] != '0' ) // Is current char 0 or 1
{
r = r | 1; // It is 1: append it to long representation
}
}
The structure of a for loop is the following:
Before the first semi-colon you define and/or initialize any values related to the loop
between the two semi-colons lies the logic that is checked at the start of each loop, if it is true the loop goes on
The code after the second semi-colon executes after the loop body is finished
So in your for loop there is nothing before the first semi-colon, nothing needs to be initialized, that's normal.
The *s will be true (different than 0) for as long as the ASCII value stored there is different than '0', that it the string termination character. So it's the same as saying strlen(s)!=0
r=(r<<1) performs a bitwise operation on r.
*s++ - '0' subtracts the character '0' from the character pointed to by s and then increments the pointer to point to the next character
This for loop will run number of times, the characters inputed in fun() function parameters, e.g. here 9.
The value of r will be decided by the bitwise operation (r<<1), subtraction (*s++ - '0') and the orring operation | of these two previous operations.
for first five iterations, value of the r will be 0, as leftshift operation on 0 will yeild 0 and ASCII value subtraction of the characters will also come as 0.
for 6th iteration, subtraction will bear value 1, and subsequently r will have 1.
for 7th iteration, leftshift operation (multiplication by 2) will have output 2, so r=2.
for 8th, leftshift operation will have output 4 and subtraction 1, so orring of (1 | 4) will have 5.
and for last iteration, leftshift operation will yeild o/p 10.
So finally You should get 10 as o/p.

Resources