这个系列的文章,讲的都是一些”不正经”的 C 语言代码。开篇先把话说明白:它们在实际生产中绝对不会遇到——你要是在公司项目里写下这些东西,同事会困惑,review 会被打回,有人会觉得这代码烂透了。这些评价都对。

但我还是想说说它们是怎么来的。

起源是一句不经意的话。有位本科同学告诉我,C 语言里有种东西叫”返回值为函数指针的函数”。我写下了 drink()(),让它一次调用变成两次(C-返回值为函数指针的函数),然后问题是:能三次吗?四次吗?顺着这个问题往下挖,typedef 套娃套到 23 层、100 层,后来干脆写了个程序来生成这些代码(这段经历记在深入返回值为函数指针的函数里,终点是C语言100级函数指针挑战)。大门从这里彻底打开了:原来语言的缝隙里到处都是房间。

于是有了后来的一整个文件夹:用下划线写完整个程序的完形填空、满屏 <% %>尊嘟假嘟、运行完就把自己置空的自杀函数指针、往 int 数组里藏中文的加密 demo、号称 O(1) 的质数判断……每一个的起点都不是”我要写个有用的东西”,而是某个瞬间冒出来的一个念头:“等等,这样是不是也行?” 然后去试。试了才发现,有的真行,有的不行,不行的那些教会我的比行了的还多。

有人说这不算学习。我的看法相反。正规的学习路线告诉你语言”能做什么”,而这些不正经的尝试在探索语言”为什么能“和”到哪一步为止“——<% 为什么等于 {、宏展开到底发生在编译的哪个阶段、指针加一到底加了多少。每一条抽象代码背后,都站着一个实打实的语言规则。发现现象、提出疑问、做个实验看看会发生什么——这本就是学习最原始的形态,只是它的产物不太像作业而已。

这个系列的每篇文章都会贴上「抽象代码」标签,语气也不会太正经。它们不适合用于生产,只适合用于”原来还能这样”的那个瞬间。

——以下为本系列目前收录的文章,会不定期更新: