1.5 第一个C语言程序
21天学通C语言(第6版•修订版)
读者也许迫不及待地想编写第一个C语言程序。为帮助读者熟悉编译器,程序清单1.1包含一个小型程序,功能快速地完成。现在,读者也许无法理解其中的所有内容,但不用担心,尽管编写、编译并运行它。
这里的演示使用的是一个名为hello.c的程序,该程序只是将单词“Hello, World!”显示到屏幕上而已。该程序常被用来介绍C语言编程,很适合读者进行学习。程序清单1.1列出了hello.c的源代码。输入该程序清单时,请不要输入最左边的行号和冒号。
程序清单1.1 HELLO.C
1: #include <stdio.h>
2:
3: int main(void)
4: {
5: printf("Hello, World!\n");
6: return 0;
7: }
请务必按软件提供的安装说明安装编译器。无论您使用的是Linux、DOS、UNIX、Windows还是其他操作系统,请务必理解如何使用您所选择的编辑器和编译器。准备好编译器和编辑器后,请按下面的步骤输入、编译并执行HELLO.C。
1.5.1 输入并编译hello.c
要输入并编译hello.c,请按下面的步骤进行:
1.在要存储C语言程序的目录中启动编辑器。正如前面指出的,可以使用任何文本编辑器,但集成开发环境(IDE)自带的大多数编译器(如Borland的Turbo C++和Microsoft 的Visual C++)都能让您以一种方便的设置来输入、编译和链接程序。请查看用户手册,了解编译器是否有IDE。
2.通过键盘输入hello.c中的源代码,内容应同程序清单1.1完全相同。换行时,请按Enter键。
请不要输入行号和冒号,它们是为了便于引用而提供的。
3.保存源代码,将其命名为hello.c。
4.通过列出目录中的文件列表,验证hello.c是否已被保存到磁盘中。文件列表中应包含文件hello.c。
5.编译并链接hello.c。执行编译器用户手册指定的命令,您将看到一条消息,指出没有任何错误和警告。
6.查看编译器消息。如果没有任何错误和警告,则说明一切正常。
如果输入的程序不正确,编译器将捕获您犯的错误,并显示错误消息。例如,如果将printf输入为prntf,您将看到一条与下面类似的消息:
Error: undefined symbols:_prntf in hello.c (hello.OBJ)
7.如果出现错误消息,请返回到第2步。在编辑器中打开hello.c,将该文件内容同程序清单1.1进行仔细比较、修正,然后进入到第3步。
8.至此,您的第一个C语言程序应编译好,可以执行了。此时如果显示所有名为hello的文件,将看到以下文件:
hello.c:使用编辑器创建的源代码文件;
hello.obj或hello.o:其中包含hello.c的目标代码;
hello.exe:编译并链接hello.c时创建的可执行程序。
9.要执行hello.exe,只须执行hello命令即可,消息“Hello, World!”将显示在屏幕上。
祝贺您!您已经输入、编译并运行了您的第一个C语言程序。应该承认,hello.c是一个很简单的程序,并不能完成任何有用的工作,但它开了一个头。事实上,当今大部分专家级C语言程序员都是以同样的方式——编译HELLO.C——开始学习的。
如果您使用的是附录G介绍的Bloodshed Dev-C++编译器,请阅读附录G,其中介绍了如何安装该编译器以及如何使用它来创建程序。该编译器可用于Windows 95或更高的版本中。
1.编译错误
当编译器发现源代码中的某些内容无法编译时,将发生编译错误。拼写错误、印刷错误等都可能导致编译器停止工作。好在现代的大多数编译器不仅仅是停止工作,还会告诉您问题出在哪里!这使得查找和修改源代码中的错误更容易。
可以有意在前面输入的hello.c程序中加入错误来说明这一点。如果您完成了前面的范例,磁盘上将有hello.c的一个拷贝。在编辑器中打开该文件,然后将光标移到printf( )所在行的末尾,并删除最后的分号。此时,hello.c的内容如程序清单1.2所示。
程序清单1.2 hello2.c:有错误的hello.c
1: #include <stdio.h>
2:
3: int main(void)
4: {
5: printf("Hello, World!")
6: return 0;
7: }
然后保存该文件。现在可以编译它了,方法是执行编译器命令。由于刚才引入的错误,编译将无法完成。编译器将显示与下面类似的错误:
hello.c(6) : Error: ';' expected
上述消息包含三部分:
hello.c:有错误的文件的名称:
(6):错误所在行的编号;
Error: ‘;’ expected:对错误的描述。
上述消息包含大量的信息,它指出:编译器发现hello.c第6行应该有一个分号,但没有。然而您知道,实际上是第5行遗漏了一个分号,这与消息所指出的不符。为何编译器报告第6行有错误,而实际上是第5行遗漏了分号呢?问题的答案在于,C编译器并不关心行之间的换行符,printf( )语句之后的分号也可以放在下一行的开头(虽然这样做容易引起混淆,不是一个好的编程习惯)。编译器遇到第6行的下一个命令后,才能确定遗漏了一个分号。因此,编译器指出第6行有错。
这指出了有关C语言编译器和错误消息的一个不可否认的事实。虽然编译器在检测和定位错误方面很聪明,但它并非爱因斯坦。您必须使用有关C语言的知识,对编译器的消息进行解读,以确定报告的错误的实际位置。通常,能够在编译器指出的行中找到错误,但如果找不到,则几乎总是在前一行。刚开始时,查找错误可能有些困难,但您很快便能得心应手。
报告的错误可能随编译器而异。在大多数情况下,通过错误消息,您应该能够知道发生了什么错误或错误的位置。
结束有关这个主题的讨论之前,请看另一个编译错误的例子。再次将hello.c装载到编辑器中,并做以下修改:
1.在第5行的末尾加上分号;
2.删除单词Hello前面的双引号。
保存文件,并再次编译该程序。这次,编译器将显示类似于下面的错误消息:
hello.c(5) : Error: undefined identifier 'Hello'
hello.c(7) : Lexical error: unterminated string
Lexical error: unterminated string
Lexical error: unterminated string
Fatal error: premature end of source file
第一条错误消息正确地指出了错误——第5行的Hello。错误消息undifined identifier意味着编译器无法识别Hello,因为它没有用引号括起。然而,其他4条错误消息呢?这些错误消息(现在无须关心它们的含义)表明,C语言程序中的一个错误有时候可能导致多条错误消息。
我们从中得到的教训是:如果编译器报告了多个错误,而您只找到一个,请修复该错误并重新编译。您可能发现,只须修改一个地方,程序便没有任何错误,并能通过编译。
2.链接程序的错误消息
链接程序错误比较少,通常是由于错误拼写C语言库函数的名称引起的。在这种情况下,将显示错误消息Error: undefined symbols:,后面为拼错的名称(名称前有一个下划线)。更正拼写后,问题将得到解决。