函数传参何时用引用符号&?
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
,为什么不加引用符号&
?
// 代码是上图识别出来的,可能会有小瑕疵
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
(不带引用符号类型的这种)
回复
1个回答

test
2024-07-12
首先,既然你没有问到为什么一定要带 *
或者 &
,那说明你知道如果传递的是结构体(对象)本身会产生对象复制。所以 *
和 &
其实都可以避免对象复制,直接将原对象传递过来。
但是引用和指针有个非常明显的区别,如果用指针 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
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容