Storage method and lifetime of variables in C language

1. Dynamic storage method and static storage method

To distinguish from the scope of variables全局变量 , variables can be divided into and 局部变量. To distinguish
from the lifetime of variables静态存储方式 , variables can be divided into and 动态存储方式.

  1. Static storage mode固定的 : the way in which the system allocates storage space during the running of the program .
  2. Dynamic storage method动态分配 : the method of storing space according to the needs during the running of the program .

The storage space in memory for users (easy to understand, roughly divided):
image.png
data are stored in static storage area and dynamic storage area respectively.

The global variables are all stored in the static storage area , and 程序开始执行when the global variables are given 分配存储区, 程序执行完毕就释放. Occupied throughout program execution 固定的存储单元, rather than dynamically allocated and freed.

All local variables are stored in the dynamic storage area, in addition to the formal parameters of the function, the variables defined in the function that are not declared with the keyword static, the field protection and return address when the function is called, etc. are all stored in the dynamic storage area middle. For these data, in 函数调用开始时分配动态存储空间, 函数调用结束时释放这些空间, this allocation and release is done dynamically.


Second, the storage class of C language variables

In C language, each variable and function has two attributes : data type (int, float...) and data storage class.

When defining and declaring variables and functions, generally the sum should be specified at the same time 数据类型. 存储类别If the user does not specify a storage class, the system will 默认automatically specify a storage class.

C language storage categories include four : automatic (auto), static (static), register (register), external (extern).

According to the storage class of the variable, the scope and lifetime of the variable can be known.


(1) The storage class of local variables

1. Automatic variables (auto)

The system default local variable storage class . When calling a function, the system will allocate storage space for the formal parameters of the function and local variables defined in the function (including local variables defined in compound statements). These storage spaces are automatically released at the end of the function call, so this type of local variable is called 自动变量.

Automatic variables are declared using the keyword auto as the storage class. For example:

int fun(int a)      //a为形参
{
    
    
    auto int b = 3; //b为自动变量
}

The auto keyword can be omitted, if not written, the system 默认will specify it as an automatic variable. The automatic variable is a dynamic storage method , the memory unit is allocated in the dynamic storage area, and released immediately after the function call ends.


2. Static local variables (static)

Sometimes it is hoped that the value of the local variable in the function will not disappear after the function call ends and continue to retain the original value , that is, the storage unit occupied by it will not be released. When the function is called next time, the variable in the function already has a value (that is, the last function value at the end of the call). At this time, it is necessary to specify the local variable as “静态局部变量”, and use the keyword static to declare. For example:

#include <stdio.h>

int fun()
{
    
    
	static int a = 0;  //静态局部变量,调用结束后内存不释放,保留值。
	a++;
    
	return a;
}

int main()
{
    
    
	printf("%d\n", fun());  //1
	printf("%d\n", fun());  //2
	printf("%d\n", fun());  //3
	printf("%d\n", fun());  //4
	printf("%d\n", fun());  //5
    
    return 0;
}

Static local variables belong to the static storage category , and memory units are allocated in the static storage area, and are not released during the entire running of the program.

Static local variables need to be assigned an initial value. If no initial value is assigned during definition, the system automatically assigns an initial value of 0, and the character type automatically assigns a value of '\0'.


3. Register variables (register) (only for understanding)

The value of a general variable is stored in memory, whether it is static storage or dynamic storage. When a variable is used by the program, 控制器the value of the variable in the memory is sent to the program by issuing an instruction 运算器.

However, if some variables are frequently used, a lot of execution efficiency will be lost in accessing the value of the variable. For example:

void fun()
{
    
    
    int a = 0;
	for (int i = 0; i < 100*100*100; i++)
	{
    
    
		a = a + 1;
	}
}

In order to improve execution efficiency, the C language allows the value of local variables to be stored in CPU的寄存器, and when needed, it is directly taken out of the register to participate in the operation, because the access speed of the register is much higher than the access speed of the memory. Such variables, which store their values ​​in registers, are called 寄存器变量and declared with the keyword register. For example:

void fun()
{
    
    
    register int a = 0; //定义a为寄存器变量
	for (int i = 0; i < 100*100*100; i++)
	{
    
    
		a = a + 1;
	}
}

