C++ 关于 调用函数时值传递和引用的理解

适合初学者。

函数参数传递机制

堆栈存储区是主调函数(过程)和被调用函数(过程)在调用发生时进行通信的主要区域。
基本的参数传递机制有两种:值传递和引用传递。

值传递:

被调用的函数的形式参数作为被调函数局部变量处理,即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本,不会影响主调函数实参变量的值。

那么为什么课本上说指针传递可以改变某些数的值呢?

指针传递的是地址,即一个指针本身是一个地址,传递给函数的是一个地址副本,但因为地址与地址副本指向的是内存中的同一个地方,所以可以修改指针指向数据的值。

但是如果要更改指针,也就是更改指针指向的地址,这样就不行了,要用指向指针的指针才可以。

void swap1(int *x, int *y)
{
    int temp;
    cout<<x<<endl;
    cout<<y<<endl;
    temp = *x;
    *x = *y;
    *y = temp;
}

int main()
{
    int a = 1,b=2;
    int *a1=&a;
    int *b1=&b;
    cout<<a<<endl;
    cout<<b<<endl;
    swap1(a1,b1);
    cout<<a<<endl;
    cout<<b<<endl;
}

引用传递

引用传递和指针有相似之处,本质上都是传递的地址,但是指针可以直接传过去,但是引用传入的是地址偏移量,系统通过地址偏移量计算到地址,来做一些更改。

void  swap2(int &x, int &y)
{
    cout<<"x="<<x<<endl;
    cout<<"y="<<y<<endl;
    int temp;
    temp = x;
    x = y;
    y = temp;

}
int main()
{
    int a = 1, b = 2;
    swap2(a,b);
    cout<<"a="<<a<<endl;
    cout<<"b="<<b<<endl;
}

但通过一个测试发现,在swap2中输出x,输出的并不是地址偏移量,而是x本身的值,只是因为被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量,我们对x做操作的时候x,系统帮我们间接寻址了,所以我们访问到的不是地址而是变量。

两重指针的应用

void change(int **t)
{
    //t是a指针的地址
    //*t是a的地址
    //**t是a
    cout<<t<<endl;
    cout<<*t<<endl;
    cout<<**t<<endl;
}

int main()
{
    int a=3;
    int *b=&a;
    change(&b);
    cout<<b<<endl;
    return 0;
}

运行结果

0x69fef8
0x69fefc
3
0x69fefc

我们能用引用更改指针的地址

  int m=10;
  int*n=&m;
  void swap(int*&a)   
  {     
     a=n;   //a地址被n替换
  } 

结束!

——————————————————————————
还有一个小知识点,

int main()
{
    int a = 1;
    int &b=a;
    cout<<&a<<endl;
    cout<<&b<<endl;
}

这里输出的a的地址与b的地址是一样的,b只相当于a的一个别名而已,也可以说一个地址有两个名字。

参考博客:
http://blog.csdn.net/xiven/article/details/4229599

http://www.cnblogs.com/zhaobing/archive/2013/03/18/2966280.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值