用 Golang 重写 rsync(3):C 里面的谜之指针
前两篇介绍了我用 Golang 重写 rsync 的基本思路,首先选了 C2Go 类工具进行了代码的自动翻译,在发现根本看不懂之后,选择了用 CGO 慢慢覆盖。
正好有人问“C 怎么不火了呢”,我就来举一个例子,关于 rsync c 程序中的指针。
上述结论只针对 ANSI C,最新的 C99,C11 没研究过,不知道有没有多少好转。
C 语言里指针无处不在,因为灵活好用,学过 C 语言的都应该能体会到,能教好指针是好老师,能学好指针的就是好学生,最好变了法的能玩指针。
同时因为 C 里面没有变长数组,所以你可以看到大量的指针。
有指代数组的
指代字符串的
同时,因为 C 语言只能返回一个返回值,所以经常性的会用来表示一个处理后的结果,其实质就是多一个返回,以至于后来 C 程序几乎形成了一个共识,函数标准返回一个 int 作为状态码,所有输出都用指针进行输出。
那么问题来了,请问下面的函数里,哪个是输出,哪个是输入?
再看这个例子
argv_p 是 char 的指针?的指针?的指针?,实际他表达的是要返回一个字符串(char *)的数组(char **),所以要求传入一个字符串(char *)的数组(char **)的指针。
同时,因为 C 语言指针的灵活度和一些基本内存管理机制的缺乏,C 里面养成一个内卷心态,就是大量使用指针在原分配内存中进行内容重构,以此来表达自己最大化利用了内存的心态。比如这个
911 行,name 被付给了 t 和 f,下面大量的 t++和 f++,实际这个函数是清理了 name 中存储的文件名称,剔除了/../这种冗余结构,处理过程中,原来的 name 的存储被重复利用,只是进行了处理部分的覆盖。当然这样做性能是很好的,而且确实很牛。但是说实话,太难懂,如果不是作者,出错的概率太大了。我改成 golang 的时候,直接用了个 strings.Builder 重新写进了一个新的内存里。
我觉得这就是为什么有这么多语言前仆后继在不同的适应领域替代 C 语言的一个体现。程序只要涉及协作,本质还是要给人看,而不是给机器看,否则我怎么能保证人人都理解一致呢。
版权声明: 本文为 InfoQ 作者【百家饭隐私计算平台创业者】的原创文章。
原文链接:【http://xie.infoq.cn/article/2300755bcc26417ba9dc96da5】。文章转载请联系作者。
评论