1.7 编程机制

编写程序时必须遵循的确切步骤取决于您的计算机环境。因为C是可移植的,所以它在许多环境中可用,包括UNIX、Linux、MS-DOS(别不相信,仍有人在使用它)、Windows和Macintosh OS。本书因篇幅所限,不能讲述所有这些环境,尤其是特定的产品会发展、消逝以及被替代。

不过,让我们首先来看一看许多C环境(包括我们刚刚提到的5种)所共有的一些方面。您完全不必知道运行一个C程序后面的事情,但了解一点是一个很好的背景知识。它还可以帮助您理解为什么编写一个C程序必须经过一些特定步骤。

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

用C语言编写一个程序时,您将编写的内容保存在一个被称为源代码文件的文本文件中。大多数C系统,包括我们提到的那些,都需要该文件的名称以.c结尾:例如,wordcount.c和budget.c。名称中小点前的部分被称为基本名,小点后的部分被称为扩展名。因此,budget是一个基本名,c是一个扩展名。组合在一起的budget.c是文件名。该名称还应该满足特定计算机操作系统的需要。例如,MS-DOS是IBM PC及其兼容机的操作系统。它要求基本名不能大于8个字符长,所以前面提到的wordcount.c名称不是一个合法的DOS文件名。一些UNIX系统对整个文件名长度,包括扩展名在内,有14个字符的限制;其他UNIX系统允许更长的名字,最长为255个字符。Linux、Windows和Macintosh OS也允许长文件名。

这样,在我们提到名称时内容就可以更具体,我们假定有一个名为concrete.c的源文件,其中包含程序清单1.2中的C源代码。

程序清单1.2 Concrete.c程序

阅读 ‧ 电子书库

现在不用管程序清单1.2中显示的源代码文件的细节,第2章中您将学习这些细节问题。

1.7.1 目标代码文件、可执行文件和库

C编程的基本策略是使用程序将源代码文件转换为可执行文件,此文件包含可以运行的机器语言代码。C分两步完成这一工作:编译和链接。编译器将源代码转换为中间代码,链接器将此中间代码与其他代码相结合来生成可执行文件。C使用被划分为两部分的这一方法使程序便于模块化。您可以分别编译各个模块,然后使用链接器将编译过的模块结合起来。这样,如果需要改变一个模块,则不必重新编译所有其他模块。同时,链接器将您的程序与预编译的库代码结合起来。

中间文件的形式有多种选择。最一般的选择,同时也是我们这里讲述的实现方式所采取的选择,是将源代码转换为机器语言代码,将结果放置在一个目标代码文件(或简称为目标文件)中(这里假定您的源代码由单个文件组成)。虽然目标文件包含机器语言代码,但该文件还不能运行。目标文件包含源代码的转换结果,但它还不是一个完整的程序。

目标代码文件中所缺少的第一个元素是一种叫做启动代码(start-up code)的东西,此代码相当于您的程序和操作系统之间的接口。例如,您可以在DOS或Linux下运行一个IBM PC兼容机,在两种情况中硬件是相同的,所以都会使用同样的目标代码,但DOS与Linux要使用不同的启动代码,因为这两种系统处理程序的方式是不同的。

所缺少的第二个元素是库例程的代码。几乎所有C程序都利用标准C库中所包含的例程(称为函数)。例如,前面的concrete.c使用了函数printf ()。目标代码文件不包含这一函数的代码,它只包含声明使用printf () 函数的指令。实际代码存储在另一个称为“库”的文件中。库文件中包含许多函数的目标代码。

链接器的作用是将这3个元素(目标代码、系统的标准启动代码和库代码)结合在一起,并将它们存放在单个文件,即可执行文件中。对库代码来说,链接器只从库中提取您所使用的函数所需要的代码(见图1.4所示)。

阅读 ‧ 电子书库

图1.4 编译器和链接器

简而言之,目标文件和可执行文件都是由机器语言指令组成的。但目标文件只包含您所编写的代码转换成的机器语言,而可执行文件还包含您所使用的库例程以及启动代码的机器代码。

在一些系统上,您必须分别运行编译和链接程序。在另外一些系统上,编译器可以自动启动链接器,所以只须给出编译命令即可。

现在我们来看一些具体的系统。

1.7.2 UNIX系统

因为C的流行开始于UNIX系统,所以我们首先讲述该系统。

一、在UNIX系统上编辑

UNIX C不具备自己的编辑器。但您可以使用一种通用UNIX编辑器,例如emacs、jove、vi或X-Windows等文本编辑器。

