关于传递指针的指针的问题

sqn1982 2014-12-13 11:29:17
在大话数据结构这本书关于建立单链表的代码中,创建单链表的的代码是通过传递头指针的指针来实现的,我觉得好像没有必要,初始化的时候传递头指针的指针我能理解,其他地方我觉得只要传递头指针就可以了,以下是代码,大家看看我说的是不是正确。

#include <stdio.h>
#include <stdlib.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;
typedef int ElemType;

static Status visit(ElemType c)
{
printf("%d ",c);
return OK;
}

typedef struct Node
{
ElemType data;
struct Node *next;
}Node,*LinkList;

/* 初始化顺序线性表 */
static Status InitList(LinkList *L)
{
*L=(LinkList) malloc(sizeof(Node));
if(!(*L))
return ERROR;
(*L)->next=NULL;
return OK;
}

/* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
static int ListLength(LinkList L)
{
int i=0;
LinkList p;
p=L->next;
while(p)
{
i++;
p=p->next;
}

return i;
}

/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
static Status ListInsert(LinkList *L,int i,ElemType e) /*???这里的LinkList *L,我能不能改成LinkList L???*/
{
int j;
LinkList p,s;
p=*L; /*???这里改成p=L???*/
j=1;

while(p && j<i) /* 寻找第i个结点,且让p指向i之前的那一个节点 */
{
p=p->next;
j++;
}

if(!p || j>i)
return ERROR;

s=(LinkList)malloc(sizeof(Node));
s->data=e;
s->next=p->next;
p->next=s;

return OK;
}

/* 初始条件:顺序线性表L已存在 */
/* 操作结果:依次对L的每个数据元素输出 */
static Status ListTraverse(LinkList L)
{
LinkList p=L->next;

while(p)
{
visit(p->data);
p=p->next;
}
printf("\n");
return OK;
}

main()
{
Status i;
ElemType e;
LinkList L;
int j,k;

i=InitList(&L);
printf("初始化L后:ListLength(L)=%d\n",ListLength(L));

for(j=1;j<=5;j++)
{
i=ListInsert(&L,1,j);
}
printf("在L的表头依次插入1~5后:L.data=");
ListTraverse(L);

return 0;
}


①static Status ListInsert(LinkList *L,int i,ElemType e) /*???这里的LinkList *L,我能不能改成LinkList L???*/
-------------》
static Status ListInsert(LinkList L,int i,ElemType e) /*???这里的LinkList *L,我能不能改成LinkList L???*/
然后里面的p=*L; 改成p=L;
如果将函数改成以上的形式可以吗?

②另外,在函数ListInsert中,这里的if(!p || j >i)判断条件的 j >i是不是多余的?会有这种情况发生吗?
...全文
210 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
li4c 2014-12-14
  • 打赏
  • 举报
回复
如果只是传递指针 的话,那就不能让你传进函数的指针指向后来分配 的节点
hyde100 2014-12-14
  • 打赏
  • 举报
回复
本身这段程序因为建立了空的头节点,只要在插入的时候传入头指针就可以了。 之所以要传入头指针的指针的原因是,头指针L代表这个单链表,而线性表的定义是有两种结构了: ①顺序存储结构 ②链式存储结构 线性表的ADT插入算法中,函数原型为:ListInsert(*L,i,e) 为了这两种存储结构的统一,都需要传入线性表的地址,这样同一个ADT就可以同时适用于这两种存储结构 了。
fly_dragon_fly 2014-12-13
  • 打赏
  • 举报
回复
可以的,你的首结点其实没数据,写代码时小心点就行了
707wk 2014-12-13
  • 打赏
  • 举报
回复
动力风暴 2014-12-13
  • 打赏
  • 举报
回复
这是带表头结点的单链表,头结点数据域没有值。 这个是可以的,我在vs2010也试过了,

static Status ListInsert(LinkList L,int i,ElemType e)

p=L;    /*???这里改成p=L???*/
调用的时候:

ListInsert(L,1,j);
另外main函数前要加上返回值类型。
zacharyLiu 2014-12-13
  • 打赏
  • 举报
回复
当然是可以的,但通常情况下,我们一般在此调用函数之前,是采用动态分配内存的方法,是使用结构体指针,因此在函数形参上,采用结构体指针,这样便于节省内存
cnyfk 2014-12-13
  • 打赏
  • 举报
回复
我的理解是应该就是楼主这样做的没有问题
lm_whales 2014-12-13
  • 打赏
  • 举报
回复
就你这个插入算法看, 这里确实不需要更新头结点,因为 你这是个带空头结点的单链表,所有数据节点都在头结点后面。 那么 static Status ListInsert(LinkList *L,int i,ElemType e) 可以改为 static Status ListInsert(LinkList L,int i,ElemType e)
sqn1982 2014-12-13
  • 打赏
  • 举报
回复
对了,这是基于C语言写的代码
sqn1982 2014-12-13
  • 打赏
  • 举报
回复
引用 7 楼 lm_whales 的回复:
C: 需要更换头结点, 形参采用指针的指针, 实参采用头结点的地址。 C++: 可以用C的方法 也可以传递指针的引用, 形参是指针的引用 实参就是头结点的名字 (实质是传递引用) 很多C++编译器,引用使用指针实现 所以引用传递,和指针值传递生成的代码相同或者相近 ( C++无空引用,所以 引用比指针传递更好 也更容易优化代码 如果不加优化代码, 这些编译器中,引用传递,和指针值传递,生成的代码相同 )
能基于我ListInsert函数的代码说的明白些吗? 这个函数是链表的插入,我想讨论的问题是是不是必须要传入头指针的指针!
lm_whales 2014-12-13
  • 打赏
  • 举报
回复
C: 需要更换头结点, 形参采用指针的指针, 实参采用头结点的地址。 C++: 可以用C的方法 也可以传递指针的引用, 形参是指针的引用 实参就是头结点的名字 (实质是传递引用) 很多C++编译器,引用使用指针实现 所以引用传递,和指针值传递生成的代码相同或者相近 ( C++无空引用,所以 引用比指针传递更好 也更容易优化代码 如果不加优化代码, 这些编译器中,引用传递,和指针值传递,生成的代码相同 )
sqn1982 2014-12-13
  • 打赏
  • 举报
回复
引用 5 楼 fly_dragon_fly 的回复:
如果要用上首结点的话,就需要传头指针的指针了,可能作者的想法跟代码在逻辑上不一致了
就算要用首节点(头节点)的话,也不需要传头指针的指针,传头指针就可以了啊,通过头指针就可以能更改头节点的数据,不是吗?
fly_dragon_fly 2014-12-13
  • 打赏
  • 举报
回复
如果要用上首结点的话,就需要传头指针的指针了,可能作者的想法跟代码在逻辑上不一致了
sqn1982 2014-12-13
  • 打赏
  • 举报
回复
如果可以的话,为什么程序还要多此一举将头指针的指针传递过来呢?
FightForProgrammer 2014-12-13
  • 打赏
  • 举报
回复
个人感觉可以,你可以自己实现以下你的想法

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