Detailed description of the role of static in C/C ++
1. in C language, the literal meaning of static can easily lead us astray. In fact, it has three functions.
(1) first introduce 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 are globally visible. I will give an example to illustrate this sentence. We need to compile two source files, A. C and Main. C at the same time.
The contents of A.C are as follows:
Char A = 'a'; // global variable
Void MSG ()
{
Printf ("Hello/N ");
}
The content of Main. C is as follows:
Int main (void)
{
Extern char a; // extern variable must be declared before use
Printf ("% C", );
(Void) MSG ();
Return 0;
}
The running result of the program is:
A Hello
You may ask: why can the global variables A and MSG defined in A. C be used in Main. C? As mentioned above, all global variables and functions without the static prefix have global visibility, and other source files can also be accessed. In this example, A is a global variable, MSG is a function, and there is no static prefix. Therefore, it is visible to other source files main. C.
If static is added, other source files are hidden. For example, if static is added before the definitions of a and MSG, Main. C will not be able to see them. This feature allows you to define functions with the same name and variables in different files without worrying about name conflicts. Static can be used as the prefix of functions and variables. For a function, the role of static is limited to hiding. For a variable, static has the following two functions.
(2) The second role of static is to keep the variable content persistent. Variables stored in the static data area will be initialized at the beginning of the program, which is also the only initialization. There are two types of variables stored in the static storage area: global variables and static variables, but compared with global variables, static can control the visible range of variables. Static is used to hide the variables. Although this is not common, I will give an example.
# I nclude <stdio. h>
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 % d/N", Count, fun ());
Return 0;
}
The running 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 role of static is that the default Initialization is 0. In fact, global variables also have this attribute, because global variables are also stored in the static data zone. In the static data area, the default values of all bytes in the memory are 0x00. In some cases, 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 assign values to elements other than 0. If it is defined as static, the first 0 operation is saved. Another example is to use a character array as a string, but it is too troublesome to add & rsquo;/0 & rsquo; at the end of the character array each time. If the string is defined as static, it saves the trouble because it is & rsquo;/0 & rsquo ;. Try a small experiment.
# I nclude <stdio. h>
Int;
Int main (void)
{
Int I;
Static char STR [10];
Printf ("INTEGER: % d; string: (BEGIN) % s (end)", A, STR );
Return 0;
}
The running result of the program is as follows:
Integer: 0; string: (BEGIN) (end)
Finally, we will summarize the three functions of static in one sentence. First, the main function of static is to hide. Secondly, because static variables are stored in the static storage area, they have persistence and default value 0.
II. C ++ has two types of static usage: static in process-oriented programming and static in object-oriented programming. The former applies to common variables and functions, and does not involve classes. The latter mainly describes the role of static in classes.
I. Static in process-oriented design
1. Static global variables
Add the keyword static before the global variable, which is defined as a static global variable. Here is an example of a static global variable:
// Example 1 # include <iostream. h> void FN (); static int N; // defines the static global Variable Void main () {n = 20; cout <n <Endl; FN ();} void FN () {n ++; cout <n <Endl ;}
Static global variables have the following features:
This variable allocates memory in the global data zone;
Uninitialized static global variables will be automatically initialized to 0 by the program (the values of automatic variables are random unless they are explicitly initialized );
Static global variables are visible in the entire file declared, but invisible outside the file;
All static variables are allocated memory in the global data zone, including the static local variables to be mentioned later. For a complete program, the distribution in the memory is as follows:
Code Area
Global data Zone
Heap Area
Stack Zone
In general, dynamic data generated by new is stored in the heap zone, and automatic variables in the function are stored in the stack zone. Automatic variables usually release space as the function exits, and static data (even static local variables in the function) is stored in the global data zone. The data in the global data zone does not release space because the function exits. Careful readers may find that
Static int N; // defines the static global variable.
Change
Int N; // defines the global variable
The program runs normally.
Indeed, defining global variables can share variables in files, but defining static global variables has the following benefits:
Static global variables cannot be used by other files;
Variables with the same name can be defined in other files without conflict;
You can change the Sample Code as follows:
// Example 2 // file1 # include <iostream. h> void FN (); static int N; // defines the static global Variable Void main () {n = 20; cout <n <Endl; FN ();} // file2 # include <iostream. h> extern int N; void FN () {n ++; cout <n <Endl ;}
Compile and run example 2, and you will find that the above Code can be compiled separately, but an error occurs during running. Try
Static int N; // defines the static global variable.
Change
Int N; // defines the global variable
Compile and run the program again to understand the differences between global variables and static global variables.
2. Static local variables
Before a local variable, add the keyword static to define the variable as a static local variable.
Here is an example of static local variables:
// Example 3 # include <iostream. h> void FN (); void main () {fn (); FN ();} void FN () {static n = 10; cout <n <Endl; n ++ ;}
Generally, a variable is defined in the function body, and stack memory is allocated to the local variable whenever the program runs the statement. However, as the program exits from the function body, the system will reclaim the stack memory and the local variables will also become invalid.
But sometimes we need to save the variable value between two calls. The general idea is to define a global variable for implementation. In this way, the variable no longer belongs to the function itself, and is no longer only controlled by the function, causing inconvenience to program maintenance.
Static local variables can solve this problem. Static local variables are stored in the global data zone, instead of in the stack. Each value is kept to the next call until the next value is assigned.
Static local variables have the following features:
This variable allocates memory in the global data zone;
Static local variables are initialized for the first time when the program executes the declaration of this object, that is, function calls will not be initialized in the future;
Static local variables are generally initialized at the Declaration. If no Explicit initialization is performed, the static local variables will be automatically initialized to 0 by the program;
It always resides in the global data zone until the program running ends. However, its scope is local scope. When the function or statement block that defines it ends, its scope ends;
3. Static Functions
Add the static keyword before the return type of the function. The function is defined as a static function. A static function is different from a common function. It can only be seen in the file where it is declared and cannot be used by other files.
Example of static functions:
// Example 4 # include <iostream. h> static void FN (); // declare the static function void main () {fn ();} void FN () // define the static function {int n = 10; cout <n <Endl ;}
Benefits of defining static functions:
Static functions cannot be used by other files;
Functions with the same name can be defined in other files without conflict;
2. Object-oriented static keywords (static keywords in the class)
1. static data member
Add the keyword static before the declaration of the data member in the class. The data member is the static data member in the class. Here is an example of a static data member.
// Example 5 # include <iostream. h> class myclass {public: myclass (int A, int B, int C); void getsum (); Private: int A, B, C; static int sum; // declare static data member}; int myclass: Sum = 0; // define and initialize static data member myclass: myclass (int A, int B, int C) {This-> A = A; this-> B = B; this-> C = C; sum + = A + B + C;} void myclass: getsum () {cout <"sum =" <sum <Endl;} void main () {myclass M (1, 2, 3); M. getsum (); myclass N (4, 5, 6); N. getsum (); M. getsum ();}
It can be seen that static data members have the following features:
For non-static data members, each class object has its own copy. Static data members are treated as class members. No matter how many objects of this class are defined, static data members also have only one copy in the program, which is shared by all objects of this type. That is to say, static data members are shared by all objects in the class. For multiple objects in this class, static data members only allocate memory once for all objects. Therefore, the values of static data members are the same for each object, and their values can be updated;
Static data members are stored in the global data zone. Space must be allocated when defining static data members, so they cannot be defined in the class declaration. In Example 5, the statement int myclass: Sum = 0 is a member that defines static data;
Static data members follow the public, protected, and private access rules like common data members;
Because static data Members allocate memory in the global data zone and all objects in this class are shared, they do not belong to a specific class object and are visible in the scope when no class object is generated, that is, when no class instance is generated, we can operate on it;
Static data member Initialization is different from general data member initialization. The static data member initialization format is:
<Data type> <class name >:< static data member name >=< value>
Static data members of a class can be accessed in two forms:
<Class Object Name>. <static data member name> or <class type name >:< static data member name>
If the access permission of the static data member is allowed (that is, the Public Member), you can reference the static data member in the program in the above format;
Static data members are mainly used when each object has the same attribute. For example, for a deposit type, the interest of each instance is the same. Therefore, the interest should be set as the static data member of the deposit class. There are two advantages: first, no matter how many deposit-type objects are defined, interest data members share the memory allocated to the global data area, thus saving storage space. Second, once the interest needs to be changed, the interest of all deposit objects will be changed once;
Compared with global variables, static data members have two advantages:
The static data member does not enter the global namespace of the program, so there is no possibility of conflict with other global names in the program;
Information can be hidden. Static data members can be private members, but global variables cannot;
2. static member functions
Like static data members, we can also create a static member function that serves all the classes rather than specific objects of a class. Static member functions, like static data members, are internal implementation of the class and are part of the class definition. A common member function generally implies a this pointer, which points to the object itself of the class, because a common member function always belongs to a specific object of a class. Generally, this is the default value. For example, the function FN () is actually this-> FN (). However, compared with common functions, static member functions do not have the "This" pointer because they are not associated with any objects. In this sense, it cannot access non-static data members of class objects or non-static member functions. It can only call other static member functions. The following is an example of a static member function.
// Example 6 # include <iostream. h> class myclass {public: myclass (int A, int B, int C); static void getsum ();/declare the static member function PRIVATE: int A, B, C; static int sum; // declare static data member}; int myclass: Sum = 0; // define and initialize static data member myclass: myclass (int A, int B, int c) {This-> A = A; this-> B = B; this-> C = C; sum + = A + B + C; // non-static member functions can access static data members} void myclass: getsum () // static member function implementation {// cout <A <Endl; // error code. A is a non-static data member cout <"sum =" <sum <Endl;} void main () {myclass M (1, 2, 3); M. getsum (); myclass N (4, 5, 6); N. getsum (); myclass: getsum ();}
Static member functions can be summarized as follows:
The keyword static cannot be specified for function definitions that appear in external classes;
Static members can access each other, including static member functions accessing static data members and accessing static member functions;
Non-static member functions can access static member functions and static data members at will;
Static member functions cannot access non-static member functions and non-static data members;
Without the additional overhead of this pointer, static member functions increase slightly compared with global functions of the class;
Call static member functions. You can use the member access operator (.) and (->) call a static member function for a class object or pointer to a class object. You can also directly use the following format:
<Class name >:: <static member function name> (<parameter table>)
Call static member functions of a class.