C语言之谈谈存储类、链接。

来源:互联网 发布:齐白石真迹价格 知乎 编辑:程序博客网 时间:2024/06/13 07:49

C语言学习的一大难区就是内存管理,存储类,链接,我认识是对内存管理操作之前所必须要掌握的。
在我们大一学习C语言的时候,曾经碰见过一些关键字:static,extern,以及在单片机编程时遇到的register。
其实当我们对存储类,链接有了了解之后, 这些疑惑都会解决。
1.存储类
首先我们讨论存储类,存储类: 变量与函数的可访问性(即作用域范围scope)与生存期(life time)。
我们可以按照一个变量的存储时期描述它,也可以按照它的作用域和它的链接来描述它。
作用域,我们可以理解为一个代码块,即{},在这个代码块里面所定义的变量,就具有代码块作用域。
例如:

#include<stdio.h>int main(){    int i;    int j = 5;    for (i = 0; i<10; i++)    {        int tmp = i*j;    }    return 0;}

在这个例子中,变量tmp他只在for循环这个代码块中作用,所以他的作用域就是for循环内部代码块内,只有在这个代码块内,才可以来访问tmp;并且tmp还是临时变量,出了代码块以后,就会被销毁。
2.链接
搞清楚存储类以后我们要弄清楚什么是链接,链接分为三种,内部链接,外部链接以及空链接。
空链接:就是只对一个定义的代码块私有的。
外部链接:变量可以在多个文件使用。
内部链接:变量只可以在一个文件使用。
3.存储时期
对于存储时期,其实我们接触的已经很多,我们把它分为了静态存储时期和自动存储时期。静态的,就是一直存在的,程序执行期间一直存在。在这里要注意,其实我们常用的关键字static,它表明的并非存储时期,而是链接类型,它表示了一个变量具有内部链接,而对于所有的变量,无论是内部的,还是外部的,他们都具有静态存储时期。
自动存储时期:这种类型的变量一般说的都是在一个代码块内的变量,当进入代码块时,它分配内存,当退出代码块时,内存被销毁。我们所有使用的局部变量都是属于自动存储时期的。
例如:

#include<stdio.h>int main(){    int i;    int j = 5;    for (i = 0; i<10; i++)    {        int tmp = i*j;    }    return 0;}

还是在这个程序中,我们所定义的tmp就是一个局部变量。他就是自动存储类型。
在C中,我们常用的存储类有五种:自动,寄存器,具有代码块作用域的静态,具有外部链接的静态,内部链接的静态。
这里写图片描述

到此,我们就可以搞清楚所有的存储类的问题了。
接下来,我们会对这5种存储类一一分析。
4.自动变量
自动变了,我们使用关键字auto,但是程序在默认情况下,代码块和函数的头部定义全部都为自动存储类,所以,这个auto我们常常会被省略。
例:

int main(){    auto int i;    ...}

这个其实就和我们平时对变量i直接声明是一样的,只不过auto大多数都被省略了。
5.寄存器变量
在这里我们提到了寄存器,寄存器,也是一种储存数据的硬件,它比内存速度更快,所以在很多时候,我们写的程序被编译器储存在了寄存器当中,这样会使得程序运行速度更快。所以寄存器和内存是分开的两个东西,寄存器变量储存在寄存器中,一般使用是为了速度更优化,需要注意的是,寄存器变量无法取地址,因为它不是开辟在内存上。
6.具有外部链接的静态变量
首先我们要知道,这是一个静态变量,关于静态变量我们要明确,静态,指的是储存方式,但是是静态储存方式的不一定是静态变量,比如:外部变量,他虽然是静态储存方式,但是却不是静态变量。
具有外部链接的静态变量,他把变量的定义声明放在所有函数之外,即创建一个外部变量,然后再引用时,通过使用extern关键字来再次声明他。

#include<stdio.h>int val = 10;int main(){    extern int val;    ...    return 0;}

在这一段代码中我们可以清楚的看到,在main()函数引用val时,前面加上了extern关键字,这个是因为,在main函数之外定义了val这个变量,这个变量就是具有外部链接的静态变量,如果漏掉了extern,他就变成一个独立的变量,会在main函数再次开辟空间进行操作。
对于像上面这个例子中的val这样的外部变量,当你不对它进行初始化的时候,他会被自动赋值0。
对于外部变量,也有限制,取名时要遵守局部环境的规则。
另外,不要使用extern来进行外部定义。
例:

extern char per = 'Y';

我们要清楚,extern知识对变量进行引用,不能进行定义。

7.具有内部链接的静态变量。
这种变量是在函数内部进行定义,他依然使用static关键字,这样他只能在一个文件中操作。
例:

static int max = 10;int main(){    ...}

他的引用依然使用存储类说明符extern来再次声明变量。
例:

static traveler = 1;int spot = 2;int main(){    extern int travler;    extern int spot;}
1 0