以下都是基于C语言的描述。
一、作用域作用域是衡量标识符作用范围的一个或多个区域。主要分为三种:
- 代码块作用域
- 函数原型作用域
- 文件作用域
- 函数作用域(goto语句)
代码块作用域一般指的是函数体,如:
void fun(int i)
{
//这里代码块作用域
}
函数原型作用域,指的是出现在函数参数部分的变量:
void use_a_VLA(int n,int m,int ar[n][m])
这里的n、m在中括号的使用就是函数原型作用域。
文件作用域 文件作用域是作用范围是工程下所有源文件,如果一个变量具有文件作用域,那么这个变量也叫全局变量。
二、受限的文件作用域 extern const static链接也有三种类型:
- 外部链接
- 内部链接
- 空链接
一个全局变量默认是具有文件作用域的,这也意味着,全局变量在不同源文件只能出现一次。如:
//a.cpp
int a=4396;
//main.cpp
int a=4;
a.cpp和main.cpp都有一个全局变量a,编译不能通过,这是因为全局变量标识符冲突,造成了重定义的现象,编译器并不知道你需要的是4396还是4。但是我确实需要定义一个只在当前文件作用的全局变量,如何做?
-
如果全局变量是不变的,可以使用
const
,默认情况下,全局常量是一个文件私有的、独享的全局变量。 -
如果你的变量可能改变,那么
static
用于修饰该全局变量,说明它是一个文件私有的、独享的全局变量。
普通意义上的全局变量是所有源文件共享的。
//a.cpp
int a=4396;
//main.cpp
int a;
编译是不能通过的,编译器仍固执的认为int a
是一个定义,因此还是重定义,但是我们将main.cpp的int a
去掉,那么又会出现没有声明a变量,如何解决?
extern
关键字,用于声明这个变量是一个声明而不是一个定义:
//a.cpp
int a=4396;
//main.cpp
extern int a;
注意,const变量默认是不共享的,因此,如果你需要共享这个变量,那么你必须在定义前加上extern
说明这个常量是共享的。
链接属性就是为了描述其文件作用域属性的。
- 内部链接
- 外部链接
- 空链接
内部链接就是文件作用域中,文件私有的变量;外部链接就是全部源文件共享的变量;空链接则表示既不是外部也不是内部,如代码块作用域、原型作用域。
四、存储时期存储时期是指变量的生存周期,分为两类:
- 静态存储时期
- 自动存储时期
静态存储时期的变量有:全局变量、static修饰的局部变量和堆上分配的变量。
自动存储时期:局部变量,也就是函数块作用域和函数原型作用域。