C++的传值、传引用、传指针介绍

C++中支持三种参数传递方式:

1) 按值传递(pass by value) 

2)引用传递(pass by reference) 

3) 指针传递(pass by pointer) 

指针:指针是一个变量,只不过这个变量中存储的是一个地址,指向内存中的一个单元。

引用:引用和原变量是同一个东西,只不过是原变量的一个别名。引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。

函数传参的三种方式:

传值:形参是实参的拷贝,改变形参的值并不会影响外部实参的值。实参和形参是处于两个不同的地址空间,传递的实质是将原函数中实参变量的值,复制到被调用函数形参所在的存储空间中。这个形参的地址空间在函数执行完毕后,会被回收掉。整个被调用函数对形参的操作,只影响形参对应的地址空间,不影响原函数中变量的值,因为这两个不是同一个存储空间。

即使形参的值在函数中发生了变化,实参的值也完全不会受到影响,仍为调用前的值。

传引用:形参相当于是实参的“别名”,对形参的操作其实就是对实参的操作。引用和原变量是同一个东西,只不过是原变量的一个别名。在被调用函数中,对引用变量的所有操作等价于对实参的操作。这样,整个函数执行完毕后,原先的实参的值将会发生改变。

传指针:形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作——在函数中对指针变量的操作,就是对实参(指针变量地址)所对应的变量的操作,函数调用结束后,原函数中的变量的值将会发生改变。被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。

传递引用给函数与传递指针的效果是一样的。

下面给出简单对比示例

★按值传递(Pass by Value),函数中对参数的修改不会影响到原始的参数。示例源码如下:

#include <iostream>
using namespace std;

void foo(int x) {
    x = 10;
}

int main() {
    int y = 5;
    foo(y); // y的值不会被修改,因为参数是按值传递的
    cout << "y = " << y <<endl; // y = 5
    
    return 0;
}

★按引用传递(Pass by Reference),函数中对参数的修改会影响到原始的参数。示例源码如下:

#include <iostream>
using namespace std;

void foo(int& x) {
    x = 10;
}

int main() {
    int y = 5;
    foo(y); // y的值会被修改,因为参数是按引用传递的
    cout << "y = " << y <<endl; // y = 10
    
    return 0;
}

★按指针传递(Pass by Pointer),调用参数(实参)需要使用取地址符&。函数中对参数的修改会影响到原始的参数。示例源码如下:

#include <iostream>
using namespace std;

void foo(int* x) {
    *x = 10;
}

int main() {
    int y = 5;
    foo(&y); // y的值会被修改;使用了取地址符&
    cout << "y = " << y <<endl; // y = 10
    
    return 0;
}

引用和指针的区别与联系

1.相同点:

底层的实现方式相同,都是按照指针的方式实现的。

2.不同点:

引用定义的时候必须初始化,指针可以不用初始化;

引用一旦初始化为指向一个对象,就不能再指向其他对象,而指针可以在任何时候指向任何一个同类型的对象;

没有空引用,但是有空指针;

在sizeof中的含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节的个数(在32为平台下,指针求sizeof永远是4);

引用++改变的是变量的内容,指针++改变的是指针的指向;

有多级指针,没有多级引用;

引用使用起来比指针安全;

如果返回动态内存分配的对象或者内存,必须使用指针,引用可能引起内存泄漏;

进一步了解学习可参见 https://blog.csdn.net/cnds123/article/details/132914674

附录、C和C++中参数传递方式说明
  按值传递(Pass by Value):这是C和C++函数参数的默认传递方式。在这种情况下,函数接收的是参数值的一个副本,而不是参数本身。因此,函数内对参数的任何修改都不会影响原始参数。
  按引用传递(Pass by Reference):在C++中,可以通过引用来传递参数。这种情况下,函数接收的是参数的引用,而不是值的副本。这意味着函数内对参数的任何修改都会影响到原始参数。在C语言中,没有直接的按引用传递,但可以通过指针实现类似的效果。
  按指针传递(Pass by Pointer):在C和C++中,都可以通过指针来传递参数。在这种情况下,函数接收的是指向参数的指针。函数内可以通过该指针修改原始参数的值。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