C++ 参考 - SomeType* &val 与 SomeType* val

C++ Reference - SomeType* &val vs. SomeType* val

我正在解决LeetCode 783. BST节点之间的最小距离并且我注意到正确解决方案和错误解决方案之间的区别是参考(&) 在我的函数调用中,如下所示:

正确答案:

class Solution {
public:
    void traverse(TreeNode* root, TreeNode* &curr, int &sol){
        if (root == nullptr) return;
        traverse(root->left, curr, sol);        
        if(curr) sol = min(sol, abs(root->val - curr->val));
        curr = root;
        traverse(root->right, curr, sol);
    }

    int minDiffInBST(TreeNode* root) {
        int sol = INT_MAX;
        TreeNode* curr = nullptr;
        traverse(root, curr, sol);
        return sol;
    }
};

错误解法:

class Solution {
public:
    void traverse(TreeNode* root, TreeNode* curr, int &sol){
        //Exactly the same as above!
};

作为一名学生,这是我第一次遇到与指针和引用相关的案例。对于这种差异的任何解释,我将不胜感激。

答案是没有引用 (void traverse(TreeNode* root, TreeNode* curr, int &sol){...}) curr 值将不会为函数的未来调用更新(将从调用堆栈执行)。

但是当有引用时(void traverse(TreeNode* root, TreeNode* &curr, int &sol){...}curr 值将被更新并用于下一次调用,直到程序终止。

如果你这样做

void foo(int * inner_ptr) {
   ptr++;
}

int main() {
   int arr[5] = {1, 2, 3, 4, 5};
   int outer_ptr = &arr[1];
   foo(outer_ptr);
}

outer_ptr 仍将等于 &arr[1]

您只更改了inner_ptrouter_ptr副本

你可以改变它指向的东西。

void foo(int * inner_ptr) {
   (*ptr) = 42;
}

但不是 outer_ptr 本身

因此你需要这个签名:(参考)

void foo(int * & inner_ptr);

或此签名:(指向指针的指针)(在这种情况下,您将在函数体中以不同方式使用它)

void foo(int * * inner_ptr);