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操作,也就相当于对传入的 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;)而是指向了一个空指针(这是合法的);如下图所示;
目前为止还没有问题,L 和 list 都指向同一个地址;
接下来继续看!
L = (Sqlist*)malloc(sizeof(Sqlist)); //用malloc申请的一个Sqlist大的空间;
使用 malloc分配内存会返回一个void类型的指针然后强转成 Sqlist* 类型的指针,那么 此时的 L所指向的内存地址将会不同!
然而 传入的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 ;
还是按照上面的分析来
通过这样的赋值后我们看看各个指针变量的变化
现在L指针所指向的地址是 list的地址
所以呢 *L 的值为 0x0000000(NULL)
接下来申请内存空间
*L = (Sqlist*)malloc(sizeof(Sqlist));
*L 是什么? 是指针变量 list所存放的值呀 即 0x0000000(可以看上表)
*L变化了 list储存的值也变化了 ,既让这样子,list所指向的值内存地址也变化了,变了什么呢,不就是刚申请的内存空间的地址吗!!!
这不刚好满足要求吗,传入一个指针修改其指向的内容!
啊,这就是多重指针的用处吗!!!
收! 以后在补充!