单指针和双指针附加之间的区别

时间:2018-10-29 08:35:00

标签: c linked-list

这可能是一个愚蠢的问题,但我真的很想知道为什么会这样。尝试为链接列表创建追加函数时,为何此单指针解决方案不起作用,但是当使用双指针时却起作用?

单指针:

void append(node *head, int value){
node *current = head;
node *new = malloc(sizeof(node));
if (new == NULL){
    printf("couldn't allocate memory");
    return;
}
new->value = value;
new->next = NULL;
if (head == NULL){
    head = new;
    return;
}
while (current->next != NULL)
    current = current->next;
current->next = new;
return;}

双指针:

void append(node **head, int value){
node *current = *head;
node *new = malloc(sizeof(node));
if (new == NULL){
    printf("couldn't allocate memory");
    return;}
new->value = value;
new->next = NULL;
if (*head == NULL){
    *head = new;
    return;
}
while (current->next != NULL)
    current = current->next;
current->next = new;
return;}

2 个答案:

答案 0 :(得分:2)

使用一个参数调用函数时,会在堆栈上创建该参数的副本。因此在某种程度上,它们与局部变量非常相似。

在单指针情况下,语句head = new;实际上只是导致对参数head的更改,并且此更改不会传播回传递给的实际头。

在双指针情况下,您将获得head的地址,可以通过执行*head = new;来对其进行更改。

答案 1 :(得分:1)

想象一下,您的记忆力在不断增强 ------------- ------------ | head 0x10 | -> | 0x20 | ------------- ------------

0x10是head的地址,而不是它指向的地址,它指向的地址是0x20。

如果仅用一个指针调用append,它将把head值复制到函数append的本地地址 这样,对于append,头可能是: ------------- ------------ | head 0x25 | -> | 0x20 | ------------- ------------

因此,标头的新地址为 0x25 ,指向 0x20

如果您使函数内的head指向另一个地址,例如: ------------- ------------ | head 0x25 | -> | 0x30 | ------------- ------------

只有函数内部的head会指向不同的地址,在调用方函数中它将仍然是: ------------- ------------ | head 0x10 | -> | 0x20 | ------------- ------------

因为要按值传递指针,所以该函数正在复制指针。 为了解决这个问题,您需要将一个指针传递给一个指针,因此您的变量将是:

local
------------- ------------- ------------ | head 0x25 | -> | head 0x10 | -> | 0x20 | ------------- ------------- ------------

现在您有了一个指向调用者指针的指针,因此您可以对其指向的位置进行更改,并将其反映在调用者头上。

例如

local
------------- ------------- ------------ | head 0x25 | -> | head 0x10 | -> | 0x30 | ------------- ------------- ------------