您要完成的两项重要工作是正确地输入程序并为存储该程序的文件选择一个合适的名称。如前所述,名称应以.c结尾。注意,UNIX是区分大小写的。因此,budget.c、BUDGET.c和Budget.c是3个互不相同但都有效的C源文件名称,但BUDGET.C则不是有效的名称,因为它使用了大写的C而不是小写的c。

使用vi编辑器,我们编写了下面的程序并将其存储在名为inform.c的文件中。

阅读 ‧ 电子书库

此段文本是源代码,inform.c是源文件。此处的要点是,源文件是过程的开始,不是结束。

二、在UNIX系统上编译

诚然,我们的程序很出色,但对计算机来说仍是无用信息。计算机不理解诸如#include或printf这样的东西(此时您可能也不理解,但很快您就会学到,而计算机则不会)。正如我们前面所讨论的,我们需要编译器将我们的代码(源代码)转换为计算机的代码(机器代码)。这些工作的结果是形成可执行文件,其中包含计算机完成任务所需的所有机器代码。

UNIX C编译器称为cc。要编译inform .c程序,您需要键入下列内容:

阅读 ‧ 电子书库

几秒钟后,会返回UNIX提示,告诉您任务已经完成。如果没有正确编写程序,您可能会得到警告和错误信息,但我们假设您编写的完全正确(如果编译器指出单词void有错误,则表明您的系统还没有更新到ANSI C编译器。下面很快就会更详细地讲述标准,而此时您只须从例子中删除单词void就行了 )。如果使用Is来列出文件,会发现有一个名为a.out的新文件(见图1.5所示)。这是包含程序转换(或编译)结果的可执行文件。要运行该文件,只须键入:

阅读 ‧ 电子书库

输出结果如下:

阅读 ‧ 电子书库

阅读 ‧ 电子书库

图1.5 使用UNIX准备C程序

如果您希望保存该可执行文件(a.out),就必须对其进行重命名。否则,该文件会被下一次编译程序时产生的一个新的a.out替代。

如何处理目标代码呢?cc编译器创建一个与源代码具有相同基本名但扩展名为.o的目标代码文件。在本例中,目标代码文件名为inform.o,但您找不到该文件,因为链接器在可执行程序被生成后将该文件删除。然而,如果原始程序使用多个源代码文件,则会保存目标代码文件。后面讨论多文件程序时,您会看到这是一个很好的主意。

1.7.3 Linux系统

Linux是一个流行的、开放源代码的、类似于UNIX的操作系统,可在包括IBM兼容机和Macintoshes在内的多种平台上运行。在Linux上准备C程序与在UNIX系统上几乎一样,不同之处是您要使用由GNU提供的被称为gcc的公共域C编译器。编译器命令将是下面的形式:

阅读 ‧ 电子书库

注意,在安装Linux时gcc的安装可能是可选项,所以如果原来没有安装gcc,您必须进行安装。一般情况下,安装过程会将cc作为gcc的别名,所以如果愿意,可以在命令行使用cc而不是gcc。

在http://www.gnu.org/software/gcc/gcc.httnl,您可以获得有关gcc的更进一步的信息,包括新发行版本方面的信息。

1.7.4 集成开发环境(Windows系统下)

因为C编译器不是标准Windows包的一部分,所以需要获得并安装一个C编译器。许多厂商,包括Microsoft、Borland、Metrowerks和Digital Mars,都提供基于Windows的集成开发环境——或叫IDE(目前,大多数是结合在一起的C和C++编译器)。所有编译器都具有用来装配C程序的快速、集成的开发环境。关键的一点是,它们都具有内置的编辑器,可用来编写C程序。这类开发环境一般都提供了让您可以命名和保存源代码文件的菜单,以及让您可以不离开IDE就能编译和运行程序的菜单。如果编译器发现任何错误,会返回到编辑器中,而且编译器可以标出有问题的行,并将它们与相应的错误消息匹配起来。

Windows IDE最初可能让人有一点望而生畏,因为它们提供多种目标,也就是说,提供了多种可让程序在其中运行的环境。例如,它们可能提供16位Windows程序、32位Windows程序、动态链接库文件(DLL)等等让您选择。许多目标都需要引入Windows图形界面的支持。为了管理这些(及其他)选项,通常需要创建一个项目,以便随后向其中添加将要使用的源代码文件名。具体步骤取决于所使用的产品。一般地,首先使用[File]菜单或[Project]菜单来创建一个项目。重要的是选取正确的项目形式。本书中的例子是一般性的例子,设计目的是在一个简单的命令行环境中运行。不同的Windows IDE提供一个或更多的选项以匹配这一不严格的假设。例如,Microsoft Visual C 7.1 提供[Win32 Console Application]选项。对于Metrowerks CodeWarrior 9.0,请选取[Win32 C Stationery],然后选择[C Console App]或[WinSIOUX C App](后者具有更良好的用户界面)。对于其他系统,请使用如[DOS EXE]、[Console]或[Character Mode executable]这样的词语来查找一个选项。这些模式将在一个类似控制台的窗口中运行可执行程序。有了正确的项目类型之后,可以使用IDE的菜单来打开一个新的源代码文件。对于大多数产品来说,可以使用[File]菜单来做到这一点。您可能必须采取附加的步骤为项目添加源文件。

