C语言求链表长度(二级指针)

startstorm 发布于 2017/03/03 11:39
阅读 250
收藏 0
c

我写了两个求链表长度的函数。用的vs2013,两个函数都能编译通过,单独运行两个函数都没有问题,但是第一个函数和GetElem函数一起就有错误。第二个函数正确。不知道为何?

第一个函数如下

int ListLength01(LNode **p)	//求线性表的长度
{
	if (p == NULL)
	{
		return -1;
	}
	static int count = 0;
	LNode **tmp = p;
	while ((*tmp)->next != NULL)
	{
		(*tmp) = (*tmp)->next;
		++count;
	}
	return count;
}

第二个函数如下

int ListLength02(LNode **p)	//求线性表的长度
{
	if (p == NULL)
	{
		return -1;
	}
	static int count = 0;
	LNode *tmp = *p;		
	while (tmp->next != NULL)
	{
		tmp = tmp->next;
		++count;
	}
	return count;
}

整个源代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define flag -1
typedef struct LNode
{
	int data;
	struct LNode *next;
}LNode;


int CreateLinkList01(LNode **L)	//创建链表
{
	if (L == NULL)
	{
		return -1;
	}
	LNode *r, *s;
	int x;
	scanf("%d", &x);
	r = *L;
	while (x != flag)
	{
		s = (LNode *)malloc(sizeof(LNode));
		s->data = x;
		r->next = s;
		r = s;
		scanf("%d", &x);
	}
	r->next = NULL;
	return 0;
}

int PrintLinkList01(LNode **L)	//打印链表
{
	if (L == NULL)
	{
		return -1;
	}
	LNode *p = (*L)->next;
	while (p != NULL)
	{
		printf("%d---", p->data);
		p = p->next;
	}
	printf("\n");
	return 0;
}


int ListLength01(LNode **p)	//求线性表的长度
{
	if (p == NULL)
	{
		return -1;
	}
	static int count = 0;
	LNode *tmp = *p;		
	while (tmp->next != NULL)
	{
		tmp = tmp->next;
		++count;
	}

	//LNode **tmp = p;
	//while ((*tmp)->next != NULL)
	//{
	//	(*tmp) = (*tmp)->next;
	//	++count;
	//}
	return count;
}


int GetElem(LNode **p, int i, int *e)	//取L1中第i个元素赋值给e
{
	if (p == NULL)
	{
		return -1;
	}
	LNode *r;
	r = *p;
	static int count;
	while (r!=NULL && count<i)
	{
		++count;
		r = r->next;
	}
	*e = r->data;
	return 0;
}

int main()
{
	LNode *L;
	int i = 0;
	int e = 0;
	int q = 2;
	L = (LNode *)malloc(sizeof(LNode));
	L->next = NULL;
	CreateLinkList01(&L);
	PrintLinkList01(&L);
	printf("\n");

	i = ListLength01(&L);
	printf("%d\n", i);

	printf("\n");
	GetElem(&L, q, &e);
	printf("%d\n", e);
	return 0;
}

 

加载中
0
GestureWei
GestureWei
第一个你修改了外部的链表结点的指针,调用完以后链表头结点变成了NULL
0
startstorm
startstorm

引用来自“GestureWei”的评论

第一个你修改了外部的链表结点的指针,调用完以后链表头结点变成了NULL

我明白了,我第一个函数虽然在函数里用一个二级指针接住形参,但二级指针还是修改了一级指针(链表外指针)的指向,第二个函数用一级指针接住形参,虽然改变,但是无法修改一级指针(链表外指针的指向)。非常感谢你。

startstorm
startstorm
回复 @GestureWei : 只要程序没有结束,static都是有效的,应该是这个意思
GestureWei
GestureWei
static可以理解为局部可见性的全局变量,生命期是跟随整个进程的
startstorm
startstorm
回复 @GestureWei : static没有理解,回去多看多练,多谢大侠指教
GestureWei
GestureWei
没有理解static变量的原因,建议多了解运行时结构
startstorm
startstorm
回复 @GestureWei : 是的,后来我就发现用static后面再统计就会累加,还是不用static
下一页
0
soiamsoNG
soiamsoNG
int ListLength01(LNode **p)	//求线性表的长度

这里 **p 你是要准备修改链表的head吗?如果不用修改用 *p 就可以。最少你中间写错了自己还会知道吧

因为C语言函数参数是只能传值所以修改head的函数才需要 **p.

* 就是为了跳过只能传值的限制。**p就是为了修改*p

startstorm
startstorm
回复 @GestureWei : 也是,还是就用*p一级指针比较好,只有想修改外部指针的时候再用**p二级指针
GestureWei
GestureWei
加const就没有必要了,不如直接一级的指针
startstorm
startstorm
回复 @GestureWei : 如果不想修改外部链表头指针,可以用*p,如果用**p加个const应该也可以吧
GestureWei
GestureWei
指针并不是为了跳过传值限制,并且也没有可以跳过的方法,C语言自身属性决定了参数传递就是传值,这个传统由来已久。
返回顶部
顶部