C/C++指针的指针(**p)和指针的引用(*&)使用案例分析


#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

int func1(int *a)
{
    a = new int;
    *a = 1;
    printf("func1 addr a=%p\n",a);
    return *a;
}

int func2(int **a)
{
    *a = new int;
    **a = 10;
    //假设是指针的指针,那函数内能够对指针的指针直接赋值
    //那返回的地址就彻底悲剧了,函数外面的指向彻底乱了
    //int i = 0,*b = 0;
    //b = &i;
    //对指针的指针直接赋值,有可能不这么直接,间接被改动
    //a = &b;
    printf("func2 addr a=%p,*a=%p\n",a,*a);
    return **a;
}


//*&: 运算符*优先级高于&,两个运算符都是从右向左结合运算;//所以,*&a 的意思就是先运算 *,得到 指针,再通过 &,获取指针的引用

//typedef int * INT_P;INT_P a 等同于 int *a,那 INT_P &a 就等同于 int *&a,也即指针的引用了

int func3(int *&a)
{
    a = new int;
    *a = 100;
    //int i = 0,*b = 0;
    //b = &i;
    //由于是指针的引用,不能对其进行赋值
    //确保了函数调用完毕后,地址指向不会乱
    //&a = &b;
    printf("func3 addr a=%p,&a=%p\n",a,&a);
    return *a;
}

int main (int argc, char *argv[])
{
     int a = 0,*p = 0;
     a = func1(p);
     printf("a=%d,addr a=%p,addr p=%p,&p=%p\n\n",a,&a,p,&p);
     a = func2(&p);
     printf("a=%d,addr a=%p,addr p=%p,&p=%p\n\n",a,&a,p,&p);
     a = func3(p);
     printf("a=%d,addr a=%p,addr p=%p,&p=%p\n\n",a,&a,p,&p);
     printf ("%s\r\n", "finish");
     return 0;
}

/*
编译运行
g++ -m32 -g aa.c -o aa;./aa
func1 addr a=0x9fc3008
a=1,addr a=0xffc59bdc,addr p=(nil),&p=0xffc59bd8

func2 addr a=0xffc59bd8,*a=0x9fc3018
a=10,addr a=0xffc59bdc,addr p=0x9fc3018,&p=0xffc59bd8

func3 addr a=0x9fc3028,&a=0xffc59bd8
a=100,addr a=0xffc59bdc,addr p=0x9fc3028,&p=0xffc59bd8

finish
*/
/*
func1:
[&p=0xffc59bd8]----->[p=null]------>null

func2:
[&p=0xffc59bd8]----->[p=0x9fc3018]------>10

func3:
[&p=0xffc59bd8]----->[p=0x9fc3028]------>100

1. 函数 func1 调用后,func1函数内部内存泄漏,返回的指针还是无效;
2. 函数 func2 调用后,返回了合法的地址,其指针的地址也全然匹配;
3. 函数 func3 调用后,返回了合法的地址,其指针的地址也全然匹配;
注意看 &p=0xffc59bd8 的地址一直不变,可是p的指向一直再变,实际能够用
一个简单的映射描写叙述:
int **pp = 5;
[pp=0x***]---->[*pp=0x****]---->[**p = 5]
*/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值