前言
cJSON 是 Dave Gamble 等人开源的超轻量级 C 语言 JSON 解析/生成库,整个库仅由 cJSON.c(约 3200 行)和 cJSON.h(约 306 行)两个文件组成,无外部依赖,MIT 协议,广泛应用于嵌入式、IoT 和各类 C 项目。
本文基于一次「源码分析 + 深度注释」的实践,整理出核心数据结构、核心流程、设计亮点以及深度注释规范。适合想啃 cJSON 源码的 C 开发者、做嵌入式 JSON 解析的同学,以及需要「读源码写注释」交作业或做笔记的同学。
核心数据结构:cJSON 结构体
结构体定义
cJSON 用一个统一的节点类型表示所有 JSON 值(对象、数组、字符串、数字、布尔、null 等),核心就是下面这个结构体(cJSON.h 第 103–123 行):
typedef struct cJSON {
struct cJSON *next; /* 同级下一个兄弟节点 */
struct cJSON *prev; /* 同级上一个兄弟节点 */
struct cJSON *child; /* 第一个子节点(仅 Array/Object 使用) */
int type; /* 节点类型(位掩码) */
char *valuestring; /* 字符串值(String/Raw 类型) */
int valueint; /* 整数值(已废弃,建议用 valuedouble) */
double valuedouble; /* 数字值(Number 类型) */
char *string; /* 键名(仅当节点是对象的子项时有效) */
} cJSON;
- next / prev:同一层级上的兄弟节点,组成双向链表(数组元素之间、对象键值对之间)。
- child:仅对 Array / Object 有效,指向「第一个子节点」,其余子节点通过 next 串联。
- type:用位掩码表示类型(见下一小节)。
- valuestring / valueint / valuedouble:按类型选用;数字统一用 valuedouble,valueint 仅为兼容保留。
- string:当该节点是某个 Object 的成员时,存键名。
也就是说,整棵 JSON 树 = 多棵「父子 + 兄弟」链表:父子用 child,兄弟用 next/prev。


