C语言的存储类别包括4种:自动的(auto)、静态的(static)、寄存器(register)、外部的(exteren)
1.自动变量(auto变量)
函数中的局部变量,如果不专门声明为(static)静态存储类别,都是动态地分配存储空间的,数据存储在动态存储区中。
形参与函数中定义的局部变量,都是自动变量,在调用结束就会自动释放这些存储空间
2.静态局部变量(static局部变量)
(1)静态局部变量属于静态存储类别,在静态存储区分配存储单元,在程序整个运行期间都不释放。而自动变量(动态局部变量)属于动态存储类别,分配在动态存储区空间而不在静态存储空间,函数调用结束后即释放。
(2)对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时已有初值,以后每次调用不需要重新赋值,而是只保留
上次函数调用结束时的值,对自动变量赋初值,不是在编译时进行的,而是在函数调用时进行的,每调用一次函数重新给一次初值,相当于执行一次赋值语句。
(3)如果在定义局部变量时不赋初值,则对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符'\0'(对字符变量)。而对自动变量来说,它的值是一个不确定的值,这是由于每次函数调用结束后存储单元已释放,下次调用时又重新分配存储单元,而所分配的单元中的内容是不可知的
(4)虽然静态局部变量在函数调用结束后仍然存在,但其他函数是不能引用它的。因为它是局部变量,只能被本函数引用。
3.寄存器变量(register变量)
一些变量使用频繁,存取变量要花费不少时间,提高效率,允许把局部变量放在CPU中的寄存器中,直接从寄存器中存取,可以提高执行效率,这种变量叫做寄存器变量
3种局部变量的存储位置不同的;自动变量存储在动态存储区,静态变量存储在静态存储区、寄存器存储在CPU中的寄存器中
4.全局变量的存储类别
全局变量都是存放在静态存储区中的,生存期是固定的,存在于整个运行过程。
一般来说,外部变量是在函数的外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的结尾。
(1)在一个文件内扩展外部变量的作用域
extern:不是定义变量,可以不指定类型,只要名称即可
extern int A;
或者
extern A;
int main(){
extern A //在主函数内可以使用A,将A的作用域扩展到此处
}
int A;
(2)将外部变量的作用域扩展到其他文件
文件1 file.c中定义 int A;
文件2 file2.c中使用 extern A;
(3)将外部变量的作用域限制在本文件内
static int A; //静态外部变量
用static声明变量的作用是
(1)对局部变量用static声明,把它分配在静态存储区,该变量在整个程序执行期都不释放,其所在的分配的空间始终存在
(2)对于全局变量用static声明,则该变量的作用域只限于本文件模块(即是被声明的文件中)
(4)存储类别总结:
static int a; //静态局部整型变量或静态外部整型变量
auto char c; //自动变量,在函数内定义
register int d; //寄存器变量,在函数内定义
extern B; //将已定义的外部变量b的作用域扩展至此
一个变量的属性可以从两个方面
(1)作用域:从空间角度
定义:一个变量在某一文件或者函数范围内有效,则被称为该变量的作用域,称为变量的可见性
(2)生存期:从时间角度
定义:在某一时刻时存在的,认为该时刻属于该变量的生存期
各种类型变量的作用域和存在性的情况
变量存储类型
函数内
函数外
作用域
存在性
作用域
存在性
自动变量和寄存器变量
√
√
×
×
静态局部变量
√
√
×
√
静态外部变量
√
√
√(只限本文件)
√
外部变量
√
√
√
√
(3)static对于全局变量和局部变量作用不同
对于局部变量来说,它使变量由动态方式改变为静态存储方式
对于全局变量来说,它使变量局部化,但是仍为静态存储
从作用域来看
凡是由static声明的,其作用域都是局限的,或者局限于本函数内(静态局部变量),或者局限于本文件内(静态外部变量)。
5.关于变量的声明和定义
一个函数一般有两部分组成:声明部分和执行语句
声明部分的作用是对有关标识符(如变量、函数、结构体、共用体等)属性进行声明
函数的声明是函数的原型,而函数的定义是对函数功能的定义。
对被调用函数的声明是放在主调函数的声明部分中的,而函数定义显然不在声明部分的范围内,它是一个独立的模块
声明:是不需要建立存储空间,声明只是为了扩展该变量的作用范围而做的“声明”。
定义:需要建立存储空间
6.内部函数与外部函数
(1)内部函数又被称为静态函数,用static声明的
如果一个函数只能被本文件中其他函数调用,它被称为内部函数,在定义内部函数时,在函数名和函数类型的前面加static,即
static 类型名 函数名(形参表);
static fun(int a,int b);
(2)外部函数
extern 类型名 函数名(形参表);
extern fun(int a,int b);
// 或者省略不写 默认
fun(int a,int b);