SqList *L 和 SqList * &L的一些理解以及多重指针的简单应用

SqList *L 和 SqList * &L
关于 SqList *L 和 SqList * &L 的理解
复习数据结构(李春葆 c++版本)时看到了 SqList * &L 当时好像没弄明白今天花点时间理顺下:
typedef struct
{
Elemtype data[MaxSize];
int length;
}SqList;

//
	void CreateList(SqList * &L,ElemType a[ ],int n)
{
     int i;     L = (SqList * )malloc(sizeof(SqList));
    for(i = 0 ; i < n ; i++)
        L->data[i] = a[i];
    L->length = n;
 }
void DispList(SqList *L)
 {
    int i;  
     for(i = 0; i < L ->length; i++)
        printf(%d”,L->data[i]);
     printf(“\n”); 
}

第一个函数是初始化,第二个是输出结构体里数组的值,第一个函数的形参是 SqList * &L ,是什么意思呢?
在这里先说下这是c++版本!!

SqList * &L 可以看做是 (SqList *)&L

一个SqList 类型的指针 ,&L 是引用,这是在c++中才有的,引用即可以理解一个变量的另外一个名字;
举个例子:

int x = 110;
int& y = x;
cout << &y << "\t"<<y++<<endl;  //这里对y操作 相对于就是对x操作
cout << &x << "\t"<<x<<endl;
	

y是x的引用,那么y是x的另一个外号,不同外号但又是同一个人,不同于指针,指针变量有自己地址,但是引用没有。
SqList *L 和 SqList * &L的一些理解以及多重指针的简单应用_第1张图片
明白了 引用,在回来看下 (SqList *) &L 即是一个 SqList *类型的引用,我们对L操作,也就相当于对传入的 SqList 类型的指针进行操作;

ElemType a[100];
	int n = 33;
	Sqlist* list;   //此时list是一个野指针;没有分配空间内存
	CreateList(list, a, n);  //通过 函数里面的操作给list分配空间
	
	//传入的是 Sqlist* 类型的 list   可以这样理解
	// (SqList *) &L = list;
	//那么对L的操作就相当于对list指针操作是一样的;

(SqList *) &L 理解了那我们想想 , 如果换成 形参类型 SqList *L 行不行呢?

void CreateList(Sqlist* L, ElemType a[], int n)
{
	int i;     
	L = (Sqlist*)malloc(sizeof(Sqlist));
		for (i = 0; i < n; i++)
			L->data[i] = a[i];
	L->length = n;

	cout << "L = " << L << endl;
	cout << "&L = " << &L << endl;
}



ElemType a[100];
int n = 33;

Sqlist* list = NULL;
cout << "list = " << list << endl;
cout << "&list = " << &list << endl << endl;
CreateList(list, a, n);

传入的实参依然是 SqList 类型的指针,按照上面的分析:
传入一个SqList 类型的指针时可以这样理解

Sqlist L = list*;
指针list 所指向的内存复制给了L ,问题是 list 并没有指向实际内存
(Sqlist* list = NULL;)而是指向了一个空指针(这是合法的);如下图所示;
SqList *L 和 SqList * &L的一些理解以及多重指针的简单应用_第2张图片
目前为止还没有问题,L 和 list 都指向同一个地址;

接下来继续看!

L = (Sqlist*)malloc(sizeof(Sqlist)); //用malloc申请的一个Sqlist大的空间;

使用 malloc分配内存会返回一个void类型的指针然后强转成 Sqlist* 类型的指针,那么 此时的 L所指向的内存地址将会不同!
在这里插入图片描述
SqList *L 和 SqList * &L的一些理解以及多重指针的简单应用_第3张图片
然而 传入的list 得到空间,这是一个单向的传值过程!!所以 Sqlist* 的形参并不会修改传入的指针,还是用引用方便一点。

但我不想用引用呢?有什么办法呢????
现在的问题是 ,一个函数我传入一个指针,如何修改修改指针所指向的内容,而且这个修改要实打实的修改,而不是修改一个副本!

1.函数返回指针(虽然不是传入指针)
这里就不多说了

Sqlist* ReturnList( ElemType a[], int n)
{
	int i;
	Sqlist* L = NULL;
	L = (Sqlist*)malloc(sizeof(Sqlist));
	for (i = 0; i < n; i++)
		L->data[i] = a[i];
	return L;
}

2.使用多重指针
为什么说是用多重指针呢?

我们先来回顾下指针的引用
int a = 20;
int *p = &a;

整型变量 a 有自己的地址
整型指针变量 p 也有自己地址
我们都知道*p 等于 20 ,因为通过地址我们可以找到内存都对应的值;

回来看函数

void CreateList(Sqlist** L, ElemType a[], int n)
{
	int i;
	cout << "L 所指向的内存地址 " << L << endl;
	cout << "L 自己内存地址 " << &L << endl;
	cout << "L 指向的地址所存储的值是 " << *L << endl;

	*L = (Sqlist*)malloc(sizeof(Sqlist));
	cout << "申请内存后 *L 所指向的内存地址 " << *L << endl;
	cout << "L 所指向的内存地址 " << L << endl;
	for (i = 0; i < n; i++)
		(**L).data[i] = a[i];
	(**L).length = 994;
}

这里的形参是一个二重指针

首先我们遇到的问题是传什么进来好呢?
指针的指向的地址?指针指向的地址所在的值?还是指针变量的其自身的地址呢?

Sqlist* list = NULL;
// &list 即指针变量的地址
// list  为null(0x0000000)
// *list 为指向null内存???不用看,肯定不行

那我们传入 &list 试试

于是可以简化为

(Sqlist** L = & list ; 

还是按照上面的分析来

通过这样的赋值后我们看看各个指针变量的变化
SqList *L 和 SqList * &L的一些理解以及多重指针的简单应用_第4张图片
现在L指针所指向的地址是 list的地址

所以呢 *L 的值为 0x0000000(NULL)

那么我们画个表来看看
在这里插入图片描述
ps:颜色相同即值相同)
这下明了吧

接下来申请内存空间

*L = (Sqlist*)malloc(sizeof(Sqlist));

*L 是什么? 是指针变量 list所存放的值呀 即 0x0000000(可以看上表)
*L变化了 list储存的值也变化了 ,既让这样子,list所指向的值内存地址也变化了,变了什么呢,不就是刚申请的内存空间的地址吗!!!

这不刚好满足要求吗,传入一个指针修改其指向的内容!

啊,这就是多重指针的用处吗!!!

收! 以后在补充!

你可能感兴趣的:(C++,数据结构)