|
指针是C语言中最为重要也是最难的一个关键点,很多数据结构都是基于指针实现的,如链表、链式队列、链栈、二叉树等。
|
|
|
所谓指针,就是一个用来存储地址的变量。这可谓指针的本质,需要牢记。
|
|
|
也许你会很纳闷,指针为什么一定要定义成某类型(int、char)呢?指针不能就是"指针类型"吗?接触过汇编的人就很容易理解为什么。存储单元的单位是字节,就是说一般地址是按字节编址的,对一个地址进行操作(读取或赋值)就要指明是对单字节(不用特别声明)、两字节(WORD PTR),还是双字节(四字节,DWORD PTR)进行操作。同样,指针是存储地址的,即指针就是一个地址,自然也要说明其类型;而且,这个类型还关乎指针自加自减时真正加减的字节数。
|
|
|
顺便说一下,数组名也是指针。数组在申请空间时,数组名存储该存储空间的首地址。注意:数组名存储的是地址,因此也是指针,只是该指针一旦赋值后就不能修改,即所谓常指针。当直接输出数组名时,输出的其实是数组的首地址。这样,当形参声明为指针时,亦可将数组名作为实参进行传递。因此,可以用指针的方式访问数组中的元素,如下例采用指针的方式遍历输出数组。
|
|
|
|
当指针作为函数参数传递时,需要特别注意C语言中的"值"传递原则。下例中的函数希望为指针p申请空间,但不能达到目的,为什么呢?
|
|
|
|
归根结底,C函数的形参与实参之间只是"值传递":当形参是普通变量时,传递的是实参的值;当形参是指针时,传递的是指针变量的值,即某变量的地址,这样可以通过指针成功地改变其所指单元的值,但自身的改变不会传回给实参。上例可改为:
|
|
|
|
注意:这样修改后,调用时实参应该是指针的"地址"(或指向指针的指针)。这样即上面所说的可以改变指针所指单元的值,因此可达到预期目的。
|
|
|