Generally, the current compilation system can automatically identify frequently used variables and automatically store them in registers without additional specification, so there are very few scenarios where registers are used to declare variables. Just to understand.


(2) The storage class of global variables

Global variables are stored in the static storage area, so their lifetime is fixed and exist throughout the running process of the program. (If the global variable is not assigned an initial value, the system automatically assigns a value of 0.) But for global variables, the scope can also have different specified ranges.

Can be divided into four types:

  1. The default domain is valid from the definition to the end of the file
  2. Extended scope, valid within the current source file
  3. Then extend the scope, it is also valid in other source files
  4. It is only valid within this source file and cannot be referenced by other files

1. Expand the scope of global variables in a file - extern usage one

Global variables are also called extrinsic variables, i.e. variables defined outside a function. If the global variable is not defined at the beginning of the file, its effective scope 只限于is defined to the end of the file, and the function before the definition point cannot refer to the variable.

For some use requirement, if the function before the definition point needs to refer to the global variable , the extern keyword should be used to refer to the variable before the reference “外部变量声明”, indicating that the scope of the external variable is extended to this position.

For example:

#include <stdio.h>

int main()
{
    
    
	printf("%d\t%d\t%d", A, B, C);
    return 0;
}

int A = 1, B = 2, C = 3;

/*
错误	C2065	“A”: 未声明的标识符
错误	C2065	“B”: 未声明的标识符
错误	C2065	“C”: 未声明的标识符
*/
#include <stdio.h>

int main()
{
    
    
	extern int A, B, C; //或者省略类型,extern A, B, C; 也可以
	printf("%d\t%d\t%d", A, B, C); //1       2       3
    return 0;
}

int A = 1, B = 2, C = 3;

2. Extend the scope of global variables to other files - extern usage 2

If one file wants to refer to an external variable already defined in another file , you cannot define an external variable with the same name in the two files, otherwise an error of repeated definition will occur.

The correct way is to do it in one file 定义, and use 外部变量Aextern in another file , that is, "extern A;". At compile time the system will thus know that the defined external variable A can be found elsewhere. The external variable A that is defined in another file will be transferred to this file, and the legal external variable A in this file.A“外部变量声明”A有“外部链接”外部变量A的作用域扩展引用

Therefore, extern can be used not only to extend the scope of external variables in this file, but also to extend the scope of external variables from one file to other files in the program.

So how does the system 区分handle both? In fact, when extern is encountered during compilation, the system will first 本文件find the definition of the external variable in , and if 找到so, it is there 本文件中扩展作用域. If 找不到so, find it 其他文件from it 外部变量的定义, if it is in other files 找到, it will 作用域扩展go to this file, if it is still there 找不到, it will be 出错processed.

Limit the scope of external variables to this file—static's restrictive effect on global variables

If you want some external variables to be referenced only by this file, but not by other files , you can add a static statement when defining the external variables. For example:

//文件1:file1.c

static int A;

int main()
{
    
    
    //······
    return 0;
}
//文件2:file2.c

extern A;

int fun(int n)
{
    
    
    //······
    A = A * n;     //报错
    //······
}

The global variables declared with static can only be used in this file. In this state we call it a static external variable. If it is confirmed that other files do not need to refer to the external variables of this file, you can add static to the external variables of this file 静态外部变量to avoid being misused by other files, which is equivalent to linking the external variables of this file 屏蔽.

It should be noted that global variables are originally stored in the static storage area, and adding static has no effect on the storage method of global variables.


3. Summary

Declaring the storage type of local variables is used to specify the variable storage area (static/dynamic storage area), and the resulting lifetime issues.

Declaring the storage type of the global variable is used to expand the scope of the variable. Global variables are stored in the static storage area from beginning to end.

The effect of declaring variables with static is:

  1. Use a static declaration for a local variable : allocate it in a static storage area, the variable is not released during the entire program execution, and the space allocated to it always exists. Change the local variable from dynamic storage to static storage.
  2. Use static declaration for global variables : the scope of this variable is limited to this file module (in the declared file). Make global variables localized (local to this file), but still in static storage.

image.png
image.png
image.png

Guess you like

Origin blog.csdn.net/jiang1126/article/details/125356117