链接列表问题

时间:2012-12-23 03:44:39

标签: c pointers linked-list

我对链接列表有点麻烦。我不明白为什么这段代码会遍历并打印链表而没有问题:

struct foo {
    int data;
    struct foo * next;
};

int main(void) {
    struct foo * bar = NULL;
    ...
    print(bar);
}

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

然而,当我将列表放在另一个结构(如数组)中时,列表会在遍历期间被销毁,因为指针会在bar[i] = bar[i]->next处重新分配:

struct foo {
    int data;
    struct foo * next;
};

int main(void) {
    struct foo ** bar = (struct foo**)malloc(SIZE * sizeof(struct foo*));
    for (i = 0; i < SIZE; i++)
        bar[i] = NULL;
    ...
    print(bar);
}

void print(struct foo ** bar) {
    for (i = 0; i < SIZE; i++)
        while (bar[i] != NULL) {
            printf("%d, bar->data);
            bar[i] = bar[i]->next;
        }
}

为什么会这样?我知道在这种情况下编写print函数的正确方法是:

void print(struct foo ** bar) {
    struct foo * helper;
    for (i = 0; i < SIZE; i++)
        for (helper = foo[i]; helper != NULL; helper = helper->next)
            printf("%d", helper[i]->data);
}

我只是想了解为什么。为什么指针不能在第一个场景中重新分配,而是在第二个场景中重新分配?我认为它与传递值和传递引用有关,但这意味着第一个函数也会破坏列表。任何人都可以提供一些见解吗?

1 个答案:

答案 0 :(得分:2)

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

此函数将copy of a pointer to struct foo作为第一个参数。无论函数用它做什么,我都确信原始指针不会被修改,因为我只是在这里处理一个副本。另一方面,指针指向的值可能会被修改。

void print(struct foo** bar)
{
    for (i = 0; i < SIZE; i++)
        while (bar[i] != NULL)
        {
            printf("%d, bar->data);
                bar[i] = bar[i]->next;
        }
}

此函数将copy of a pointer to pointer to struct foo作为第一个参数。再次,不能从这里修改指向指针的原始指针,另一方面它指向的值(这里是pointer to foo)可以被修改。当然,bar指向的指针指向的值也可以修改。

如果您已正确理解这一点,您应该意识到为什么将struct something而不是struct something*传递给函数,这在性能方面是一个坏主意。