Why does the print statement not get executed at all? - c

This is the program:
#include<stdio.h>
int main()
{
int i=(-5);
while(i<=5){
if (i>=0){
break;
}
else{
i++;
continue;
}
printf("hello\n");
}
return 0;
}
My question is, why does 'hello' not get printed at all?

Because you have used continue incorrectly. It basically stops the line that is after it and goes to the condition checking part of the while loop. That's why it doesn't print hello.
From standard $6.8.6.2
A continue statement causes a jump to the loop-continuation portion of
the smallest enclosing iteration statement; that is, to the end of the
loop body.

You have a single if else statement. Everything that happens inside that loop will happen inside the if or the else. In your particular case, it will execute the else statement until 'i' is 0(the continue makes it so that it goes back to the loop condition, but in your case the continue is completely unnecessary because it's the last statement in the else), then it will execute the if and break out of the loop

Stepping though the loop, we have
1st pass i == -5, if condition false, else branch taken, i incremented to -4, continue to start of while loop
2nd to 4th pases same for i == -4 to i == -2
5th pass i == -1, if condition false, else branch taken, i incremented to 0, continue to start of while loop
6th pass i == 0, if condition true, break from while loop, return 0 from main
Neither of the if branches cause the flow to pass through the printf line.

The reason why printf() statement will never execute is because you had break statement in if and continue statement in else. Both statement are useful to break or skip the flow of execution of program.
Click here to learn when to use those statements.
Now, here i is initialized with -5. So until i reaches the value 0, else() part of the code will be executed. Else has continue statement, that will skip all the following statements and start next iteration. So, printf() statement will be skipped every time.
Once i will be incremented up to 0,if() part of code will be executed. If() has break statement that will break the loop and execution of the program will be over by main() returning 0 as there are no more statements following loop other than return 0.
Hope it'll be helpful.

Related

Why printf() in while() as a condition prints different output

First code
#include<stdio.h>
int main()
{
while(printf("Hello"))
return 0;
}
Produces only Hello as a output
Second code
#include<stdio.h>
int main()
{
while(printf("Hello"));
return 0;
}
Second code prints Hello for infinite times.
Third code
#include<stdio.h>
int main()
{
while(printf("Hello"))
{}
return 0;
}
Third code also prints Hello for infinite times.
Compiler used - GCC 9.0.1
why this is happening?
while takes a statement after the closing ).
6.8.6 Iteration statements
iteration-statement:
while ( expression ) statement
....
In
while(printf("Hello"))
return 0;
that statement (which is basically while's argument) is return 0; (6.8.6)
In
while(printf("Hello"));
the statement is ; (an empty (null)/expression statement (6.8.3)).
In
while(printf("Hello")){}
it's an empty compound statement ({}, 6.8.2), which is semantically equivalent to ;.
Your code snippets are examples of misleading whitespace—where the whitespace makes humans understand things differently from a compiler.
Less misleading renderings would be:
while(printf("Hello"))
return 0;
,
while(printf("Hello"))
; //or perhaps a {} instead of the null statement
and
while(printf("Hello"))
{}
printf returns number of characters printed (which is 5). Any non zero number evaluates to true. So the loop is an infinite loop.
The rest depends on what happens withing the loop. In the second and third cases, the loops are empty (contain no statements) so they keep executing
In the first case, return 0 is executed within the loop. Return breaks the control flow out of the loop causing the loop (and in this case the program) to stop executing
In your first code snippet, the return 0; statement is part of the while loop's 'body'; in fact, it is the entirety of that body! So, on the first run through that loop, the program exits (because that what return 0; does when executed in main) and the loop is, thus, abruptly terminated.
In the second and third snippets, you have an empty body for the loop, but that does not prevent it from running, as the printf("Hello") function call will return the number of characters that were output - which will be non-zero, and thus interpreted as "true".
In the first one the body of the while is the return 0 so it will return after the first iteration. Meanwhile with the other two version is the same, having an empty body so they infinitely going on doing nothing but the condition is keep evaluating which will print "hello".
while(printf("Hello"))
return 0;
is same as
while(printf("Hello"))
{
return 0;
}
First Code:
printf("Hello") returns the number of characters.
When printf("Hello") is used inside while loop it will print Hello and return 5.
Since it is greater than 0 while loop consider this as true and execute the statement below the while, which is return 0.
The return 0 makes the main function to return 0 and stop the exeution.
The code
while(printf("Hello"))
return 0;
is same as
while(printf("Hello"))
{
return 0;
}
Second Code:
Since you used ; after while() ,it will not execute the statement after ;.
So the statement return 0 is not executed and while checks the condition infinite times printing infinite Hello.
Third code:
While will execute the statements only within the { }.
Since its empty every time after searching for statement it will go back and check the condition.
Since the condition is always true it will not reach the return 0 and it will print Hello infinite times.

C loop while - beginner

My first question here on forum. I'm not sure why the output of the code is "hi" whereas I'm thinking it should be null. I might be missing here something badly. Help appreciated.
#include <stdio.h>
int main(void)
{
int i = 0;
while (i == 0)
{
printf("hi\n");
i++;
}
}
Your while loop will run what you have enclosed in it up until the stopping condition is false. you have int i = 0 as your starting value and your while loop condition says while (i == 0) to print "hi". Since i = 0, your condition is true one time and will print "hi" once before i increments and becomes false on the next pass.
The output of your code is correct, the while loop is entered because i == 0 and then i changes to 1 so the condition is false on the second iteration which makes the loop end and thus the program too.
You are confusing while loops with until loops (which C doesn't have). The while loop will execute its body while a condition is true, not until it is true. So if you want to print "hi" 10 times, you will need to write
int i = 1;
while (i <= 10) {
printf("hi\n");
++i;
}
#include <stdio.h>
int main(void)
{
int i = 0;
while (i == 0)
{
printf("hi\n");
i++;
}
}
while loop works in such a way that the loop executes only if the condition inside the parenthesis is true. In the above code, the value of 'i' is initially set to 0, which satisfies the condition of the while loop. It enters inside the loop, goes on to print 'hi' and then increments the value of 'i'.
Now the condition of while is again checked. Since the condition fails this time ,as the value of 'i' has been incremented, it exits out of the loop and the program terminates. I hope it answers your question.
like #iharob said, i==0 returns 1 which creates an infinite loop running and printing hi hi hi hi hi
if i was to do them, I would put in an if statement inside the while loop to check if i is still 0 or changed. if its 0, print hi, else, return 0;
it is obvious that the syntax that your are looking for is a do ... while loop
because programs run from up to down and left to right, the moment that your program reaches the while checks the i and it is still 0 but for the next loop it won't print anything because i=1.

Why is 'continue' statement ignoring the loop counter increment in 'while' loop, but not in 'for' loop?

Why does it tend to get into an infinite loop if I use continue in a while loop, but works fine in a for loop?
The loop-counter increment i++ gets ignored in while loop if I use it after continue, but it works if it is in for loop.
If continue ignores subsequent statements, then why doesn't it ignore the third statement of the for loop then, which contains the counter increment i++? Isn't the third statement of for loop subsequent to continue as well and should be ignored, given the third statement of for loop 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
...
}
Because continue goes back to the start of the loop. With for, the post-operation i++ is an integral part of the loop control and is executed before the loop body restarts.
With the while, the i++ is just another statement in the body of the loop (no different to something like a = b), skipped if you continue before you reach it.
The reason is because the continue statement will short-circuit the statements that follow it in the loop body. Since the way you wrote the while loop has the increment statement following the continue statement, it gets short-circuited. You can solve this by changing your while loop.
A lot of text books claim that:
for (i = 0; i < N; ++i) {
/*...*/
}
is equivalent to:
i = 0;
while (i < N) {
/*...*/
++i;
}
But, in reality, it is really like:
j = 0;
while ((i = j++) < N) {
/*...*/
}
Or, to be a little more pedantic:
i = 0;
if (i < 10) do {
/*...*/
} while (++i, (i < 10));
These are more equivalent, since now if the body of the while has a continue, the increment still occurs, just like in a for. The latter alternative only executes the increment after the iteration has completed, just like for (the former executes the increment before the iteration, deferring to save it in i until after the iteration).
Your increment of i is after continue, so it never gets executed
while(i<10) //causes infinite loop
{
.........
continue
i++
......
}
In any loop, continue moves execution back to the top of the loop, not executing any other instructions after the continue statement.
In this case, the for loop's definition is always executed (per standard C), whereas the i++; statement is NOT executed, because it comes AFTER the continue statement.
Because the third part of the for is always executed.
continue statement jumps the control to the end of the statements in current iteration of loop i.e. it skips the execution of the statements in the current iteration and moves to the next iteration of the loop.
With while loop, continue statement causes control to reach the end of statements (including increment statement), thus causing loop to continue forever.
With for loop, continue statement jumps the control to end of statement and excutes the increment statement (In for loop, increment statement is considered seperate from the statments written within the body of the loop).
for loop holds condition statements and increment, so when the condition is satisfied it goes to execute the statement inside for loop,but if write continue statement than it will again reached to first line of for loop i.e. increment and checking of condition statement, if satisfied than again comes in for execution.
For while loop it just checks the condition statement and if condition satisfied it goes for the execution of statements in the while loop.
so continue will not execute any line after it.and hence your condition satisfied every time and goes for the infinite loop.
continue bypasses the rest of the block and begins again at the top of the block if the conditional of the loop is met.
The next question is: "What do I do, then?"
There are two answers I can think of.
Example:
void foo ()
{
size_t i = 0;
do
{
/*...*/
if ( /*...*/ )
{
/*...*/
continue;
}
/*...*/
i++;
} while ( /* loop conditional */ );
}
Solution #1: Manually Increment
void foo ()
{
size_t i = 0;
do
{
/*...*/
if ( /*...*/ )
{
/*...*/
i++;
continue;
}
/*...*/
i++;
} while ( /* loop conditional */ );
}
Solution #2: A uniquely valid application of goto*
void foo ()
{
size_t i = 0;
do
{
/*...*/
if ( /*...*/ )
{
/*...*/
goto foo_next;
}
/*...*/
foo_next:
i++;
} while ( /* loop conditional */ );
}
goto is valid in this case because incrementation in two places is technically the same instruction. This solution is especially relevant when the per-iteration-volatile variables are more complex; such as, setting multiple variables or modifying a value with an equation or function.
In the event of a single increment or decrement statement, Solution #1 may prove favorable; however, it should be noted that: if the code is modified after such an implementation, one must remember to update both instances of the statement (which may be prone to bugs, especially if the modifications take place after an extended period of time**). Therefore, I highly reccomend Solution #2.
*Some consider any and all use of goto bad practice. I recommend you decide for yourself, and leave you this: google for "c goto bad"
**A comment reminding of this necessity may suffice, but — if my advice has been followed — the per-iteration-volatile variables in are restricted to a single statement. And I quote:
There is never a reason to comment a single line
-Linus Torvalds (source: http://yarchive.net/comp/linux/coding_style.html)

Condition in a 'for' loop

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

Difference between "while" loop and "do while" loop

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.

Resources