指针函数未显式返回值却可运行?链表代码疑问求助
#include <stdio.h> #include <stdlib.h> struct node { int data; struct node * prev; struct node * next; }; struct node * addtoempty(struct node * x,int value) { x=malloc(sizeof(struct node)); x->data=value; x->prev=NULL; x->next=NULL; } struct node *addatbeginning(struct node * x, int value){ struct node * ptr=malloc(sizeof(struct node)); ptr->data=value; ptr->next=x; ptr->prev=NULL; x->prev=ptr; x->next=NULL; x=ptr; } int main() { struct node * head=NULL; head=addtoempty(head,2); head=addatbeginning(head,5); printf("%d",head->data); return 0; }
我在实现双向链表时遇到疑问:上述代码中,
addtoempty和addatbeginning两个返回值类型为struct node*的函数未显式返回任何值,但程序仍能输出5;若不将函数调用结果赋值给head则会报错,请问这是为什么?
为什么未显式返回值仍能输出5?
这属于C语言中的未定义行为。C标准明确规定:声明了返回值类型的函数,如果没有执行显式的return语句,返回值是调用栈上的随机数据。但在你的编译环境中,刚好把函数最后操作的变量(比如addtoempty里的x、addatbeginning里的x)留在了返回值专用寄存器(比如x86架构的eax)中,所以巧合地返回了正确的节点指针地址。
这种结果完全依赖编译器实现、优化等级甚至操作系统,换环境后可能直接崩溃或输出垃圾值,绝对不能依赖。正确写法是在两个函数末尾加上return x;,让返回值符合预期逻辑。
为什么不赋值给head会报错?
当你不把函数调用结果赋值给head时:
- 调用
addtoempty后,head依然是初始的NULL,后续调用addatbeginning会把NULL作为参数x传入,执行x->prev=ptr;时就是对空指针解引用,直接触发段错误或程序崩溃。 - 即便
addtoempty巧合返回了正确指针,但head未被更新,后续操作还是会访问空指针,必然触发错误。
只有将函数返回的新节点指针赋值给head,才能让head始终指向链表的有效头节点,保证后续操作访问的是合法内存地址。
内容的提问来源于stack exchange,提问作者riprandy
相关产品推荐
相关产品推荐

