按值传递指针时内部会发生什么?

时间:2012-07-29 23:00:39

标签: c pointers linked-list

假设我有以下链表结构:

struct linked_list
{
    struct linked_list *next;
    int data;
};
typedef struct linked_list node;

以下函数打印链表:

void print(node *ptr)
{
    while(ptr!=NULL)
    {
        printf("%d ->",ptr->data);
        ptr=ptr->next;
    }
}

当我写这篇文章时,现在在main()函数中:

print(head); // Assume head is the pointer pointing to the head of the list

这实际上是按值调用。因为ptr中的print会收到head的副本。我们无法修改head函数中的print(),因为它是按值调用的。

但我怀疑是,因为ptr收到head的副本,但它能够打印链表的值。这是否意味着print()函数接收链表的整个副本?如果它没有收到链表的整个副本怎么能打印清单?

2 个答案:

答案 0 :(得分:4)

您的函数会收到指针的副本。指针的副本指向与原始指针相同的位置。

指针就像一个地址。这是一个类比。想象一下,在一张纸上写下你的地址。如果你想把它交给朋友你复制地址:也就是说,你在一张新纸上写下相同的地址,然后把那张纸给你的朋友。但如果他们去他们副本上写的地址,他们就会到达完全相同的地方,就像他们去了原始纸上的地址一样。

答案 1 :(得分:0)

print收到head的地址的副本,这意味着不会复制代表head的数据:该函数正在使用实际的头部,因此实际的链表,而不是副本。

这意味着您可以更改head,例如head->data,您可以修改链接列表的其余部分。您唯一不能做的是更改传入指针所指向的 节点,即您无法在head = NULL中执行print并期望它是反映在print之外。

因此,以下任何更改都会反映在函数之外:

// pick one:
ptr->data = 20;
ptr->next = NULL;
ptr->next = malloc(sizeof(node));
ptr->next->data = 20;
// etc.

以下不是

ptr = NULL;
ptr = malloc(sizeof(node));