Storage categories for C + + variables (dynamic storage, static storage, automatic variables, register variables, external variables)
dynamic storage mode and static storage mode
We've learned about the scope of variables. Scopes are analyzed from the perspective of space, and are divided into global variables and local variables.
Variables also have another attribute--the storage period (storage duration, also known as lifetimes). A storage period is the period in which a variable exists in memory. This is analyzed from the point of view of the existence of the variable value. The storage period can be divided into static storage periods (the static storage duration) and the dynamic storage period (active storage duration). This is determined by the static storage mode of the variable and the dynamic storage.
Static storage means that the system allocates fixed storage space for variables during the operation of the program. The dynamic storage mode is that the system allocates storage space dynamically during the program operation.
Let's take a look at the storage space in memory for the user to use. This storage space can be divided into three parts, namely:
- Program Area
- Static Storage Area
- Dynamic Storage Area
The data is stored in both the static and dynamic storage areas. Global variables are all stored in a static store, and the global variable is allocated a storage unit when the program starts executing, releasing the space when the program is finished. They occupy fixed storage units during program execution, rather than dynamically allocating and releasing them.
The following data is stored in the dynamic store:
function Form argument. Allocates storage space to parameters when calling a function.
An automatic variable in a function (a local variable without a static declaration, as described later).
field protection and return address, etc. when the function is called.
For these data, the dynamic storage space is allocated at the start of the function call and the space is freed at the end of the function. This allocation and release is dynamic during program execution, and if you call the same function two times in a program, you assign and release it two times, and two times the storage address assigned to local variables in this function may be different.
If you include several functions in a program, the storage period of a local variable in each function is not equal to the execution cycle of the entire program, it is only part of the entire execution cycle of the program. Depending on the function call, the system dynamically allocates and frees the storage space for local variables.
In C + +, a variable has a property of the storage category (storage Class) In addition to the properties of the data type. A storage category refers to the way data is stored in memory. Storage methods are divided into two categories: static storage and dynamic storage. Includes 4 types: Automatic (auto), Static, register (register) and external (extern). Depending on the storage category of the variable, you can know the scope and storage period of the variable.
Automatic variable
A local variable in a function that, if not declared with the keyword static, is dynamically allocating storage space to the system. The formal parameters of a function and the variables defined in the function, including the variables defined in the compound statement, belong to this class. When this function is invoked, the system allocates storage space to the variables defined in the parameters and functions, and the data is stored in the dynamic store. These spaces are automatically freed at the end of a function call. If a variable is defined in a compound statement, the storage space is allocated when the variable is defined, and the space is automatically freed at the end of the compound statement. Therefore, such local variables are called automatic variables (auto variable). Auto variables are declared with the keyword auto as the storage category. For example:
int f (int a)//define F function, A is parameter
{
auto int b, c=3;//defines an integral type of B and C as an automatic variable
}
Storage category auto and data type int are in any order. The keyword auto can be omitted, if you do not write auto, the system defaults to the automatic storage category, which belongs to the dynamic storage mode. Most variables in a program belong to an automatic variable. In the examples in the previous chapters of this tutorial, the variables defined in the function are not declared as auto, but are automatically designated as automatic variables by default. The following two kinds of writing functions are the same in the function body:
auto int b, c=3;
int B, c=3;
Declaring static local variables with static
Sometimes you want the value of a local variable in a function not to disappear after the function call ends, which means that the storage unit it occupies is not freed, and the variable retains the value at the end of the last function call at the next time the function is called. You should then specify that the local variable is a static local variable (static locals variable).
The value of the "example" static local variable.
#include <iostream>
using namespace std;
int f (int a)//definition F function, A is parameter
{
auto int b=0;//definition B is an automatic variable
static int c=3;//define C as static local variable
b=b+1;
c=c+1;
return a+b+c;
}
int main ()
{
int a=2,i;
for (i=0;i<3;i++)
cout<<f (a) << "";
cout<<endl;
return 0;
}
The results of the operation are:
When you call the F function 3 times, the values for B and C are as shown in the table.
Description of static local variables:
Static local variables allocate storage units within the static storage area. is not released during the entire run of the program. Automatic variables (i.e., dynamic local variables) belong to the dynamic storage category, stored in the dynamic storage space (rather than the static storage space), and then released after the function call ends.
The initial value of the static local variable is evaluated at compile time, that is, only once, when the program is running, it already has initial values. Each time the function is called, the initial value is no longer assigned, but only the last time the function call was left. An initial value for an automatic variable, rather than at compile time, is done at the time of the function call, and each time the function is called again the initial value is equivalent to executing an assignment statement.
If you define a local variable without an initial value, for a static local variable, the compile-time automatically assigns the initial value of 0 (to the numeric variable) or the null character (for the character type variable). In the case of an automatic variable, the value is an indeterminate value if the initial values are not assigned. This is because the storage unit is freed at the end of each function call, and the storage unit is reassigned at the next call, and the value in the allocated cell is indeterminate.
Although a static local variable still exists after the function call ends, other functions cannot reference it, that is, it is "invisible" in other functions.
Under what circumstances should local static variables be used?
1 You need to preserve the value of the function at the end of the last call. For example, you can use the method in the following example to find n!.
"Example" outputs the factorial value of the 1~5 (that is, 1!,2!,3!,4!,5!).
#include <iostream>
using namespace std;
int FAC (int); function declaration
int main ()
{
int i;
for (i=1;i<=5;i++)
cout<<i<< "!=" <<FAC (i) <<endl;
return 0;
}
int FAC (int n)
{
static int f=1;//f is a static local variable, the value of f at the end of the function does not release
f=f*n;////On the basis of F's original value times n return
F;
}
Run result is
1!=1
2!=2
3!=6
4!=24
5!=120
Each time you call FAC (i), you output an I, preserving the value of this i! for the next multiplication (i+1).
2 If the variable is referenced without changing its value after initialization, then it is convenient to use static local variables, so as not to reassign the value each time it is invoked. However, it should be seen that the use of static storage to occupy more memory, and reduce the readability of the program, when the number of calls often confused static local variables of what is the current value. Therefore, if not necessary, do not use static local variables more.
Declaring register variables with register
In general, the value of a variable is stored in memory. When a program uses the value of which variable, the controller emits an instruction to send the value of the variable in memory to an operator in the CPU. After the operation of the operator, if the need to save the number, and then from the operator to send data to memory storage. As shown in the figure.
To improve execution efficiency, C + + allows the value of local variables to be placed in the CPU registers, need to be taken directly from the register to participate in the operation, no longer in memory to access. This variable is called a register variable and is declared with the keyword register. For example, you can rewrite the FAC function in example 4.14 as follows:
int FAC (int n)
{
Register int i,f=1;//Definition I and f are register variables for
(i=1;i<=n;i++) f=f*i;
return f;
}
The definition F and I are local variables stored in registers, which can save a lot of execution time if the value of n is large.
Defining a register variable in a program is only a recommendation (not a mandatory) for compiling the system. Today's optimized compilation system can identify frequently used variables and automatically place these variables in registers.
Declaring external variables with extern
A global variable (an external variable) is defined outside of a function, and its scope begins at the definition of a variable to the end of this program file. Within this scope, global variables can be referenced by functions in this file. The global variable is assigned to the static store at compile time.
It is sometimes necessary to declare global variables with extern to extend the scope of global variables.
1 Declare global variables within a file
If the external variable is not defined at the beginning of the file, its valid scope is limited to the end of the file at the definition. If the function before the definition point wants to refer to the global variable, you should use the keyword extern to declare the variable as an external variable, indicating that the variable is a global variable that will be defined below. With this declaration, you can legitimately reference the global variable from the declaration, which is called an advance reference declaration.
"Example" uses extern to make a forward reference declaration to an external variable to extend the scope in the program file.
#include <iostream>
using namespace std;
int Max (int,int); function declaration
void Main ()
{
extern int a,b;//a,b Reference declaration for global variable
cout<<max (a,b) <<endl;
}
int a=15,b=-7;//defines global variable a,b
int max (int x,int y)
{
int z;
z=x>y?x:y;
return z;
}
The results of the operation are as follows:
The global variable A,B is defined after main, but the global variable A and B cannot be referenced in the main function because the location of the global variable is defined after the function main, so if the 5th line of the program is not there Now we have a forward reference declaration with extern to A and B in line 2nd of the main function to indicate that A and B are variables that will be defined later. This makes it possible to use global variables A and b legitimately in the main function. If you do not make an extern declaration, there will be errors at compile time and the system considers A and B undefined. It is generally possible to place the definition of a global variable before all the functions that reference it, so that you can avoid adding an extern declaration to the function.
2 declare an external variable in a multiple-file program
If a program contains two files, use the same external variable num in two files, and you cannot define an external variable num separately in two files. The correct approach is to define the external variable num in either file and the external variable declaration in another file with extern to Num. That
The compilation system thus knows that NUM is an external variable that has been defined elsewhere, and that it first found in this file the absence of the external variable num, if so, extend its scope to the start of the line (as described in the previous section), and if there is no such external variable in this file, look for the external variable num from other files when the program is connected, if so, To extend the scope of the external variable num defined in another file to this file, the external variable num can be legitimately referenced in this file.
Analysis of the following example:
Filel.cpp
extern int a,b;
int main ()
{
cout<<a<< "," <<b<<end!;
return 0;
}
file2.cpp
int as3,b=4;
┆
Integer variables A and b are defined in the source program file Ffle2.cpp, and the initial value is given. Use extern to declare external variables A and B in filel.cpp. After the compilation is connected to a program, the scope of A and B in file2.cpp extends to the File2.cpp file, so the cout statement in the main function outputs a and B values of 3 and 4.
Using extern to extend the scope of a global variable, although it can be convenient for programming, should be very prudent, because when executing a function in a file, the value of that global variable may be changed, thus affecting the result of function execution in another file.
Declaring static external variables with static
Sometimes in the program design, some external variables are expected to be limited to the reference of this file, but not to other files. You can then add a static declaration when you define an external variable. For example:
File1.cpp
static int a=3;
int main ()
{
┆
}
File2.cpp
extern int A;
int fun (int n)
{
┆
a=a*n;
┆
}
A global variable A is defined in filel.cpp, but it is declared with static, so it can only be used for this file, although the "extern int A;" is used in the CPP file, but the global variable A in Filel.cpp is still not available in File2.cpp file.
This plus static declaration, and only external variables (global variables) for this file, is called static external variables. This provides convenience for the modularization and universality of the program. If you already know that other files do not need to refer to the global variables of this file, you can add static to the global variables in this file, and become statically external variables to avoid misuse by other files.
It should be noted that it is not a mistake to assume that external variables declared with static are static storage (stored in static storage), and that dynamic storage is not static (stored in a dynamic store). In fact, both forms of external variables are stored in a static way, but the scope is different, the memory is allocated at compile time.
C + + Variable Properties summary
A variable has 3 properties in addition to the data type:
Storage Category C + + allows the use of Auto,static,register and extern 4 storage categories.
A scope is a range in a program that can reference the variable.
The storage period refers to the amount of time the variable is stored in memory.
The above 3 attributes are related, the programmer can only declare the storage category of variables, through the storage category can determine the scope and storage period of variables.
Be aware of the use of storage categories. Auto, static, and register 3 storage categories can only be used in the definition statement of a variable, such as:
Auto Char c; Character type automatic variable, define static
int A;//static local integer variable or static external integer variable
register int D;//integer register variable, define
extern int B in function; Declare a defined external integer variable
Description: extern can only be used to declare a defined external variable, not the definition of a variable. As long as you see extern, you can decide that this is a variable declaration, not a statement that defines a variable.
The following is an analysis of the links between them from different angles.
1 from the scope angle, there are local variables and global variables. The storage categories they use are as follows:
Local variables
Automatic variables, i.e. dynamic local variables (leaving the function, the value disappears)
Static local variable (left function, value still retained)
Register variable (away from function, value disappears)
Formal arguments (can be defined as automatic variables or register variables)
Global variables
Static external variables (referenced in this file only)
External variables (that is, non-static external variables that allow other file references)
2) from the variable storage period (the existence of time) to distinguish between dynamic storage and static storage of two types. Static storage is the entire running time of the program, while dynamic storage is the temporary allocation unit when the function is called.
Dynamic storage
Automatic variables (valid within this function)
Register variable (valid within this function)
Formal parameters
Static storage
Static local variables (valid within functions)
Static external variables (valid in this file)
External variables (other files can be referenced)
3 the position from which the value of the variable is stored. Can be divided into:
In-memory static storage
Static local Variables
static external variable (function external static variable)
External variables (can be referenced by other files)
In-Memory dynamic storage: Automatic variables and formal parameters
Registers in the CPU: register variables
4 The concept of scope and storage period.
From the preceding narration, we can know that the nature of a variable can be analyzed from two aspects, one is from the scope of the variable, the other is the length of time from the value of the variable, that is, the storage period. The former is from the angle of space, the latter is from the angle of time. The two are connected but not the same thing. The following figure is a schematic of the scope, and the following figure is a schematic of the storage period.
If a variable is valid within the scope of a file or function, the file or function is called the scope of the variable, and the variable can be referenced in this scope, so that the variable is "visible" within the scope, which is also known as the variable's visibility, such as the variable a?b in the graph as it is visible in the function F1.
If a variable value exists at some point, it is considered to be the storage period of the variable, or the variable "exists" at this time. The following table represents the scope and existence of various types of variables.
where "√" means yes, "X" indicates no. You can see that both the visibility and the existence of the automatic and register variables are consistent within the function. The visibility and existence outside the function are also consistent. The visibility and existence of static local variables outside the function are inconsistent. The visibility and existence of static external variables and external variables are consistent.
If a variable is valid within the scope of a file or function, the file or function is called the scope of the variable, and the variable can be referenced in this scope, so that the variable is "visible" within the scope, which is also known as the variable's visibility, such as the variable a?b in the graph as it is visible in the function F1.
If a variable value exists at some point, it is considered to be the storage period of the variable, or the variable "exists" at this time. The table in the book represents the scope and existence of various types of variables.
You can see that both the visibility and the existence of the automatic and register variables are consistent within the function. The visibility and existence outside the function are also consistent. The visibility and existence of static local variables outside the function are inconsistent. The visibility and existence of static external variables and external variables are consistent.
5 The static declaration makes the variable statically stored, but it has different effects on local variables and global variables.
For local variables, static changes the variable from dynamic storage to a static storage method. For global variables, it causes the variables to be localized (local to this file), but still stored in a static way. From the scope point of view, where there is a static declaration, its scope is limited, or limited to this function (static local variables), or limited to this file (static external variables).