C语言复习篇之存储类、链接和内存管理
存储类、链接和内存管理
对存储类、内存管理这方面的学习,能够让我们更加的理解程序的一个运行过程,理解程序在运行中的具体机制和它的实现方法。虽然对于写代码本身并没有太大的帮助,但是它能够使得我们更好的理解程序,更容易去判断程序是否能按我们的意愿来实现,或者说让我们纠错更容易的知道是哪里出了问题。
当然,复习的第一步依然是概念:
1.存储类型
C语言中的存储类型有下面几个关键字:auto、static、register、extern。
auto:自动存储类,由系统自动分配栈存储空间,用户不用操心。这种类型的变量是局部于某个程序范围内的,只能在某个程序范围内使用,一般在函数体内,定义变量的缺省方式就是属于auto类变量。
static:静态存储类,既可以在函数体外也可以在函数体内定义,它在内存中是以固定地址存放的,在整个程序的运行过程中它都不会消失,并且static类型的变量只被初始化一次,且变量的值具有继承性。举个例子:
- void func(void)
- {
- int i = 0;
- i += 1;
- printf("%d\n",i);
- }
- int main(void)
- {
- func();
- func();
- func();
- return 0;
- }
运行结果:1,1,1
但是如果定义是这样的:static int i = 0;结果就不一样了,变成了1,2,3 。我们可以看到加了static关键字之后,每次调用函数func不会重复赋值而是延续上次运算的结果。
register:寄存器存储类型,这种类型是比较牛的,因为不是你写了register关键字它就会变成寄存器类型的变量,这是要看“心情”的,若是“心情”不好就会直接降级成为auto型变量。我们知道寄存器内运行速度是很快的,所以资源就比较宝贵,你定义了这样一个变量之后,编译器会自动判断是否需要满足你。因此对于寄存器变量的定义一般是使用频率比较高的变量。
extern:外部存储类型,用于外部变量的声明,它的作用范围是从定义开始到程序运行结束,它对于变量的类型和值是没有改变的权限的,因为extern关键字是用于声明而不是定义。
声明 | 定义 |
可以多次声明 | 只能定义一次 |
不分配内存,不可初始化 | 分配内存空间,可以初始化 |
定义是特殊的声明 |
2.作用域
代码块作用域:在代码块中({.....}之内的变量)定义的变量的作用的范围。如:局部变量,static局部变量。
函数原型作用域:函数声明(int fun(int x),小括号内的范围)使用变量作用的范围。
文件作用域:在所有函数之外定义的变量的作用的范围,又分为本文件作用域(全局变量static,函数static)和多文件作用域(全局变量和函数)。
3.链接
链接类型其实是和作用域对应起来的。
空链接:具有代码块作用域和函数作用域的变量是空链接。
内部链接:具有文件作用域的变量,它可以在一个文件的任何地方使用。
外部链接:具有文件作用域的变量,它可以在一个多文件程序的任何地方使用。
4.存储期
静态存储期,从变量定义开始到整个程序运行结束。
自动存储期:栈里定义的变量(由系统分配维护),程序进入这些变量的代码块时,将为这些变量分配内存,退出时释放内存。
动态存储期:堆里定义的变量,用户自己定义,malloc( )开始到free ( )或者退出代码块结束。
下面的总结和一个例子:
- int a; //全局变量,静态存储期,外部链接,多文件作用域
- static int b; //全局变量,静态存储期,内部链接,本文件作用域
- void fun(void)
- {
- int x; //局部变量,自动存储期,空链接,代码块作用域
- static int y; //局部变量,静态存储期,空链接,代码块作用域
- }
- int main(void)
- {
- ....
- ....
- return 0
- }
代码分析比较:
- A: B:
- int main(void) int main(void)
- { {
- char *p = "abcdefg"; char p[]="abcdefg";
- *p = ‘x’; *p = ‘x’;
- printf("%s\n",p); printf("%s\n",p);
- return 0; return 0;
- } }
- //A 错误,B正确。
以上代码为什么会有这样的结果呢?这就是一个存储位置的问题了,代码A中字符串“abcdefg”存储于常量区只读数据段,因此是不能改变它的,试图改变它的结果只有一个段错误;而代码B就不同了,数组元素是在栈中分配内存的,可以进行改变等操作。
网上下载的两个图表:
转载于:https://blog.51cto.com/doublewen/765202