目录
存储类别
根据一个变量的作用域(可见的范围)和生命期(它存在多长时间)来划分存储类别。
作用域
根据作用域可分为块作用域,函数作用域,函数原型作用域,文件作用域。
块作用域:在{}之间都一个属于块作用域。块里面定义的变量,作用范围是从定义处到包含该定义的块的末尾。
函数作用域:这个我也不太清楚,书上讲仅用于goto语句的标签。
函数原型作用域:这个比较常见,函数原型的形参名(变量名)是也,如下所示:
int mighty(int mouse,double large);//里面的mouse,large都属于函数原型作用域
它们的作用范围是从形参定义处到原型声明结束。
文件作用域:变量的定义在函数外面,具有文件作用域,作用域为:从它定义处到该定义所在文件的末尾
链接
C变量具有三种链接属性:外部链接,内部链接和无链接。
无链接:具有块作用域,函数作用域或函数原型作用域的变量都是无链接变量。这意味着这些变量属于定义它们的块,函数或原型私有。
内部链接:内部链接变量即在该文件内部使用。使用static进行修饰,一旦变量使用static修饰后,外部文件将无法访问,只有文件内部才能够进行访问。
外部链接:外部链接就是跨文件访问,使用extern进行修饰,一般出现在多文件程序中。
存储期
作用域和链接描述了标识符的可见性。存储期描述通过这些标识符访问的对象的生存期。C对象有4种存储期:静态存储期,线程存储期,自动存储期,动态分配存储期。
静态存储期:在程序运行期间始终占有同一内存单元,静止不变。注意:对于文件作用域变量,关键字static表明了它的链接属性,而不是存储期,以static声明的文件作用域具有内部链接。但是无论内部链接还是外部链接,所有的文件作用域变量都具有静态存储期。
线程存储期:以关键词_Thread_local声明一个对象时,每个线程都获得该变量的私有备份。它的存储期从被声明时到线程结束一直存在。
自动存储期:块作用域的变量一般都具有自动存储期。当程序进入定义这些变量的块时,为这些变量分配内存,当退出这个块时,释放刚才为变量分配的内存。也就是说一个函数调用完毕后,它占用的内存可用于存储下个被调用函数的变量。
动态分配存储期:这个比较重要,更加主动一点,通过函数malloc()进行。
double* ptd;
ptd=(double*) malloc(30 * sizeof(double));//分配30个大小为double类型的空间,ptd指向这个块的首元素
也可以说通过malloc(),我们创建了一个30个double类型大小的数组,通过ptd[n]进行访问第n+1个数。它可以创建动态数组,例子如下:
ptd=(double*)malloc(n*sizeof(double));//其中n是变量
还有一个函数free(),它是用来释放malloc()分配的内存,静态内存的数量在编译时是固定的,在程序运行期间也不会改变。自动变量使用的内存数量在程序执行期间自动增加或减少。但是动态分配的内存的内存数量只会增加,除非用free()进行释放。它的代码框架如下:
double* temp=(double*)malloc(n * sizeof(double));//分配动态内存
free(temp);//释放内存,一般应该在内存不需要的时候再执行
存储类别 | 存储期 | 作用域 | 链接 | 声明方式 |
---|---|---|---|---|
自动 | 自动 | 块 | 无 | 块内 |
寄存器 | 自动 | 块 | 无 | 块内,使用关键字register |
静态外部链接 | 静态 | 文件 | 外部 | 所有函数外 |
静态内部链接 | 静态 | 文件 | 内部 | 所有函数外,使用关键字static |
静态无链接 | 静态 | 块 | 无 | 块内,使用关键字static |