在此代码中:
void push(node **head, int data) {
node *temp = malloc(sizeof(node));
temp->data = data;
temp->next = *head;
*head = temp;
}
为什么temp->next = *head
不够?
为什么有必要将*head
设为temp
?这完成了什么?
答案 0 :(得分:2)
方法push()
有两个参数:指向node
指针的指针(指向链表的指针)和要插入列表的值。
需要*head = temp;
的原因是调用者的链接列表最终被修改。如果没有此行,则不会修改调用者的链接列表。
这是一个高度简化的例子,说明为什么这是必要的。假设我有一个修改int的方法:
void foo(int *bar) {
int baz;
baz = *bar;
baz = 42;
}
通过传入指针调用foo()
后,指针指向的变量不会发生任何事情。当foo()
完成时,所有堆栈变量(即bar
和baz
)将不再存在,并且永远不会保存对bar
的值的修改。 / p>
回到你问题中的例子。如果该行永远不会被调用,那么调用者的副本就会发生 nothing (即在调用该函数之后,就好像该元素从未被添加到列表中),原因与调用者的副本相同传入foo()
的任何内容都没有改变。
出于这个原因,您经常会看到insert()
函数的不同方法签名:
node *push(node *head, int data);
这就像这样调用:
// assume head is a pointer to a node
head = push(head, 42);
效果是一样的,但是因为只有一个指向节点的指针被传入,所以push()
对列表结构所做的任何操作都不会应用于head
,直到进行赋值。
答案 1 :(得分:1)
它将头部重置为新节点,允许我们迭代所有元素。 Push将新节点放在列表的开头。 Head就像链接列表的起点,使用它可以获得所有元素。如果磁头未设置为新节点,则将丢失对新插入数据的引用,从而导致内存泄漏。
答案 2 :(得分:0)
假设它是一个基于列表的堆栈(根据Push
操作猜测),那么该项应该添加到列表的开头,以便可以轻松弹出。
这样,当调用者再次尝试使用堆栈时,列表的头部将使用新数据项进行更新。