C语言大学实用教程(第3版)(txt+pdf+epub+mobi电子书下载)


发布时间:2020-11-05 16:21:58

点击下载

作者:苏小红

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

C语言大学实用教程(第3版)

C语言大学实用教程(第3版)试读:

前言

随便进入一家书店,来到计算机图书专柜,都可以看到琳琅满目的C语言书籍。在这种状况下写书,特色和实用性非常重要。

本书的目标是力争成为最易懂、最专业、最时尚、最实用的C语言教材和参考手册。

它首先是一本教材,适合于程序设计的初学者和想更深入了解C语言的人。每行文字的落笔,都以把问题讲清楚、讲明白、讲透彻,又不累赘为目标。同时抛弃了一些陈旧的内容,把程序设计领域最新、最有价值的思想和方法渗透到古老的C语言中,赋予C语言焕然一新的面貌。

读者都有这样的体会:只追求浅显的教材,在读过一遍之后便可送人,没有长久保留的必要,也不会有常读常新的感觉。这本书不同,我们做了大量的搜集和整理工作,把各种知识点、实际经验和常用算法等分散渗透到各个相应章节中,并在附录A中提供索引,或者独立组织成文。这样做的目的就是便于读者随时查阅,使本书成为一本有保留价值的参考手册。毕竟很多深刻的内容不是简简单单读一遍就能掌握的,需要逐渐积累。愿读者每次重读本书字句,都能获得新的提高。

C语言在本书中仅是起点,而非终点。本着面向未来的精神,我们把程序设计中最基本的、放之四海而皆准的思想和方法挖掘出来,以C语言为工具描述它们,却不拘泥于C语言。以此培养读者无论在学习、工作中使用什么语言编程,都具有灵活应用这些思想和方法的能力。

趣味也是本书的一大特色。学习本身是一件充满乐趣的事情,它之所以使很多人感到枯燥,是因为没有人帮助他们发掘趣味。本书的作者都是有多年开发和授课经验的大学教师,并一直乐在其中。他们自然而然流露出的对C语言的赞叹、喜爱和沉迷之情,一定会感染读者。那些驾轻就熟的诙谐语言和生动有趣的示例,更能带给读者全新的学习体验。

全书共分10章,内容包括:程序设计ABC,数据类型、运算符与表达式,键盘输入与屏幕输出,程序的控制结构,函数,数组,指针,结构体与共用体,文件操作,C程序设计常见错误及解决方案等。最后一章C程序设计常见错误及解决方案,可谓本书的画龙点睛之笔。文前的“致本书读者”则是作者多年从事程序设计的亲身体验和感悟,正所谓“众里寻他千百度,蓦然回首,那人却在灯火阑珊处。”,希望这点点滴滴的感悟能引起读者的共鸣。

本书注重教材的可读性和可用性,每章开头有内容关键词和重点与难点提示,指导读者阅读;每章结尾安排本章小结,帮助读者整理思路,形成清晰的逻辑体系和主线,其中还给出了每章中的常见编程错误;典型例题一题多解,由浅入深,强化知识点、算法、编程方法与技巧;很多例题后面给出了思考题,不仅帮助读者了解什么是对的,还要了解什么是容易出错的。本书还将程序测试、程序调试与排错、软件的健壮性和代码风格、结构化与模块化程序设计方法等软件工程知识融入其中;习题以巩固基本知识点为目的,题型丰富,包括简答题、选择题、阅读程序写出运行结果、程序改错、程序填空和编程题等各种全国计算机等级考试二级考试的常见题型;附录中给出了实用学习资料列表。

本课程于2007年被教育部评为“国家级精品课程”。本书是普通高等教育“十一五”国家级规划教材,为方便高等院校各专业C语言教学和学生的自学,我们还为读者提供以下全方位的辅教和辅学方面的信息服务。

与本书同时配套出版的《C语言大学实用教程学习指导(第3版)》,提供全部习题解答、上机实验指导和案例分析内容。实验指导部分给出了在Visual C++6.0和Code::Blocks+gcc+gdb(本书后面将其简称为Code::Blocks)集成开发环境下的标准C程序调试方法。以主要知识点为主线设计的实验题目,兼具趣味性和实用性,并以循序渐进的任务驱动方式,指导读者完成实验程序设计,最后还给出了一个贯穿全书内容的综合应用实例(学生成绩管理系统)可作为课程设计内容。学习指导部分不仅给出了趣味经典实例,还给出了常见错误案例分析,帮助读者了解错误发生的原因、实质、排错方法以及解决对策。

