static storage class working in c - c

I'm a beginner so please bear with me. Recently, I started reading storage classes in C and I stumbled upon this question:
‪
#‎include‬<stdio.h>
int fun()
{
static int num = 16;
return num--;
}
int main()
{
for(fun(); fun(); fun())
printf("%d \n", fun());
return 0;
}
This program outputs : 14 11 8 5 2.
1) Can any please tell me how does this code work?
2) When I keep --num in fun() ,it is running an infinite loop. Why it happens like that?

static int num = 16; means that num will be initialized as 16 and it will not be destroyed when the function returns.
return num--; means that num value will be returned but after that num value will be decreased and saved because num is declared as static.
I MARKED different calls to fun() with numbers (just to follow execution flow, not to be used as real code) so it could be shown how variable num is changing.
for(fun1(); fun2(); fun4())
printf("%d \n", fun3());
fun1() "is called" only once as initialization. fun2() is a control expression, if the result is zero than execution of for loop stops. fun3() "is called" each time in the loop. fun4() "is called" each time at the end of loop"
How values are changing:
fun1() called
num: 16
fun2() called
num: 15
fun3() called
num: 14
14
fun4() called
num: 13
fun2() called
num: 12
fun3() called
num: 11
11
fun4() called
num: 10
fun2() called
num: 9
fun3() called
num: 8
8
fun4() called
num: 7
fun2() called
num: 6
fun3() called
num: 5
5
fun4() called
num: 4
fun2() called
num: 3
fun3() called
num: 2
2
fun4() called
num: 1
fun2() called
num: 0 ==> stop
If you change num-- to --num than for loop control expression (marked as fun2()) never gets 0.

Well, first thing i hope you knows what is the Storage Class in C.Now when we are dealing with static variable, This variable is persists until the end of the program and stored in data segment.Some characteristics of static variable are as follow:
Storage = memory
Default initial value = Zero
Scope = Local to the block in which the variable is defined.
Life = Value of the variable persists between different function call.
So now coming to your question.
Working of code:Well for this we will start from main(). Thinking at compiler level, first focus will be at for loop. In the for loop, one time initialization will be carried out. Now num = 15.Then it will check condition given. Now for C, it will only compare Zero and Non-Zero values. Now for this it returns 14 and it is non-zero so it get inside the loop. Now the magic of compiler get began. Read this for some information. so in your case wile returning it will first return value and then decremented value by 1.so first 14 will be printed , inc/dec block in for loop will get executed.Then again condition will gets evaluated. And again , while printing your function will return value first then decremented by 1. And after all this iteration your output will be there.
When you wrote --num ,then simple thing is it will decremented value by 1 first and then return a value. Now as mentioned earlier, Compiler only checks Zero and Non-Zero values. Whn you are dealing with --num then it goes into negative values and it still got decremented its value, so it will never meet at Zero. so resultant infinite loop. You can modify some values to check your results like modify num=17 for --num, You should probably get same result.

There is a nice post on this site that goes through static variables:
What does "static" mean?
But basically a static variable keeps its value throughout the life of the program.
I will step through the code with you, but a good resource in future to do this with is gdb:
https://www.gnu.org/software/gdb/
int fun()
{
static int num = 16; /* Essentially this line is only seen once by the program.
** The 'num' variable keeps its value for the life of the program.
*/
return num--; /* Returns the value of 'num' and *afterwards* subtracts 1 from 'num'. */
}
int main()
{
for(fun(); fun(); fun())
printf("%d \n", fun()); /* This line runs the for loop until 'num' == -1, as the
** condition is fun(), which is true while it returns a
** value > 0. fun() is run twice when the loop starts, once in
** the intialising part of for() (the first term), then once by
** the conditional term (the middle term). From there on it is
** run once by the printf(), once by the updating term
** (the end term), and once by the conditional term,
** until the conditional term is not fulfilled.
*/
return 0;
}
As for why it doesn't run when return --num; is the last line in fun(), it is because the conditional statement in the for loop will never receive a 0 (0 and only 0 is false, every other number is true) . The outputs of the program would be: 13, 10, 7, 4, 1, -2, etc; meaning the conditional statement will receive: 14, 11, 8, 5, 2, -1, etc.

Related

Can someone explain output of this C program? [duplicate]

