lept_json的学习之parse_array

本文介绍lept_json库中parse_array的功能,探讨JSON数组的语法和数据结构选择,包括顺序表和链表的优缺点。解析过程利用递归,遇到元素存储于栈中,解析完成后分配内存生成数组。此外,讨论了释放数组的free函数和单元测试策略。
摘要由CSDN通过智能技术生成

lept_json库的学习之array

这一节讲一下parse_array

JSON数组语法

Array是一个复合数据类型,Array自身不存储实际值,而只存储其元素Element,再由它的元素存储实际值。
Array语法如下:
[](空数组) [element1,element2,…](多个元素).

数据结构

array的数据结构这里讲两种

顺序表,也就是C/C++中的数组,
线性表最大的好处是能以 O ( 1 ) O(1) O(1) 用索引访问任意元素,次要好处是内存布局紧凑,省内存之余还有高缓存一致性(cache coherence),
因为它内存都紧密的排放再一块了。
但顺序表的缺点是不能快速插入元素,而且我们在解析 JSON 数组的时候,还不知道应该分配多大的一整块内存才合适。

链表
它的最大优点是可快速地插入元素(开端、末端或中间),但需要以 O ( n ) O(n) O(n) 时间去经索引取得内容。如果我们只需顺序遍历,那么是没有问题的。还有一个小缺点,就是相对数组而言,链表在存储每个元素时有额外内存开销(存储下一节点的指针),而且遍历时元素所在的内存可能不连续,令缓存不命中(cache miss)的机会上升。(这里是项目原话,我并不清楚缓存不命中什么意思)

这里其实就涉及到数据结构知识里的顺序表和链表的区别了,
顺序表在插入删除元素时,需要对目标元素位置后面的所有元素进行重排,所以插入删除操作消耗时间。
而链表则是在寻找的时候只能一个一个往下找,在索引的时候会花费很多时间,而增加和删除只需要把前后节点的link修改一下就可以,而且链表不会需要固定一个上限,可以无限的往后link新的节点。但也因此,其内存不连续。

就此二者而言,各有优劣。

在这个json中,使用的是顺序表,叶老师通过之前string用到的堆栈来解决解析array时会遇到的数组大小未知问题。
一下是数据结构代码:

typedef struct lept_value lept_value;//前向声明
struct lept_value{
   
	//我们可使用 C 语言的 union 来节省内存:
	union{
   
		struct {
    lept_value* e;  size_t size,capacity; }m_arr;/* array */
		struct  {
    char* s; size_t len; }m_str;      /* string */
		double m_num;                               /* number */
	}u;
	lept_type type;
};

valuee是数组,size是大小(元素个数元素大小),capacity是容量(分配的内存大小)
在确定完数据结构之后,其实就可以写接口api了,不过我打算把所有接口统一到最后讲(虽然也就是贴一下代码),现在先讲解析。

Parse_Array

因为数组中包含了value,很容易想到我们将会使用到递归结构。
遇到左中括号([)开始,解析第一个元素,第一个元素解析完如果是逗号(,),则解析下一个元素,直到遇到右中括号为止(])。
每解析一个元素时,我们用一个临时元素value来存储这个解析得到的值,然后把临时值压栈,直到整个数组元素全部解析完,再把栈内元素全部弹出,分配内存,生成数组。
上代码:

static int lept_parse_value(lept_context& c, lept_value& v); /* 前向声明 */
static int lept_parse_array(lept_context& c, lept_value& v) {
   
	size_t size = 0;
	int ret;
	EXPECT(c, '[');
	lept_parse_whitespace(c);//解析数组中存在的空白
	if (*c.json == ']') {
   
		c.json++;
		lept_set_array(v, 0);//set_array接口
		return LEPT_PARSE_OK;
	}
	for (;;) {
   
		lept_value e;//临时value
		lept_init
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值