从大一学c以来,脑海里一直有这样的一个认识。当指针作为函数参数时 操作是会起效的。当时上课的老师也是这么说。而且自己也一直没遇到这方面的问题。侥幸自己掌握了指针的一大特点。但事实未然,暗涌流动。
前些天在帮学弟解答链表的问题。是用c写的。指针的操作很多。因为之前数据结构这块学的还算可以。所以自然很自信的在学弟面前滔滔不绝。他把它运行错误的程序给我看时,我一开始真没找到错误(抱歉,源程序不在身边,下面我大致示意一下)。程序的大致过程是:定义了头指针,然后链表初始化函数使用这个指针作为参数进行初始化,使他指向某个节点。链表生成函数使用头指针作为实参在头指针后面不断挂接新的节点。一切都这么自然。完全是符合链表的原理的。然而奇怪的事发生了。链表遍历函数同样是调用这个头指针 想进行输出。结果显示链表根本没生成!!!怎么回事?函数参数是指针,所有的操作应该是有效力的。为什么定义的头指针后面还是没有指向任何节点?难道编译器有问题?最怕这种逻辑上没有错误的错误。查了大半天,依旧没有发现错误所在。在学弟面前颇感压力。无奈,我查看了一下当时自己写的链表程序。其原理相同。经过仔细对比。唯一不同的地方是在涉及指针作为实参的函数中 我的函数类型全为指针返回类型,而学弟的程序中这些函数全为void 型。难道错误在这?我试着将学弟的程序修改成返回指针类型。结果正确!!! 当时我蒙了。google.(网上和你犯相同错误的大有人在!)在一位网友的答复中,我顿悟!原来错误在这,指针的谎言!
举个例子:
void f(int *p)
{
(*p)++;
}
void main()
{
int i = 5;
int *p = &i;
f(p); //对i来讲 是传址操作,但是对p来讲是传值操作
}
上面的程序运行的话 大概学过c语言的都知道i的值会变为6;但是你有没有想过f的参数p其实也是一份拷贝!为什么同样是拷贝,这个i值就会改变,而学弟的链表没有生成呢?
首先我们来分析 为什么i的值会改变。虽然对p保存的值做了拷贝 但是 它依旧保存着变量i的地址,经过"*"运算,找到了内存中的 i,然后对i进行了加一运算。i的值当然改变了
而对链表的头指针进行操作,你一直是以它的副本为头指针进行操作,所有的新结点都是挂在着个副本的后面。一旦程序结束 ,你原先的头指针当然没有改变!!。

上面说明了学弟的程序为什么错了。我们只要讲这个指针副本作为返回值 从函数返回 用之前定义的头指针接收一下即可。
以上是我对这个错误个人的分析。可能会有错误。还望各位方家指出。写这篇文章的目的 一是自己的总结。而是希望帮助初学者或水平同等的人能更好的理解指针传址操作的本质。
指针陷阱多。有本书讲指针陷阱的,看来是要好好看看。