C语言内存管理--作用域和生命周期
C语言内存管理--作用域和生命周期
作用域和生命周期
C语言作用域分为:
- 代码块作用域(代码块是{}之间的代码段)
- 函数作用域
- 文件作用域
普通局部变量
- 在{}内部定义的变量就是局部变量。
- 只有执行到定义变量的这个语句,系统才会给这个变量分配空间。
- 当离开{},这个非static局部自动释放。
- 局部变量的作用域在当前{},离开此{},无法使用此变量。
- 不同的{}中,变量名字可以一样,同一个{}中变量名字不可以一样。
- {}的普通局部变量,加不加auto关键字等价,普通局部变量也是自动变量。
- 如果普通局部变量不初始化,值为随机值。
static局部变量
- 在{}内部定义的static局部变量。
- static局部变量,在编译阶段就已经分配空间了,函数没有调用前,他已经存在。
- 当离开{},static局部变量不会释放,只有程序结束static才会自动释放。
- 如果static局部变量不初始化,他的值默认为0,static局部变量初始化只会执行一次,但可以多次赋值。
for(int i = 0;i<10 ;i++){
static int a = 1;
a++ ;
}
上面这段代码中,static虽然在for循环内,但它只会初始化一次,但a++可多次使用。
- static变量只能使用常量初始化,不可以使用变量值初始化。因为static在函数没有执行的时候就已经存在了,而普通变量只有在函数运行时才定义并赋值。
普通全局变量(外部链接)
-
定义在函数外面的变量。
-
只要定义了普通全局变量,在任何函数都能够使用此变量。
-
如果使用普通全局变量时,在前面找不到此普通全局变量的定义,则需要声明后才可使用。
void fun(){
extern int a ;
a = 10 ;
}
int a = 1 ;
int main(){
printf("a = %d",a) ;
return 0 ;
}
如上面代码段中,普通全局变量a定义在fun函数后面, 所以需要在fun函数内使用extern声明普通全局变量a的存在。
- 普通全局变量不初始化,默认值为0。
- 声明只能全局变量使用,局部变量不能使用。
- 普通全局变量只能定义一次,可以声明多次。
- 普通全局变量在编译阶段就已经存在,它的生命周期为程序执行周期,程序结束才会释放。
普通全局变量的缺陷
函数中,程序员写的全局变量a是有第三次被系统认为是定义,其他的都是声明。对于全局变量b没有初始化,有两个是声明,一个是定义,但我们无法确定哪一个b是定义,哪两个是声明。不过c++对这里做了优化,不允许我们这么做,但是c允许,所以这里是C语言中全局变量的一点缺陷。
int a ;
int a ;
int a = 1 ;
int a ;
//
int b ;
int b ;
int b ;
int main(){
return 0 ;
}
static全局变量(内部链接)
-
static的作用域和普通全局变量的作用域不一样(文件作用域)。
-
extern关键字不能使用。
-
一个文件只能有一个同名static全局变量的定义,一个文件不能出现多个。多个文件中可以存在相同名字的static全局变量。
-
static全局变量只能在当前文件使用。如在main.c文件中有一个static int a ;在tast.c中就不能使用main.c中的全局变量a。
全局变量不安全,能够不用的话就尽量不用!
普通函数和static函数区别
- 所有文件只能有一次普通函数的定义,而每个文件都可以有一次static函数定义。
- 普通函数所有文件都能使用,前提有使用前声明,static函数只能在该文件内使用。