C语言结构体自引用 图解教程(小白版)
C语言结构体:全局结构体变量与局部结构体变量
示例代码
#include<stdio.h>// 定义结构体类型struct Stu,同时定义全局变量 s1、s2structStu{//学生的相关属性charname[20];intage;}s1,s2;// s1,s2 是全局变量intmain(){structStus3;// s3是局部变量,定义在main函数内部return0;}一、自引用是什么(一句话 + 一张图)
一个结构体里藏一个"指向自己这种类型"的指针,让它能像糖葫芦一样一个个串起来,就是链表。
structNode{intdata;structNode*next;// 指向另一个同类型的Node};Mermaid 图解:三个节点怎么串起来的
看懂这张图:每个方框是一个 Node,方框里的
next就是那个"指针"(● 表示指向下一格的门牌号),箭头就是"顺着 next 找到下一个"。
ASCII 示意图(更贴近内存的样子)
Node1 Node2 Node3 +---------------+ +---------------+ +---------------+ | data = 10 | | data = 20 | | data = 30 | | next ------------> | next ------------> | next = NULL | +---------------+ +---------------+ +---------------+ ↑ ↑ ↑ 从这出发 顺着箭头走到这里 这里到头,停!二、为什么只能放"指针",不能直接放"自己"(图解核心)
直接放自己会无限套娃,编译器算不出大小,直接报错。
// ❌ 错误structNode{intdata;structNodenext;// 套娃,死循环};放指针就对了,因为指针只占固定大小(一张"门牌号纸条"):
记忆点:指针是一张记地址的纸条,只占8个字节;直接放自己是把整个屋子搬进来,会套娃。
三、指针 next 是怎么"指过去"的(动态图)
structNoden1={10,NULL};structNoden2={20,NULL};n1.next=&n2;// 把n2的地址写到n1的next里用一张 Mermaid 图表达"游标 p 一路走"的过程:
代码对应的每一步:
structNode*p=&n1;// p 先指向 n1while(p!=NULL){printf("%d ",p->data);// 打印当前指向的数据p=p->next;// p 顺着 next 挪到下一个}游标p像一个"手电筒",一直往下一格照,照到空的(NULL)就停下来。
四、完整可运行例子 + 内存图解
#include<stdio.h>structNode{intdata;structNode*next;};intmain(){structNoden1={10,NULL};structNoden2={20,NULL};structNoden3={30,NULL};n1.next=&n2;// 串起来n2.next=&n3;structNode*p=&n1;while(p!=NULL){printf("%d ",p->data);p=p->next;}printf("\n");return0;}运行结果:10 20 30
p 一开始在这里 ▼ [10] ──► [20] ──► [30] ──► NULL ▲ ▲ ▲ │ p=next │ p=next │ 遇到NULL,循环结束五、给小白的三张"记忆卡片"
六、易错点(配图记更牢)
- 自引用成员必须带
*:struct Node* next; - 最后一个节点的 next 要置 NULL,否则游标一路乱走会崩溃:
c.next=NULL;// 给链表打上"终点站"标记- 指针访问成员用
->,别写成p.next; - 遍历条件是
while(p != NULL),不是while(p)出错就跑飞。
七、一句话总结
自引用 = 结构体里放一个指向同类型的指针,像手电筒一样从第一个节点一路照到 NULL,
就能把零散的节点串成一条灵活的链表。