由于C语言没有引用的,所以引用传入只能靠二级指针来实现。详细看代码及其注释。
int a=5;
int *pa= &a;
/*
先回顾下一级指针:
pa的值是a的地址。*pa等价于 a,*pa =15会使得a==15,但pa的值依旧是a的地址,只是a的值变了。
*/
int **ppa =&pa;
int b=4;
int *pb =&b;
int **ppb =&pb;
/*
ppa中存储了pa的地址,*ppa代表了什么呢?
*ppa代表了 pa。
假设我们*ppb 赋给 *ppa,即*ppa =*ppb 会怎样?ppa的值会改变吗?
ppa的值可以用什么表示,那肯定是 ppa,ppa 就是 ppa的值,就像变量 a 一样,a就代表着a值。 既然ppa的值就是ppa,那*ppa =*ppb就不会改变ppa的值,那他的意义何在?*ppa代表了pa,而pa代表着a 的地址,*ppa = *ppb 就等价于 pa = pb。这样操作就相当于:
原先pa中存了a的地址,现在存了b的地址,但是ppa中依旧存的是pa的地址,即ppa的值没有改变,改变
的是ppa所指的地址(即ppa的内容)所指的地址。23333。。。。绕死人。
其实只要明白非常重要的一点:
ppa代表了pa的地址,*ppa代表pa,无论你怎么对*ppa操作只会影响pa,ppa的值依旧是pa的地址,这又回到了一级指针的概念。
*/
此外提下很基础的东西,但有时深了容易忽视,下面是有问题的代码:
#include<stdio.h>
typedef struct node{
int key;
struct node** next;
};
void fun(struct node** p)
{
(*p) = (struct node*)malloc(sizeof(struct node));
(*p)->key =5;
struct node* p1 = (struct node*)malloc(sizeof(struct node));
(*p)->next =&p1;
p1->key=6;
printf("(*((*p)->next))->key = %d\n",(*((*p)->next))->key);
}
int main()
{
struct node *head =NULL;
struct node** p =&head;
fun(p);
printf("(*p)->key = %d\n",(*p)->key);
printf("(*((*p)->next))->key = %d\n",(*((*p)->next))->key);
}
上面的代码,main中最后一个key输出不等于6,这是为什么呢?其实原因很简单,因为p1在fun结束后,p1内存被释放了。虽然这样说很简单,但是如果上面的代码改成如下呢?
#include<stdio.h>
typedef struct node{
int key;
struct node** next;
};
void fun(struct node** p)
{
(*p) = (struct node*)malloc(sizeof(struct node));
(*p)->key =5;
struct node* p1 = NULL;
(*p)->next =&p1;
}
int main()
{
struct node *head =NULL;
struct node** p =&head;
fun(p);
printf("(*p)->key = %d\n",(*p)->key);
if(NULL == *((*p)->next))
{
printf("come in\n");
}
}
come in 会被输出吗?还是不会的。说说个人的理解,如果理解错了,希望大家能够指出。前一个代码其实涉及两块内存的释放:一是p1本身的内存,二是p1所指的内存。而这个代码仅仅是释放了p1本身的内存。但不管p1有没有开辟所指内存,一旦fun结束内存栈都会被释放掉,导致next在main是一个野指针。