《C Primer Plus》 第12章 存储类别、链接和内存管理 学习总结
目录
12.1 存储类别
12.1.1 作用域
作用域:描述程序中可访问标识符的区域。
C变量的作用域有四种:块作用域、函数作用域、函数原型作用域、文件作用域。
块作用域:用一对花括号括起来的代码区域。
{ }
函数作用域:仅用于goto语句的标签。
函数原型作用域:用于函数原型中的形参名(变量名)。范围是从形参定义道原型声明结束。编译器只关心函数原型中形参的类型,形参名并无大碍。(除了变长数组)
void use_a_VLA(int n,int m,ar[n][m];
文件作用域:变量的定义在函数的外面。其具有文件作用域变量,也称为全局变量
12.1.2 链接
C变量有三种链接属性:外部链接、内部链接或无连接
无连接:具有块作用域、函数作用域或函数原型作用域的变量都是无连接变量。也就是其私有。
内部链接:只能在一个翻译单元使用。
外部链接:可以在多文件程序中使用。
12.1.3存储期
C对象有四种存储期:静态存储器、线程存储期、自动存储期、动态分配存储期
静态存储期:在程序执行期间一直存在。文件作用域变量就具有静态存储期。
线程存储期:用于并发程序设计,从被声明到线程结束一直存在。
自动存储期:块作用域的变量都具有自动存储期,程序进入定义这些变量的块时,为这些变量分配内存;退出时,释放刚才为变量分配的内存。
void bore (int number)
{
//变量number和index在每次调用bore()函数时被创建,离开函数时被销毁。
int index;
for(index=0;index<number;index++)
puts("they don't make them the way they used to.\n);
return 0;
}
其他5种存储类别
存储类别 | 存储期 | 作用域 | 链接 | 声明方式 |
---|---|---|---|---|
自动 | 自动 | 块 | 无 | 块内 |
寄存器 | 自动 | 块 | 无 | 块内,使用关键字register |
静态外部链接 | 静态 | 文件 | 外部 | 外部 |
静态内部链接 | 静态 | 文件 | 内部 | 所有函数外,使用关键字static |
静态无连接 | 静态 | 块 | 无 | 块内,使用关键字static |
12.1.4 自动变量
属于自动存储类别的变量具有:自动存储期、块作用域、无连接。默认情况下,声明在块或函数头中的任何变量都属于自动存储类别。
关键字auto(存储类别说明符)
int main(void)
{
auto int plox;
}
嵌套块
内层块会隐藏外层块的定义。离开内层块后,外层块变量的作用域又回到了原来的作用域。
#include<stdio.h>
int main(void)
{
int x=30; //原始的x
printf("%d",x);
{
int x=77; //新的x,隐藏了原始的x。
printf("%d",x);
}
return 0;
}
未初始化,其值未定。
12.1.5 寄存器变量
在块中带有register存储类别说明符声明的变量(或函数头中的形参)。具有自动存储期、块作用域、无链接,且无法获取地址。未初始化,其值未定。
12.1.6 块作用域的静态变量
在块中带static存储类别说明符声明的变量属于“静态、无连接”存储类别,具有静态存储期、块作用域。无连接。未显式初始化,字节为0。
12.1.7 外部链接的静态变量
在所有函数外且没有使用static存储类别说明符声明的变量属于“静态、外部链接”存储类别。具有静态存储期、文件作用域、外部链接。未显式初始化,字节为0。
12.1.8 内部链接的静态变量
在所有函数外部且使用了static存储类别说明符声明的变量属于“静态、内部链接”存储类别。具有静态存储期、文件作用域、内部链接。
12.2 随机数函数和静态变量
随机数函数:rand(),srand()
rand():伪随机,有实际序列,但数字在其值范围内均匀分布。
12.4 分配内存:malloc()和free()
需要#include<stdlib.h>
为函数提供原型。
malloc():是动态内存分配函数,用来向系统请求分配内存空间,函数返回一个指向指定字节数内存块的指针。
free():通常malloc()要与free()配套使用。申请到的空间不再使用时,要用free()函数将内存空间释放掉,函数以该内存块的地址作为参数。
两者结合使用才被称为“动态内存分配”。
calloc():把块中所有位设为0.
12.5 ANSI C 类型限定符
12.5.1 const类型限定符
const在类型名之后、*之前,说明该指针不能用于改变它所指向的值。放在 * 右侧限定了指针本身不能改变。
在函数原型和函数头,形参声明const,保证数据不被更改。
全局变量使用const避免暴露数据。文件共享则需改用extern关键字。
12.5.2 volatile类型限定符
除了被当前程序修改,还可被其他进程修改。警告编译器不要进行假定优化。
12.5.3 restrict类型限定符
允许编译器优化某部分代码。
用于函数形参中的指针,编译器可以假定在函数体内其他标识符不会修改该指针所指向的数据。
_Atomic类型限定符
(并发程序设计QAQ实在看不懂)
最后附上malloc()函数和calloc()函数区别文章malloc()和calloc()区别