C语言存储类别和链接
目录
C语言存储类别和链接
最近详细的复习C语言,看到存储类别的时候总感觉一些概念模糊不清,现在认真的梳理一下。C语言的优势之一能够让程序员恰到好处的控制程序,可以通过C语言的内存管理系统指定变量的作用域和生存周期,实现对程序的控制。
存储类别
- 基本概念
对象:在C语言中所有的数据都会被存储到内存中,被存储的值会占用一定的物理内存,这样的一块内存被称为对象,它可以储存一个或者多个值,在储存适当的值时一定具有相应的大小。(C语言对象不同于面向对象语言的对象)
标识符:程序需要一种方法来访问对象,这就需要声明变量来实现,例如: int identifier = 1
,在这里identifier
就是一个标识符,标识符是一个名称并遵循变量的命名规则。所以在本例中identifier
即是C程序指定硬件内存中的对象的方式并提供了存储的值的大小“1”。在其它的情况中 int * pt
、int arr[10]
,pt就是一个标志符,它指定了储存地址的变量,但是表达式*p不是一个标志符,因为它不是一个名称。arr
的声明创建了一个可容纳10个int
类型元素的对象,该数组的每一个元素也是一个对象。
作用域:描述程序中可访问标识符的区域。因为一个C变量的作用域可以是块作用域、函数作用域、文件作用域和函数原型作用域。
块作用域:简单来说块作用域就是一对花括号括起来的代码区域。定义在块中的变量具有块作用域,范围是定义处到包含该定义块的末尾。
函数原型作用域:范围是从形参定义处到函数原型声明的结束。我们知道编译器在处理函数形参时只关心它的类型,而形参的名字通常无关紧要。例如:
void fun(int n,double m); 同样可以声明为 void fun(int ,double );
还有一点要注意的是函数体的形参虽然声明在函数的左花括号之前但是它具有的是块作用域属于函数体这个块。
文件作用域:变量的定义在所有函数的外面,从它的定义处到该文件的末尾处均可见称这个变量拥有文件作用域。所以文件作用域变量也被称为全局变量
链接:C变量有三种链接属性:内部链接、外部链接和无链接。具有块作用域、函数原型作用域的变量都是无链接变量,这就意味这他们属于定义他们的块或者函数原型私有。文件作用域变量可以是外部链接或是内部链接,外部链接可以在多个文件中使用,内部链接只能定义它的文件单元中使用。
存储期
指对象在内存中保留了多长时间,作用域和链接描述了对象的可见性。存储期则描述了标识符访问对象的生存期。
C对象有4种存储期:
1) 静态存储期:如果一个对象具有静态存储期,那么它在程序的执行期间一直存在。文件作用域变量具有静态存储期,注意关键字static
表明的是链接属性而不是存储期。以static
声明的文件作用域变量具有内部链接,无论具有内部链接还是外部链接,所有的文件作用域变量都具有静态存储期。
还有一种情况块作用域变量也可以拥有静态存储期,把变量声明在块中并在变量名前加static
关键字,例:
int fun(int num) { static int Index; ... }
在这里变量Index
就被存储在静态内存中,从程序被载入到程序结束都会存在,但是只有程序进入这个块中才会访问它指定的对象。
2) 线程存储期:用于并发程序设计,一个程序的执行可以分为多个线程,具有线程存储期的变量从被声明时到线程结束一直存在。以关键字_Thread_local
声明一个对象时,每个线程都获得该变量的私有备份。
3) 自动存储期:块作用域变量通常具有自动存储期,当程序进入定义这些变量的块时,会为这些变量分配内存,当程序离开这个块时会自动释放变量占用的内存,这种做法相当于把自动变量占用的内存视为可重复利用的工作区或暂存区。
4) 动态分配存储期
五种存储类别
- 五种存储类别
存储类别 | 存储期 | 作用域 | 链接 | 声明方式 |
---|---|---|---|---|
自动 | 自动 | 块 | 无链接 | 块内 |
寄存器 | 自动 | 块 | 无链接 | 块内 关键字regsiter |