Not able to understand the output of C program - c

There's this code in C
int fun()
{
static int num = 40;
return num--;
}
int main()
{
for(fun(); fun(); fun())
{
printf("%d ", fun());
}
getchar();
return 0;
}
the output comes out to be: 38 35 32 29 26 23 20 17 14 11 8 5 2
I'm not able to figure out why the program doesn't continue to print beyond 2. i.e. in the negatives .shouldn't it continue printing ... -1 -4 -7....infinite loop Can anyone explain ?

fun() is evaluating to 0 here:
for(fun(); fun(); fun())
// ^
0 is the equivalent of false in C, so the loop is exiting.
The code relies on the fact that num - 1 is a multiple of 3, as fun() is evaluated once at the start of the loop and then 3 times every loop. If, for example, you changed the definition to
static int num = 41;
fun() would return 0 in the wrong place and your loop would continue into the negative numbers.

The whole magic happens inside your for() loop.
The basic format is like this:
for (<pre-iteration>; <condition>; <post-iteration>)
<code>
Code inside pre-iteration will be executed once before the first iteration/loop.
Code inside condition is evaluated before each and every iteration. If the resulting value is true, the loop continues, if it's false, the loop is left.
Code inside post-iteration is executed after each and every iteration.
To make the whole code easier to understand, it's important to know that you're able to write such a for() loop using a while() loop as well:
<pre-iteration>
while (<condition>) {
<code>
<post-iteration>
}
Back to your example:
for (fun(); fun(); fun())
{
printf("%d ", fun());
}
Using a while() this can be written like this:
fun();
while (fun()) {
printf("%d ", fun());
fun();
}
Since fun() will return the value of the static value num and then decrement it by 1 the first iteration will look like this:
// This is going to be the first call, so the static variable is initialized: num = 40
fun(); // returns 40; num = 39
while (fun()) { // returns 39; num = 38 (true -> loop continues)
printf("%d ", fun()); // returns 38; num = 37 (-> 38 is written to console)
fun(); // returns 37; num = 36
}
The next iteration (code before the loop is no longer executed for obvious reasons):
fun(); // no longer executed
while (fun()) { // returns 36; num = 35 (true -> loop continues)
printf("%d ", fun()); // returns 35; num = 34 (-> 35 is written to console)
fun(); // returns 34; num = 33
}
This continues till the last iteration:
fun(); // no longer executed
while (fun()) { // returns 0; num = -1 (false -> loop exits)
printf("%d ", fun()); // no longer executed
fun(); // no longer executed
}
I'm not able to figure out why the program doesn't continue to print beyond 2. i.e. in the negatives .shouldn't it continue printing ... -1 -4 -7....infinite loop Can anyone explain ?
Yes, it might continue, but only if that specific call to fun() wouldn't return 0, i.e. set the initial value of num to 41 and the program will run indefinitely (or at least till the return value happens to be 0 at some point).

Let's look at what happens in the second call to fun() in the for loop. The first time the loop is entered, fun() has been evaluated once already, so num is 39. The second time we get to the loop, fun() has been executed three more times, so it is now 36. This process continues, until eventually, the second call to fun() returns 0. In C, 0 means false, so the loop terminates at that stage.

When
printf("%d ", fun());
is run, fun() has value 2
Then the last fun() in the next command is executed to increase the counter (normally):
for(fun(); fun(); fun())
fun() is 1.
Then the condition to continue the for loop is performed, which is the second fun() in:
for(fun(); fun(); fun())
At this point, fun() is 0 which makes the for loop stop.

for(fun(); fun(); fun())
second part of for() loop is a condition - if fun() returns 0, which is interpreted as false, the loop terminates. lately i got a brain fart and wrote a statement that condition is true only for positive numbers.

When you print fun(), you do not see the actual value of num, but the value of num+1.
This is because you are using a postfix-decrement (num--) and not a prefix-decrement (--num).
So when you 2 is printed, the actual value of num is 1.
At the end of this iteration, fun() is invoked, setting num to 0.
At the beginning of the next iteration, num is evaluated as false and the for loop is terminated.

Related

what is the diffference between adding a return keyword during recursive function call and not adding return keyword?

int main ()
{
static int i = 5;
if (--i)
{
return main();
}
printf("%d", i);
return 0;
}
output: 0
int main()
{
static int i = 5;
if (--i)
{
main();
}
printf("%d", i);
return 0;
}
output: 0 0 0 0 0
int main()
{
static int i = 5;
if (--i)
{
main();
printf("%d", i);
}
return 0;
}
output: 0 0 0 0
why does return keyword cause this behaviour ?
and why does snippet 3 produce the a different ouput ?
Please explain in detail.
In the version with return, when the program starts i is initialized to 5. It decrements i to 4. This is non-zero, so the if block is entered.
It executes return main(). This calls main recursively, and when that returns, we exit the program (never executing the printf() call).
In the recursive call to main(), we decrement i to 3. This is also non-zero, so the if block is entered.
It executes return main(). This calls main recursively, and when that returns, we return from this call, again not executing the printf() call.
The same thing happens when i is decremented to 2 and 1, so I won't describe them.
Finally, we enter main() when i is 1. We decrement it to 0. This is 0, so the if block is not entered. We continue with the rest of the function and execute printf("%d", i);, which prints 0. Then the function returns.
Each of the previous recursive calls then return as well, so nothing else is printed.
In the version without return, everything is the same except the functions don't return immediately after the recursive calls return. They continue to the printf() statement. But these all happen after all the recursive calls have happened, so i == 0 when each of them calls printf(), and you get 5 0's.
In the third version, the printf() call is inside the if block. It's similar to the second version, but it only prints 0 in the cases where --i != 0. So it prints 0 after each recursive call, but not inside the final call, because that one skips over the if block. So it prints 0 one less time than the second version.

