函数传参何时用引用符号&?

void del(LNode *L)
{
    LNode *p = L->next;
    LNode * q;
    while (p->next != NULL)
    {
        if (p->data == p->next->data)
        {
            q = p->next;
            p->next = q->next;
            free(q);
        }
        else
            p = p->next;
    }
}

这个代码是删除一个非递减单链表中的重复元素。我的第一个问题是,函数参数为什么不写成LNode *&L,为什么不加引用符号&

18b0a41f7c2225f18d10755c54beea6.jpg

// 代码是上图识别出来的,可能会有小瑕疵

typedef struct LNode {
    ElemType data;
    struct LNode* next;
} LNode, *LinkList;

//在第i个位置插插入元素e(带头结点)
// 在第i个位置插插入元素e(带头结点)
bool ListInsert(LinkList &L, int i, ElemType e)
{
    if (i < 1)
        return false;
    LNode *p;  // 指针p指向当前扫描到的结点
    int j = 0; // 当前p指向的是第几个结点
    p = L;     // L指向头结点,头结点是第0个结点(不存数据)
    while (p != NULL && j < i - 1)
    { // 循环找到第i-1个结点
        p = p->next;
        j++;
    }
    if (p == NULL) // i值不合法
        return false;

    LNode *s = (LNode *)malloc(sizeof(LNode));
    s->data = e;
    s->next = p->next;
    p->next = s; // 将结点s连到p之后
    return true; // 插入成访
}

我的第二个问题是,为什么这个代码带了&,我想知道Linklist &L可不可以写成Linklist L(不带引用符号类型的这种)

阅读 2k
1 个回答

首先,既然你没有问到为什么一定要带 * 或者 &,那说明你知道如果传递的是结构体(对象)本身会产生对象复制。所以 *& 其实都可以避免对象复制,直接将原对象传递过来。

但是引用和指针有个非常明显的区别,如果用指针 LNode *L,在函数内部对 L 赋值不会影响到外面的变量(实参);但如果是用引用,LNode &L,在函数内部对 L 赋值的时候是会影响到实参的。至于 LNode* &L 是指针的引用,可以在函数内部修改指针本身(即 L = 新指针,而不是通过 *L来修改指针指针的实际值)。

两个问题中都没有对形参 L 赋值,所以用指针还是引用都无所谓,目的就是使用不复制对象的方法把这个对象带到函数里面来。重要的区别就在于对形参赋值是否会改变实参。

看看下面的示例:

#include <iostream>
using namespace std;

struct Person {
    int value;
};

void print(const Person& p) {
    cout << p.value << endl;
}

void test1(Person *p) {
    Person *n = new Person();
    n->value = 22;
    p = n;
}

void test2(Person &p) {
    Person *n = new Person();
    n->value = 22;
    p = *n;
}

int main() {
    Person *p1 = new Person();
    p1->value = 11;

    Person p2;
    p2.value = 11;
    
    cout << "before test1" << endl;
    print(*p1);
    test1(p1);
    cout << "after test1" << endl;
    print(*p1);
    
    cout << "before test2" << endl;
    print(p2);
    test2(p2);
    cout << "after test2" << endl;
    print(p2);
    
    return 0;
}

输出

before test1
11
after test1
11
before test2
11
after test2
22
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