按值传递指针和引用之间的区别?

Posted

技术标签:

【中文标题】按值传递指针和引用之间的区别?【英文标题】:Difference between passing a pointer by value and reference? 【发布时间】:2020-04-10 16:22:21 【问题描述】:

我目前正在学习数据结构和算法课程,我的教授给我们提供了材料,其中包括接收指针值指针/参考值的函数。

这些函数如下所示:

int function1(int a); // Pass by value
int function2(int &ref); // Pass by reference

int function3(int* ptr); // This will take in a pointer value
int function4(int*& ptr); // This will take in a pointer/reference value

我了解按值传递按引用传递之间的区别。我也尝试将后两个示例都实现为基本函数,但我不完全确定这两个参数与引用传递有何不同,或者它们之间有何不同。

有人能解释一下这两个函数参数是如何工作的以及如何实际使用它们吗?

【问题讨论】:

第一个是传值,第二个是传引用 注意第二个是对指针的引用 【参考方案1】:

[...] 但我不完全确定这两个论点与 通过引用传递或它们之间的区别。

在第一个函数中

int function3(int* ptr);
//            ^^^^ 

您通过指针传递给int。按值表示int*

第二个,

int function4(int*& ptr);
//               ^^ --> here

您通过reference指针传递给int。这意味着您正在传递对 int* 类型的引用。


但是按值传递指针和按引用传递指针有何不同? 通过值传递常规变量类型(例如整数)的用法 还是参考?

一样。当您按值传递指针时,您对传递的指针所做的更改(例如:分配另一个指针)将仅在函数范围内有效。另一方面,在指针通过引用的情况下,可以直接对main()中的指针进行修改。例如,请参阅以下演示。

#include <iostream>    
// some integer
int valueGlobal 200 ;

void ptrByValue(int* ptrInt)

    std::cout << "ptrByValue()\n";
    ptrInt = &valueGlobal;
    std::cout << "Inside function pointee: " << *ptrInt << "\n";


void ptrByRef(int *& ptrInt)

    std::cout << "ptrByRef()\n";
    ptrInt = &valueGlobal;
    std::cout << "Inside function pointee: " << *ptrInt << "\n";


int main()

    
        std::cout << "Pointer pass by value\n";
        int value 1 ;
        int* ptrInt &value ;
        std::cout << "In main() pointee before function call: " << *ptrInt << "\n";
        ptrByValue(ptrInt);
        std::cout << "In main()  pointee after function call: " << *ptrInt << "\n\n";
    
    
        std::cout << "Pointer pass by reference\n";
        int value 1 ;
        int* ptrInt &value ;
        std::cout << "In main() pointee before function call: " << *ptrInt << "\n";
        ptrByRef(ptrInt);
        std::cout << "In main()  pointee after function call: " << *ptrInt << "\n\n";
    

输出

Pointer pass by value
In main() pointee before function call: 1
ptrByValue()
Inside function pointee: 200
In main()  pointee after function call: 1

Pointer pass by reference
In main() pointee before function call: 1
ptrByRef()
Inside function pointee: 200
In main()  pointee after function call: 200

【讨论】:

好的,谢谢,这更有意义。但是,按值和按引用传递指针与按值或按引用传递常规变量类型(如整数)有何不同? 尝试使用这些函数交换两个变量(不返回任何内容) - 这是一个让您理解的经典示例。【参考方案2】:

通过引用传递指针允许您更改指针而不仅仅是指向的值。因此,如果您以这种方式在函数int function4(int*&amp; ptr) 中分配指针:

ptr = nullptr;

调用者将指针设置为“nullptr”。

在函数int function3(int* ptr) 中,传递的指针被复制到变量ptr 仅在函数3 的范围内有效。在这种情况下,您只能更改指针指向的值,而不能更改指针(或者更好地指定您可以更改指针,但只能在函数范围内)。所以前面的表达式ptr = nullptr;在调用者中是没有作用的。

【讨论】:

【参考方案3】:

如果要修改外部 int 值,请使用:

int function1(int* ptr) 
    *ptr = 100; // Now the outside value is 100
    ptr = nullptr; // Useless. This does not affect the outside pointer

如果您想修改外部int* 指针,即重定向该指针,请使用:

int function2(int*& ptr) 
    ptr = nullptr; // Now the outside pointer is nullptr

或者这个:

int function3(int** ptr) 
    *ptr = nullptr; // Same

【讨论】:

【参考方案4】:

第一个和第二个分别按代码中的注释传递值和引用。

第三个是按值取整型指针作为参数,可以为它分配一个内存位置,但指针的值只在函数范围内局部变化。

第四个保存一个带引用的整数变量的值,因为有一个 amperson(&) 用于引用该值(它是一个指针)。

它们是函数声明,而不是定义,所以除非它们是用函数体定义的,否则你无法探索它的实际用途。 (或者你可以用整数值做的无限可能性的列表) 如果您想要按值传递与按引用传递的情况,经典示例是在函数中交换两个或多个值(不返回值),其中按引用传递有效并且按值传递失败,或者您的第一个和第三个函数只会在函数内部本地更改值,而第二个和第四个函数会整体更改值。

【讨论】:

以上是关于按值传递指针和引用之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章

Java按值调用和按引用调用的区别

按值传递/指针/引用说明

为啥要在 C++ 中按值传递对象 [重复]

VB 参数传递:按值传递和按地址传递

是否传递指针参数,在 C++ 中按值传递?

js按值传递和按引用传递