C语言二级指针

由于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是一个野指针。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值