本教材的多媒体教学课件、全部例题和习题的源代码都可在我们的C语言程序设计教材网站(http://book.sunner.cn)或华信教育资源网(http://www.hxedu.com.cn)上免费下载,我们研制的C语言编程题考试自动评分系统(已获软件著作权登记)也将免费提供给使用本教材的教学单位。有需要者可直接与作者本人联系(sxh@hit.edu.cn)。该系统可以根据程序的结构和语义以及程序运行结果对C语言编程题自动评分,对于有语法错误的编程题也能评分。

学时建议:前面加星号*的章节和习题为有一定深度和开放性的选学内容,如果授课学时为30学时,教师可以留给学生自学;如果授课学时为50学时,则可以有选择地讲授。具体课时分配建议如右表所示。

全书由苏小红统稿,第2、3、4、6、7章及附录由苏小红编写,第1、5、9、10章及致本书读者由孙志岗编写,第8章及5.9节由陈惠鹏编写。在本次修订中,第4、6、7、8章和附录的修订工作由苏小红完成,第1、5、9、10章的修订工作由孙志岗完成,第2、3章的修订工作由马建芬完成。本次修订压缩了教材的篇幅,删去了所有与Turbo C相关的陈旧内容,加强了对重点内容的阐述。

在本书的写作过程中,王宇颖教授在百忙之中审阅了全部初稿,对本书提出了许多宝贵意见。在书稿的校对、例题和习题程序的调试过程中,王甜甜、赵玲玲、傅忠传、赵巍、车万翔、张卫、郭萍、温东新、侯俊英、李希然、张洪志、李秀坤、张彦航、黄虎杰、秦兵、刘劲锋、王庆北、孙大烈、郝惠馨、单丽莉、刘国军、刘秉权、徐志明、李漾、张冬雨、娄久等做了大量工作。

国防科技大学的徐锡山教授,长春理工大学光电信息学院的苗长彦、南京邮电大学计算机学院的朱立华、太原理工大学的马建芬等老师以及本书的策划童占梅老师为教材的修订提出了许多宝贵的意见和建议,其中太原理工大学的马建芬还参与了部分章节的修订工作,还有很多热心的读者给我们来信提出意见和建议,在此一并向他们表示衷心的感谢。

因编者水平有限,书中错误在所难免,恳请读者批评指正。作者E-mail地址为sxh@hit.edu.cn,sun@hit.edu.cn,chp@ir.hit.edu.cn。华信教育资源网网址为http://www.hxedu.com.cn。我们会在每次重印时修改发现的错误,并及时将教材勘误表刊登于我们的教材网站(http://book.sunner.cn)上,欢迎读者给我们发送电子邮件或在网站上留言,提出宝贵意见。

编著者

于哈尔滨工业大学计算机科学与技术学院

第1章 程序设计ABC

内容关键词

计算机、计算机的工作原理

程序设计语言、程序设计语言的工作原理

二进制、内存

重点和难点

冯·诺依曼机工作过程

编译运行与解释运行

计算机在读者手中是否还只是一个上网、聊天、游戏、看电影的工具?你是否觉得“编程”是件高不可攀的事情?“黑客”是否还是你崇拜的对象?如果你给出的答案是“是”,那么这本书将力图把它们变成“否”。

本章将用最通俗的语言向你展现计算机以及程序设计的无穷魅力。你将了解到计算机对人类生活的影响;它是如何获得如此魔力的;程序设计扮演什么样的角色;程序设计语言是怎样的语言;怎样驾驭语言成为“编程高手”。

1.1 计算机与人

[1]

计算机界的泰斗——图灵(Turing)(如图1-1所示)曾经做过一个梦。梦中他与隔壁的一个人聊天,谈了很多事情。聊天结束,他走到隔壁,想见见这个人,却只看到一台计算机,原来一直陪他说话[2]的是这台计算机。这便是著名的“图灵测试”的一个形象化的故事。让计算机像人一样地思考,与人自然交流,也就是所谓的“人工智能(Artificial Intelligence)”,它一直是计算机行业的梦想。所以我们给计算机又起了一个可爱的昵称——电脑,期望其能与人脑相当,控制机器做出像人甚至超越人的事情。图1-1 阿兰·图灵

有很多科幻故事描绘了计算机真正成为电脑时的景象。如《变形金刚》里的机器人大战,《AI(人工智能)》里探讨的人类与机器的感情关系,《终结者》里机器人企图消灭人类等。在最有想象力的《Matrix(黑客帝国)》中,计算机不仅奴役了人类的躯体,使人类成为机器的生物电池,更奴役了人类的精神,让人类生活在计算机程序构成的虚拟世界里,按照计算机的指挥去行动、思考。如此下去,计算机简直都要让上帝下岗了。

这些都是文学家、艺术家的幻想,目前及可预见的未来,计算机还不可能达到这样的智能程度。即便达到了,人类的智慧也是有能力控制它的。目前,有两件事可以表现出计算机有过人的“智能”。一件是在1997年,IBM公司研制的深蓝(Deep Blue)超级计算机在一场“人机大战”中打败了国际象棋大师卡斯帕罗夫,被誉为“人工智能的一大胜利”;另一件发生在2011年,还是IBM公司,他们研制的“沃森(Watson)”软件系统参加了一个有近50年历史的电视知识竞赛节目——危险边缘(Jeopardy!),战胜了两位人类——节目史上最高奖金得主和连胜纪录保持者。在一般人看来,这两件事似乎都能说明计算机已经有了超越人类的“智能”,但从专业角度看,这两件事的达成虽然不容易,但依靠的并不是想象中的“人工智能”。比如深蓝的主要研制者之一,许峰雄博士曾在公开场合说:“AI is bullshit.”在他看来,胜利靠的只是不知疲倦地高速运算,并不是什么智能。而沃森所依靠的,除了强大的运算,还有事先存储的2亿页百科全书、字典、文学作品等资料。每当主持人提出一个新问题,沃森都能用每秒翻100万本书的速度查找答案,人类自然望尘莫及。

我们可以尽情地幻想人工智能,但目前计算机超乎常人的本领只有两样:不知疲倦地高速运算和海量的存储能力。然而,仅此两项,就已经足以影响我们的生活,甚至完全改变我们的生活。

当计算机技术与通信技术融合时,就形成了信息技术(Information Technology),诞生了一个新名词IT。IT的力量,带来的是又一次的工业革命。现在有很多流行的名词,像“云计算”、“物联网”、“智慧地球”等等。它们所描绘的,都是无所不在的网络和星罗棋布的大大小小的计算机如何改变着我们学习、生产和生活的方式,乃至改变社会的运作方式。

如果早几年写这本书,可能作者还要列举一些轰轰烈烈的计算机推动产业的例子。但今天不同了,已经不需要了,因为几乎所有的人都已经体会过IT所带来的成功与便利。但我要说的是,即使你每天与计算机和网络为伴,你所体会的还只是冰山一角。

从某种程度看,IT业更像发电厂、自来水厂,是其他行业的支持者。IT业纵深研究的主要目的之一,是为其他行业提供更好的服务。这种努力的结果已经显现出来,各行各业几乎都开始逐渐离不开IT了。比如,在自动控制领域,计算机的出现简直令其改天换地。因为这一[3]领域主要应用嵌入式系统(Embedded System),而且实时性要求高,所以这个行业里的程序员对C/C++及计算机底层技术的掌握程度甚至超过了绝大多数计算机专业人士。再比如玩钢筋水泥的建筑业,对建筑师来说,鼠标已成为安全帽以外的另一个标配。如果不用计算机画设计效果图,不用软件仿真各种应力对建筑的影响,那么这个建筑师就落伍了。国外的众多建筑公司协同软件公司开发了很多非常流行的专用软件,为建筑这一最古老的工程行业带来了新的动力。国内也正在做这方面的努力。这样看来,“水泥+鼠标”绝不仅仅是网络

[4]泡沫下IT人士的理想,而在另一领域,“听诊器+鼠标”则成了医生的一个梦。“21世纪是生物技术的世纪”,这一论点几乎毋庸置疑。就像其他学科一样,生物医学技术的飞速发展同样依靠IT技术。比如当前的研究热点基因组图谱工程,其工作量巨大,如果没有计算机的帮助,几乎不可能完成。在医学上,CT、核磁共振和彩超等医疗器械也广泛使用了计算机技术,未来的远程医疗将更加依赖IT。

IT对其他学科有影响,而反过来,其他学科对IT也有影响。比如,“DNA计算机”就是利用生物技术建造的全新架构的计算机,它成本更低、速度更快、容量更大,在一些领域很可能完全替代现有的计算机。再比如,计算机科学里很重要的一个方向——软件工程,它从建筑工程里借鉴了很多宝贵的管理、设计经验。在计算机专业,现在有越来越多的研究方向是与生物、机械、控制、管理等方向结合的交叉方向。

由此可见,不管未来是什么样的世界,它都离不开IT。不管读者从事什么工作,IT都将是你的有力工具。

1.2 计算机与程序设计语言

计算机很神奇,其魔力可用古老的中国哲学——《易经》来解释。“易有太极,是生两仪,两仪生四象,四象生八卦,八卦定吉凶,吉凶生大业。”“吉凶”与“大业”可代表世间万物,《易经》中的这句话阐述的哲学观点是,万物起源于“两仪”,也就是“阴阳”。按此观点,如果计算机想“什么都能干”,想控制万物,那么它只要抓住万物的本质——“阴阳”——就可以了。计算机确实以“阴阳”为根本,并把它俩表示成“0”和“1”,命名为“二进制(Binary)”。

二进制是否源自于《易经》,各界人士有很多论战,并无定论,有兴趣的读者可以去网上搜索一下相关文章,但计算机靠二进制来表达万物确是真的。

计算机为什么用二进制呢?为什么不用我们日常熟悉的十进制?一方面,二进制在电器元件中容易实现。二进制只有0和1两个数,在电学中具有两种稳定状态,并可以用0和1表示的东西很多。例如,电压的高和低、电容器的充电与放电、脉冲的有与无、晶体管的导通与截止,等等;而要找出具有十种稳定状态的电子元件则是很困2难的。另一方面,二进制数的加法运算规则只有2=4条,非常简单,而十进制的加法运算公式从0+0=0到9+9=18共有加法运算规则210=100条。显然,计算机进行二进制运算比进行十进制运算要简单得多。

英文里“Computer”是“Compute(计算)”加“er”后缀派生而来的。直译过来就是“计算的机器”,简称计算机。从名字上看,计算机不过是一台机器,它只会计算,事实上也确实如此。它把万物都表达成二进制的“0”与“1”的排列组合的形式,形成一个个二进制数序列,然后用各种运算手段对这些数序列进行计算,结果还是二进制数序列。这样做看上去并不复杂,你我稍加学习都能做到同样的事情,但是我们都没有计算机算得快、记得多,且不知疲倦,所以计算机大有用处。

正因为计算机只会计算,所以专门研究计算的数学在计算机科学中是很重要的。现实世界中的各种过程都被抽象成数学模型,表达成一个个数学公式;各种事物都用数字表示,代入公式中求解。这里面的奇特原理,实非本书所要阐述的重点;若读者有兴趣,可以广泛阅读其他专业资料。本书在后面的章节也会简单地介绍这方面的知识。

不管多么复杂的算式,计算机都能算。怎么让计算机知道你想让它算什么呢?最理想的情况是对着它说一声:“嗨,计算机,帮我把《高等数学》第12页第25题做了。”答案马上打印出来,甚至直接用电子邮件发给老师。不过目前计算机还做不到,但将来肯定能做到。这里面的主要问题是计算机听不懂“人话”。

也许你听说过甚至用过iPhone 4S的Siri软件,它能根据人的语音指示去回答问题、搜索资料、安排日程等。比如你可以对着手机说:“Siri,附近哪里有麦当劳。”Siri就会在手机地图上为你标记最近的麦当劳餐厅的位置,并指明路线。看上去好像计算机已经理解了我们说的话,但其实它的“理解力”非常有限,准确度也不高。如果发音稍有含糊,遣词造句也不够大众化,问题又比较生僻,那么Siri就很难给出想要的结果,甚至会闹笑话。为什么会这样?Siri是套非常复杂的系统,集成了语音识别、自然语言处理和搜索等顶尖技术。这些技术都是用计算机语言编写的程序实现的,这些程序没有“智能”,只会将用户说的话和内置的各种模式匹配,如果匹配对了,就做对应的动作,否则就会犯错。整个过程是先要有人懂计算机语言,用计算机语言对计算机说话(编写程序),再一点点教计算机学会我们的语言(完善各种模式)。因为人类的表达和思维都太多样了,所以不可能穷尽所有的模式,计算机也就不可能完全精确地理解我们的语言(为了做到“精确”,联想公司的“乐助理”采用了比较有喜感的“人肉”方式,由真正的人听用户的语音,再做出反应)。那么精确控制计算机的唯一途径,就是我们学习并掌握计算机语言,也就是“程序设计语言”。

在弄清程序设计语言之前,我们先看一看计算机是如何工作的。[5]

1946年,冯·诺依曼在总结前人工作的基础上,率先在计算机中采用二进制,并且提出了著名的“冯·诺依曼机”结构。这一结构至今仍然被几乎所有的计算机采用,他也因此被誉为“计算机之父”(如图1-2所示)。图1-2 冯·诺依曼和世界上第一台计算机——ENIAC

冯·诺依曼机,把计算机简化为控制器、运算器、存储器、输入和输出设备五个部分。控制器和运算器就是CPU,它被比作计算机的大脑;存储器被分为内存和外存两部分,它们使计算机具有记忆能力;输入设备就是计算机的耳朵和眼睛,是人给计算机发送指令的工具,如键盘、鼠标;输出设备是计算机给人反馈结果的设备,如显示器、打印机。

人与计算机的一次对话是这样完成的:用户从键盘输入程序和数据(程序就是用计算机语言书写的指令集合),程序和数据被存入计算机的内存;然后由CPU逐一读出每条指令、数据,按指令对数据进行运算;运算的结果写回内存,并显示给用户。如果用户认为有长久保存结果的必要,则将其存入外存备用。

硬盘、磁盘等均为外存,它们与内存的主要区别是数据可以在里面长久保存。内存在每次计算机关闭后都会丢失所有数据,而外存则不会。外存除了可以保存数据,也可以保存程序。使用过计算机的读者应该知道,想运行某个程序,只需在命令行输入程序名,或者在窗口双击该程序的图标即可,并不需要输入程序代码。这些程序就是预先保存在外存的,当用户需要运行它时,只要发出运行命令,它们就被读入内存,然后按照上面的过程执行。

图1-3是一个简化了的计算机工作过程示意图,计算机的实际工作过程当然比这复杂得多,但它还是完整地体现了其基本工作原理,尤其体现了“软件指挥硬件”这一根本思想。在整个过程中,如果没有软件程序,计算机什么也干不了,可见软件程序多么重要。而且,如果软件程序编得好,计算机就运行得快且结果正确;程序编得不好,则可能需要运行很久才出结果,且结果还不一定正确。程序是软件的灵魂,CPU、显示器等硬件必须由软件指挥,否则只是一堆没有灵性的工程塑料与金属的混合物。这本书就是要教会读者怎样用C语言又快又好地编写程序(软件)。图1-3 简化了的计算机工作过程示意图

1.3 程序设计语言的故事

计算机直接能够读懂的语言是机器语言(Machine Language),也叫机器代码(Machine Code),简称机器码。这是一种纯粹的二进制语言,用二进制代码来代表不同的指令。[6]【例1.1】下面这段程序是用我们通常使用的x86计算机的机器语言编写的,功能是计算1+1。

10111000

00000001

00000000

00000101

00000001

00000000

这段程序是不是给你一种看“天书”的感觉?在最早的用拨钮开关和纸带打孔的方式向计算机输入程序的时代,程序员编写的都是这样的程序。很明显,这种程序编起来很费力气,人类很难读懂。从那时候起,让计算机能够直接懂得人的语言就成了计算机科学家们梦寐以求的目标。

有人想出了这样的办法,编一个可以把人类的语言翻译成计算机语言的程序,这样计算机就能读懂人类语言了。这说起来容易,做起来难。就拿计算1+1来说,人们可以用“1+1等于几”、“算一下1+1的结果”、“1+1得多少”……多种说法,再加上用英语、法语、日语、韩语、爪哇语等来描述。如果想把这些都自动转换成上面的机器码,是可望而不可及的。所以人们退后一步,打算设计一种中间语言,它还是一种程序设计语言,但比较容易翻译成机器代码,且容易被人学会和读懂。于是诞生了“汇编语言(Assemble Language)”。【例1.2】用汇编语言计算1+1的程序。

这个程序的功能是什么?从程序中ADD和1的字样,或许我们能猜个大概。没错,它还是计算1+1的。这个程序经过编译器(也是一个程序,它能把CPU不能识别的语言翻译成CPU能直接识别的机器语言)编译,就会自动生成例1.1的程序。这已经是很大的进步了,但并不理想。这里面的MOV是什么含义?好像是Move的缩写。这里的AX又代表什么?这是一个纯粹的计算机概念。从这个小程序,我们能看出汇编语言虽然已经开始贴近人类的语言,但还全然不像我们所期望的那样,里面还有很多计算机固有的东西必须要学习。它与机器语言的距离很近,例1.2的每行程序都直接对应例1.1的三行代码。也许以后你有机会学习、使用汇编语言,那时你将学到更多有关计算机内部的知识。

程序设计语言要无限地接近自然语言,所以它注定要不停地发展。此时出现了一道分水岭,人们把机器语言和汇编语言称为低级语言,把以后发展起来的语言称为高级语言。低级语言并不比高级语言“低级”,而是说它与计算机(硬件)的距离的级别比较低。高级语言高级到什么程度呢?我们先看一个很著名的高级语言——BASIC语言,怎样完成1+1的计算。【例1.3】用BASIC语言计算并显示1+1。

怎么样?如果你不知道英文PRINT的中文意思,马上查字典吧。比起前两个例子,它确实简单了不少,而且功能很强。前两个例子的计算结果只保存在CPU内,并没有输出给用户,就算你拿纳米显微镜往里看也看不到。这个例子直接把计算结果显示在屏幕上,它才是真正功能完备的程序。如果让你把计算“1+1”改成计算“10-8”,能自己想出来怎么改前两个程序吗?第三个程序呢?相信读者很快就体[7]会到了高级语言的魅力。

因为高级语言易学、易用、强大,所以它发展很快,其种类已经不能用“百家争鸣”来形容。据一位民间人士Bill Kinnersley耗时多年[8]的不完全统计,目前已经有超过2 500种计算机语言,其中绝大多数都是高级语言。

1.4 C语言的故事

高级语言门类繁多,其中影响最大的是C语言;高级语言此起彼伏,其中寿命最长的也是C语言。Tiobe每个月都会统计各种程序设计语言的受欢迎程度。图1-4是2001年到2011年的统计图,可以看到C语言始终稳居前两位。图1-4 截至2011年12月编程语言受欢迎程度趋势图(来源:http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html)

20世纪60年代,美国AT&T公司贝尔实验室(AT&T Bell Laboratory)的研究员Ken Thompson(如图1-5所示)闲来无事,手痒难耐,想玩一个他自己编的、模拟在太阳系航行的电子游戏——[9]Space Travel 。他背着老板,找到了一台空闲的机器——PDP-7。但这台机器没有操作系统,而游戏必须使用操作系统的一些功能,于是他着手为PDP-7开发操作系统。后来,这个操作系统被命名为——UNIX。[10]

1971年,同样酷爱Space Travel的Dennis M.Ritchie为了能早点儿玩上游戏,加入了Thompson的开发项目,合作开发UNIX。他的主要工作是改造B语言,使其更成熟。后来这个语言被命名为C语言。

1973年初,C语言的主体完成。Thompson和Ritchie迫不及待地开始用它完全重写了UNIX。此时,编程的乐趣使他们已经完全忘记了那个“Space Travel”,一门心思地投入到了UNIX和C语言的开发中。随着UNIX的发展,C语言自身也在不断地完善。直到今天,各种[11]版本的UNIX内核和周边工具仍然使用C语言作为最主要的开发语言,其中还有不少继承自Thompson和Ritchie之手的代码。

在开发中,他们还考虑把UNIX移植到其他类型的计算机上使用。C语言强大的移植性(Portability)在此显现。机器语言和汇编语言都不具有移植性,为x86开发的程序,不可能在Alpha、SPARC和ARM等机器上运行。而C语言程序则可以在任意机器上运行,只要那种计算机上有C语言编译器和库。

C语言继续发展,在1982年,很多有识之士和美国国家标准协会(American National Standards Institute,ANSI)为了使这个语言健康地发展下去,决定成立C标准委员会,建立C语言的标准。委员会由硬件厂商、编译器及其他软件工具生产商、软件设计师、顾问、学术界人士、C语言作者和应用程序员组成。1989年,ANSI发布了第一个完整的C语言标准——ANSI X3.159—1989,简称“C89”,不过人们也习惯称其为“ANSI C”。C89在1990年被国际标准组织ISO(International Organization for Standardization)一字不改地采纳,所以也有“C90”的说法。1999年,在做了一些必要的修正和完善之后,ISO发布了新的C语言标准,命名为ISO/IEC 9899:1999,简称“C99”。

C99之后,C语言的发展基本停止。直到今天,C的标准文档只在字面上做过两次少量的修订。其最新的草案(WG14 N1124)于2005年发表,“http://www.open-std.org/jtc1/sc22/wg14/”提供免费下载。此“草案”是对C语言最精准的描述,所有关于C语言的疑惑都可以在其中找到答案。它与官方最终文本相比只会有很少的区别,通常情况就可以当做正式版使用。如果您是一个完美主义者,一定要正式版,请联系http://www.iso.org,售价大约40美元,不包邮。

C99虽然新,修正了C89中很多不完善甚至被广泛诟病的地方,但它扩展的一些新特性在实践中并不被看好,编译器对其进行支持的进度也比较缓慢。相对而言,支持C89的编译器就遍地开花了,大多数教科书、资料也都是以C89为核心进行讲述,大量的软件也根据C89标准编写,所以本书也以C89为蓝本讲述,但适当时候会对C89不完善的地方加以说明,并介绍C99的改进。

值得一提的是,在1983年,Thompson和Ritchie共同获得了图灵奖。虽然这个奖项的授予是因为他们在UNIX上的开创性工作,但谁也不能忽视C语言在其中发挥的巨大作用。如图1-5所示,Thompson(左)和Ritchie(右)1999年接受前美国总统克林顿授予的国家技术勋章。图1-5 Thompson(左)和Ritchie(右)1999年接受前美国总统克林顿授予的国家技术勋章

看了上面的讲述,如果你认为C语言就是用来开发UNIX的,那可就大错特错了。它是一种通用语言,任何想让计算机做的事情,都可以用它编程实现。你可不要小看这个能力,2 500种计算机语言中,真正“什么都能做”的语言很少。比如说开发操作系统,除了C语言和马上会讲到的C++语言以外,还没有任何一个成熟的系统采用其他高级语言(这样说有些武断,笔者的能力确实无法做一个最完备的统计。在能及范围内,此论点成立)。而且现在使用C++语言开发操作系统的也是凤毛麟角,还不是用于做关键的核心开发,由此,C语言的能力可见一斑。在很长时间内,C语言一直是应用最广泛的语言。

既然C语言如此强大,那还要其他语言作甚?此言差矣。C语言的万能源自于它的简单、灵活,对各种需求的适应性强。适应性和专用性是一对冤家对头,这就注定了C语言很难专用化。有一个笑话说:“如果你想用C语言来造汽车,那么你不得不自己先造轮子。”而很多其他高级语言都已经把各种轮子造好放在那里,任由你挑选。另外,C语言距离机器代码比其他高级语言更近。因此也有人把C语言看成唯一的介于低级语言和高级语言之间的语言。这就使它距离自然语言比较远,其思维还是顺应计算机而不是顺应人的,所以学起来比较费劲,用起来也不简单。【例1.4】下面是用C语言编写的计算1+1的程序,里面有英文单词,也有不知所云的符号(很快你就会知其所云了)。

在当今世界,C语言已经偏居一隅,除其固守的系统软件开发阵地和历史延续下来的大型软件外,几乎仅在小型的且追求运行效率的软件和嵌入式软件开发方面还有一定空间。这一点点空间也正在逐渐缩小。取而代之的是C++,Java和C#等后生语言,以及一些很专门化的语言。有趣的是,C语言有为数不少的铁杆迷,他们对其爱不释手,对那些后生语言不屑一顾。这样的人,在代表最高编程水平的黑客社区里特别多。能轻松驾驭C语言几乎是“高手”必备的素质之一。

C++从名字上看就知道其与C语言有着不解的渊源。它的设计者Bjarne Stroustrup早年曾在Thompson和Ritchie的实验室工作,而C++又几乎完全兼容C语言的语法,且所有流行的C++编译器都能编译C程序,所以很多人认为C++就是C语言的升级。在很多场合,它俩也被放在一起,称为C/C++。这个“++”加上的,便是大名鼎鼎的“面向对象(Object Oriented)”。

在面向对象被广泛接受之前,流行的是结构化程序设计思想。C和Pascal等语言都是结构化的,后面章节你会学到详细的结构化思想。面向对象的程序设计思想对程序设计的影响可谓翻天覆地,整个计算机界的思维都因其而改变,程序设计更加贴近现实世界,更加符合人类固有的习惯。C++借助C语言的影响力,携面向对象的威力,其影响迅速增大。在20世纪90年代曾有民间组织统计,当年发布的软件中,90%以上采用C++语言开发。

C++兼有C语言的能力,也是一种“什么都能干”的高级语言,所以学习和使用起来也不简单。做系统开发的毕竟是少数,直接面向最终用户的应用开发才是语言的必争之地。Java语言就是在这种情况下诞生的。

Sun公司推出的Java语言,以纯面向对象、平台无关和易学易用而著称。它全面照搬了C++语法,并去掉了其不常用和不成功的部分,化繁为简,迅速博得了程序员的认可,获得了越来越多的支持。Java语言融合了很多先进的程序设计思想、方法,不管是桌面应用,还是网络服务、嵌入式应用都可用它进行高效的开发。当然,如果要做底层的、占用资源少的程序,Java语言就无能为力了。Java语言的市场做得很不错,它已经被广泛接受,以至于很多客户都指名道姓地要求开发商必须用Java语言为其开发软件,尽管他们并不十分明白Java语言究竟如何。

Java语言的成功,让软件大鳄微软(Microsoft)公司坐不住了。它及时推出了C#(读作C Sharp)语言。“#”这个符号就是4个加号围坐一圈,所以有人戏称其为C++++。从名字可以看出它与C/C++的渊源。没错,它也照搬了C/C++的语法。

C#语言诞生在Java语言之后,所以它能把Java语言的成功之处吸收进来,把不成功之处抛弃,打造了一个似Java而非Java,还有点超越Java的语言。但它年龄不大,2000年诞生(Java语言诞生于1995年),所以还没有多少惊世之举,不过前途不可限量。

目前,C/C++,Java和C#语言即将形成三足鼎立之势,其他语言仅能在其专属领域里得以发挥作用。同时,C++,Java和C#语言也在不断地完善、扩充自身,极力挤压其他语言的空间。在此种情况下,C语言的空间变得越来越小,那么为什么还要学习C语言呢?相信聪明的读者已经能从上面的故事中找到答案了。C语言可以说是C++,Java和C#语言的基础,还有很多专用语言也学习和借鉴了C语言,比如进行Web开发的PHP语言,做仿真的MATLAB内嵌语言等。学好C语言对以后再学习其他语言大有帮助。计算机科学发展很快,若干年之后,什么技术、什么语言尽显风流无法预言。唯有掌握最基础的,才能以不变应万变,并立于不败之地。

在这里我们并不想误导读者,使读者认为学习C语言是学其他语言的必由之路。相反,有不少人认为,C语言学得太好有碍于继续学习其他语言,典型例子就是前面提到的那些不愿接受新事物的C语言的铁杆迷们。其他语言从C语言所继承的主要是语法和一些基本概念等外在的东西。每一种语言都有其内涵,那是它独特的神韵。已经完全陶醉于一种语言的人,很难领会、接受另一种语言的神韵,这就造成了学习新语言的障碍。比如,有为数不少的人在使用C++的时候总按照C的习惯去编程,导致程序表面看上去是C++的,但内部却还是结构化而非面向对象的,完全发挥不出C++的威力,以至于C++之父跳出来疾呼“C++是一个全新的语言,使用的时候请忘记C语言”。同样的现象在从C++程序员转变成Java程序员时也发生了。可见,唯有以包容的心态去面对,以客观的手段去选择,才能将各种语言把玩于手中,趋利避害,成为语言的主宰而并非奴隶。所以,学习语法是次要的,学神韵是最重要的。各种语言的语法都大同小异,就算互不抄袭,也基本难以逾越几条普遍规则。只要熟练掌握一种语言的语法,再学任何其他语言的语法基本上只要几天,甚至几个小时就可以搞定。但要真正掌握语言的神韵,就非一蹴而就了。

学习程序设计的道路不止一条,从C语言开始也不见得是最明智的。但既然现在有机会从此入门,那么为什么不牢牢抓住这个机会呢?

敬请步入程序设计的奇妙世界……

1.5 程序设计语言的工作原理

虽然本书力图让学习C语言成为一件快乐的事情,但总无法避免讲述一些可能有点枯燥的理论。阳光总在风雨后,不经历跋涉的辛苦与攀岩的枯燥,又怎能体会到“会当凌绝顶,一览众山小”的快乐呢?所以,先学点枯燥的(其实,至少对计算机爱好者而言,这些内容并不枯燥,反倒非常有趣)吧,为了快乐。1.5.1 运行

程序源代码是静态的,只有运行起来才能发挥作用。

编译运行是最经典、效率最高的运行方式。C/C++的高性能很大程度上归功于编译。用编译语言开发一个软件所要经历的过程是:编辑、编译、链接和运行。

编辑(Edit),就是用程序设计语言编写源代码(Source Code)。这是一个创造艺术品的过程,你所有的思维、能力、知识都体现在这个过程中。本书的其余章节讲的都是怎样把这个过程做好。

对于编译(Compile),用户只需要发出编译指令,其余的事情都交给编译器(Compiler)自己完成。前面提到过编译器,它是把程序设计语言转换成目标代码(Object Code)的软件。这个转换过程很复杂,如果读者将来有机会学习《编译原理》这门课程的话,会了解其复杂程度。我们作为编译器的用户,可以全然不管这些。鼠标一点,键盘一按,轻轻松松,编译完成。程序设计的意义就在这里体现出来,因为我们编写程序时,是把复杂的东西都“包装”在程序里,给用户一个最简单的使用界面。

如果程序员编写的源代码有问题,通常指语法错误,那么编译器会报错,并停止编译。因为程序员编写的代码它读不懂,不知道该转成什么。一些聪明的编译器还会找出程序中逻辑上的问题和不安全的地方。当遇到编译器给出错误提示时,就要分析出错的原因,重新修改代码后,再重新编译。如此往复,直到编译成功为止。

链接(Link)过程很简单,有时候甚至完全体会不到,所以很多人习惯上把它也算做编译的一部分。在这个过程中,链接器(Linker)把用户程序和支持它运行的必需的其他程序都“合成”在一起,形成最后的可执行文件(在DOS,Windows下扩展名为.exe的文件)。可执行文件里面都是执行代码,也就是机器语言代码。全部转换过程完毕,用户就可以把这个文件复制给别人用了。通常,使用者并不需要程序的源代码,有这个可执行文件足矣。使用者唯一要做的就是运行(Run)它。

不要以为程序能运行就万事大吉了。运行时还会出现错误,开发者必须捕获这些错误,并通过修改源代码解决错误,重新编译、链接,最终交付无错的可执行文件。有些错误很快就会被发现和及时改正;有些错误则隐藏很深,很长时间才会发现,比如著名的2000年问题——千年虫。

还有一种被大量采用的程序运行方式,称为解释运行。最具有代表性的是BASIC,JavaScript,PHP,ASP,Perl、Python和Ruby等语言。这些语言的共同特点是运行速度慢,但简单。

用这类语言编写的程序在运行时,必须先运行一个“解释器”。解释器能读懂这种语言,按照程序指令一步一步地工作,完成开发者需要的功能。因为必须一条一条地解释语句并执行,所以速度很慢,比编译语言要慢数十甚至上百倍。因为解释器的功能可以做得很强,并且可以把计算机的复杂性隐藏起来,所以这类语言都比较易学。

解释语言简单好用,获得了大量的支持者。甚至有人预言,它将完全替代编译语言。说此话的人好像忘记了一件事情,那就是解释语言的解释器几乎都是用C/C++开发的。编译语言的编译器、链接器可以用编译语言自己编写,而解释语言只能借助编译语言发展。

解释语言还有一个致命伤——源代码必须交给用户。对把源代码视作最高商业机密的软件企业来说,这简直是自砸饭碗,不会有人愿意这样做。因而,也有人预言,解释语言的生命力不会长,不过他也错了。现在,解释语言已经是高级语言中不可或缺的一部分,它在Web开发和应用软件脚本扩展等领域发挥着巨大作用。通过法律的保护,人们已经不再特别介意源代码的保密,甚至有人愿意公开源代码与人交流。至于速度问题,一方面,因为硬件性能提升、成本下降,硬件瓶颈不再突出;另一方面,解释语言也采用了很多提高速度的办法。有一种办法是:先编译、后解释。它演变出了一种新类型的语言。

Java和C#语言都是先编译、后解释的。编译器并不把它们编译成机器代码,而是编译成一种中间代码(Java语言中称为字节码,C#语言中称为MSIL),当然,这个中间代码必须在其支持的平台上运行。Java语言提供的平台称为JVM(Java Virtual Machine),它纯粹靠解释字节码来运行程序;C#语言的运行平台称为CLR(Common Language Runtime),它并不是一个纯粹的解释器,而是翻译器,把MSIL代码翻译成机器代码,再运行它。

总之,它们都要有平台才能运行,所以它们都比编译语言慢,Java语言比C#语言更慢。不过它们具备解释语言最大的好处——简单,而且只需经过一次编译,避免了源代码的传播,非常适合开发大型应用软件。1.5.2 内存

通过前面的介绍我们知道,程序在运行时是和数据一起保存在内存(Memory)中的,由CPU执行。内存是怎样存储它们的呢?

程序和数据都是以二进制形式存储的,存储单位是字节(Byte)。每台计算机的内存都能存储一定字节数的内容,也就是我们俗称的“内存大小”。通常,每个存储单元能保存1字节。程序和数据怎样存储和该往哪里存储并不需要用户操心,操作系统和编译器会打理这一切。但在程序运行时,我们经常需要知道某个数据究竟保存到了什么地方,这就需要知道地址信息。

内存的每个单元都被分配一个唯一的整数,称为地址(Address)。这就像门牌号码一样,用它就能找到你要找的地方。因此知道数据所在的地址,也就知道了数据的存储位置。程序指令存储在内存中,所以它也有地址。关于地址,将在第7章讲到很多奇妙的用法。

1.6 本章小结

本章简要介绍了计算机程序设计语言发展中的人和事。总的来说,计算机和计算机语言都越来越易用,越来越符合人类自身的习惯。C语言是这个发展过程中的一个里程碑。

程序可以指挥计算机做各种事情。但是计算机不能直接读懂高级语言,必须由编译器或者解释器把高级语言翻译为机器可读懂的机器语言。

驾驭计算机必须编写程序。仅懂得程序设计语言还不足以编写好的程序,至少需要了解一定的计算机工作原理,比如计算机的工作过程、二进制和内存等基础知识。

习题1

1.1 列举几种读者所知道的计算机硬件和软件。

1.2 冯·诺依曼机模型有哪几个基本组成部分?

1.3 尝试把例1.4改为计算“123+456”。

1.4 列举几种程序设计语言。

1.5 列举几个在生活和学习中成功应用IT的例子。

[1]:① Alan Turing(1912—1954),生于英国伦敦,被认为是20世纪最著名的数学家之一。美国计算机协会(ACM)在1966年设立的每年一届的以他的名字命名的“图灵奖(Turing Award)”,是计算科学领域的最高荣誉,是计算机界的“诺贝尔奖”。

[2]:② 图灵测试:图灵在1950年的文章《计算机器和智能》中讨论了可以把一个机器视为有智能的条件。他说,如果一个机器可以在一个博学的人面前成功地假扮成一个人的话,那么我们可以说这个机器是有智能的。

[3]:① 嵌入式系统:简单地说,将计算机嵌入到另一个系统里,控制那个系统工作,就是嵌入式系统。典型的嵌入式系统有机器人、手机和智能家电等。这是IT未来的主要发展方向之一。

[4]:① 20世纪末,随着Internet的发展,网络经济迅速崛起,很多年轻的网络公司很快壮大起来,其股票市值扶摇直上。21世纪初,因为这些公司中的绝大部分都不盈利,股票开始大幅下跌,投资人信心崩溃,“网络泡沫”破灭,众多网站合并、倒闭或惨淡维持。那时诞生了一个观点,就是互联网要和传统行业结合发展,也就是所谓的“水泥+鼠标”。

[5]:① John Von Neumann(1903—1957),生于匈牙利的布达佩斯,是20世纪最杰出的数学家之一,现代计算机之父。

[6]:① 美国Intel公司推出的系列CPU统称为x86 CPU。使用x86 CPU的计算机被称为x86计算机。目前绝大部分个人计算机都使用这个家族的CPU或者兼容其指令系统的CPU。早期的286、386、486及现在流行的奔腾(Pentium)系列都在此列。

[7]:① 改为“PRINT 10-8”即可。另两个程序要分别改成“10111000|00001010|00000000|00101101|00001000|00000000”和“MOV AX,0A|SUB AX,08”。

[8]:② 在http://people.ku.edu/~nkinners/LangList/Extras/langlist.htm 可以看到这2500种语言的列表和简介。另外,网站http://www.levenez.com/lang/搜集了大约50种极具代表性的语言故事和资料,它们都正在或曾经叱咤风云。

[9]:① 这个游戏是真实存在的,请参考http://cm.bell-labs.com/cm/cs/who/dmr/spacetravel.html。

[10]:② Dennis M. Ritchie生于1941年,卒于2011年10月,C语言发明人。后人评价道:“他的名字并非耳熟能详,但是,如果你用显微镜来仔细观察一台计算机,会发现到处都有他做的贡献。”

[11]:③ UNIX的发展有很多分支,产生过多种流派,可以参见http://www.levenez.com/unix/。

第2章 数据类型、运算符与表达式

内容关键词

基本数据类型

常量和变量

标识符命名

常用运算符和表达式

运算符的优先级与结合性

重点与难点

变量的定义,使用变量的基本原则,变量占内存的字节数

增1和减1运算符、强制转换运算符

赋值与表达式中的类型转换

将数学表达式写成合法的C语言表达式

典型实例

计算圆的面积和周长

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载