Not understanding the function of static int in C - c

I'm trying to understand this piece of code, but I don't know why the amount of a static variable sometimes changes and sometimes not.
#include <stdio.h>
int func1 (int x)
{
extern int a;
static int y=0;
printf("%d\n%d\n",a,y);
a=x+5; y=x+1;
{int y=10; printf("%d\n",y);}
return y;
}
int a;
int main()
{
a=func1(1);
printf("%d\n",a);
{
int a=1;
printf("%d\n", a);
}
a=func1(a);
printf("%d",a);
return 0;
}
Here is the output:
0
0
10
2
1
2
2
10
3
At first, when a = func(1) is run, y is declared as 0 and then changes to 2 and it prints 2. But when it runs a = func(a) when a is 2, I expected that y will become 0 through static int y = 0 but y doesn't change. Why it doesn't happen?

A static object is initialized, conceptually, when it is created.
The lifetime of a static object begins when the program starts executing and continues until execution ends.
So, when the program starts executing, y is initialized to 0. After that, its value changes only when it is modified, as with assignment statements. The statement that defines it, static int y = 0;, does not modify it after the initialization.

Variables declared as static inside of a function retain their value through the lifetime of the program, even when the variable name goes out of scope. The initializer for a static variable is only applied at program startup.
So when the program starts, y is initialized to 0. Then in the first call to func it sets y to 2. This value is retained even after the function exits. So when func is called a second time, y is still 2 when the function starts.

static means you have only one shared value of the variable, you can imagine it declared as a global variable keeps its value between multiple function calls.
First times you called the funct1 with x = 1 so y returned as 2.
The next time you called the function func1 with x = 2, the value of y will not be declared again but will use the last value of last call (y=2), and update it with y = x + 1 to be 3.
TLDR;
Read the static declaration of a variable only once (static int y = 0), and do not back to it again, use the last value of it next times.

Related

Giving int data type to variable y in Program2 changes the output of that program. What will be the reason for it? Memory allocation in stack segment

(output printed is written in comment)
Just by giving int data type of the variable y which is within the paranthesis the output is different in program 2.
How Memory allocation in stack segment will happen differently in both the cases.
Program 1
#include <stdio.h>
int main ()
{
int y=10;
{
y=4; // this variable
printf("%d\t",y); //Output = 4
}
printf("%d",y); //Output = 4
}
Program 2
#include <stdio.h>
int main()
{
int y=10;
{
int y=4; // this variable
printf("%d\t",y); // Output = 4
}
printf("%d",y); // Output = 10 this output differ
}
#include <stdio.h>
int main ()
{ // <--------- Scope 1 Begin
int y=10; >
{ // <--------- Scope 2 Begin
y=4;> this variable
printf("%d\t",y);>Output = 4
} // <-------- Scope 2 End
printf("%d",y);>Output = 4
} // <-------- Scope 1 End
In your first program here, you modify the y variable that you created in Scope 1. The second scope effectively does nothing here, as you still modify the original y from Scope 1. There is only one variable that was created here.
#include <stdio.h>
int main()
{ // <--------- Scope 1 Begin
int y=10;>
{ // <--------- Scope 2 Begin
int y=4;> > this variable
printf("%d\t",y); >Output = 4<
} // <-------- Scope 2 End
printf("%d",y); > Output = 10 this output differ <
} // <-------- Scope 1 End
However, in your program 2, by adding int before y=4 in Scope 2, you are instead initializing a new variable instead of assigning to y from Scope 1. This means that you are not modifying the y variable declared in Scope 1 when you do int y=4 from within Scope 2. As a result, the first y has the same value as when it was initialized. There are two variables that were created here.
As for memory usage, you can't really be sure without looking at the assembly output. It could be pushed and popped from the stack, or it could be optimized into a register, or it could even be removed altogether with a printf call with a literal.

If a variable is defined previously and is waiting on a function to return a value, what is the value of that variable?

This is for programming in C.
Say I had the follow code in my program:
int fun1(int x);
int main (void)
{
int a = 5;
a = fun1(10);
}
int fun1(int x)
{
\\Program arbitrarily ends here
return x;
}
In my memory diagram what would the value of a be assuming the program terminates before fun1 is able to return a value? Would the value of a be undetermined (??) or would it be 5?
The value of a is already initialized to 5. Now, according to the condition, you want to know the results of that circumstance when the fun1() ends before it could return a value; assume the following:
int fun1(int x)
{
// return x;
}
Here we've supposed the function quits before returning the value.
You'll still get the output 5 before, during or after execution of the program since it returns nothing but the variable a is preassigned to 5 and it can't be changed to 10 unless the function returns 10 and assigns to the variable.
But remember, if you don't assign anything to a, then it may show an unexpected value (I got 4195638 when used printf() for a).

