问一个关于链表初始化的问题
我的程序如下:
#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++编程指南》里面着重讲了关于内存操作的问题。你说的这种情况他也讲的很清楚。这主要是与函数的调用机制以及函数内申请的变量的存储方式有关。
[解决办法]
因为你要对指针进行修改,所以当然要传指针的地址,也就是用二级指针