C++の传值、传址与传引用[ 入门 ]

C++の传值、传址与传引用

1. 概念

  1. 值传递:形参是实参的拷贝,改变形参的值并不会改变实参的值,从被调函数角度来看,值传递是单向的(实参->形参)。 在被调函数结束之后,形参自动销毁,并不会传到主调函数中
  2. 传址:形参是指向实参的指针,当对形参进行改动时,就相当于对实参进行改动。将实参地址传给形参,注意,这时形参指针和实参指针指向同一块地址。因此,改变形参就会修改实参。
  3. 传引用:形参是实参的“别名”,对形参的改动也就是对实参的改动。这时候,形参与实参使用相同的内存空间,二者的地址完全一样。
    注意:这一切都取决于你是否要改变主要参数的实参!!!

2. 简单例子

代码如下:

#include <iostream>
using namespace std;

void swapValue(int a, int b){
    int temp = a;
    a = b;
    b = temp;
}

void swapRef(int &a, int &b){
    int temp = a;
    a = b;
    b = temp;
}

void swapPtr(int *a, int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(){
    int a = 1;
    int b = 4;
    cout << "Original Status: " << endl;
    cout << "a = " << a << "\t" << "b = " << b << "\t" << "&a = " << &a <<"\t" <<"&b = " << &b << endl;

    swapValue(a, b);
    cout << "After passing by value :" << endl;
    cout << "a = " << a << "\t" << "b = " << b << "\t" << "&a = " << &a <<"\t" <<"&b = " << &b << endl;

    swapRef(a, b);
    cout << "After passing by ref: " << endl;
    cout << "a = " << a << "\t" << "b = " << b << "\t" << "&a = " << &a <<"\t" <<"&b = " << &b << endl;

    swapPtr(&a, &b);  //这里会恢复原值,因为上面引用已经交换过了。
    cout << "After passing by Ptr: " <<endl;
    cout << "a = " << a << "\t" << "b = " << b << "\t" << "&a = " << &a <<"\t" <<"&b = " << &b << endl;
    return 0;
}

运行后,结果如下:

Original Status:
After passing by value :
a = 1   b = 4   &a = 0x61fe1c   &b = 0x61fe18
After passing by ref:
a = 4   b = 1   &a = 0x61fe1c   &b = 0x61fe18
After passing by Ptr:        //注意这里貌似是没有通过指针交换,实际上是因为上面的引用已经换过了,传指针又将其恢复了。
a = 1   b = 4   &a = 0x61fe1c   &b = 0x61fe18

3. 三种方式比较

  1. 功能上:传值不可以在主调函数中改变实参;传指针与传引用则可以在主调函数中改变实参的值。而且,指针是最灵活的。

  2. 传递效率上:指主调函数中实参传递到被调函数中的形参中的效率。对于32位的机器,小于4字节的参数,可以看出是值传递效率更高,要是大于4字节参数或者自定义的数据类型(class、struct),最好就是使用传址或者传引用。

  3. 执行效率上:指在被调函数体内执行的效率。传值的话就是直接寻址,指针与大部分情况下的引用则是通过间接寻址的方式执行的。所以传值执行效率稍高些。对于传过来的变量的频繁操作且总次数很多的情况下,传址和传引用有较多的效率损失。

    综合2和3来看,传引用效率始终是不低于传指针的。所以C++优先传引用而非指针。😙

  4. “Reference when possible, Pointers when needed!”

4. 一个可能忽视的点

考虑如下代码:

int add(int a, int b){
	return a + b;
}
int main(){
    int m = 0, n = 1;
    int ret = add(m, n);
    return 0;
}

实参m、n值传递给被调函数add,进行相应计算。但是我们不需要修改实参,我们想要的就只是一个返回值,所以在6行,程序开始运行add子程序,执行完之后,还是在第6行继续进行,将add函数返回值赋值给ret。

这个例子是不让自己混淆 上面讨论的修改实参问题 与 直接拷贝返回值。

https://www.cnblogs.com/h2zZhou/p/9559123.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值