【发布时间】:2021-04-08 18:47:57
【问题描述】:
编辑:我的结构是这样的:
struct node{
int key;
struct node* next;
}
typedef struct node* LIST;
我正在编写一个名为print_list_iteratively 的函数,它采用单链表并以相反的顺序迭代地打印其元素。让我把我的 3 个函数放在下面,然后解释一下我的问题是什么?
LIST reverse_list(LIST L) {
LIST current = L, prev = NULL, subsequent = NULL;
while (current != NULL) {
// first we need to get the next element to not lose the link.
subsequent = current->next;
// now reverse the pointer
current->next = prev;
// we need to update our prev to create link between the currrent and next element.
// in short, we need to get the address of current node
prev = current;
// finally update the current
current = subsequent;
}
return (L = prev);
}
上面的代码将链表L反转,返回链表L的新头部。
void print_list(LIST L) {
while (L) {
printf("%d ", L->key);
L = L->next;
}
}
print_list 按连接顺序打印列表中的元素。
前面提到的print_list_iteratively函数我都需要写了。
void print_list_iteratively(LIST l) {
// first reverse the list, then call print_list. that's all.
printf("address of function parameter is %p\n", l);
l = reverse_list(l);
print_list(l);
}
我对这些功能没意见;它们按预期工作,但是当我试图理解函数如何将列表作为参数并返回它时,按值传递和按引用传递的概念让我感到困惑。让我简单地写一个 main 来测试这些,我们会看看事情是如何混合起来的。
int main(void) {
l = insert(l, 5);
l = insert(l, 10);
l = insert(l, 15);
l = insert(l, 45);
print_list(l);
print_list_iteratively(l);
print_list(l);
return 0;
}
当第一个print_list 函数被调用时,它会打印5->10->15->45. 下一个print_list_iteratively 在列表l 上被调用,它又在函数体中调用reverse_list 和print_list。 print_list 内 print_list_iteratively 给出反向列表 45->15->10->5. 最终,print_list 内主要打印 5.
我想知道为什么第二个print_list 刚刚打印了5?我已经将列表发送到 print_list_iteratively 传递值,而不是传递引用,尽管如此,它改变了我原来的列表 insinde main 函数。有人能解释一下这个例子中的列表是如何传递给函数的,以及它们是如何从函数中返回的吗?感谢您的回答。
【问题讨论】:
-
current->next = prev;该代码更改了原始列表。您按值传递了头指针,但它不会阻止更改列表字段。 -
typedef struct node* LIST;在 typedef 后面隐藏指针会导致代码混乱。看起来您正在传递一个值,但您正在传递一个指针。我建议将其更改为typedef struct node LIST;并传入LIST *。 -
风格问题:不要在 typedef 中隐藏指针,所以使用
typedef struct node LIST;。大写单词通常保留给宏,因此将LIST重命名为例如tList。 -
@kaylum,谢谢,知道了。让我再问一个关于按值传递列表头的问题。在我的过程 reverse_list 中,我按值获取原始列表的头并将其分配给 L,但此分配只是将头指针的值复制到 L。列表 L 与我的主函数中的列表相同,但因为我没有'不发送我的原始列表的地址,L 不指向原始列表指向的位置。但是,当操作完成时,head 会受到函数更改的影响,因为最初它们都具有相同的 head 值。
-
@kaylum,函数对该地址进行了操作,这就是我原来的列表发生变化的原因,对吧?很高兴能得到你的想法。
标签: c pointers pass-by-reference singly-linked-list pass-by-value