我尝试创建一个函数,将一个节点添加到列表的开头,然后更改变量“head”(保存列表的前一个开头)以包含新节点。
void addToStart(node * n, node * first){
printf("[Before adding] Node: %d, First: %d\n",&(*n),&(*first));
n->next = first;
first = n;
printf("[After adding] Node: %d, First: %d\n",&(*n),&(*first));
}
int main(){
node * head = createNode(0);
printf("This is the location of head: %d\n",&(*head));
node * fred = createNode(2);
addToStart(fred,head);
traverse(head); //Displays the list starting from the given node
return 0;
}
这是输出:
This is the location of head: 10113040
[Before adding] Node: 10113072, First: 10113040
[After adding] Node: 10113072, First: 10113072
(0)[10113040]->NULL
问题是我期望该函数改变什么 head
所指的,但实际上什么都没有改变。
最佳答案
因为addToStart
将头指针的副本作为节点*
。要改变头部,需要使用
void addToStart(node * n, node ** first){
// ^
printf("[Before adding] Node: %d, First: %d\n",&(*n),&(**first));
n->next = *first;
// ^
*first = n;
// ^
printf("[After adding] Node: %d, First: %d\n",&(*n),&(**first));
}
编辑 C 中的每个函数都有自己的参数副本,因此实际上不存在像 C++ 或其他语言那样的引用。无论您在何处使用引用,快速而肮脏的选项(可能并不总是有效!)是在每个提及前面添加一个额外的 *
。在这里,您希望 first
作为引用。 first
是一个节点指针,因此它已经是一个node *
。要将其用作“引用”(事实上),它会获得一个额外的 *
,因此 node **
。同样,无论在哪里引用它,它都会获得一个额外的 *
:*first = ...
。
参见a Java answer that's related有关 Java 内部结构的更多信息。基本上,第一个 *
隐含在 Java 实例变量中。因此,Java 中的 Node n;
有点像 C 中的 Node *n;
。
希望有所帮助 - 请务必查看页面顶部链接的重复问题以及那里的答案。如果您遇到其他代码问题,请提出另一个问题!
C 向导请注意:是的,我知道盲目添加 *
是一个坏主意!不过,有时它很有用。我正在尝试以一种能够让 OP 向前迈出一步的方式来回应 OP 的评论。
关于c - 为什么我的链表头没有改变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39209296/