前段时间看见大家在积极的讨论指针有关的问题;这不由的让我想起当初自己学习指针,真是要了老命啊,一直没搞懂带"*"的问题,一个带"*"还好理解,多了就晕了,回忆起来,这是我当初的“死板”学习;现在做嵌入式,系统方面接触的比较多,当你看内核代码的时候,就有好多指针操作,所以深知指针的重要性,现在这段时间开始写这一系列的专题分享给大家,希望对大家理解指针有一定的帮助,同时Linux应用编程还是在同步更新的,这周会写进程的文章分享。在今天开始写文章之前,插一个面试题,也是我自己这几天无意发现的;这里我以一个void set()函数,和void set1(void)函数(c语言里面没有函数重载这个用法,所以就这样区分写了)为示例:
注:新一点的编译器不会通过编译,比如5.11的dev-c++就编译不能通过。这里我主要讨论的问题是void set()和void set1(void),这里可以从上面的图中可以看到不带void为参数的函数,里面可以写多参数进去,而且不会有问题,但是写了void参数,那就不能写参数就进去(这个在实际开发当中,当然是没有人吃饱了饭去这样写代码,但是往往在一些公司面试笔试题目就会有这种坑爹的题目,你说你对c语言是掌握的好,但是有可能就因为这道题目,叫你说出它的区别了,你一下不知所措了,可能就被out了)。
一、什么是指针?
1、我们先从最熟悉的普通变量说起;当我们定义一个普通变量,变量在我们的编译器的帮助下,会把我们已经写好的变量名和实际的物理地址衔接起来(这个变量名其实就是一个物理地址的助记符,方便我们理解分析),从而实现了对内存中指定地址区域的数据的操作,这就是变量的实现原理,变量在内存中的地址又称作指针,我们说“变量的地址” 就等价于 “变量的指针”,但是指针和指针变量是不一样的。从这里我们可以看出指针跟普通变量没啥子区别,所以看到指针操作不要害怕,要静下来慢慢享受,哈哈哈。
二、指针变量的概念:
1、 从上面我们可以看到,每个变量都有一个符号地址(变量名)和物理地址(在内存中的位置,又叫做指针)。变量是可以存储数据的,但是指针变量与普通变量不同,它用来存放普通变量的地址,即指针变量是用来存放普通变量的指针。要知道,指针变量也是一个变量,在内存中也是占内存的,只不过它不存放基本类型数据,而是存放其他基本类型变量的地址。既然指针变量也有自己的物理地址,那么指针变量的地址用什么 来存储呢?用比该指针类型高一级的指针变量来存放指针变量的地址,如二级指针变量存放一级指针变量的地址,三级指针变量存放二级变量的地址,依次类推。
2、指针使用三部曲:定义指针变量、关联指针变量、解引用
(1)当我们int *b定义一个指针变量p时,因为p是局部变量,所以也遵循C语言局部变量的一般规律(定义局部变量并且未初始化,则值是随机的),所以此时b变量中存储的是一个随机的数字。
(2)此时如果我们解引用b,则相当于我们访问了这个随机数字为地址的内存空间。那这个空间到底能不能访问不知道(也许行也许不行),所以如果直接定义指针变量未绑定有效地址就去解引用几乎必死无疑;如果虽然随便指定一个东西也是不行的。
(3)定义一个指针变量,不经绑定有效地址就去解引用,就好象拿一个上了镗的枪随意转了几圈然后开了一枪。
(4)指针绑定的意义就在于:让指针指向一个可以访问、应该访问的地方(就好象拿着枪瞄准目标的过程一样),指针的解引用是为了间接访问目标(就好象开枪是为了打中目标一样)
三、实际操作:
注:上面是我进行了一维和二维指针以及多维指针的操作和一些各种地址的打印操作,&b,&c,&d,都是打印指针本身的地址(也就可以印证上面说的话,指针和普通变量一样,都有自己的地址)。
四、总结:
今天的分享主要是讲了一下指针的概念,这非常重要,对后面的指针操作有非常大的理解作用,很多人学晕了,就是这入门指针概念这块没有彻底理解它,所以导致后面对指针的操作,会感到感觉没有学指针一样,一脸懵逼的状态,看到指针就头痛,所以希望这篇文章对大家有用。