This question already has answers here:
unexpected output in C (recursion)
(3 answers)
Closed 4 years ago.
#include <stdio.h>
int main()
{
static int i = 5;
if (--i)
{
main();
printf("%d\n", i); // will this line executes ?
}
return 0;
}
Output:
0
0
0
0
does code below main(); printf statement instructions is placed to stack every time when main recursive calls happens and executed while terminated from this program?
i is reduced by successive calls to main until zero is reached.
Then printf is called for each level of recursion.
(Note that the behaviour of calling main from itself is well-defined although ill-advised in C, in C++ the behaviour is undefined.)
if (--i)
This will evaluate true the first time (--i == 4). The code recurses into main(). (Recursion: A function calling itself.)
As i is static, it will retain its value of 4 (as opposed to an automatic variable, which would be initialized to 5 again). The if (--i) in this second execution of main() will again be true (evaluating to 3), and will again call main() (for a third execution of the function).
The same for --i == 2 and --i == 1, for four executions of main() (including the first, non-recursive one) total that are evaluating the if condition to true.
The next recursion will evaluate the if condition to --i == 0, and thus false. Skipping the if clause, the function call will just return. i is zero at this point, and -- being static, i.e. only one persistent i for all instances of main() -- will remain at that value.
The main() call one level up the stack -- the one that evaluated --i == 1, then called main() and was waiting for it to return -- will now continue with the statement after the call to main(), and printf() the current value of i... which is 0.
The same happens three more times (for a total of four) until the top-most main() returns. You get four times the current value of i, which is 0.
Note that calling main() from your program is allowed in C, but not in C++. This is specifically for calling main() recursively; for other functions, it is allowed in either language.
(--i) will decrease the value of i to 4 when it is called for the first time and it will continue the decrement of i until (i==0) due to recursion.
Since you have declared the variable i with static keyword and hence a single memory is allocated to it and all the changes are reflected back to it

Control Flow of if statement and function calls