Function call in for loop and static variable

#include <stdio.h>
int main() {
int r() {
static int num = 7;
return num--;
}
for(r(); r(); r())
printf("%d",r());
return 0;
}
The output is 52. How i m getting the output is out of my knowledge this question what i had learned about static went totally wrong.
First time you run r() it will return 7, next time 6 and so on.
The for loop will stop when r() value is 0.
The code flow is:
r() // 7 [1st expression in the for loop]
if (!r()) stop for loop; // 6, so goes into for loop [2nd expression in the for loop]
print (r()) // 5
r() // 4 [3rd expression in the for loop]
if (!r()) stop for loop // 3, continues again
print (r()) // 2
r() // 1 [3rd expression in the for loop]
if (!r()) stop for loop // 0 so exits the for loop
It first prints 5, then 2 (without newlines), hence the output is 52.
#include <stdio.h>
int r(){
static int num = 7;
return num--;
}
int main()
{
for(r();r();r())
printf("%d",r());
return 0;
}
the static var is like a global var (I mean not in the stack) but only visible for the function r
the result is 52 because it prints 5 then 2
the initial value of num is 7
the for call a first time r (init part of the for), so num is decremented to be 6 and r returns 7 for nothing,
the test is performed and num is again decremented to be 5 and because 6 is return and is not 0 the for continue,
now the print is done with again a call decrementing num to 4 with the result 5 being printed
r called (modif part of the for) decrementing num to 2 and returning 3 for nothing
again the test decrementing num to 2 and returning 3 != 0 the loop continue
again the print is done with again a call decrementing num to 1 with the result 2 being printed
r called (modif part of the for) decrementing num to 0 and returning 1 for nothing
the test is performed and num is again decremented to be -1 and because 0 is return by r the loop stops

Why the Semicolon is not emptying the loop body?

The semicolon at the end of the for loop is suppose to empty the body and create a null loop. But why this is printing 6?
void main()
{
int i;
for(i=1;i<=5;i++);
{
printf("%d\n",i);
}
}
The loop body is empty, otherwise it would print 1, 2, 3, 4, 5. But the loop head runs nethertheless and in each iteration it increases i. When it reaches 6 which is not <=5 the loop ends. Printing i after the loop prints i as 6. Incrementing i is a side effect of the loop.
It is.at the end of the loop i will be 6 and the printf does this.
The for loop for(i=1;i<=5;i++); will run exactly 5 times, incrementing i from 1 to 6 (even though the for loop body is a no-op). Thus, in here:
{
printf("%d\n",i);
}
the program will print the current value of i, that is 6.
Because you declare the int outside the null loop, the value is saved outside the increment loop.
Read more about it here
The extra brackets do not do anything here because the semicolon exits the loop.
Read more about brackets here.
Try this for fun
#include <stdio.h>
int main(void)
{
int i;
for (i = 1; i <= 5; i++) /* void */;
/* floating block one */
{
int i = 42; /* new i, hides old i */
printf("%d\n",i);
}
/* floating block two */
{
printf("%d\n",i);
}
}
it is quite simple:
for(i=1;i<=5;i++); will be executed 5 times, from 1 to 5
then i=6 ends the for loop and then a new "scoped" statement is executed:
printf("%d\n",i);
therefore prints 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++)) ;

After recursion call the next printf automatically prints the incremented values

I came across the strange thing in recursion, please go through the below code in printing numbers in descending order.But sooner it completes recursion and executes next printf statement it increments automatically without increment statement in the program.
int main()
{
int count=10;
counter(count);
}
int counter(int count)
{
if(count>0)
{
printf("%d\n",count);
counter(count-1);
printf("%d",count) //THIS STATMENT MAKES THE VALUE INCREMENT
//AFTER THE RECURSION
}
}
output:
10
9
8
7
6
5
4
3
2
1
1 //2nd printf results in increment without any increment operator
2
3
4
5
6
7
8
9
10
When you call
counter(count-1);
the new invocation of the function is called with the value of counter-1 but the value of counter in the current invocation of the function does not change. Hence, when the function returns, the next call to printf prints the value of counter.
If you visualize the call when count is 2, you get
printf("%d\n",2);
counter(1);
printf("%d\n",2); // I am assuming you have \n there.
If you expand the call to counter(1), you get:
printf("%d\n",2);
printf("%d\n",1);
counter(0);
printf("%d\n",1);
printf("%d\n",2);
counter(0) does not print anything. It returns without doing anything. Hence, that block of code is equivalent to:
printf("%d\n",2);
printf("%d\n",1);
printf("%d\n",1);
printf("%d\n",2);
If you start from a higher number, like 10, you get:
printf("%d\n",10);
printf("%d\n",9);
...
printf("%d\n",2);
printf("%d\n",1);
printf("%d\n",1);
printf("%d\n",2);
...
printf("%d\n",9);
printf("%d\n",10);
That explains the output.
Your answer is not accurate to explain the answer.
It will still increase the after you change the value counter directly
int main()
{
int count=10;
counter(count);
}
int counter(int count)
{
if(count>0)
{
count = count-1
printf("%d\n",count);
counter(count);
printf("%d",count) //THIS STATMENT MAKES THE VALUE INCREMENT
//AFTER THE RECURSION
}
}
above code will still make some same output with a little changing

Resources