第1章
The C Programming Language, Second Edition
导 言
在本书的开篇,我们首先概要地介绍C语言,主要是通过实际的程序引入C语言的基本元素,至于其中的具体细节、规则以及一些例外情况,在此暂时不多做讨论。因此,本章不准备完整、详细地讨论C语言中的一些技术(当然,这里所举的所有例子都是正确的)。我们是希望读者能尽快地编写出有用的程序,为此,本章将重点介绍一些基本概念,比如变量与常量、算术运算、控制流、函数、基本输入/输出等。而对于编写较大型程序所涉及的一些重要特性,比如指针、结构、C语言中十分丰富的运算符集合、部分控制流语句以及标准库等,本章将暂不做讨论。
这种讲解方式也有缺点。应当提请注意的是,在本章的内容中无法找到任何特定语言特性的完整说明,并且,由于比较简略,可能会使读者产生一些误解;再者,由于所举的例子并没有用到C语言的所有强大功能,因此,这些例子也许并不简洁、精练。虽然我们已经尽力将这些问题的影响降到最低,但问题肯定还是存在。另一个不足之处在于,本章所讲的某些内容在后续相关章节还必须再次讲述。我们希望这种重复给读者带来的帮助效果远远超过它的负面影响。
无论是利还是弊,经验丰富的程序员都应该可以从本章介绍的内容中推知自己进行程序设计所需要的一些基本元素。初学者应编写一些类似的小程序作为本章内容的补充练习。无论是经验丰富的程序员还是初学者,都可以把本章作为后续各章详细讲解的内容的框架。
1.1 入门
学习一门新程序设计语言的唯一途径就是使用它编写程序。对于所有语言的初学者来说,编写的第一个程序几乎都是相同的,即
请打印出下列内容
尽管这个练习很简单,但对于初学语言的人来说,它仍然可能成为一大障碍,因为要实现这个目的,我们首先必须编写程序文本,然后成功地进行编译,并加载、运行,最后输出到某个地方。掌握了这些操作细节以后,其他事情就比较容易了。
在C语言中,我们可以用下列程序打印出“hello, world”:
如何运行这个程序取决于所使用的系统。这里举一个特殊的例子。在UNIX操作系统中,首先必须在某个文件中建立这个源程序,并以“.c”作为文件的扩展名,例如hello.c,然后再通过下列命令进行编译:
如果源程序没有什么错误(例如漏掉字符或拼错字符),编译过程将顺利进行,并生成一个可执行文件a.out。然后,我们输入
即可运行a.out,打印出下列信息:
在其他操作系统中,编译、加载、运行等规则会有所不同。
下面对程序本身做些说明。一个C语言程序,无论其大小如何,都是由函数和变量组成的。函数中包含一些语句,以指定所要执行的计算操作;变量则用于存储计算过程中使用的值。C语言中的函数类似于Fortran语言中的子程序和函数,与Pascal语言中的过程和函数也很类似。在本例中,函数的名字为main。通常情况下,函数的命名没有限制,但main是一个特殊的函数名—每个程序都从main函数的起点开始执行,这意味着每个程序都必须在某个位置包含一个main函数。
main函数通常会调用其他函数来帮助完成某些工作,被调用的函数可以是程序设计人员自己编写的,也可以来自于函数库。上述程序段中的第一行语句
用于告诉编译器在本程序中包含标准输入/输出库的信息。许多C语言源程序的开始处都包含这一行语句。我们将在第7章和附录B中对标准库进行详细介绍。
函数之间进行数据交换的一种方法是调用函数向被调用函数提供一个值(称为参数)列表。函数名后面的一对圆括号将参数列表括起来。在本例中,main函数不需要任何参数,因此用空参数表()表示。
函数中的语句用一对花括号{}括起来。本例中的main函数仅包含下面一条语句:
调用函数时,只需要使用函数名加上用圆括号括起来的参数表即可。上面这条语句将"hello, world\n"作为参数调用printf函数。printf是一个用于打印输出的库函数,在此处,它打印双引号中间的字符串。
用双引号括起来的字符序列称为字符串或字符串常量,如"hello, world\n"就是一个字符串。目前我们仅使用字符串作为printf以及其他函数的参数。
在C语言中,字符序列\n表示换行符,在打印中遇到它时,打印输出将换行,从下一行的左端行首开始。如果去掉字符串中的\n(这是个值得一做的练习),即使打印输出完成后也不会换行。在printf函数的参数中,只能用\n表示换行符。如果用程序的换行代替\n,例如:
C编译器将会产生一条错误信息。
printf函数永远不会自动换行,这样我们可以多次调用该函数以分阶段得到一个长的输出行。上面给出的第一个程序也可以改写成下列形式:
这段程序与前面程序的输出相同。
请注意,\n只代表一个字符。类似于\n的转义字符序列为表示无法输入的字符或不可见字符提供了一种通用的可扩充的机制。除此之外,C语言提供的转义字符序列还包括:\t表示制表符;\b表示回退符;\"表示双引号;\\表示反斜杠符本身。2.3节将给出转义字符序列的完整列表。
练习1-1 在你自己的系统中运行“hello, world”程序。再有意去掉程序中的部分内容,看看会得到什么出错信息。
练习1-2 做个实验,当printf函数的参数字符串中包含\c(其中c是上面的转义字符序列中未曾列出的某个字符)时,观察一下会出现什么情况。