递归typedef中指针类型“不匹配”为何被允许?
关于C语言链表中typedef指针类型匹配的疑问
我正在learn-c.org上学习C语言,在完成typedef声明与结构体相关单元的学习后,接触到了所谓的「链表递归定义」,整体理解较为顺畅,但对一处看似存在指针类型不匹配的代码感到困惑。代码如下:
typedef struct node{ int val; struct node* next; }node_t; // usage node_t* head = NULL; head = (node_t*) malloc(sizeof(node_t)); head->val = 1; head->next = (node_t*) malloc(sizeof(node_t)); head->next->val = 2; head->next->next = (node_t*) malloc(sizeof(node_t)); head->next->next->val = 3;我理解通过
typedef struct node,我们可以在结构体内部声明node指针next。但我的困惑点在第11行:我们为下一个节点动态分配内存时,将void指针强制转换为node_t指针,而非node指针——但head->next是(node*)类型。为何这是被允许的?是不是C会在后台自动转换为(node*),而node_t*只是为了提升代码可读性?
解答
核心逻辑很简单:node_t就是struct node的别名,二者指代的是同一个结构体类型,所以node_t*和struct node*是完全等价的指针类型,不存在所谓的“类型不匹配”问题。
typedef struct node {...} node_t;这句话的作用,就是给struct node这个结构体类型起了个更简洁的名字node_t,它们俩本质是同一个东西,没有任何区别。- 既然类型本身等价,对应的指针类型自然也完全一致,把
malloc返回的void*转成node_t*或者struct node*效果完全相同,赋值给head->next(struct node*类型)当然合法。 - 补充个细节:在C标准里,
malloc返回的void*可以直接赋值给任何对象指针类型,不需要手动强制转换,加转换只是部分编码习惯或者老编译器的要求。 - 用
node_t*确实是为了提升代码的可读性和简洁性,避免每次都写冗长的struct node*。
内容的提问来源于stack exchange,提问作者sh34v3
相关产品推荐
相关产品推荐