I am getting the output ' 0,1,2,0'. Please someone help me how this function call is working. I have this doubt that after decrementing n, if statement will not execute as it will not be greater than 0. Thus there will be no output. But the result is something else.
#include <stdio.h>
void fun(int);
int main(void)
{
int a=3;
fun(a);
return 0;
}
void fun(int n)
{
if(n > 0)
{
fun(--n);
printf("%d,", n);
fun(--n);
}
}
You're calling fun() from within itself, both before and after the printf(). So you're going to see the printf from the deepest invocation of fun() first.
#ForceBru is absolutely right, you can - and, if you want to be a programmer, need to be able to - trace the code out in your head or on paper. Here's an example.
on the first invocation of fun(), as is 3. 3 > 0 so fun() is called again, with the _pre_decremented value ( so n is set to 2, and 2 is passed to fun().
The whole process happens again. 2 > 0 so --n or 1 is passed to fun.
In the 3rd invocation deep, n is 1. That's still greater than 0, so fun(--n) is run again, with n being predecremented to 0.
Now within the fourth invocation of fun(), n is finally 0. Nothing happens.
Third invocation, first fun() returns. Rember, this fun() invocation's n was 1, but it's been decremented to 0 by this time. 0 is printed. n is then decremented again ( to -1, it being a signed int) and fun(-1) is called, but since -1 > 0 is false, nothing happens. The third invocation returns.
The second invocation was passed 2 but has since decremented to 1. 1 is printed and then fun(--n) turns into fun(0) and the next fun() invcocation isfun(-1)and also does nothing. The second invocation offun()` returns.
Finally, the first invocation of fun(), the one from main, is executing agian. It started with 3, but decremented to 2. A 2 is printed. Then --n, or 1, is passed to fun() one last time. 1>0 so fun() is invoked again, and outputs--1or 0 just like it did the first time it was passed a 1. The first invocation's recursive calls tofun()then finish, and the program finishes, having output a0, 1, 2, 0`.
Do walk through that yourself on paper, as recursive functions can be pretty confusing. I didn't understand why you got that output myself until I walked through the code, and I've been programing in c for 20 years!

Understanding recursion function call

Where will the value of n be stored after first call to factorial()?
When n=1 then return 1 is sent, why doesn't res becomes equal to 1 in main function?
#include<stdio.h>
int factorial(int n)
{
if(n<=1)
return 1;
else
return n*factorial(n-1);
}
int main()
{
int res =factorial(3);
printf("%d",res) ;
}
The run-time stack will have four functions in total: main(), factorial(3), factorial(2), and factorial(1). Each of these gets its own variable space. There are three instances of the variable n, one for each call to factorial.
When factorial(1) returns 1, that value isn't returned to main(), because main() is not what called it: factorial(2) called it. That instance performs the operation 2*1 and returns 2. The caller of that instance is factorial(3), which receives the 2, performs the operation 3*2, and returns a value of 6 to its caller, main().
Does that help clear it up? If not, I have two suggestions:
(1) Search this topic on StackOverflow and the internet in general; there are plenty of detailed walk-through examples of factorial.
(2) Insert print statements to trace the flow of data and execution. Within factorial, separate the computation and the return, so you can put a print in between:
catch = factorial(n-1)
result = n * catch
print n, catch, result
return result
Each time a function is called, its parameter and local variables are pushed onto the stack. In the case of a recursive function, there will be a set of the variables on the stack for each active invocation of the function.
In this example, the first call to factorial has n set to 3. Within the function, factorial is called again, this time with n set to 2. It calls itself one more time with n set to 1. In this last call, it returns a value of 1. This gets returned to the prior invocation where n is 2, which then returns 2 * 1 which is 2. This value is returned to the first invocation where n is 3 and returns 3*2 which is 6 back to main.
So the call stack looks like this:
main
|--> factorial(n==3)
|--> factorial(n==2)
|--> factorial(n==1)
return 1
return 2*1
return 3*2
print 6
n is not stored in the way of global or static variables - it's stored on the stack. Calling a function with arguments the arguments are being pushed on the stack.
See what's happening when your running your program:
factorial(3) gets called (in main)
As n is not equal or smaller to 1 factorial(2) is called and the result will be multiplied by n (is 3).
As n is not equal or smaller to 1 factorial(1) is called and the result will be multiplied by n (is 2).
As n is now equal or smaller to 1 the function returns 1
factorial(2) returns 1*2
factorial(3) returns 2*3
res will be 6

Recursion on Recursion in C

I have a hard time understanding the part of the code where the program is recalling on the recursion multiple times.
The output is 1233333. If I change the recursion line to just fun (++count;). the output is 123, which I understand the logic, but when you start calling on the recursion multiple times, I become lost.
#include <stdio.h>
int fun(int count) {
printf("%d\n", count);
if(count < 3) {
fun(fun(fun(++count)));
}
return count;
}
int main()
{
fun(1);
return 0;
}
First function calls 1 as the argument and 1 is printed
then it enters the if statement
The count gets incremented
fun(fun(fun(2)))
2 is printed and and enters if and
count is incremented to 3
fun(fun(fun(3))))
3 is printed.But this time it is doesn't enter the if instead 3 is returned
return(3)
and 3 is returned to the previous nested calls
fun(fun(3))
this happens 4 times
and hence the output
1233333
fun(fun(fun(++count)));
Is basically equivalent to:
int tmp = fun(++count);
tmp = fun(tmp);
fun(tmp);
Firstly fun(1) will be called
Print 1
Fun(fun(fun++1)=fun(fun(fun(2)))
So,
fun(2) will be called
Print 2
Fun(fun(fun(3)))
Fun(3) called
Print 3
If confition false
Return 3, now
Fun(fun(3))
Again print 3
Return 3 then
Fun(3)
Print 3
Return 3
And recursion return back to the position of fun(2)
Fun(fun(fun(2))) will be fun(fun(3) //because 3 is
returned
Fun(fun(3))
Print 3
Then return 3
Fun(3)
Print 3
And also return 3
So after all the things printed values will be
1 2 3 3 3 3 3
Calling a function like this is not really a recursion. You can say it nested function call. In your case, you are calling function fun() three times and passing the value returned by earlier call of function.
fun(fun(fun(++count)));
So, first fun() call will take a value ++count. Whereas the second fun() call will take the value returned by first call of function as parameter. Similarly, the third call will take a value returned by second call of fun() as parameter.
To understand things easily, you can consider following example
fun3(fun2(fun1(++count)));
In this example fun1() will take ++count as parameter. fun2() will take returned value by fun1() as parameter. Similarly, fun3() will take returned value by fun2() as parameter.
I hope this explains.

Values obtained in case of a recursive function

Can anyone explain to me the reason behind the output of this program to be 0 0 0 0 0?
Here we are using a static variable var whose values will not change due to function calls. The values of var will be 4, 3, 2, 1 during the recursive calls. When var becomes zero the recursion terminates and control moves on to the printf statement.
Why is the output not 1,2,3,4?
main(){
static int var=5;
if(--var)
main();
printf(" %d ",var);
}
Again if you use if condition var-- then program output will be -1 -1 -1 -1 -1 -1?
In your recursion call printf() executes when main() returns. And because var is a static variable its value remain 0 (last value = 0 same for all function call)
Note if() condition false when var becomes 0 (last value, after main(); call you don't change var - notice diagram).
Hope following diagram will help you to understand (read comments):
main() <---------------+
{ |
static int var=5; | <----"Declared only one/first time with value 5"
if(--var) |
---- main(); ---------+ // called if var != 0
| // main called for var = 4, 3, 2, 1
|// recursion stooped
|// return with 0 value
|// now no operation applied on `var` so it remain 0
+--> printf(" %d ",var); // called when return ed
}
Remainder life of static function is till program terminates (so values not loss), and Scope is within function.
14.1.6 Static Variables
The scope of static automatic variables is identical to that of
automatic variables, i.e. it is local to the block in which it is
defined; however, the storage allocated becomes permanent for the
duration of the program. Static variables may be initialized in their
declarations; however, the initializers must be constant expressions,
and initialization is done only once at compile time when memory is
allocated for the static variable*.
Second question:
Again if you use var-- then your output will be -1 -1 -1 -1 -1 -1?
Suppose if your condition will be var-- then if() condition fist checks true or false before decrement --. (because in expression var--, -- is postfix).
And because if() breaks when var == 0 then recursive call stops and function returns with decremented value from 0 to -1. And because after return var doesn't change hence output is -1 for all.
The values of var will be 4, 3, 2, 1 during the recursive calls. When var
becomes zero the recursion terminates and control moves on to the
printf() statement.Why is the output not 1, 2, 3, 4?
A static variable is a variable that has been allocated statically—whose lifetime or "extent" extends across the entire run of the program.
So the value of var changes every time and at last it becomes 0 and printf() executes after the return of main and as the value of var is 0 ,every printf() statement will print 0.
Static variables are those variables whose life time remains equal to the life time of the program.Static variables get are initialized once. The value of the variable will change after every system call . If you had not declared the variable as static there would have been an infinite recursion resulting in an segmentation fault .

Resources