前言
想要解决的问题
在学习数据结构中创建单链表的时候,疑惑:已经定义了Node
,用到结构体指针的时候直接用*Node
就好了,为什么还要再定义一个*LinkList
呢,为什么传参的时候又要用LinkList *L
呢?
下面我们就来循序渐进,由浅入深来解决问题,这里举两个例子作为比较。
首先来看这个例子:
找出一个长度为10的int型数组的最大和最小值(这里限定必须要用函数来实现)
int arr[] = {1,8,10,2,-5,0,7,15,4,-5};
对于指针不熟悉的同学来说,一开始最容易想到这种方法(传个指针去接收)
从打印结果可以看出,此法不通,最终的最大值和最小值任是我们给的初始值,这就类似于想通过swap(int a, int b)
来交换a和b的值,我们知道这种方法只能交换传过去的副本,但原始数据的a,b并没有交换,所以我们使用指针来解决swap(int *a, int *b)
,这里和之前的swap(int a, int b)
有“异曲同工”之处,大家细细品味一下。
那该如何解决呢,参照交换a,b的方法,我们也传指针就是了,所以这里就变成了传指针的指针。
我们发现,拿到了我们想要的最大值和最小值。
好了,现在我们再来看一下我们一开始提的问题。
解决疑惑
首先我们先来看一下这个问题:
如果想为指针p申请一段内存,下面代码能实现吗?
#include<stdio.h>
#include<stdlib.h>
void getMemery(int *p)
{
/*申请1024个int大小*/
p = (int*)malloc(sizeof(int)*1024);
}
int main()
{
int *p = NULL;
getMemery(p);
if (p == NULL)
printf("未被分配到内存");
return 0;
}
运行结果:
未被分配到内存
这是为什么呢?我们还是利用前面所知来分析,由于传递给getMemory函数的参数都是一个副本,因此函数内的p也是外部p的一个副本,因此即便在函数内部,将p指向了一块新申请的内存,仍然不会改变外面p的值,即p还是指向NULL。
如何修改呢?我们需要传入p的地址,即指向int类型指针的指针。
#include<stdio.h>
#include<stdlib.h>
void getMemery(int **p)
{
/*申请1024个int大小*/
*p = (int*)malloc(sizeof(int)*1024);
}
int main(void)
{
int *p = NULL;
getMemery(&p);
if (p == NULL)
printf("未被分配到内存\n");
printf("address of p is %p",p);
free(p);
return 0;
}
运行结果:
address of p is 0000000000B65A20
从运行结果可以看到,p的值被改变了,而不再是初始的NULL。
好了,想必到这里,大家应该明白了文章开头所提的问题了。
CreateListHead方法中传的就是指向指针的指针,即Node **L
。