could anyone explain behavior of the 'static int i' variable? [duplicate] - c

This question already has answers here:
unexpected output in C (recursion)
(3 answers)
Closed 8 years ago.
I executed this program and am unable to understand why the output is "0" four times. Can anybody help me understand how it works? I do not understand why "printf" executes when the condition fails and why it executes four times.
int main()
{
static int i=5;
if(--i)
{
main();
printf("%d ",i);
}
}

Your main function prints 4 times 0 because the printf statement occurs after the recursive call and i is a static variable. A static variable is initialised only once and it is not destroyed after the function terminates since it is not allocated into the function stack.
As result, the value of i used by the printf is always 0 as i is decremented each time main is called and the first printf function is executed after the deepest function has returned because i=0.
To better understand this solution, let's look at the stack call :
main() i=5 (First call)
if(4) // True
main() (Second call)
if(3) // True
main() (Third call)
if(2) // True
main() (Forth call)
if(1) // True
main() (Fifth call)
if(0) //False End recursion No print because the condition is false
return
print(i) // 0 (Forth Call)
print(i) // 0 (Third call)
printf(i) // 0 (Second call)
print(i) // 0 (First call)
The main is called 5 times but the application prints 4 zeros because the the last call does not print anything as the if condition is false.

i is static so it is initialized only once. Every time you call main it is decremented when i == 1 then the `if statement condition will be false here:
if(--i)
the recursion will stop and i will be 0, the recursion will then unwind and the program will print four 0s.
For completeness sake, the draft C99 standard section 6.2.4 Storage durations of objects paragraph 3 says(emphasis mine):
An object whose identifier is declared with external or internal linkage, or with the
storage-class specifier static has static storage duration. Its lifetime is the entire
execution of the program and its stored value is initialized only once, prior to program
startup.

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

using statement bodies in printf in C

I am taking a course where we were doing a lot with systems level programming, and now we are getting to the point where we are starting the introduction to C. We are given some code and told to state the values printed out by each 'printf' statement. I know how to do regular printing statements in languages like Java and Python. But the code given has bodies to the print sections which I have not seen before. The statements are executed in the order A, B, C, D. Here is the code:
int t; /* This variable is global */
{
int t = 2;
printf("%d\n", t); /* A */
{
printf("%d\n", t); /* B */
t = 3;
}
printf("%d\n", t); /* C */
}
{
printf("%d\n", t); /* D */
}
The part that confuses me is that some of the print statements have bodies. A print statement inside a print statement?
So here is what I am thinking: t = 2 so when we get to A, it executes the body within A first. So the first statement in that body is to print t which at this point is 2. Then after we print 2, we change the value in t to 3. After that we go to C which just prints t which is 3 (I guess? I'm not sure here). After that we go to the body that contains D. Int t is a global variable declared above, but it is never initialized (except in the first portion of code). So in the second portion that contains D, would there be an error since t is not initialized in that block of code?
2
3
3
Error
I feel like I am wrong.
First, you have a global variable t, which is initialized to 0 (AFAIK, all global variables in C are initialized to 0 if not explicity initialized)
Then, a block is opened and a local variable t is declared and initialized to 2, which shadows the global variable with the same name (in java this is an error, the compiler will complain and refuse to use the same name), for the whole block.
The first printf, which is inside the block, prints 2.
Then a nested block opens, with a printf in it. This printf will also use the local variable t, printing 2 again.
Then t is assigned 3. This "t" cannot be other than the local variable.
Then, the nested block closes and we are back into the first still opened block in which local t was declared. The printf here prints 3.
Then the first block finishes and so the local variable t is gone. A new block opens and the last printf prints the value of global variable t, which is the only one known in this block. It prints 0.
The curly braces begin and end new scopes, just like they do with functions.
There are two "main blocks" in your program. One contains a definition of variable t, thus shadowing the global t. Therefore 2, 2, and 3 is printed out. The second block can access the global t, so the printf in the second block prints out the value of the global t.
Global variables are initialized to 0 by default, so the last printf call prints 0 to the screen.
Local variables are not initialized with any value, so the last printf call would yield undefined behavior.
The output is
2
2
3
and after that
0
if the "global" t really is global or (probably1) some random value if it is local.
1 Undefined behavior occurs. Anything may happen. In this case, it's probably a random value getting printed out.

static storage class working in 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.

Why Output is 0000 and How? [duplicate]

This question already has answers here:
unexpected output in C (recursion)
(3 answers)
Closed 8 years ago.
I executed this program and am unable to understand why the output is "0" four times. Can anybody help me understand how it works? I do not understand why "printf" executes when the condition fails and why it executes four times.
int main()
{
static int i=5;
if(--i)
{
main();
printf("%d ",i);
}
}
Your main function prints 4 times 0 because the printf statement occurs after the recursive call and i is a static variable. A static variable is initialised only once and it is not destroyed after the function terminates since it is not allocated into the function stack.
As result, the value of i used by the printf is always 0 as i is decremented each time main is called and the first printf function is executed after the deepest function has returned because i=0.
To better understand this solution, let's look at the stack call :
main() i=5 (First call)
if(4) // True
main() (Second call)
if(3) // True
main() (Third call)
if(2) // True
main() (Forth call)
if(1) // True
main() (Fifth call)
if(0) //False End recursion No print because the condition is false
return
print(i) // 0 (Forth Call)
print(i) // 0 (Third call)
printf(i) // 0 (Second call)
print(i) // 0 (First call)
The main is called 5 times but the application prints 4 zeros because the the last call does not print anything as the if condition is false.
i is static so it is initialized only once. Every time you call main it is decremented when i == 1 then the `if statement condition will be false here:
if(--i)
the recursion will stop and i will be 0, the recursion will then unwind and the program will print four 0s.
For completeness sake, the draft C99 standard section 6.2.4 Storage durations of objects paragraph 3 says(emphasis mine):
An object whose identifier is declared with external or internal linkage, or with the
storage-class specifier static has static storage duration. Its lifetime is the entire
execution of the program and its stored value is initialized only once, prior to program
startup.

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