C++中的指针传递,传递给形参的指针仍是实参的一个拷贝。

1.起因

今天在看CPlusPlusThings时看到的关于const使用的一个代码:

void func(const int var); // 传递过来的参数不可变
void func(int *const var); // 指针本身不可变

传递过来的参数及指针本身在函数内不可变,无意义!

表明参数在函数体内不能被修改,但此处没有任何意义,var本身就是形参,在函数内不会改变。包括传入的形参是指针也是一样。

输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加const 修饰。

2.思考

const位于*号后时,表示指针指向的对象不能改变,且不能指向一个常量。

1.形参指针是实参的拷贝

我一开始以为把指针作为参数,作用类似于引用,既可以修改所指向的地址,也可以修改指向对象的值。但实际上,指针作为参数的时候,仍是一个传值,将变量的地址传入函数,我们可以修改指向的值,不能修改指向的对象。

看下面代码:

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

void F(int *pi)
{
    pi = (int *)malloc(sizeof(int));
}

main()
{
    int *pi = NULL;
    F(pi);
    printf("%d/n", pi == NULL);

最后的返回值是1. 即使传入了指针,还是不能保留改变的结果。

原因是,传递给形参的指针,会产生一个实参的拷贝,这个拷贝跟实参指向相同,所以我们能通过传递指针的方式改变原指针指向的值。

实例

void swap(int *p,int *q)
{
	int *r=q;
	*q=*p;
	*q=*r;
}

int main()
{
	int a=5,b=4;
	int *p=a,*q=b;
	swap(p,q);
}

2.为什么不能修改原指针指向的对象

先看个例子:

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

int f(int *q)
{
    int a = 10;
    q = (int*)malloc(sizeof(int));
    *q = a;
    return 0;
}

int main()
{
    
    int *p = NULL;
    f(p);
    printf("%d", *p);
    return 0;
}

这个程序会崩溃。p仍旧是NULL,无法返回值。

因为传递指针会产生拷贝,而这个拷贝的指针和实参,实际上是两个不同的变量,证明如下。

#include <iostream>


int f(int *q)
{
    std::cout << &q << std::endl;
    return 0;
}

int main()
{
    int a = 10;
    int *p = &a;
    f(p);
    std::cout <<  &p;
    return 0;
}

结果:
两个指针的地址不一样。

所以,虽然拷贝的指针和实参是指向的同一个地址,但却是两个不同的指针,在对形参指向的对象做改变的时候,不会影响到实参。

3.总结

可以理解成两个指向同一地址的指针,你可以通过这两个指针修改这个地址上的值,却不能只通过修改一个指针的指向就改变另一个的指向。

所以关于一开始的代码。

void func(int *const var); // 指针本身不可变

是无意义的,跟

void func(int *var)

起一样的作用。因为指针本身就不会改变。

参考资料1:指针变量也是传值调用的(C语言)!作者:RiderOnStorm

参考资料2:C语言中的地址传递(传指针,传递给形参的指针仍然是实参指针的一份拷贝)作者:踏樰无痕丶zz(链接里有怎么通过二级指针解决不能修改指向对象的方法)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值