August 17th, 2016

笔者最近在开始一些C的应用程序开发,主要在linux下进行,目标是跨平台的应用程序。虽然是基于某开源程序进行开发,看了不少源码,也动手扩展和修改了开源程序,感触颇多。C其实是语法最为简单的编程语言之一。但是在实际的开发中,尤其是用C来开发一些系统应用程序,会感觉到比Java之类的要难的多,究竟是为什么呢?有人可能会说是手动内存分配的复杂性,字符串处理的不便捷…都没错,笔者认为,总结一句话是标准化和工业化程度决定了使用的难易程度

如果我们使用Java来开发一个程序,Java的标准化框架和包,会相对来说极大的规范程序员的编程行为,为程序员带来相对很大的便利性。越是高层次的语言,这越是明显。很多语言,将很多问题提炼到语法层面,通过增加语法的复杂度,从而强制性的让程序员规范编程行为和思路,也是一个原因,比如绝大部分语言提供try catch来做异常捕获。然而,C语言并没有原生的try catch

C语言,虽然有标准C库,但是在使用的时候,往往会遇到不同平台的差异,这也是为什么多数C程序需要通过configure在编译程序前获得这些差异的原因。所以即使是标准C库,在跨平台方面也有诸多问题。在Java等语言中,很多有差异的问题被重写了,或者被屏蔽了,从而在标准库方面更为统一,因此易用性提高很多。

另一个方面,当我们要进行一些系统编程时,比如线程控制、文件读写、网络读写时,平台的差异更大。虽然,诸如POSIX等标准试图解决问题,但是由于Unix的各大分支(包括linux)长期的历史原因,依旧不能很好的做到统一。而在这方面,Java等语言在统一化方面做的就十分完整和到位。

C语言由于语法十分简单,导致程序员的编程行为风格迥异。而面向对象的提出,使得程序员在编程行为上有了一次高度的统一。C++是面向对象的先驱之一,然而由于C++保留了对C的兼容性,反而也限制了C++在标准化上的进程。显然,不会有人觉得C++比Java简单。当然,C不是不能“面向对象”,面向对象不是一种语法,而是一种编程范式,只是C在“面向对象”时并没有我们熟知的范式而已。而且大部分的C程序不采用面向对象,面向对象也不见得是万能药。在使用Java标准库之外的第三方库时,之所以觉得没有违和感,原因之一就是大家都遵循了面向对象的原则。当然,不同的语言的范式原则不一定是面向对象。

那么,如果要基于C语言来做开发(应用程序),应该如何开展呢?究竟要做些什么准备呢?通过阅读源码,笔者认为,程序员应该有意识的积累和准备一些常用的数据结构和算法、系统封装,还需要对系统底层有比较深入的理解,这样就能形成一层标准层,有了这个标准层,算是入门,并且有能力开始工程实践了。否则举步维艰。

通常来讲,这些标准层包含:

  • 内存池。提高内存分配和管理的效率和便利性,甚至可以自己实现GC。
  • 日志。日志之所以如此重要,你懂得,别指望IDE来调试。
  • 异常处理。利用C库和宏,实现一个try catch,会十分有用。
  • 字符串处理。便捷的字符串处理毋庸置疑是极其重要的。
  • 常用的数据结构。比如:list、map、array。
  • 封装并屏蔽平台差异。比如socket、thread、file等系统直接相关的调用。

针对上述的内容,笔者会结合开源软件,逐步做一些总结。


1块2块也是钱,小额赞助