This question already has answers here:
What does "static" mean in C?
(20 answers)
Closed 26 days ago.
I have this C function with a static variable:
void plus_five() {
static int i = 10;
i += 10;
printf("%d", i);
}
int main() {
for(int i = 0;i < 10;i++) {
plus_five();
}
return 0;
}
I get this output:
10
20
30
40
50
60
70
80
90
100
Why does the variable get incremented even when it is set to 10 every time the function is executed?
Variables declared inside of a function as static are initialized once at program startup and retain their value through successive function calls.
This means the first time plus_five is called i will have the value 10, and the function will increase the value to 20. On the next call, i has retained its value of 20 and is increased to 30, and so forth.
Why does the variable get incremented even when it is set to 10 every time the function is executed?
Because you marked it static, which means (in this context) that you want the variable to persist for the entire life of the program. The variable only gets initialized once, and from then on it keeps whatever value you give it.
Think of a static variable as a global variable that's only visible from inside the function where it's declared.
'Why does the variable get incremented even when it is set to 10 every time the function is executed?' is a wrong question.
The variable actually is incremented. It is incremented due to the i += 10 expression, and it doesn't depend on being (or not being) 'set to 10 every time the function is executed'.
Now the actual question is not 'whether/why the variable is/is not incremented' but rather 'why the variable is not re-initialized to 10 on every execution of the function?'
And the answer is: because that's what the keyword static means: the variable is initialized only once and preserves its value between calls to the function.
Related
I am learning about global variables in C using book C programming a modern approach.
Below is given an example from the book why using same global variable for multiple functions is bad idea.
I don't understand why function print_all_rows executes function print_one_row only once.
Let's say I call first function print_one_row and then function print_all_rows.
At the beginning of program i is set to 0 by default by compiler. Once program finishes execution of print_one_row function the value of i is 11.
Program enters into function print_all_rows, sets i to 1, calls function print_one_row and then increments i to 12 instead of 2.
Why is it incrementing i to 12 and not to 2 if I changed the value of i to 1?
int i;
void print_one_row(void)
{
for (i = 1; i <= 10; i++)
printf ("*" ) ;
}
void print_all_rows(void) {
for (i = 1; i <= 10; i++) {
print_one_row();
printf ("\n") ;
}
}
In print_all_rows, just before the first call to print_one_row, i has the value of 1.
Then print_one_row is called. When that function returns, i has the value of 11. Then the loop increment in print_all_rows is evaluated which increments i from 11 to 12, then the condition is evaluated which is false, then print_all_rows returns.
Because i is glocal variable (common for both functions) and its value is 11 after first call of print_one_row. With this value (11) the second iteration of for loop in print_all_rows exits and there are no more calls of print_one_row.
Update: Hi, I did not misunderstood the goal of the function. I was just surprised that static int sum = 0 does not execute each time the function is called, so I don't understand that. The goal of the function is correct: to sum the values and give the final value, and it works fine. The question is: Why isn't the sum changing into 0 each time the function is called? I suppose that's how it is set up by convention? That since I put static int sum, it will run only once and make it equal to zero, but then it won't run this line of the code again when the function is called?
In the following code, the only way I could make this function work was when I declared that sum = 0.
I was expecting the output to be 55, 45, 50, since sum is getting value 0 each time it is run! But for some reason, after the second time the function is called, the first line "static int sum = 0;" is skipped. Why? Thanks a lot =)
#include <stdio.h>
int sum (int num)
{
static int sum = 0;
sum = sum + num;
return sum;
}
int main()
{
printf("%d ",sum(55));
printf("%d ",sum(45));
printf("%d ",sum(50));
return 0;
}
Since sum (variable) is getting value 0 each time it (sum function) is run!
No, it's not.
But for some reason, after the second time the function is called, the first line static int sum = 0; is skipped. Why?
It is not skipped. That is just your impression. But the initialization of 0 happens only once prior to program startup.
If the function is called everytime there's a call to sum(), why doesn't sum (variable) gets the value of 0, since it is written in the beginning of the function?
Because sum is qualified with the static storage class specifier, which means that the sum variable is not destroyed after the function has been executed once and it retains its value for the whole entire program execution.
An object whose identifier is declared without the storage-class specifier_Thread_local, and either 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.
Source: ISO/IEC 9899:2018 (C18), §6.2.4/3
Omit static at the sum variable and you get your desired result.
Note that the purpose of the sum function is pretty useless in that way. I guess it is just for testing purpose only.
EDIT:
For me it seems that you actually got the function from somewhere else and misunderstood the purpose of the program and the function sum.
The original purpose of the function sum is to sum the input values provided at different function calls to sum() and return the current sum at each function call.
That is the reason, why sum (variable) is qualified with static (to retain its value).
The purpose is not to just pass the input value through, which is what think the purpose of sum() is.
This question already has answers here:
srand() — why call it only once?
(7 answers)
C program - srand() [duplicate]
(6 answers)
Closed 3 years ago.
I have this code I need to write, and I created this function. Irrelevant of what it does for the code, I need it to generate a random number (a) between 0 and (i), an integer with a previously initialized value. Somehow despite seeding, I always get the same number.
I have tried entering a number instead of i and it works properly by giving me a different random number each time I execute. I also tried declaring a new int variable inside in the function and giving it the value of i, but it still doesn't work.
elementptr position_current(elementptr first, int i){
elementptr current = first;
int j = 1;
printf("%d\n", i);
srand(time(NULL));
int a = rand() % i;
printf("%d\n",a);
for(j=1;j<a;j++){
current = current->next;
}
return current;
}
I expect (a) to get a different value each Time I run the code, however it's always getting the same value(2).
Can someone tell me what could be wrong?
I'm guessing you're calling this function many times in a single second. Since time only changes once a second, you're reseeding the same value over and over.
Don't call srand over and over. Call it exactly once in your main function, then never call it again, and rand will produce successive values based on that seed one at a time.
Where do the results of an uninitialized array in C come from? Are they randomly assigned values or it's just previous values that are stored in the memory?
#include <stdio.h>
int main (void)
{
int values[10];
int index;
values[0] = 197;
values[2] = -100;
values[5] = 350;
values[3] = values[0] + values[5];
values[9] = values[5] / 10;
--values[2];
for ( index = 0; index < 10; index++ )
printf ("values[%i] = %i\n", index, values[index]);
return 0;
}
and the output:
$ ./a.exe
values[0] = 197
values[1] = 0
values[2] = -101
values[3] = 547
values[4] = 8
values[5] = 350
values[6] = 51
values[7] = 0
values[8] = 44045216
values[9] = 35
Chapter and verse:
6.2.4 Storage durations of objects
...
5 An object whose identifier is declared with no linkage and without the storage-class
specifier static has automatic storage duration, as do some compound literals. The
result of attempting to indirectly access an object with automatic storage duration from a
thread other than the one with which the object is associated is implementation-defined.
6 For such an object that does not have a variable length array type, its lifetime extends
from entry into the block with which it is associated until execution of that block ends in
any way. (Entering an enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. The initial value of the object is indeterminate. If an
initialization is specified for the object, it is performed each time the declaration or
compound literal is reached in the execution of the block; otherwise, the value becomes
indeterminate each time the declaration is reached.
Emphasis added.
Basically, objects with auto storage duration are not implicitly initialized to any particular value - they have the value of whatever was last written to that particular memory location1. You cannot rely on that value being 0 (or anything else).
That last sentence in the quote above applies to situations like this:
for (;;)
{
int x;
do_something_with( x );
}
Each iteration of the loop effectively destroys and re-creates x, and you cannot rely on value written to x in any iteration of the loop to be carried over to the next iteration. In practice on x86-like systems it most likely will be carried over, but don't assume that's the case everywhere.
Note that an implementation may decide to initialize auto variable with some known value when building in debug mode or something.
The mechanics of which are wide and varied and not worth going into here.
What do you think "uninitialized" means?
It means the value has not been set.
Because it has not been set, it could have any value stored there.
Maybe 0, maybe 547...
Any value is valid, and there are no guarantees what you will find.
Uninitialized values are just memory addresses that have not yet been written to by your application. It would be like having a notepad that is used by everyone around you. When your program runs, it's given a small section of that notepad that may or may not have been used by someone else before. If it was (most likely), then it will still have something written on it, but probably will not make any sense to you. If you want to know what's there, you must write something. In general, we will write 0's to it which is like erasing everything to start with empty paper.
Well this is C programming 101.
C is a procedure-oriented language and does not implement some features present in Object Oriented languages (such a Java) such as "automatic" and guaranteed initialization of variables.
If you declare an auto variable (on stack not dynamically allocated) in C and do not provide an initial value, then this variable will have what we call a "garbage value". This is the general behavior but specific implementations can vary.
Let me give an example:
int a; //a variable with no initial value
printf("%d", a);
We can't predict what this will print. May be 0 or may be anything else. The program can crash too. Essentially, this is undefined behavior.
If the same was done in Java, then that would surely print 0 (because Java initializes all integers to 0 by default).
Now coming to your array question: It does not matter whether this is a single integer or an array of integers. Any memory location to which you don't assign a value explicitly will have a "garbage value". It can be 0 or something else. This behavior is completely machine dependent and unpredictable.
Bottom line is: ensure that variables are initialized before use.
im going through an old exam past paper and had this question
int c = 0;
int count_calls()
{
c = c + 1;
return c;
}
Now it asks why would this go wrong i.e. the number of calls counted is incorrect? is it right to say that no matter what c is set to in the count_calls() function it will always be zero due to the fact c is always defined as 0 outside the class? and would changing it to ++c or +CC fix this issue?
function increments global variable (and it will be correctly incremented by 1 every time the function was called), but when it returns, it creates local copy.
in the range of int type, it can count calls
generally speaking, it's bad code (it can't be used in parallel)
it wouldn't changed with moving to ++c