为什么我可以在C语言中多次遍历我的链表

4
我有一个链表,最后一个节点指向NULL,并有一个函数通过在while循环中遍历该列表来打印元素。我会上传我的源码,但它相当冗长,所以我会简化它。
struct xrec{
    *some elements*
    struct xrec *next;
};
typedef struct xrec EMPLOYEE;

void listEmployee(EMPLOYEE * list){ // list is head node
int i = 0;

    while (list != NULL){
        printf(*%d. print elements..*, i+1);
        list = list->next; // point to next structure
        i++;
    }
}

我可以随意调用该函数,因为我将其设置在一个do-while循环中的switch语句中。但是,在第一次调用之后,我的头节点不会指向NULL吗?因此,我再也无法打印出元素了,对吗?但是每次调用该函数时,它总是回到第一个节点。为什么?我非常确定我在调用该函数后从未将列表重定向回第一个节点。


是的,因为你遍历到了列表的末尾。如果你想再次遍历列表,你需要跟踪列表头的位置,例如 head = list,然后每次从 head 开始遍历。 - Marc B
我不知道你所指的head是哪一个。如果你指的是list,那么在函数内部是有影响的,但函数外部没有影响(如果代码的其余部分没有影响的话)。 - Jason Hu
2个回答

4

函数的参数是其本地变量。也就是说,它们(它们的值)是参数的副本。因此,在这个声明中:

void listEmployee(EMPLOYEE * list);

list是函数的本地变量。在函数内部更改参数不会影响函数调用的参数(及其值)。

您可以这样想象函数的调用方式

EMPLOYEE * head;

//...

listEmployee( head );

//...

void listEmployee( /* EMPLOYEE * list */ )
{
   EMPLOYEE * list = head;
   //...

因此,在函数内部,它的局部变量list会改变。head不会被改变,因为它在函数中没有被使用。


2
list变量是一个指向节点的指针;当你遍历列表时,你会改变这个指针。因此,当你到达末尾时,list不再是头部。
但你正在更改的变量不是作为参数传递给函数的那个变量。当你调用函数时,你传递的指针将被复制到一个新的变量list中;是这个副本被改变了,而不是原始变量。原始变量保持不变。
值传递和引用传递之间的区别可能值得查一下。在这里,指针是按值传递的。这有点令人困惑,因为指针实际上是一个引用...但它是传递值的引用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接