传递指针的值和引用有什么区别?

4

我目前正在学习数据结构和算法课程,我的教授提供了一些材料,其中包括接受指针值指针/引用值的函数。

这些函数看起来像这样:

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
第一个是传值调用,第二个是传引用调用。 - M.M
请注意,第二个是指向指针的引用。 - CinCout
4个回答

7
[...] 但我并不完全确定这两个参数与按引用传递的方式有什么不同,或者它们之间有什么不同。
在第一个函数中,
int function3(int* ptr);
//            ^^^^ 

你通过值传递指向 int 的指针。意味着传递 int* 的值。
第二个例子中,
int function4(int*& ptr);
//               ^^ --> here

您通过引用传递指向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

好的,谢谢,这样更有意义了。但是将指针按值传递和按引用传递与按值或引用传递常规变量类型(如整数)有何不同? - Brian
1
尝试使用这些函数交换两个变量(不返回任何内容)- 这是一个经典的例子,让你理解。 - user11422223

2

通过引用传递指针可以更改指针而不仅仅是指向的值。因此,如果您在函数 int function4(int*& ptr) 中进行指针分配,可以这样做:

ptr = nullptr;

在函数 int function3(int* ptr) 中,传递的指针被复制到变量 ptr 中,该变量仅在函数3的作用域内有效。在这种情况下,您只能更改指针指向的值,而不能更改指针本身(或者更好地说,您可以更改指针,但仅在函数的作用域内)。因此,先前的表达式 ptr = nullptr; 对调用者没有影响,因为它将指针设置为“nullptr”。


2
如果您想修改外部的 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
}

1
第一和第二个分别是按值传递和按引用传递,如代码中所述。
第三个通过值传递整数指针作为参数,可以分配内存位置,但指针的值仅在函数范围内局部更改。
第四个保持整数变量的值与引用相同,因为有一个&符号来引用该值(即指针)。
它们是函数声明,而不是定义,因此除非它们被定义为具有函数体,否则您无法探索其实际用途。(或者您可以从整数值执行的无限可能性列表中选择)
如果您想要一个按值传递与按引用传递的案例,则经典示例将是在函数内交换两个或多个值(不返回值),其中按引用传递有效,按值传递失败,或者您的第一个和第三个函数仅在函数内部局部更改值,而第二个和第四个函数会完全更改值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接