Why is the output of the following two segments different?

#include <stdio.h>
int main()
{
static int i = 5; // here
if (--i){
printf("%d ", i);
main();
}
}
Output: 4 3 2 1
#include <stdio.h>
int main()
{
int i = 5; // here
if (--i){
printf("%d ", i);
main();
}
}
Output: 4 4 4 4... (Segmentation fault)
Any idea how static int variable is taken into account only once and int is taken over and over again?
When you declare a static variable in a function, the function "remembers" the last value of the variable even after it terminates.
void Foo() {
static int x = 5;
}
In the example above, you are telling the compiler that x shall be "remembered" and has an initial value of 5. Subsequent calls to Foo() does not reassign x a value of 5, but uses the previously remembered value.
In contrast:
void Bar() {
int x = 5;
}
Here, you are telling the compiler that everytime Bar() executes, a new variable x is to be created on the stack and assigned a value of 5.
A variable declared as static inside of a function retains its value each time the function is called. It is initialized only once, when the function is first called. So when the function calls itself the value of i is retained from the prior call.
A local variable that is not static is specific to a given call of a function, so each time the function is called a new copy of the variable is created and initialized. This results in i being 5 each time, which in turn results in infinite recursion leading to a stack overflow and a core dump.

Heap and Stack segment

I came across a small puzzle for which I was trying to find the output. Once I managed to get the output, I tweaked in 1 line and the output is totally different. Why does the output of the following two programs vary?:
a)
#include<stdio.h>
int fun()
{
static int num = 40;
return num--;
}
int main()
{
for(fun(); fun(); fun())
{
printf("%d ", fun());
}
getchar();
return 0;
}
Output:
38 35 32 29 26 23 20 17 14 11 8 5 2
b)
#include<stdio.h>
int fun()
{
static int num;
num = 40;
return num--;
}
int main()
{
for(fun(); fun(); fun())
{
printf("%d ", fun());
}
getchar();
return 0;
}
Output: Infinite loop printing 40 everytime
There is just one difference: The declaration and initialization are done at the same time in (a) but separately in (b). How does that effect the final outcome?
static int num = 40;
static int num;
These both get evaluated once. num does not live on the runtime stack (but rather in the data segment) Then,
num = 40;
gets evaluated every time you call fun(). You're reassigning a variable that was declared outside the stack to 40, causing it to loop forever.
In the first one, num will only be initialised to 40 the first time the function is called. In the second one, it is set to 40 every time the function is called.
first one, num gets initialized once, no matter how many times you call the function
second one, num gets set to 40 every time you call the function
Two concepts need to be looked into here
lifetime of variable
scope of variable
The lifetime of a variable is the period over which it exists. If num were defined without the keyword static, the lifetime would be from the entry into fun() to the return from fun(); so it would be re-initialized to 40 on every call.
The scope of variable is where the variable name can be seen. Here, num is visible only inside function fun().
The keyword static is used to extend the lifetime of a variable to the lifetime of the program. In case of static declaration initialization occurs only once and then the variable retains its value inside the routine fun(). So if you are overwriting it by setting it to value of 40 in the second case its values keeps getting set to 40 on every call to fun(). The declaration of the variable num as static is redundant in your second code.

How to initialize a variable once in an if statement and use it outside the if statement

I am trying to initialize an int with a particular value once only and use it repeatedly.
void some_method(int par){
int ch=1;
if (ch==1){
int x = par;
}
int y = x + 2;
}
I know this code will definitely not work because x is only within the scope of the if statement. some_method() is called repeatedly in a while loop, so if I declare x outside the if statement then every time some_method() is called, default to zero. I just want x to remain constant. I thought about just making x a global variable, but I am sure there has got to be a better solution than that. Any suggestions will be helpful!
Thanks.
This can be done with static variables:
void some_method(...)
{
static int initialized = 0, x;
if(!initialized)
{
x = ...
initialized = 1;
}
/* Use x. */
}
Note that you then need to "pay" for the check of initialized on every call, but if the work done to compute the value of x is expensive enough it might be worth it.
You can declare the variable "x" outside of the if block, but declare it as static:
void some method (some parameter) {
static int x = some_default_value; // this is your default value
inx y = x + 2;
}
Alternatively, if you're only using your code there, and x is a constant, you can just define it using a #define outside of your method.

Resources