二级指针与函数参数

一级指针的简单使用

学习了一学期c语言后,对一级指针做函数参数的操作自以为已经相当熟练,不会出现程序崩溃的情况,但是在昨天用二级指针做函数参数的时候发现自己的一级指针好菜…
问题如下

void a(int *p)
{
    int m=5;
    p=&m;
    printf("%d\n",*p);
}
int main()
{
    int *s;
    int n=6;
    s=&n;
    printf("%d\n",*s);
    a(s);
    printf("%d\n",*s);
}

在这段代码里,用一个一级指针p做形参,将指针s做实参进行参数传递,本以为这样做可以改变指针s的原指向关系,即预期结果是s由指向n变为指向m,从而最后一句输出语句结果为5。但是运行代码后结果如下
运行结果
可见形参p确实指向了m并且输出为5,但是调用a()函数结束后s依旧指向n且输出为6。
也就是说通过a()函数并没有改变s的指向关系。
通过分析发现,当s作为实参传递的时候,系统会在调用函数a()时自动为形参p分配一段临时空间,此时p指向s,执行语句p=&m后,p作为一个不同于指针s的指针指向m,但指针s的原指向关系并未发生改变,函数调用结束后释放形参p及函数所占空间。画一张图理解一下。
图解

所以由此便牵扯到了另一个问题,咳咳,敲黑板。划重点!!!

void temp(char *p,int n)
{
    p=(char*)malloc(sizeof(char)*n);
    strcpy(p,"hello");
    puts(p);
  //printf("%x\n",p);//输出地址
    return;
}
int main()
{
    char *s;
    temp(s,10);
    puts(s);
//  printf("%x\n",s);//输出地址
    return 0;
}

上述代码的运行结果是什么呢?两次puts()究竟会不会输出内容?
1秒钟时间思考一下。
结果如下
结果
很显然,temp()函数中成功用malloc()函数为字符串指针p分配内存空间,且成功输出字符串"hello",而函数结束后puts(s)并没有得到结果。
原因已经说过了,函数内只会对临时指针变量p进行操作,当然分配的空间也是为p分配,s并没有得到任何空间,puts(s)是不会得到结果的。
再对指针p和s指向的地址进行输出,结果如下
结果
s仍然指向NULL(0)。
这里还有一个很重要的知识点提一下,使用malloc()函数为指针变量分配内存空间后,一定要及时free()释放,否则会造成内存泄露,具体百度。

那如何实现用指针参数申请内存,既然一级指针无法做到,那就用“指针的指针”----二级指针

二级指针与函数参数

一级指针变量用来存储指向方块的地址,同理
二级指针变量p用来存储一级指针变量的地址,且只能存储一级指针变量的地址。
例如

int main()
{
    int **p,*t,m=5;
    t=&m;
    p=&t;
    printf("%d %d %d\n",**p,*t,m);
    return 0;
}

输出结果
5 5 5
画个图理解一下。
图片
分别输出一下p,&t,*p,t,&m看一下结果

    printf("%x %x %x %x %x\n",p,&t,*p,t,&m);

jiag
总结:二级指针变量p存储一级指针变量t的地址,故p==&t都为60ff08
对二级指针变量p进行一次取值运算*p,
得到一级指针变量t存储的内容,即指向的m的地址,故*p==t==&m都为60ff0c

问题又回到如何实现用指针参数申请内存
将上述代码修改成这样

void temp(char **p,int n)
{
    *p=(char*)malloc(sizeof(char)*n);
    strcpy(*p,"hello");
    puts(*p);
    printf("%x\n",*p);//输出地址
    return;
}
int main()
{
    char *s;
    temp(&s,10);
    puts(s);
    printf("%x\n",s);//输出地址
    return 0;
}

运行结果
运行结果
其中**p是临时二级指针变量,故能存储一级指针变量s的地址,所以调用temp()函数时用&s而不用s,temp()函数内部对*p进行操作实际是对字符串指针s进行操作。

详细看博客https://www.cnblogs.com/dingou/p/5937024.html

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
回答: 当函数参数传入二级指针时,可以实现返回一个地址的目的。二级指针作为入参,可以在函数内部修改一级指针指向的地址,从而改变实参的值。通过传入一级指针的地址,可以在函数内部将二级指针指向一个新的地址,并返回该地址。这样既能返回一个地址,又能返回一个结果。\[2\] 例如,可以使用二级指针作为入参来实现动态分配内存,并将分配的内存地址返回给调用者。在函数内部,可以通过修改二级指针指向的地址来分配内存,并将分配的地址赋值给一级指针。\[3\] 这样,调用者就可以通过传入一级指针的地址来获取分配的内存地址。 #### 引用[.reference_title] - *1* *3* [C语言函数参数:一级指针、二级指针的应用小结](https://blog.csdn.net/u012351051/article/details/120937818)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [函数传参过程中的二级指针问题](https://blog.csdn.net/m0_60413945/article/details/128102042)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdnGuoYuying

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值