I am beginner in C and I was experimenting with for loop and I came across a infinite loop which should not be a infinite loop, can anyone help me understand why it is a infinite loop
void main()
{
int i;
for(i=1,printf("Initialization");i++ <=5,printf("\nCondition");printf("%d",i))
printf("\nInside the loop :");
}
while this is not a infinite loop
void main()
{
int i;
for(i=1,printf("Intialization");printf("\nCondition"),i++<= 5;printf("%d",i))
printf("\nInside the loop\n");
}
The reason is that your loop conditions (between two semicolons) look like this:
i++ <=5, printf("\nCondition") // First loop
printf("\nCondition"), i++<= 5 // Second loop
Both conditions are comma expressions, meaning that only the last part matters in terms of generating the value (both parts are good for their side effects, though).
In the first case, the overall condition result is what printf("\nCondition") returns. It always returns non-zero*, interpreted as "true", so the loop is infinite.
In the second case, the overall result is what i++<=5 returns, which starts off as "true", and becomes "false" after five iterations. That is when the second loop terminates.
* Specifically, printf returns the number of characters printed, so in your case that would be 10. This is not essential to understanding why the loop is infinite, though.
you have 2 conditions remember that printf returns number of characters printed and that is always non zero hence results in infinite loop
Simple comma operator realizes all side effects in operands, discards result of it's first operand, and then evaluates it's second one. So, in first snippet, althought i++ will be realized, condition <= result will be discarted, so effective condition in for will be result of printf("\nCondition"), that's 10=true. In second snippet first operand result printf(...) = 10 will be discard, and will be used as pure condition just i<=5.
Here some doc :
https://en.wikipedia.org/wiki/Comma_operator,
https://uvesway.wordpress.com/2012/11/02/c-loops-for-and-the-comma-operator/
If we write more than one condition in for loop condition portion compiler will check all conditions but it will consider the right most condition to check whether the condition is TRUE/FALSE.
In your first program you write two conditions one is i++<5,printf("\ncondition").
printf always return number of printable characters in that function.so every time printf returning 9 in your program for that only condition never become false.
But in your second program you write i++<5 is right most condition for that when ever i value becomes 5 condition becomes false so control will come out side of the loop.
If you want to check whether printf returning number of printable characters then try this.
enter code here
unsigned int a=printf("HAI");
in this case printf will return 3 to the integer variable a
Related
#include <stdio.h>
int main() {
int i = 10;
while (i++ != 0);
printf("%d", i);
}
Output: 1
I do not understand the while loop.
i is incremented until the int variable saturates (32767 when int is 16 bits long) and then starts counting up from -32.768 to zero. When i becomes zero, the while-loop stops. Because of the post increment i++, i will be one when the while loop is finished. So you get one as a result printed to your output.
Edit: Long explanation:
When executing the while condition the first time, it will be checked if 10 is not equal to 0. After this check, i is incremented to 11, next check is 11 not equal to zero, and i becomes 12. This continues until you reach the highest possible value for int. When this maximum value is incremented, you get the lowest possible value, but this is also not equal zero. So the condition is still true, but now you have a negative number, and a negative number incremented will get zero. So after some time, i becomes zero and the while condition is false and since i is incremented after this check, you will get an output of one.
The code has undefined behavior:
the while loop has an empty body consisting of a null statement ;.
hence the loop iterates doing nothing more than the side effect in the test i++ != 0.
i starts at 10 so the first test is true, i is incremented to 11 and the loop continues with the test again... i is incremented all the way to INT_MAX, which is a least 32767, but more commonly 2147483647 and incrementing i with this value has a undefined behavior because it causes a signed arithmetic overflow. What happens then is undefined, the program could stop, run an infinite loop, turn the lights off... anything is possible.
on your system, i will probably just get the value INT_MIN an no bad side effect will happen.
the loop continues, incrementing i through all the negative values...
until i finally becomes 0, making the test evaluate to false and break the loop after the side effect of ++ happens for the last time, leaving i with the value 1.
the last statement printf("%d",i); prints 1, without a newline, which may prevent the output from reaching the terminal on some legacy systems.
So depending on the system, the program can:
print 1 and exit immediately
print 1 after pause and exit
run forever and print nothing*
crash with some kind of error
cause a more of less important side effect, such as summoning aliens from Sirius to invade planet Earth...
(*) gcc -O2 compiles the posted code to a single jmp instruction on Godbolt's Compiler Explorer.
This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 6 years ago.
Prog 1:
#include<stdio.h>
int main()
{
int i=0;
while(i<=8,i++);
printf("%d",i);
return 0;
}
Prog 2:
#include<stdio.h>
int main()
{
int i=0;
while(i++,i<=8);
printf("%d",i);
return 0;
}
The output of Prog 1 is 1 and that of Prog 2 is 9.
Can someone explain whats going here. How the two codes are different?
The comma operator evaluates both of its arguments in turn, throwing away the result, except for the last. The last evaluated expression determines the result of the entire expression.
i<=8,i++ - here the value of the expression is the value of i++, which is the value of i before being incremented. It's 0 so the loop immediately terminates.
i++,i<=8 - here the value of the expression is the value of i<=8 which is 0 only when i is incremented to 9.
On a personal note: I think the second form, while somewhat comparable to a for loop, is less clear to the reader of the code than an actual for loop.
1 while ( condition )
2 statement;
3 more_code();
In the above code snippet, the statement can be executed repeatedly as long as condition is true. On each iteration of the while loop, condition is evaluated to either true or false. If it's false, the while loop ends and execution continues beyond it's scope (in this case, line 4 with more_code().
We are usually accustomed to enclosing parts of code that we want to be executed in loop with curly brackets { and }, but that is not mandatory. If we do not do so, the looping code will consist of single statement, the one immediately following the while part.
It could actually be argued that the more common situation, where we combine while with curly brackets enclosed block of code could be interpreted as providing this block of code in place of a single statement, with braces providing information that the block should be treated (by compiler analysing it's relation with preceding and following code) as if it was a single statement.
However, as it is perfectly valid to provide a single statement, not a usual block of code, it's worth to understand that there is a valid statement that is empty. We get an empty statement by typing a semicolon without preceding it with a code causing anything. So following is perfectly valid:
1 code;
2 ; // empty statement
3 ; // another empty statement
or in fact this:
1 code;; // a "code" statement followed by empty statement in the same line
The while( condition ) part is not terminated with a semicolon, so if it's supposed to control some actual code (apart from condition), it should not be followed by a semicolon. If it is immediately followed by a semicolon, that semicolon will constitute (and be so interpreted by compiler) an empty statement, so the looping code will be empty. If that's unintended, then the code we wanted to be looped, whether a block of code or a statement, will not be looped, but rather executed once, after (and if) loop ends.
1 int a = 0;
2 while ( a < 3 ) ; // Next line is not part of loop - only the empty statement this semicolon creates is. This loop is infinite, or in other words it will never end.
3 a++; // This won't be executed even once.
4 printf("This never happens.");
(It's worth realizing that lines are only important for us, humans, in C. Lines and indentation can be misleading if they represent the intentions of programmer, when he failed to write the code functioning as he wanted it to.)
Therefore what happens in both snippets from the question, is we get condition evaluated continuously until it yields false. To understand what's going on we need to examine the way comma operator works.
(Note, while comma as a character can be used with a completely different meaning in various places in C - I can think of function declarations, definitions and calls - in this case comma character is part of condition, therefore it acts as an operator - something akin to + or % operators.)
expression1 , expression2
Comma operator causes expression1 to be evaluated first, then expression2, and returns the value of expression2.
Upon every evaluation of condition, we will thus evaluate both expressions, (in this case both being operands, i++ and i<=8), then consider value of the right one as result of comma operand itself, and thus as value of our condition. So the loop will keep repeating as long as the right operand resolves as true.
While usually we use condition to control the execution of loop, often, as in this case, condition may have "side" effects (intentional or unintended). In our case variable i is affected by every evaluation of condition: it is increased by one.
Our example differs only in order of operands of condition, therefore pay attention to the right operand which really controls the execution of the loop.
Let's examine the second example first. In this case we have condition i++, i<=8. This means upon every evaluation we first increase i, then check if it's less than or equal to 8. So on first evaluation of condition we will increase i from 0 to 1 and conclude that 1<=8, so the loop continues. The loop so constructed will break when i becomes 9, ie. on the 9th iteration.
Now as for the first example, the condition is i<=8, ++i. Since comparison has no side effects, that is we could perform any number of comparisons in any order and if that's the only thing we did, that is if we did not perform any other action in a way or order dependent of results of the comparisons, those comparisons would do absolutely nothing. As is in our case, we evaluate i<=8 which evaluates to true or false, but we make no use of this result, just proceed to evaluating the right operand. So left operand absolutely doesn't matter. Right operand, on the other hand, has both a side effect and it's value becomes value of entire condition. Before each loop iteration we check if i++ evaluates to true or false.
i++ is a unary operator of post-incrementation. It returns value of i then increases it by one (the difference between i++ and ++i is subtle but crucial in cases like this one). So what happens is we first check whether i is true or false, then i is increased by one.
In C there is no boolean type. Integers are considered to be true if they have a non-zero value.
So upon first evaluation of i++ we get 0, that is false. This means the loop is broken without even a single iteration. However it does not break evaluation of i++, which causes i to increase by one before we're done with the loop and execution proceeds beyond it. So once we're done with the while loop, i is already 1.
If we want to be very precise in our understanding, the part where we take the result of evaluating entire condition happens, chronologically, after we are finished executing any code involved in this evaluation. So we first memorize that i was 0 at the point we got toward i++ part, then we increase i by one, and then we are finished executing condition, so we provide value of 0 to the code that decides if we should do another (in this case first) iteration or jump beyond looping part and move on. This is exact reason why everything within condition will actually happen even though the fact that loop will end was already determined: it was determined, but it was not checked and acted upon until condition finishes executing.
The expression separator operator , forces evaluation from left to right, and is also a sequencing point.
Prog 1: consider i <= 8, i++. i <= 8 is evaluated and discarded then i++ is evaluated. The entire expression has the unincremented value of i. Since i is initially 0, the while loop terminates on the first iteration. The output will be that singly incremented value of i, i.e. 1.
Prog 2: i++ is evaluated and the result discarded, then i <= 8 is evaluated with the new value of i since , is a sequencing point. So the while loop runs until i <= 8 is no longer true with the incremented value of i. The output will be 9.
can anyone explain the working of the for loop in the following code:
#include<stdio.h>
#include<conio.h>
int main()
{
char i=0;
for(i<=5&&i>=-1;++i;i>0)
printf("%d\n",i);
getch();
}
Let's break the for statement down, we have three phases, the initialiser, the test, and the modifier:
for(<Initialiser>; <Test>; <Modifier>)
<content>;
In your case:
for(i<=5&&i>=-1;++i;i>0)
// initialiser: i<=5&&i>=-1;
// test: ++i;
// modifier: i>0
The initialiser is done first. Here no assignment is done. Two boolean expressions (denoted by the >= and <= operators are compared in a logical &&. The whole initialiser returns a boolean value but it doesn't do anything. It could be left as a blank ; and there would be no change.
The test uses the pre-increment operator and so returns the result of i+1. If this result is ever 0 it evaluates as false and the loop will terminate. For any non-zero value it evaluates to true and continues. This is often used when i is initialised to a value less than zero and so the test will increment i until i+1 results in a zero, at which point the loop terminates.
Finally we have the modifier, which in this case simply uses the > operator to evaluate to a boolean value. No assignment is done here either.
The fact is that you've gotten the test and the modifier confused and put them in the wrong positions but before we sort that out let's see how it would work…
We begin with:
char i = 0;
…and for all intents and purposes this does the same thing as our for loops initialiser would do in normal circumstances. The next thing to be evaluated is the for loop's initialiser:
i<=5 && i>=-1;
Because i is 0 it is less-than-or-equal-to 5 and it is greater-than-or-equal-to -1. This expression evaluates to 1 but nothing is done with that value. All we've done is waste a bit of time with an evaluation.
Next up is the modifier to test whether or not the for loop's inner block should be executed:
++i;
This evaluates to 1 and also assigns that value to i. Now, as it's evaluated to a non-zero number, the loop executes:
printf("%d\n",i);
And the digit 1 is printed to the screen... Now it's the modifier that gets executed:
i>0
Well, i is 1 so that is greater-than 0. This evaluates to 1 (or true). Either way, this is ignored. The purpose of the modifier isn't to test or check anything. It's there so that you can change the state of the program each time the for loop iterates. Either way, the loop repeats and it will do this for a very long time. Why? Because ++i is going to evaluate to a non-zero number for a while. Whether or not it will ever terminate depends on how your system deals with integer overflows.
This is what you meant to do:
#include<stdio.h>
#include<conio.h>
int main()
{
for(char i=0; i<=5&&i>=-1; ++i)
printf("%d\n",i);
}
Do you see the difference? Our initialiser now starts the loop with the state of i as zero. We then test if it's within the bounds of -1 to 5 and each time we iterate we increment i by 1. This loop will output:
0
1
2
3
4
5
This snippet:
for(i<=5&&i>=-1;++i;i>0)
printf("%d\n",i);
Does the same as this:
i<=5 && i>=-1; //statement with no effect
while(++i)
{
printf("%d\n",i);
i>0; //statement with no effect
}
So, it's going to print i until ++i evaluates to 0. This will happen after i overflows and becomes negative, then incrementing towards 0. That will take 255 iterations to happen, since chars can store up to 256 different values.
for ( variable initialization; condition; variable update ) {
}
the variable initialization phase is done only once when the for loop starts.
the condition is checked everytime before running code inside the loop. if the condition is false then the loop is exited.
the variable update is done after the first iteration, from the second iteration it is done before the condition check.
I am experimenting about what can be put into a for loop declaration in C and how it can be used. I tried the following:
#include <stdio.h>
int stupid(int a)
{
if(a == 3)
return 1;
else
return 3;
}
int main(void)
{
int i, j;
for(i=0; stupid(i)==3,i<10; i++)
printf("%d\n", i);
return 0;
}
When I run the program it just prints the number from 1 to 10, and if I use && instead of comma between the stupid(i)==3 and i<10, then the program just prints the numbers up to 3. Why?
I don't really understand how this works and I was expecting the loop to pass all numbers and "skip" 3, but continue up to 10 and that's not really happening. Why does this happen? Is there some site where this is more clearly explained?
The second clause in the for loop (in your case stupid(i)==3,i<10) is a conditional that is evaluated prior to each entry of the loop body. If it evaluates to true then the loop body is executed. If it evaluates to false then the loop ends and execution continues after the loop body.
With the comma (stupid(i)==3,i<10), the code evaluates stupid(i)==3, forgets the result, and then evaluates i<10, and uses that result for the loop condition. So you get the numbers from 0 to 9.
stupid(i)==3 && i<10 will evaluate to true only if both parts of the expression are true, so when i=3, stupid(i)==3 is false, and the loop exits.
The comma operator evaluates the part before the comma, discards the result, evaluates the part after the comma, and returns that. So in your for loop the part after the comma is i < 10 and this is what is returned as condition for the for loop. That is why it prints the numbers 1 to 10 if you have the comma operator in it.
If you put the && operator in it, it means that both conditions before and after the && have to be met. Otherwise the loop terminates. So if i == 3 the left part evaluates to false and your loop ends.
The comma operator evaluates both, but then overall returns the value of its second operand. Since stupid() doesn't have any side effects, that means nothing much of use really happens here and you're overall just checking to see if i<10.
When you change it to && then both functions must return true (non-zero) for the iteration to continue. On the first pass through, on which the statement evaluates to false, the for loop halts and control continues past it.
The for loop will only continue if the conditions are met. If you place an if statement within the for loop to verify that stupid(i) is equal to three, the for loop will continue.
Using the , operator expands to each line being run. The last line is expected to return a Boolean expression that indicates whether the next iteration should be executed.
In this case, while stupid() does get called, it only checks the return value from the expression i < 10 to decide further execution.
In the for loop, there are three expressions needed, and they are separated by semicolons.
The first is an initializer, and it is run one time before the loop starts. It usually initializes the loop variables.
The second is a condition, and it is run right after the initializer and then before each subsequent iteration. If it is true, the loop statements are run. If it is false, the loop is over.
The third is an expression that is run right after each iteration and right before the condition is checked before the next iteration. It usually progresses the loop by changing the loop variable.
Your condition stupid(i)==3,i<10 uses the comma operator. The comma operator runs each side, but it returns only the value of the right hand side. The value of stupid(i)==3 is completely ignored. The condition stupid(i)==3 && i<10 is true only if both sides are true.
Remember, when the condition is false, the loop is over -- the iteration is not just skipped, the entire loop is over. To get what you want, use
for(i=0; i < 10; ++i) {
if (stupid(i)==3) {
printf("%d\n",i);
}
}
This will go through 0-9, but skip the code if stupid(i) is not 3.
Use:
int main(void)
{
int i,j;
for(i=0; i<10; i++, i+=i == 3)
printf("%d\n", i);
return 0;
}
The limit condition on can only terminate the loop when the condition comes true, not skip iterations. If you want to skip some value, you have to do it at the counting part of for(), or do this with if().
i+=i==3 adds 1 to i when i becomes 3, as i==3 evaluates to 1 if the condition is met and to 0 otherwise (and adding 0 simply does not make any difference).
What is the difference between while loop and do while loop. I used to think both are completely same.Then I came across following piece of code:
do {
printf("Word length... ");
scanf("%d", &wdlen);
} while(wdlen<2);
This code works perfectly. It prints word length and tascans the input. But when I changed it to
while(wdlen<2){
printf("Word length... ");
scanf("%d", &wdlen);
}
It gives a blank screen. It do not work. So there is some functional difference between both loops. Can anybody explain it?
Is there any other difference in these two?
The do while loop executes the content of the loop once before checking the condition of the while.
Whereas a while loop will check the condition first before executing the content.
In this case you are waiting for user input with scanf(), which will never execute in the while loop as wdlen is not initialized and may just contain a garbage value which may be greater than 2.
While : your condition is at the begin of the loop block, and makes possible to never enter the loop.
Do While : your condition is at the end of the loop block, and makes obligatory to enter the loop at least one time.
do {
printf("Word length... ");
scanf("%d", &wdlen);
} while(wdlen<2);
A do-while loop guarantees the execution of the loop at least once because it checks the loop condition AFTER the loop iteration. Therefore it'll print the string and call scanf, thus updating the wdlen variable.
while(wdlen<2){
printf("Word length... ");
scanf("%d", &wdlen);
}
As for the while loop, it evaluates the loop condition BEFORE the loop body is executed. wdlen probably starts off as more than 2 in your code that's why you never reach the loop body.
do while in an exit control loop.
while is an entry control loop.
While:
entry control loop
condition is checked before loop execution
never execute loop if condition is false
there is no semicolon at the end of while statement
Do-while:
exit control loop
condition is checked at the end of loop
executes false condition at least once since condition is checked later
there is semicolon at the end of while statement.
The difference is in when the condition gets evaluated. In a do..while loop, the condition is not evaluated until the end of each loop. That means that a do..while loop will always run at least once. In a while loop, the condition is evaluated at the start.
Here I assume that wdlen is evaluating to false (i.e., it's bigger than 1) at the beginning of the while loop, so the while loop never runs. In the do..while loop, it isn't checked until the end of the first loop, so you get the result you expect.
Do while loop will be executed atleast once.......but while loop will check the condition first and then it may or may not get executed depending on the condition.
In your example wdlen may assume any garbage value which is > 2 so while loop will never get executed.
whereas do while loop will be ececuted and will tell u to enter the value and check that value in terminating condition
while(wdlen<2){
...
}
If wdlen (assuming it's a stack variable) is not initialized or assigned a value before the while loop is entered, it will contain whatever was in that space in memory before (i.e. garbage). So if the garbage value is < 2, the loop executes, otherwise it doesn't.
do{
...
}while(wdlen<2)
will execute once and then checks on condition to run loop again, and this time it might succeed if by chance wdlen which is uninitialized is found to be less than 2.
Probably wdlen starts with a value >=2, so in the second case the loop condition is initially false and the loop is never entered.
In the second case the loop body is executed before the wdlen<2 condition is checked for the first time, so the printf/scanf is executed at least once.
while test the condition before executing statements within the while loop.
do while test the condition after having executed statement within the loop.
source: let us C
while test the condition before executing statements in the while loop.
do while test the condition after having executed statement inside the loop.
In WHILE first check the condition and then execute the program
In DO-WHILE loop first execute the program at least one time then check the condition
The difference between do while (exit check) and while (entry check) is that while entering in do while it will not check but in while it will first check
The example is as such:
Program 1:
int a=10;
do{
System.out.println(a);
}
while(a<10);
//here the a is not less than 10 then also it will execute once as it will execute do while exiting it checks that a is not less than 10 so it will exit the loop
Program 2:
int b=0;
while(b<10)
{
System.out.println(b);
}
//here nothing will be printed as the value of b is not less than 10 and it will not let enter the loop and will exit
output Program 1:
10
output Program 2:
[nothing is printed]
note:
output of the program 1 and program 2 will be same if we assign a=0 and b=0 and also put a++; and b++; in the respective body of the program.
While Loop:
while(test-condition)
{
statements;
increment/decrement;
}
Lower Execution Time and Speed
Entry Conditioned Loop
No fixed number of iterations
Do While Loop:
do
{
statements;
increment/decrement;
}while(test-condition);
Higher Execution Time and Speed
Exit Conditioned Loop
Minimum one number of iteration
Find out more on this topic here: Difference Between While and Do While Loop
This is valid for C programming, Java programming and other languages as well because the concepts remain the same, only the syntax changes.
Also, another small but a differentiating factor to note is that the do while loop consists of a semicolon at the end of the while condition.
The difference between a while constructs from Step 1 versus a do while is that any expressions within the do {} will be running at least once regardless of the condition within the while() clause.
println("\nStep 2: How to use do while loop in Scala")
var numberOfDonutsBaked = 0
do {
numberOfDonutsBaked += 1
println(s"Number of donuts baked = $numberOfDonutsBaked")
} while (numberOfDonutsBaked < 5)
Here is detail explaination: Explanation
Visit: coderforevers
The most important difference between while and do-while loop is that in do-while, the block of code is executed at least once, even though the condition given is false.
To put it in a different way :
While- your condition is at the begin of the loop block, and makes possible to never enter the loop.
In While loop, the condition is first tested and then the block of code is executed if the test result is true.