C语言非常道
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.1 C实现

源文件里的内容是一些文本,或者说是符号的堆积,这些文本程序员倒是看得明白,但它们并不是机器指令,处理器不认得,所以不能直接提交给处理器执行。因此,我们还必须有一个翻译软件,来把源文件转换为可执行程序。

C语言的本质是一套语法规则,而一个C程序则是按照这些语法规则而编写的文本符号的集合(源文件)。一个翻译软件则反过来,按照既定的语法规则来分析源文件的内容,将它们翻译成最终的机器指令。从这个意义上说,一套完整的翻译软件实际上是C语言本身的一个实现,一个现实的化身,简称C实现。

历史上,第一个C语言翻译程序当然出自该编程语言的发明者之手。1972年,美国贝尔实验室的Brian Kernighan和Dennis Ritchie发明了C语言,并且不难想象,也正是他们创造了世界上第一个C程序翻译软件,或者说实现了C。

在之后的岁月里,有很多人、很多公司也致力于编写C实现,所以现在有大量的C实现可用。在本书中,我们仅推荐GCC和CLANG。

和人们熟知的Linux一样,GCC也是开放源代码的自由软件,而且一直在不断地推出新的版本。GCC最早的意思是GNU C Compiler,也即“GNU C编译器”。GNU是1983年发起的一个软件开源运动,目标是创建一套完全自由的操作系统。它的发起者还成立了自由软件基金会,此时的GCC就是一个开源且免费的C实现。

到后来,GCC不单单可以翻译C程序,还包括C++、Objective-C、Fortran、Ada和Go,等等,所以GCC的意思则变成了GNU Compiler Collection,也就是“GNU编译器集合”。

LLVM CLANG是APPLE公司赞助和主推的项目,现阶段,与GCC相比它的翻译速度更快,诊断消息也更加详尽、清晰和明确,这有助于我们更快地找到出错的原因。

问题在于,C语言之父写的C实现还不够用吗?为什么还会有那么多人和企业在不断地编写C实现呢?

我们知道,不同的计算机系统有不同的处理器,运行着不同的操作系统。不同的处理器有不同的机器指令集,翻译一个程序,实际上是将源文件的内容转换为那种处理器可识别的机器指令。C实现是一套软件程序,得有人为那种处理器编写这套软件。正是因为C语言广受欢迎,才会有那么多人针对各种不同的处理器编写了大量的C实现。

另一方面,C实现本质上是一套软件,它和别的程序没有什么区别,唯一的区别是别的程序用来听歌、玩游戏、聊天和购物,而C实现则用来把源文件变成可执行程序。和别的程序一样,C实现也要运行在操作系统上。

我们平时在计算机上做事情都要依赖操作系统,取决于个人的习惯和喜好,它可能是UNIX、Linux、Windows或者其他操作系统。操作系统为我们使用计算机提供了一个最基本的平台或者说环境,让你更方便地在计算机上完成各种操作。比如说在Windows下,你可以看到有哪些程序和文档,也可以通过键盘和鼠标打开文档、启动程序。

不同的操作系统在外观、操作方式,乃至内部的运作机制上都有差别。运行在操作系统上的可执行程序并不是一个仅仅包含了机器指令的文件,它还夹带了很多操作系统的私货。如果没有这些私货,操作系统将不知道这个程序该如何加载到内存,也不知道怎么去执行它。换句话说,针对不同操作系统而编写和翻译的程序,具有不同的格式,在文件的结构和内容上是不一样的。针对Windows编写的程序,无法在Linux上运行,反之亦然,因为它们不能识别对方的某些格式。

所以,运行在不同操作系统上的C实现,它本身的可执行文件格式要符合那个操作系统的要求。不过用不着担心,因为C是简洁、灵活、高效的计算机语言,经久不衰,深受欢迎,对绝大多数操作系统来说,都有人编写能在它上面工作的C实现。

基于以上叙述,我们就很容易理解一个事实:不同的计算机系统具有不同的处理器和操作系统,因而需要有各自不同的C实现。比如,GCC有Linux下的版本和Windows下的版本,CLANG也是如此。

GCC诞生于Linux操作系统,它们彼此之间的支持和包容性是最好的。而CLANG呢,也能运行在Linux上。GCC的官方网站是https://gcc.gnu.org/, CLANG的官方网站是http://clang.llvm.org/, Linux用户可以访问上述链接来了解更多信息并下载和安装它们。

考虑到Windows的流行性和用户数量,下面再来说说Windows上的情况。Windows的大部分代码都是用C语言写的,但是从那以后,该操作系统的所有者Microsoft公司不愿在C语言上投入过多的精力。微软公司曾经开发过一款非常流行的产品Microsoft Visual C++,简称MSVC或者VC,它的6.0版本,也即VC6,直到现在还被国内的大量用户作为学习C语言的主要工具。问题在于,它是一个C++的实现而不是C实现,而且它产生于1998年,所以充其量仅支持C语言的第一个标准C89,毕竟在名义上C++是C的超集,并且兼容后者。要知道,从那之后C语言又经历了两次标准化,分别是1999年的C99和2011年的C11,经过这两次标准化之后,C语言已经发生了很大的变化。换句话说,使用VC6学习C语言并不是明智的选择。

Microsoft公司现今的编程工具是Visual Studio系列,但依然只是针对C++、C#和F#等编程语言,而不是C语言。

令人稍感欣慰的是有很多人依然在努力将C移植到Windows平台上,所以我们现在可以使用GCC和CLANG的移植版本。GCC在Windows操作系统上的移植版本在最早的时候被称为MinGW,意思是“针对Windows的最小化GNU”。GNU是Linux上的软件项目,由于平台之间的差异,没有办法完全移植到Windows上,只能是移植一个可用的基本部分,这就是所谓的“最小化GNU”。

当GCC更新的时候,MinGW也会做相应的版本升级,但由于各种原因,这个维护工作在后期变得乏力,而且不能支持64位应用程序的开发。于是有好事者在此基础上创建出一个新的分支来,称为MinGW_W64,该分支可用于生成32位或者64位的Windows应用程序,而且更新较快。

你可以通过http://mingw-w64.org/了解MinGW_W64的更多信息;下载和安装的网络链接是https://sourceforge.net/projects/mingw-w64/files/

对于初学者来说,学习C语言固然不易,但下载、安装和配置C实现却是第一个拦路虎。本书建议使用GCC和CLANG来完成后面的学习过程,但是,软件随时都在升级,印在书上的详细步骤很快就会过时。因此,考虑到本书的主旨,本书不会详细地介绍它们的下载和安装过程,完整的教程会放在网站http://www.lizhongc.com/上供大家参考。