假设我有以下链表结构:
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()
函数接收链表的整个副本?如果它没有收到链表的整个副本怎么能打印清单?
答案 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));