1、自引用结构体的基本定义
C语言中,结构体不能包含自身类型的直接实例(即,不能定义 struct Node node;
),但可以包含指向自身类型的指针(即 struct Node *next;
)。
#include <stdio.h> #include <stdlib.h> // 单链表节点 // 定义自引用结构体 struct Node { int data; struct Node *next; // 指向自身类型的指针 }; int main() { struct Node node1, node2; node1.data = 10; node2.data = 20; node1.next = &node2; // 让 node1 指向 node2 node2.next = NULL; // node2 是链表的最后一个节点 printf("Node1 data: %d\n", node1.data); printf("Node2 data: %d\n", node1.next->data); return 0; }
2、结构体不能包含自身的原因
如 struct
直接包含自身类型的变量,编译器无法确定结构体的大小。 struct Node
包含一个 struct Node
成员,导致无限递归,编译器无法计算 struct Node
的大小。但指针 struct Node *next
只是一个地址,占用固定大小(通常是 4
或 8
字节),不会导致递归问题。
3、typedef 和自引用结构体
可以使用 typedef
来简化结构体的定义。
#include <stdio.h> #include <stdlib.h> // 定义自引用结构体 typedef struct Node { int data; struct Node *next; } Node; // 创建新节点 Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); if (!newNode) { printf("内存分配失败!\n"); exit(1); } newNode->data = data; newNode->next = NULL; return newNode; } // 在链表末尾插入新节点 void appendNode(Node** head, int data) { Node* newNode = createNode(data); if (*head == NULL) { *head = newNode; return; } Node* temp = *head; while (temp->next != NULL) { temp = temp->next; } temp->next = newNode; } // 打印链表 void printList(Node* head) { Node* temp = head; while (temp != NULL) { printf("%d -> ", temp->data); temp = temp->next; } printf("NULL\n"); } // 释放链表内存 void freeList(Node* head) { Node* temp; while (head != NULL) { temp = head; head = head->next; free(temp); } } int main() { Node* head = NULL; // 添加节点 appendNode(&head, 10); appendNode(&head, 20); appendNode(&head, 30); // 打印链表 printf("链表内容: "); printList(head); // 释放内存 freeList(head); return 0; }