【问题标题】:When printing out a linked list, why is the original head pointer not changed打印出链表时,为什么原来的头指针没有改变
【发布时间】:2014-04-29 22:32:14
【问题描述】:

我已经编写了一些代码来创建一个整数的单链表并打印出这些项目。打印出列表中的所有项目后,我打印出“head->item”并得到第一个节点中整数的值。

我很纳闷为什么我可以这样做,因为在 print() 函数中,我写了“head = head->next”,所以这意味着 head 被改变了对吧?

main()
    int n;
    int value;
    ListNode *head = NULL;
    ListNode *temp = NULL;
    printf("Enter a value: ");
    scanf("%d", &n);
    while (n != -1)
    {
        if (head == NULL)
        {
            head = malloc(sizeof(ListNode));//create the head first
            temp = head;//get temp to have the same value as head, so we do not accidently edit head
        }
        else
        {
            temp->next = malloc(sizeof(ListNode));//allocate space for the next node
            temp = temp->next;//let temp be the next node
        }
        temp->item = n;//allocate a value for the node
        temp->next = NULL;//specify a NULL value for the next node so as to be able to allocate space
        scanf("%d", &n);
    }
    print(head);
    printf("%d\n", head->item);//why can I still get the integer in the first node
    while (head != NULL)
    {
        temp = head;
        head = head->next;
        free(temp);
    }
    head = NULL;
    return 0;
}
void print(ListNode *head)
{
    if (head == NULL)
    {
        return;
    }
    while (head != NULL)
    {
        printf("%i\n", head->item);
        head = head->next;
    }
}

【问题讨论】:

  • head print 函数的变量改变了,但main函数的变量没有改变

标签: c pointers linked-list


【解决方案1】:

head 可以看作是对列表的“引用”,但它实际上是一个数字(第一个节点的地址)。 因此,以head 作为参数调用函数只需将此“数字”(地址)复制到堆栈,并创建一个使用相同地址启动的新变量(也称为head)。 由于函数内部的head 是一个不同的变量,因此更改它不会更改原始head

考虑这种情况:

void func(int x)
{
    x=1;
}
...
int x=0;
func(x);
printf("%d",x); //Prints '0'
...

确保您理解为什么在这个简单的示例中x 的值没有改变。确实,指针似乎改变了参数传递的行为,但这并不意味着突然间一切都“通过引用”传递了。

记住这条规则:为了在函数中修改变量的值,你需要发送一个指向该变量的指针。那么当您想将 指针 更改为变量时会发生什么?好吧,根据规则,您必须将 pointer 传递给指针。

因此,如果您想修改 head(您可能不会),请像这样重构它:

void print(ListNode **head)
{
    if (*head == NULL)
    {
        return;
    }
    while (*head != NULL)
    {
        printf("%i\n", *head->item);
        *head = *head->next;
    }
}

现在实际调用的是print(&head)

【讨论】:

  • 非常感谢,您加深了我的理解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-25
  • 2020-08-17
  • 1970-01-01
  • 2015-03-07
相关资源
最近更新 更多