c语言指针详解(经典,非常详细)的问题

指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。

如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示:


将这种关系转换为C语言代码: 指针变量也是一种变量,也会占用存储空间,也可以使用&获取它的地址。C语言不限制指针的级数,每增加一级指针,在定义指针变量时就得增加一个星号*。p1 是一级指针,指向普通类型的数据,定义时有一个*;p2 是二级指针,指向一级指针 p1,定义时有两个*

如果我们希望再定义一个三级指针 p3,让它指向 p2,那么可以这样写:

四级指针也是类似的道理: 实际开发中会经常使用一级指针和二级指针,几乎用不到高级指针。

想要获取指针指向的数据时,一级指针加一个*,二级指针加两个*,三级指针加三个*,以此类推,请看代码:

p1 的地址;*(*p3) 得到的是 p1 的值,也即 a 的地址;经过三次“取值”操作后,*(*(*p3)) 得到的才是 a 的值。
方框里面是变量本身的值,方框下面是变量的地址。

指针(pointer)到底是什么,弄清楚这个问题很重要,这是我们所讨论的话题的源头,而在阐述指针是什么之前,我们需要先来看一下变量的概念。

我们知道,计算机的内存(primary storage)被划分为多个存储单元,这些存储单元可以以单个或者顺序相连组成一个更大单元的方式被使用。每一个单独的存储单元都是一个字节(byte),它通常由8个位(bit)组成,每一个位可以表示的值只有01。每一个存储单元都被一个及其分配的标识唯一地表示,而这个标识就是地址。

下图表示了存储单元单独被操作时的情形,矩形表示存储单元,矩形内的内容是存储在这个内存单元的具体的值。矩形上方的数就是每个内存单元的地址。因为每个单元为一个字节,而每个字符型常量(character constant)所占据的正是一个字节,如下所示:

这次的情况是顺序连成组进行操作,对于整型常量(integer constant),在32位计算机中需要四个字节来存储(有一点要声明,208位置的那个矩形里的1078345超出了int类型的范围,是long C只规定了long型数据长度不小于int型,int型数据长度不小于short型,并规定int型为16位,long型为32位,然而很多编译器采取的策略是使longint型数据占据相同的内存字节数,即全为32位),所以地址以4个单位增长(也就是说现在的一个矩形表示4个内存单元),这次矩形下面多了几个小写字母,存储在矩形里面的值不是固定唯一的,而是可变的。我们可以把矩形认为是一个变量(variable),每次我们要引用矩形里的值时,机器都是通过地址来定位(那个矩形)并取得其中的值的,而对于我们来说要记住这些地址几乎是不可能的,所以高级语言提供了用名字来访问内存位置的特性,它们就是变量名,即上图的abcd

现在用变量名替换掉上图中的地址:

大家要注意,变量名与地址的关联是由编译器为我们实现的,具体的实现方式我们无需关心,但要清楚硬件仍然是通过地址访问内存位置的。接下来,继续看图:

来看新增的Ptr,同样是个变量,它也有地址,它的值是变量a的地址。至此可以给出指针的定义了:指针是一种用于存放另一个变量的地址的变量。上图中的Ptr就是一个指针,并且我们说它指向了变量a(因为Ptr的值是变量a的地址),要注意指针中只能存放地址,不能将一个整型量或者其他非地址类型(整型数0及具有0值的整形常量表达式除外,后面的文章会细致讲解)的数据赋给一个指针!

还有,指针这个词,由于是对pointer这个词翻译得来,完整的叫法应该是指针变量,由于指针变量中存的地址,而在很多英文资料中,指针(pointer)的涵义不完全都是指针变量,有时也指地址,请大家在阅读或参考资料时注意区分!

(注:本章及后续章节中用以表示内存的矩形中的值及其地址只是为了简洁易读从而采用十进制数表示。)

我要回帖

更多关于 c语言指针详解(经典,非常详细) 的文章

 

随机推荐