因为Windows IDE一般可处理C和C++,所以您应该指明您需要一个C程序。在某些产品,如Metrowerks CodeWarrior中,可以使用项目类型来指明希望使用C。而在其他一些产品,如Microsoft Visual C++中,可以使用.c文件扩展名来指明希望使用C而不是C++。然而,大多数C程序也可以作为C++程序运行。“参考资料9:C和C++的差别”对C和C++进行了比较。

可能遇到的一个问题是:显示程序执行的窗口在程序终止时突然消失。如果遇到这种情况,那么可以使程序暂停,直到按下[Enter]键。要做到这一点,请在程序的末尾,恰好在return语句之前,添加下面一行:

阅读 ‧ 电子书库

该行读取一次按键,因此程序将暂停直到按下[Enter]键时。有时,根据程序函数的需要,可能已经有一个等待按键的指令。在这种情况下,需要使用getchar ()两次:

阅读 ‧ 电子书库

例如,如果程序最后做的事情是请您输入您的体重,那么就应当键入您的体重并按[Enter]键以输入数据。程序将读取体重,第1个getchar ()将读取[Enter]键,第2个getchar ()将导致程序暂停,直到再次按下[Enter]键。如果现在您对此还不太理解,那么在学习更多关于C输入的知识后您就明白了。

虽然各种IDE都有许多共同的原则,但在细节方面会因产品而异,而在一个产品系列中,又会因版本而异。您必须要经过一些实践,才能知道编译器的工作方式。您甚至可能必须阅读手册或尝试使用联机帮助。

1.7.5 IBM PC的DOS编译器

对很多人来说,如今在PC上运行DOS已经过时了,但是有些人的计算机资源有限,预算不多,还有些人喜欢更简单的操作系统,在这样的系统中没有窗口环境中的铃声、哨声和令人分心的事物,对这些人来说,DOS仍是一种选择。许多Windows IDE另外提供了允许您在DOS命令行环境中编程的命令行工具。在许多系统上(包括几种UNIX和Linux变体)可用的Comeau C/C++编译器,拥有一个命令行DOS版本。另外,有许多在DOS下工作的属于免费软件和共享软件的C编译器。例如,有一种基于DOS的GNU gcc编译器版本。

源代码文件应该是文本文件,而不是字处理程序文件(字处理程序文件包含字体和格式方面的附加信息)。应该使用文本编辑器,例如Windows Notepad、某些DOS版本自带的EDIT程序。如果使用字处理程序,则必须使用[Save As]来以文本格式保存文件。文件扩展名应该是.c。某些字处理程序自动为文本文件添加.txt扩展名。如果遇到这种情况,需要改变文件名,用c代替txt。

PC机的C编译器通常(但不总是)会生成以.obj为扩展名的中间目标代码文件。与UNIX编译器不同,C编译器在完成编译时通常不会删除它们。有些编译器产生带有.asm扩展名的汇编语言文件或使用其自己的特殊格式。

有些编译器在编译后就会自动运行链接器,而其他编译器可能需要您手动运行链接器。链接将产生可执行文件,该可执行文件在原始的源代码基本名后添加.EXE扩展名。例如,编译和链接一个名为concrete.c的源代码文件会产生一个名为concrete.exe的文件。有些编译器提供一个选项以创建一个名为concrete.com的文件作为代替。在任何一种情况下,都可以在命令行键入基本名来运行该程序:

阅读 ‧ 电子书库

1.7.6 Macintosh上的C

最著名的Macintosh C/C++编译器是Metrowerks CodeWarrior编译器(CodeWarrior的Windows和Macintosh版本有非常相似的界面)。该编译器提供一个与Windows编译器中所看到的相似的基于项目的IDE。通过[File]菜单中选取[New Project]来开始编译工作。编译器将提示您选择项目类型。对于较新的CodeWarrior版本,请使用[Std C Console]选项(在不同的Code Warrior版本中找到该选项的路径也不相同)。您可能不得不在68KB版本(用于Motorola 680×0系列处理器)、PPC版本(用于PowerPC处理器)或者Carbon版本(用于OSX)之间进行选择。

新的项目中有一个小的源代码文件作为初始项目的一部分。可以尝试编译和运行该程序以了解是否正确地设置了系统。