易妖游戏网
您的当前位置:首页C++の传值、传址与传引用[ 入门 ]

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

来源:易妖游戏网

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

1. 概念

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。

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

因篇幅问题不能全部显示,请点此查看更多更全内容