如何阅读 C 语言的声明

众所周知,C 语言的一大难点就在于变量声明。 比如说如下的几个例子: char* const *(*next)(); char *(*c[10])(int **p); void (*signal(int, void(*)(int)))(int); 基本上每一个都是晦涩难懂,看了简直像杀人。但其实也是相对来会所比较简单的一个。如果熟悉编译原理,其实可以通过人脑编译器的手段来解决难懂问题。毕竟,代码也需要编译器进行翻译。 首先我们得知道运算符号的优先级顺序。这里只说在声明期间会出现的符号。主要分为变量名,括号内内容,后缀操作符如:[], (),前缀操作符如: *,类型描述符如:const, volatile, 其中, 如果 const 或 volatile 后面跟着类型如 int, long 等,那么它作用于类型。其他情况下,const 和 volatile 作用于左边的指针。 理解了这个顺序,就可以来看看如何解读第一个声明了。 首先,next 先拿出来,说明,next 是一个 … 变量。声明变成了 char* const *(*)(); 然后看到 *,说明 next 是一个指向 … 的指针。声明变成了 char* const *(); 然后就是 ()符号,说明 next 是一个指向函数的指针。然后再是一个 * 表明读取指针的内容即该函数地址。所以声明等价于 char* const…

JSON 解析器

这篇博客主要是最近开始玩 C,所以准备找个东西练手,突然发现,顺手写个 JSON 解析器吧。于是就开始了。 相对于其他比较成熟的上层语言。C 主要的问题就是没有基础的数据结构,而且相对于弱类型语言而言,C 的类型在解析的时候有个类型转换的坑。但是相对于其他的强类型语言而言,C 又有一个好处,那就是没有一个 void* 解决不了的问题,如果有,那就用两个。 不过相对于工作时的清闲,现在上课的时候确实没有什么时间进行额外的代码编写。所以断断续续写了一周多。 主要的使用方法就是: struct value *val = parse_new(); char *json1 = “{\”fff\”:[2,4,5,6]}”; parse(val, json1); map_display(*(struct map*)val->value); struct value key; key.type = STRING; key.value = (void*)”fff”; list_display(*(struct list*)(map_find(*(struct map*)val->value, key)->value)); 首先初始化一个 val 对象作为头,然后直接调用 parse 函数。这样就可以把数据解析完成了。 其实还是挺简单的。主要的目的也只是检查自己对 C 语言的熟悉程度。目前也只是个简单的版本。之后会慢慢的进行优化。比如目前就不支持 null, 非十进制数字解析等等。 说道 JSON 的解析,其实 JSON 本身的格式非常的简单。按照 官网的说法,状态转换也无外乎以下几种: 相对于细节上,整体看下来的话其实更简单:{…

C 的假装 OOP 写法

之前微博上说 C 的一个好处就是没有什么是一个 void* 解决不了的,然后因为自己用 C 写一个小程序,遇到了一个问题,就是因为 C 是强类型,但是如果需要写一个相对通用的数据结构。这个稍微有点麻烦。 比如说,hashmap,我们常用的都是 <string, string> 的一个 map,于是,相对来说的话,hash 函数比较容易。但是,如果是需要实现 Java 那样的通用数据结构呢,是不是需要对每个特定的数据对象写一个? 所以这边就扯到了这么个比较好玩的技巧。 先看下效果: main.c #include “value.h” #include “value_a.h” #include “value_b.h” int main(void) { struct value v1; value_a_instance(&v1); v1.set(&v1, (void*)”hello”); v1.display(&v1); printf(“%lld”, v1.hash(&v1)); struct value v2; value_b_instance(&v2); double a = 2.0f; v2.set(&v2, (void*)&a); v2.display(&v2); printf(“%lld”, v2.hash(&v2)); printf(“%lf”, *(double*)v2.data); return 0;…

VIM 浏览器预览插件

插件的地址:GITHUB. 写这个插件的原因很简单。因为之前一直再写一个页面,因为在主力的编辑器是 VIM,所以就顺手用了。但是遇到一个很尴尬的地方,就是在想观看编写的效果的时候,常常会需要使用 Finder,然后进入当前的工作目录,然后双击 html 文件。 非常痛苦。于是去查了下 vim 有没有这么一个插件,可以方便的进行浏览器预览的。 当然也是查到了相关的方式,比如这篇博客: ” 在浏览器预览 for win32 function! ViewInBrowser(name) let file = expand(“%:p”) exec “:update ” . file let l:browsers = { \”cr”:”D:/WebDevelopment/Browser/Chrome/Chrome.exe”, \”ff”:”D:/WebDevelopment/Browser/Firefox/Firefox.exe”, \”op”:”D:/WebDevelopment/Browser/Opera/opera.exe”, \”ie”:”C:/progra~1/intern~1/iexplore.exe”, \”ie6″:”D:/WebDevelopment/Browser/IETester/IETester.exe -ie6″, \”ie7″:”D:/WebDevelopment/Browser/IETester/IETester.exe -ie7″, \”ie8″:”D:/WebDevelopment/Browser/IETester/IETester.exe -ie8″, \”ie9″:”D:/WebDevelopment/Browser/IETester/IETester.exe -ie9″, \”iea”:”D:/WebDevelopment/Browser/IETester/IETester.exe -all” \} let htdocs=’E:\\apmxe\\htdocs\\’ let strpos = stridx(file, substitute(htdocs, ‘\\\\’, ‘\’, “g”)) if…