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;
}