如何理解传值与传址(Pass by Value and Pass by Address)以及指针?

[禁止转载]

传值与传址(Pass by Value and Pass by Address)及指针是学C和C++比较头疼的问题,该博客是专门为博主女朋友写的。

先看一个经典例子:如何通过函数交换两个变量的值

首先写一个小程序如下:

void swap1(int a, int b)  
// 参数是普通变量
{
    int t;
    t = a;
    a = b;
    b = t;
}
int main()
{
    int x = 3;
    int y = 5;
    swap1(x, y);
    cout << "After swap1: x=" << x << "  y=" << y << endl;
    return 0;
}

结果如下:
swap1

由图可知,虽然在函数里交换了值,但是实参x,y的值并没有改变,这是因为进入函数swap1时,形参a,b是拷贝实参的副本,形参拷贝了值、在函数里改变了值,但都不会影响实参值的变化。通常把这种情况叫做“传值”

那如何切实改变x,y的值呢?需要用到指针。写一个小程序如下:

void swap2(int* a, int* b) 
// 参数是指针
{
    int t = *a;
    *a = *b;
    *b = t;
    // 用了解指针符号*,所以以上操作相当于目的地址所存值的交换
}
int main()
{
    int x = 3;
    int y = 5;
    int *ptx = &x;
    int *pty = &y;
    cout<< "*ptx=" << *ptx << "  *pty=" << *pty << endl;
    swap2(ptx, pty);
    cout << "After swap2: *ptx=" << *ptx << "  *pty=" << *pty << endl;  
    return 0;
}

结果如下:
swap2
可以看出值确实发生了交换,背后的原理是什么呢?

首先我们把传递的参数从普通变量换成了指针,指针与变量的区别是:指针可以知道两处内存存放的东西

  • 指针本身a : 存的是指针a所指变量的地址
  • 指针所指向地址*a : 存的是变量的值

已知形参拷贝的是副本,但指针的副本也和实参指针一样存着变量的地址值,通过访问这个地址,我们改变这个地址所存的东西,也就是变量的值。这样实参所指变量也会被改变,因此达到通过函数交换变量值的目的。

通常把这种情况叫做“传址”

上述代码中存在一个问题:通过修改目的地址所存变量的值来到达交换的目的。是不是有些繁琐?
为什么不直接交换两个指针的指向

于是就有一下程序:

void swap3(int* a, int* b) 
  // 参数是指针
{
    int *t;
    t = a;
    a = b;
    b = t;
}
int main()
{
    int x = 3;
    int y = 5;
    int *ptx = &x;
    int *pty = &y;
    cout<< "*ptx=" << *ptx << "  *pty=" << *pty << endl;
    swap3(ptx, pty);
    cout << "After swap3: *ptx=" << *ptx << "  *pty=" << *pty << endl;  
    return 0;
}

结果如下:
swap3
诶?居然没有调换成功。

其实还是那个道理,形参是实参的一个副本,改变形参的值是不会影响实参的,虽然这里参数仍然是指针,但这种情况也叫做“传值”

所以想改变指针的指向,我们需要用 指向指针的指针 来解决
void swap4(int** a, int** b) 
// 参数是指针的指针
{
    int *t;
     t= *a;
    *a = *b;
    *b = t;
}
int main()
{
    int x = 3;
    int y = 5;
    int *ptx = &x;
    int *pty = &y;
    cout<< "*ptx=" << *ptx << "  *pty=" << *pty << endl;
    swap4(&ptx, &pty);
    cout << "After swap4: *ptx=" << *ptx << "  *pty=" << *pty << endl;   // 此时swap1为传值,swap2为传址
    return 0;
}

swap4
调换成功,道理不解自明,只是需要注意一下指针的指针的写法。

在引入“引用”机制后也可通过引用&解决

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值