首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

问一个关于链表初始化的有关问题

2012-02-10 
问一个关于链表初始化的问题我的程序如下:#includestdio.h#includemalloc.h#definenull0typedefstruct

问一个关于链表初始化的问题
我的程序如下:
#include   <stdio.h>
#include   <malloc.h>
#define   null   0
typedef   struct   node
{
int   data   ;
struct   node   *next   ;  
}slnode   ;  
void   initiate(slnode   *h)   //初始化头节点
{
h=(slnode*)malloc(sizeof(slnode));
h-> next   =   null   ;
printf( "链表初始化完毕, ");
}
void   append(slnode   *p,int   x)   //增加一个节点
{
slnode   *s   ;  
s=(slnode*)malloc(sizeof(slnode));
s-> data=x   ;  
s-> next   =   p-> next   ;  
p-> next=s     ;

}
void   main()
{
slnode   *p   ;
initiate(p);   //初始化
append(p,1);   //增加一个节点
}
初始化没有问题但是     增加一个节点就会出现内存错误的问题  
如果我把初始化函数改为
void   initiate(slnode   **h)   //初始化头节点
{
*h=(slnode*)malloc(sizeof(slnode));
(*h)-> next   =   null   ;
printf( "链表初始化完毕, ");
}
h用指针的指针的化,就不会出现问题,为什么非得用指针的指针来初始化呢??


[解决办法]
其实也可以用指针函数来返回分配的接点..

slnode *initiate(slnode *h) //初始化头节点
{
h=(slnode*)malloc(sizeof(slnode));
h-> next = null ;
printf( "链表初始化完毕, ");

return p;
}

void main()
{
slnode *p ;
p = initiate(p); //初始化
append(p,1); //增加一个节点
}



[解决办法]
楼上的也是名人,怎么说得这么乱?

简单的说,若要修改一个变量,你要传这个变量的指针或引用进函数,若要修改一个指针,你要传这个指针的指针或引用进函数.
[解决办法]
当传递指针的时候,
只有对指针 *解引用后的操作才可以反馈。

传值和传址是一个相对的概念,
传址也是传值,不过它传递的是一个地址值,
然后 *操作这个地址指向的数据,而不是修改这个地址值本身,
那么这个操作就可以被反馈,
因为实参和行参值一样,就是指向同一个地址,那么这个地址中的内容被修改了,实参指向这个地址,自然也一样被修改了,结果反馈。

如果在行参中,修改的是指针本身,也就是把传递进来的地址值给修改了,
实参根本就不会有任何变化。
[解决办法]
所以,
void initiate(slnode *h) //初始化头节点
{
h=(slnode*)malloc(sizeof(slnode));
h-> next = null ;
printf( "链表初始化完毕, ");
}

这样的操作修改的 行参,
它和实参没有关系,
实参指向 x,
行参h指向 malloc 获得的地址,
函数退出后,实参还是指向 x, 没有完成初始化。

如果:
void initiate(slnode **h) //初始化头节点
{
*h=(slnode*)malloc(sizeof(slnode));
(*h)-> next = null ;
printf( "链表初始化完毕, ");
}
由于传递的是p的地址,
那么 *h 就是 p,
所以 *h=(slnode*)malloc(sizeof(slnode));
即是 p=(slnode*)malloc(sizeof(slnode));
... //下同
这样就在函数中完成的 p 的初始化, 正确
[解决办法]
你可以看看林瑞写的《高质量C/C++编程指南》里面着重讲了关于内存操作的问题。你说的这种情况他也讲的很清楚。这主要是与函数的调用机制以及函数内申请的变量的存储方式有关。
[解决办法]
因为你要对指针进行修改,所以当然要传指针的地址,也就是用二级指针

热点排行