In C language, the literal meaning of static can easily lead us astray, but it actually has three functions.
(1) Let’s start with the first and most important one: hiding.
When we compile multiple files at the same time, all global variables and functions without the static prefix have global visibility. To understand this sentence, I will give an example. We want to compile two source files at the same time, one is ac and the other is main.c.
The following is the content of ac
char a = 'A'; // global variable
void msg()
{
printf("Hello\n");
}
Below is the content of main.c
int main(void)
{
extern char a; // extern variable must be declared before use
printf("%c ", a);
(void)msg();
return 0;
}
The result of running the program is:
A Hello
You may ask: Why can the global variable a and function msg defined in ac be used in main.c? As mentioned before, all global variables and functions without the prefix static have global visibility and can be accessed by other source files. In this example, a is a global variable and msg is a function, and neither of them has the prefix static, so they are visible to the other source file main.c.
If static is added, it will be hidden from other source files. For example, if static is added before the definition of a and msg, main.c will not be able to see them. With this feature, functions and variables with the same name can be defined in different files without worrying about naming conflicts. Static can be used as a prefix for functions and variables. For functions, the role of static is limited to hiding, while for variables, static has the following two functions.
(2) The second function of static is to keep the variable content persistent. Variables stored in the static data area will be initialized when the program starts running, and this is the only time they are initialized. There are two types of variables stored in the static storage area: global variables and static variables. However, compared with global variables, static can control the visible range of variables. In the final analysis, static is still used to hide. Although this usage is not common, I will still give an example.
#include
int fun(void){
static int count = 10; // In fact, this assignment statement has never been executed
return count--;
}
int count = 1;
int main(void)
{
printf("global\t\tlocal static\n");
for(; count <= 10; ++count)
printf("%d\t\t%d\n", count, fun());
return 0;
}
The result of the program is:
global local static
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1
(3) The third function of static is to initialize the value to 0 by default. In fact, global variables also have this property, because global variables are also stored in the static data area. In the static data area, the default value of all bytes in the memory is 0x00. Sometimes this feature can reduce the workload of programmers. For example, to initialize a sparse matrix, we can set all elements to 0 one by one, and then assign values to the elements that are not 0. If it is defined as static, the operation of setting them to 0 at the beginning is omitted. For example, you want to use a character array as a string, but you think it is too troublesome to add '\0' to the end of the character array every time. If the string is defined as static, this trouble is omitted because there is '\0' there. Let's do a small experiment to verify it.
#include
int a;
int main(void)
{
int i;
static char str[10];
printf("integer: %d; string: (begin)%s(end)", a, str);
return 0;
}
The program's running results are as follows
integer: 0; string: (begin)(end)
Finally, let's summarize the three functions of static in one sentence. First, the main function of static is hiding. Second, because static variables are stored in the static storage area, they have persistence and a default value of 0.
4. Summary of functions and variables declared with static
Static declared variables have two characteristics in C language:
1) The variable will be placed in the global storage area of the program, so that the original value can be kept the next time it is called. This is the difference between it and stack variables and heap variables.
2) The variable uses static to tell the compiler that it is only visible within the scope of the variable. This is the difference between it and global variables.
Tips:
A. If the global variable is only accessed in a single C file, you can modify this variable to a static global variable to reduce the coupling between modules;
B. If the global variable is only accessed by a single function, you can change this variable to a static local variable of the function to reduce the coupling between modules;
C. When designing and using functions that access dynamic global variables, static global variables, and static local variables, you need to consider the reentrancy problem;
D. If we need a reentrant function, then we must avoid using static variables in the function (such functions are called: functions with "internal memory" functions)
E. Situations where static variables must be used in functions: For example, when the return value of a function is a pointer type, the address of a static local variable must be used as the return value. If it is of auto type, an incorrect pointer is returned.
Adding static before a function makes it a static function. However, the meaning of "static" here does not refer to the storage method, but to the fact that the scope of the function is limited to this file (so it is also called an internal function). The advantage of using internal functions is that when different people write different functions, they don't have to worry about whether the functions they define have the same name as functions in other files.
Extended analysis:
The term static has an unusual history. Initially, the keyword static was introduced in C to represent local variables that survive exiting a block. Later, static took on a second meaning in C: to represent global variables and functions that cannot be accessed from other files. To avoid introducing a new keyword, the static keyword was used to represent this second meaning. Finally, C++ reused this keyword and gave it a third meaning that was different from the previous ones: to represent variables and functions that belong to a class rather than to any specific object of this class (the same meaning as this keyword in Java).
The difference between global variables, static global variables, static local variables and local variables
Variables can be divided into: global variables, static global variables, static local variables and local variables.
According to the storage area, global variables, static global variables and static local variables are all stored in the static storage area of the memory, and local variables are stored in the stack area of the memory.
According to the scope, global variables are valid in the entire project file; static global variables are only valid in the file in which they are defined; static local variables are only valid in the function in which they are defined, but the program only allocates memory once, and the variable will not disappear after the function returns; local variables are valid in the function in which they are defined, but they become invalid after the function returns.
If the word static is added before the description of a global variable (external variable), it becomes a static global variable. Global variables are static storage methods, and static global variables are also static storage methods. There is no difference between the two in terms of storage methods. The difference between the two is that the scope of non-static global variables is the entire source program. When a source program consists of multiple source files, non-static global variables are valid in each source file. Static global variables, on the other hand, have limited scope, that is, they are only valid in the source file that defines the variable, and cannot be used in other source files of the same source program. Since the scope of static global variables is limited to one source file, they can only be used by functions in the source file, thus avoiding errors in other source files.
From the above analysis, we can see that changing a local variable to a static variable changes its storage method, that is, changes its lifetime. Changing a global variable to a static variable changes its scope, limiting its scope of use.
Static functions have different scopes from ordinary functions. Functions that are only used in this file or in the current source file should be declared as internal functions (static). Internal functions should be declared and defined in the current source file. Functions that can be used outside the current source file should be declared in a header file, and the source files that use these functions should include this header file.
What is the difference between static global variables and ordinary global variables: static global variables are initialized only once to prevent them from being referenced in other file units;
What is the difference between static local variables and ordinary local variables: static local variables are initialized only once, and the next time they are initialized, they are based on the result of the previous time;
What is the difference between static functions and ordinary functions: static functions have only one copy in memory, and ordinary functions maintain a copy in each call.
If global variables and static variables are not initialized manually, they are initialized to 0 by the compiler. The value of local variables is unknown.
|