有些同学在初接触指针时候,感觉学习困难,表达方式别扭,而且在得知指针的作用仅仅是对系统内存单元的间接表示之后更加不解:何必那么麻烦,直接采用直接表示不香吗?
不!作为C语言的核心和灵魂,指针的地位是不可撼动的!本文就来聊聊指针的重要作用之一:通过函数调用改变主调函数中的存储单元。
既然要利用函数,引入函数的作用你要清楚:它主要是为了提高代码的重用性,对程序进行模块化处理,提高程序可读性的同时提高效率。
我们看一个简单的例子,在这个例子中,我企图通过函数直接改变我主调函数中的变量X的值。
我想通过函数改变主函数中变量的值,表达愿望很强烈,可是实际运行一遍之后发现主函数中的X不为所动。
采用这种直接表示改不了的原因,主要是两个X不是一回事,不是同一个内存单元,所以哪怕两个X名字一样,但是生命周期决定着“你的X见到我的就不灵了”。
如果使用间接操作那结果就不一样了,哪怕你佚名更姓,不变的是地址,就是化成灰我也能够用指针指向你的地址,准确地把你表示出来,对你进行改变。
其实两个例子可以体现出一个重要规律,你想在对哪一段内存做或读或写的操作,前提一定是能够把那段内存表示出来。
通过函数直接表示访问不了主函数的X,所以它改变不了,而换成地址采用间接访问可以把主函数的X表示出来,所以就能对它进行操作。
坚定信念,只要使用变量名做实参,不管它在函数中做了什么操作,函数调用结束回来之后,变量一定不会在函数中被改变!
接着我们来练习一下,看另外一个例子:我在主函数中定义两个变量,又企图通过一个水杯倒水的函数交换主函数中的变量。
坚定信念!只要你使用变量名做实参,不论在函数中跳得多么欢实,当你回到主调函数以后,依然会保持不变!
那我想通过函数对主函数中的变量进行交换,显然就可以通过想改变谁就传递谁的地址,采用间接访问的方式进行改变,没什么难度。
接着我们盯着这个例子做一点改变,如果我水杯换水时候,把指针x和指针y前面的*去掉会怎么样呢?当然会语法错误,因为我采用水杯换水时候引入的工具人t的类型不匹配。
既然是类型不一致引起语法错误,那我把工具人也改为int *,然后交换指针x和y不就完了吗?
这里容易产生一个误解:就是我的指针x和指针y分别存储的是主函数中x和y的地址,所以经过我一番水杯倒水的操作以后,我就会把x和y的地址交换。
这是错误的。变量x和y两个单元在内存分配结束之后地址是不可能被改变的。
就好像你向系统申请了两个房间,然后把房间的号码抄写在了本子上,接着你交换了本子上的内容,但是房间和房间号码的对应关系是不会被改变的。
在这里交换p和q的值,其实改变的是p和q的指向,但他们指向的内存单元的地址本身是不会变的。
进一步,我在主函数中又定义了两个指针变量r和s,分别指向了我x和y的地址,然后在传参时候我不再使用x和y的地址,而使用指针变量r和s,也能够达到交换的目的。
但是呢,我在这里说这么一句话,你在这里采用函数调用的时候,使用的是对r和s的直接表示,所以根据我们已经坚定的信念,不管将来在函数里面有什么操作,当函数调用结束以后,r和s的值是不可能被改变的。
也就是说r和s的指向没有发生改变,但是我r和s所指向的x和y是有可能被改变的。
神奇!那么如果我想要改变r和s的值,也就是它们的指向怎么办呢?
那就去盖中盖使用地址传参呗!只不过将来我函数中形参的类型就需要使用二级指针了,希望读者可以有能力自行完成这一部分内容,并对指针和二级指针反复推演,强化记忆。
感谢阅读,学习使人强大。
举报/反馈