cJSON中#define cJSON_IsReference 256 和 #define cJSON_StringIsConst 512这定义的大小是?

在 cJSON 中,#define cJSON_IsReference 256 和 #define cJSON_StringIsConst 512 是位掩码(bitmask),它们的值(256 和 512)是精心选择的,目的是在 cJSON 结构体的 type 字段中进行按位操作,以标记不同的对象属性。


1. 为什么是 256 和 512?

这两个值是 2 的幂,对应二进制表示中的单个位

  • 256 = 0x100 = 0000 0001 0000 0000(第 9 位为 1,其余为 0)

  • 512 = 0x200 = 0000 0010 0000 0000(第 10 位为 1,其余为 0)

这样设计是为了:

  1. 避免冲突type 字段的低 8 位(0-7)用于存储 JSON 数据类型(如 cJSON_NumbercJSON_String 等),而高位(8-15)用于存储额外标志。

  2. 支持位运算:可以通过 |(或)设置标志,&(与)检查标志,~(非)清除标志。


2. type 字段的结构

cJSON 结构体的 type 字段是一个 int,其布局如下:

| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Reserved       | StringIsConst | IsReference | JSON 数据类型(如 String、Number) |
  • 低 8 位(0-7):存储 JSON 数据类型(如 cJSON_String = 4cJSON_Number = 8)。

  • 高位(8-15):存储额外标志,如 IsReference(第 9 位)和 StringIsConst(第 10 位)。


3. 如何设置和检查这些标志?

cJSON 提供了宏来操作这些标志:

// 设置标志
#define cJSON_SetFlag(object, flag) ((object)->type |= (flag))
#define cJSON_UnsetFlag(object, flag) ((object)->type &= ~(flag))

// 检查标志
#define cJSON_IsReference(object) ((object) && ((object)->type & cJSON_IsReference))
#define cJSON_StringIsConst(object) ((object) && ((object)->type & cJSON_StringIsConst))

示例

cJSON *obj = cJSON_CreateString("Hello");
cJSON_SetFlag(obj, cJSON_StringIsConst); // 标记为常量字符串

if (cJSON_StringIsConst(obj)) {
    printf("该字符串是常量,不会被 cJSON_Delete 释放\n");
}

4. 为什么不用 enum 或 bool

  • 性能优化:位运算比 bool 或 enum 更高效,尤其是在频繁操作 JSON 树时。

  • 内存节省type 字段只需要 16 位(int),而如果用多个 bool 变量会占用更多内存。

  • 兼容性:cJSON 设计为轻量级,适用于嵌入式系统,位操作是最优选择。


5. 总结

十进制值 十六进制 二进制(位位置) 用途
cJSON_IsReference 256 0x100 0000 0001 0000 0000(第 9 位) 标记对象是引用(共享数据)
cJSON_StringIsConst 512 0x200 0000 0010 0000 0000(第 10 位) 标记字符串是常量(不应释放)

这两个宏的值(256 和 512)是按位设计的,确保它们不会与 JSON 数据类型(低 8 位)冲突,并能高效地进行标志管理。

你可能感兴趣的:(C语言,c语言,数据结构,开发语言,嵌入式硬件,算法)