首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

初学数据结构,请问一个单链表的有关问题

2012-02-19 
初学数据结构,请教一个单链表的问题一直无法静下心来学习数据结构,总是觉得太难呵呵,今晚,决定认真地学习

初学数据结构,请教一个单链表的问题
一直无法静下心来学习数据结构,总是觉得太难呵呵,今晚,决定认真地学习他,学好他,就看了链表,就难住了。
我看到它初始化链表的函数是这样写的:

C/C++ code
void InitList(struct sNode **HL){    *HL=NULL;}

我看到形参就愣了,初始化链表,不就是将表头指针置为空指针吗?为什么要用二级指针,直接将表头指针置空不就行了吗?如:
C/C++ code
void InitList(struct sNode *HL){    HL=NULL;}
这就是我的疑问。
但我想,他这样写,应该是有他的意思,应该不会是作者的错或者打印的错,那么,就只能是我错了,那又是为什么呢?为什么要用二级指针?
接下来是重点了,是我自己对这个问题的想法,但身边没什么人可问,也不敢肯定,所以就来发贴了,我是这样想的:

我们都知道,C语言的函数调用有传值和传址之分,将一个常规变量的地址传递给一个相应类型的指针形参,那么,就可以改变这个变量的值,而直接将这个变量传过去,却是不行,因为传值的思想是“将变量复制多一份”,那么,对于指向结构体的指针,是不是也一样呢?我们虽然传的是指针,但实际上,传的是这支针所指向的结构体的未知地址(因为还没初始化,定义的时候系统随机分配空间,所以说不知这支针指向何处,用未知地址来表达不知可不可以),所以我们在初始化函数中修改到的并不是这支针,而是这支针所指向的结构体,所以,要达到初始化的目的,我们要传的,是这支针的地址,才能达到修改这支针的目的。

我是这样想,自己感觉好像也说得过去,但就是不敢肯定,请各位大虾解答解答。

[解决办法]
用二级指针,只是因为在初始化时要为这个单链表建立一个专门的头指针,而与参数传递没有直接的关系。
一般是这样写代码的吧?

C/C++ code
void InitList(struct sNode *HL){    HL=(struct sNode *)malloc(sizeof(struct sNode));    HL->next = NULL;}
[解决办法]
建议楼主看看这个,月经贴了
http://topic.csdn.net/u/20091111/18/3ce14f1c-f0ff-4290-b1dc-d175a51667e9.html
[解决办法]
一级指针是带不回去的,lz那样做没有修改实参的值
要达到目的,要么用二级指针,或者用指引的引用
[解决办法]
你在调用InitList里对链表定义估计是
struct sNode *p; /*此时p是指向一个节点(struct sNode )类型的指针*/
InitList(p); /*如果用InitList(struct sNode *HL)的形式,那么是相同类型的变量,会出现变量拷贝,也就是HL也指向p指向的那个节点,InitList()内部执行了HL=NULL;是不会影响P指针的*/

/*如果用InitList(struct sNode **HL)的形式,那么不用变量拷贝,也就是*HL指向p,InitList()内部执行了**HL=NULL;则会改变P指针的指向,达到改变指向内容的目的*/


C/C++ code
void InitList(struct sNode **HL){    **HL=NULL; /*我认为第一个初始化应该有两个星号*/}
[解决办法]
一级指针是带不回去的,lz那样做没有修改实参的值
要达到目的,要么用二级指针,或者用指引的引用
[解决办法]
看不懂呢,唉,也得学习了
[解决办法]
case1:
void InitList(struct sNode **HL)
{
*HL=NULL;
}

case2:
void InitList(struct sNode *HL)
{
HL=NULL;
}

不要把指针过分地特殊化,其实 struct sNode* HL;中HL是一个指针变量。当调用函数,传递指针变量的时候,它也跟传递普通变量一样要临时拷贝指针变量。所以case2中函数内部的HL并非调用函数时的实参。所以HL = NULL;不会传递回实参。同样地,case1中二级指针变量HL也是一个临时变量。但是由于HL是一个二级指针,所以*HL是不变的,对*HL赋值可以传回实参。




[解决办法]
这个函数的作用是初始化链表头,就是要初始化这个HL这个指针.

void InitList(struct sNode *HL)
这个函数,执行的时候就是初始化了它的指向.
21: HL = NULL;
00402088 mov dword ptr [ebp+8],0

void InitList(struct sNode **HL)
这个函数,因为传过来的是指向链表头的指针,就等于对链表头赋值.
26: *HL = NULL;
004020B8 mov eax,dword ptr [ebp+8]
004020BB mov dword ptr [eax],0


执行时的汇编代码
37: sNode* p = NULL;
004020F8 mov dword ptr [ebp-4],0 //dword ptr [ebp-4]地方就是0

38:
39: InitList(p);
004020FF mov eax,dword ptr [ebp-4] //eax里面就是0
00402102 push eax //参数传过去的是0,并不是p的地址
00402103 call @ILT+730(InitList) (004012df)
00402108 add esp,4
40: InitList(&p);
0040210B lea ecx,[ebp-4] //得到p的有效地址
0040210E push ecx //这里传过去的才是真正p
0040210F call @ILT+745(InitList) (004012ee)


00402114 add esp,4

不知道我的理解对不对,仅供参考

热点排行