ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

C语言结构体自引用 图解教程

C语言结构体自引用 图解教程

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 图解:三个节点怎么串起来的

指向

指向

尾巴

Node1
data=10
next=●

Node2
data=20
next=●

Node3
data=30
next=NULL

结束

看懂这张图:每个方框是一个 Node,方框里的next就是那个"指针"(● 表示指向下一格的门牌号),箭头就是"顺着 next 找到下一个"。

ASCII 示意图(更贴近内存的样子)

Node1 Node2 Node3 +---------------+ +---------------+ +---------------+ | data = 10 | | data = 20 | | data = 30 | | next ------------> | next ------------> | next = NULL | +---------------+ +---------------+ +---------------+ ↑ ↑ ↑ 从这出发 顺着箭头走到这里 这里到头,停!

二、为什么只能放"指针",不能直接放"自己"(图解核心)

直接放自己会无限套娃,编译器算不出大小,直接报错。

// ❌ 错误structNode{intdata;structNodenext;// 套娃,死循环};

Node

Node里的Node

Node里的Node里的Node

...无穷无尽...

放指针就对了,因为指针只占固定大小(一张"门牌号纸条"):

纸条上只写一行地址

Node
data
next: 纸条

另一个Node

记忆点:指针是一张记地址的纸条,只占8个字节;直接放自己是把整个屋子搬进来,会套娃。


三、指针 next 是怎么"指过去"的(动态图)

structNoden1={10,NULL};structNoden2={20,NULL};n1.next=&n2;// 把n2的地址写到n1的next里

用一张 Mermaid 图表达"游标 p 一路走"的过程:

p从n1出发

p = p->next 往后挪

p再往后挪

指针p

data=10

data=20

NULL
循环结束

代码对应的每一步:

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,循环结束

五、给小白的三张"记忆卡片"

放自己

放指针

结构体自引用

里面放 指针 next

为什么是指针?

无限套娃 报错 ❌

只占固定8字节 ✅

指针用箭头访问 p->data

遍历: p = p->next

走到 NULL 结束


六、易错点(配图记更牢)

  1. 自引用成员必须带*:struct Node* next;
  2. 最后一个节点的 next 要置 NULL,否则游标一路乱走会崩溃:
c.next=NULL;// 给链表打上"终点站"标记
  1. 指针访问成员用->,别写成p.next;
  2. 遍历条件是while(p != NULL),不是while(p)出错就跑飞。

七、一句话总结

自引用 = 结构体里放一个指向同类型的指针,像手电筒一样从第一个节点一路照到 NULL,
就能把零散的节点串成一条灵活的链表。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进