链表头节点插入疑问:无返回值函数失效,带返回值函数可行?
链表头节点插入函数失效原因解析
先看你给出的两个函数:
无法工作的无返回值版本
// void insert_start(struct node *head, int data) // { // struct node *ptr = (struct node *)malloc(sizeof(struct node)); // ptr->next_ptr = head; // ptr->data = data; // head=ptr; // }
可以正常工作的带返回值版本
struct node *insert_start(struct node *head, int data) { struct node *ptr = (struct node *)malloc(sizeof(struct node)); ptr->next_ptr = head; ptr->data = data; return ptr; }
核心原因:C语言的值传递机制
C语言里函数参数是按值传递的——当你把外部的head指针传给无返回值版本的函数时,函数内部的head只是原指针的一个副本。你在函数里执行head=ptr,只是修改了这个副本的指向,完全不会影响到外部原来的head指针。
打个比方:就像你把家里钥匙复制了一把给别人,别人修改自己手里的复制钥匙,你手里的原钥匙根本不会变。所以这个函数执行完,外部的链表头还是原来的节点,新创建的节点没被关联到链表上,看起来就像没生效。
而带返回值的版本,会把新创建的头节点指针返回出去。调用时只要把返回值赋值给原来的head(比如head = insert_start(head, 5);),外部的head就会指向新节点,链表的头也就成功更新了。
额外补充:无返回值版本的修复方法
如果非要用无返回值的方式实现,可以用指针的指针作为参数,直接修改外部指针的指向:
void insert_start(struct node **head, int data) { struct node *ptr = (struct node *)malloc(sizeof(struct node)); ptr->next_ptr = *head; ptr->data = data; *head = ptr; }
调用时要传head的地址:insert_start(&head, 5);,这样函数里的*head就是外部原指针本身,修改它就能更新链表的头节点。
内容的提问来源于stack exchange,提问作者World Travellzzz
相关产品推荐
相关产品推荐

