复撸C系列(5)-指针(1)

来源:互联网 发布:淘宝介入处理流程 编辑:程序博客网 时间:2024/06/06 17:18


指针

指针作为C语言的精华,也是入门的难点。是很多初学者很惧怕的东西,我也是敲了2年代码才比原来理解得更好一些,不敢说运用得出神入化,但也还算凑合。下面谈谈自己的理解。

 

指针是什么?

不同的书,不同的人都有不同的理解形式,有的人把他作为一种很特别的类型,有的人把他作为一种概念上抽象的东西。我当然也有自己的理解:

        指针 = 一种用于存放地址的变量类型

它本身也要占据内存,一般在32位机型上占4个字节,也就是一个int的大小。要注意一点,无论是什么样类型的指针,占的大小都是一样的。(本文假设环境就是32位,后面不再赘述)

比如:

int *p;

void **p;

struct Node *p;

double*****************p;(夸张一点,我没见过这么惨绝人寰的使用)

 

当你敲下上面的任意一句,运行的到这里的时候,就会分配一个4字节的内存,里面存了一个地址一个数值

如下的代码,在运行时内存是什么样子的?



是这样的:



(这里的内存地址我随便写的)

此处注意,p本身也是占据内存的,p的内存里放了a的地址,以便可以通过p来操作a。

那有人会问了,我为什么不直接操作a?非要弄一个指针来指向它之后再操作它呢?对此我的理解是: 编译器是不会关心你指针与否来操作一块内存,它只知道把你的代码翻译成机器代码(error,warning什么的还是人为的东西,是用来辅助程序员的,编译器也是人写的也是程序啊亲)。其实你敲的这些代码,只是对自己的一种助记符,永远记住:代码是写给人看的不是写给机器看的,一个好的程序员,应该认真对待自己的代码,不要仅仅“能实现”就觉得完事了。C因高效著称很大原因也是因为指针的小巧。

 

讲到这里,不得不说下左值和右值。

这个简单理解起来就是:左值代表内存单元,右值代表内存单元里的值。

p本身占据一块内存,刚才我们写的里面值存放的是: 0x101010 ,如果你接下来给它赋值:


我们分别画出图来:

                                                                             (p = NULL)


                                                                           (p = 0x12345)



(int b = 99; p = &b )

上面的图,注意箭头我没有指到里面,内存中实际上也不可能有箭头这样的东西,这样画是为了方便理解。这里p作为左值,它里面原先的内容由“0x101010”一直变到了”0x025564”,里面的内容只要是个整型值随便什么都可以的(但是要有意义)。

这里明白了p本身占内存,里面存的不过是个整型值之后,我们来看看它的右值,这里就举一个例子,很清楚明白:


这里p作为右值,把它的内容”0x101010”写到了刚分配的指针变量 p2的内存里面,如图:


左值右值明白了之后,我们来看看解引用,也就是”*p” 这种表达式。

“*p”可以理解为,跳转到p所存地址的内存,也就是拿到这块内存的控制权。这里很显然”*p”代表了a这个变量,如果我写:


那内存里就变成了这个样子:



作为右值赋值给其他变量,写如下代码:



那内存就成了这个样子:



小结:

这次介绍了指针的基本概念,以及指针作为左值右值的时的含义及用法。我们通过以上可以发现:无论你声明的是普通变量(inta ,struct Node….),还是指针变量(int*a, Node *p….),本身都是存在于内存里的,本质上还是通过地址来进行操作(即便你写的是 int a ,在编译器眼里不过也是一个地址,然后这个地址按照一个整形来解释),而指针(无论几级指针)作为存放地址的变量,有着灵活的特点(指针可以很方便地表达很多数据结构如:链表,树,图….),每当你写下一句代码时,你脑袋里面要有它们在内存里大概分配情况的样子,作为一个C\C++程序员,对内存还是要敏感。

有点晚了明天还上班,其他零散的知识,以及指针和数组、指针作为函数参数就放到后面讲吧。




0 0
原创粉丝点击