看到这,可能会产生一个疑问:为什么不先查找得到那个节点的父节点指向自己的指针的引用呢?
这又是一个很有趣的小知识点, 这里就不展开了。
实际上这是指针的知识点, 经常会在链表中遇到, 一不小心链表就会因为这个小问题而写残了。
我以前曾接介绍过这个问题,但不记得具体在哪里介绍了, 大概实在 hash table 研究与实现 或 memcached 源码阅读之 hash table 吧。
好了, 这个修改操作其实就是链表的替换操作, 我就不展开讨论这个知识点了。
如果你看过我的 sphinx 源码阅读之json, hash table配置分析器 的话, 你就会发现这个解析其实就是个自动机。
自动机可以使用一系列状态及模拟栈来实现, 也可以直接使用一些列的递归函数实现。
本质上是等价的, 建议自己都实现一下。
/* Utility to jump whitespace and cr/lf */
static const char *skip(const char *in) {
while (in && *in && (unsigned char)*in<=32) in++;
return in;
}
/* Parse an object - create a new root, and populate. */
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated) {
const char *end=0;
cJSON *c=cJSON_New_Item();
ep=0;
if (!c) return 0; /* memory fail */
end=parse_value(c,skip(value));
if (!end) {
cJSON_Delete(c); /* parse failure. ep is set. */
return 0;
}
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
if (require_null_terminated) {
end=skip(end);
if (*end) {
cJSON_Delete(c);
ep=end;
return 0;
}
}
if (return_parse_end) *return_parse_end=end;
return c;
}
/* Default options for cJSON_Parse */
cJSON *cJSON_Parse(const char *value) {
return cJSON_ParseWithOpts(value,0,0);
}
上面两个函数, 其实对我们有用的只有一句 end=parse_value(c,skip(value));, 也就是我们只需要了解一下 parse_value 函数即可。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-57098-6.html
不强硬
还好俺是穷光蛋