我尝试编写一个函数,将一个节点添加到列表的开头,然后更改变量"head"(保存列表的前一个开头)以包含新节点。
void addToStart(node * n, node * first){
printf("[Before adding] Node: %d, First: %dn",&(*n),&(*first));
n->next = first;
first = n;
printf("[After adding] Node: %d, First: %dn",&(*n),&(*first));
}
int main(){
node * head = createNode(0);
printf("This is the location of head: %dn",&(*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
将头指针的副本作为node *
。要更改标题,您需要使用
void addToStart(node * n, node ** first){
// ^
printf("[Before adding] Node: %d, First: %dn",&(*n),&(**first));
n->next = *first;
// ^
*first = n;
// ^
printf("[After adding] Node: %d, First: %dn",&(*n),&(**first));
}
Edit C中的每个函数都有自己的参数副本,因此不像c++或其他语言中那样存在引用。无论在何处使用引用,快速而肮脏的选择(这可能并不总是有效!)是在每次提及前附加一个额外的*
。在这里,您希望first
作为参考。first
是一个节点指针,所以它已经是一个node *
。要将其用作"引用"(就像它一样),它会获得一个额外的*
,因此是node **
。类似地,无论它被引用到哪里,它都会得到一个额外的*
: *first = ...
。
有关Java内部的更多信息,请参阅Java答案。基本上,第一个*
隐含在Java实例变量中。因此,Java中的Node n;
(有点)类似于c中的Node *n;
。
希望能有所帮助-一定要看看页面顶部的链接重复问题,以及那里的答案。如果您遇到另一个代码问题,只需问另一个问题!
注意C向导:是的,我知道盲目添加*
是一个坏主意!不过,有时它还是有用的。我正试图以一种能使OP向前迈进一步的方式回应OP的评论。