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
(不带引用符号类型的这种)
首先,既然你没有问到为什么一定要带
*
或者&
,那说明你知道如果传递的是结构体(对象)本身会产生对象复制。所以*
和&
其实都可以避免对象复制,直接将原对象传递过来。但是引用和指针有个非常明显的区别,如果用指针
LNode *L
,在函数内部对L
赋值不会影响到外面的变量(实参);但如果是用引用,LNode &L
,在函数内部对L
赋值的时候是会影响到实参的。至于LNode* &L
是指针的引用,可以在函数内部修改指针本身(即L = 新指针
,而不是通过*L
来修改指针指针的实际值)。两个问题中都没有对形参
L
赋值,所以用指针还是引用都无所谓,目的就是使用不复制对象的方法把这个对象带到函数里面来。重要的区别就在于对形参赋值是否会改变实参。看看下面的示例:
输出