目录
第1章程序设计和C语言1
1.1计算机与程序、程序设计语言1
1.2C语言的特点2
1.3简单的C语言程序3
1.4C语言程序的结构6
1.5运行C程序的步骤与方法8
1.6程序设计的任务10
1.7算法——程序的灵魂11
1.7.1程序是什么11
1.7.2什么是算法12
1.7.3怎样表示一个算法13
1.8结构化程序设计方法19<p>目录</p> <p> </p> <p>第1章程序设计和C语言1</p> <p>1.1计算机与程序、程序设计语言1</p> <p>1.2C语言的特点2</p> <p>1.3简单的C语言程序3</p> <p>1.4C语言程序的结构6</p> <p>1.5运行C程序的步骤与方法8</p> <p>1.6程序设计的任务10</p> <p>1.7算法——程序的灵魂11</p> <p>1.7.1程序是什么11</p> <p>1.7.2什么是算法12</p> <p>1.7.3怎样表示一个算法13</p> <p>1.8结构化程序设计方法19</p> <p>1.9学习程序设计,培养科学思维21</p> <p>本章小结23</p> <p>习题23</p> <p>第2章*简单的C程序设计——顺序程序设计25</p> <p>2.1顺序程序设计举例25</p> <p>2.2数据的类型及存储形式29</p> <p>2.2.1C语言的数据类型29</p> <p>2.2.2数据的表现形式——常量和变量29</p> <p>2.2.3整型数据31</p> <p>2.2.4字符型数据36</p> <p>2.2.5浮点型数据41</p> <p>2.3用表达式进行数据的运算43</p> <p>2.3.1C表达式43</p> <p>2.3.2C运算符44</p> <p>2.3.3运算符的优先级与结合性462.3.4不同类型数据间的混合运算46</p> <p>2.3.5强制类型转换47</p> <p>2.4*常用的C语句——赋值语句48</p> <p>2.4.1C语句综述48</p> <p>2.4.2赋值表达式50</p> <p>2.4.3赋值语句53</p> <p>2.5数据的输入输出56</p> <p>2.5.1C语言中输入输出的概念56</p> <p>2.5.2用printf函数输出数据57</p> <p>2.5.3用scanf函数输入数据62</p> <p>2.5.4字符数据的输入输出65</p> <p>本章小结67</p> <p>习题68</p> <p>第3章选择结构程序设计71</p> <p>3.1简单的选择结构程序71</p> <p>3.2选择结构中的关系运算73</p> <p>3.2.1关系运算符及其优先次序73</p> <p>3.2.2关系表达式73</p> <p>3.3选择结构中的逻辑运算74</p> <p>3.3.1逻辑运算符及其优先次序75</p> <p>3.3.2逻辑表达式76</p> <p>3.4用if语句实现选择结构78</p> <p>3.4.1if语句的三种形式78</p> <p>3.4.2if语句的嵌套80</p> <p>3.5用条件表达式实现选择结构83</p> <p>3.6利用switch语句实现多分支选择结构86</p> <p>3.7选择结构程序综合举例88</p> <p>本章小结94</p> <p>习题94</p> <p>第4章循环结构程序设计96</p> <p>4.1程序需要循环96</p> <p>4.2用while语句和do…while语句实现循环96</p> <p>4.2.1用while语句实现循环96</p> <p>4.2.2用do…while语句实现循环98</p> <p>4.2.3while循环和do…while循环的比较99</p> <p>4.2.4递推与迭代101</p> <p>4.3用for语句实现循环104</p> <p>4.3.1for语句的执行过程104</p> <p>4.3.2for语句的各种形式106</p> <p>4.3.3for循环应用举例108</p> <p>4.4循环的嵌套110</p> <p>4.5用break语句和continue语句改变循环状态110</p> <p>4.5.1用break语句提前退出循环110</p> <p>4.5.2用continue语句提前结束本次循环111</p> <p>4.6几种循环的比较113</p> <p>4.7循环程序举例113</p> <p>本章小结116</p> <p>习题117</p> <p>第5章利用数组处理批量数据119</p> <p>5.1数组的作用119</p> <p>5.2怎样定义和引用一维数组120</p> <p>5.2.1怎样定义一维数组120</p> <p>5.2.2怎样引用一维数组元素120</p> <p>5.2.3一维数组的初始化121</p> <p>5.2.4利用一维数组的典型算法——递推与排序122</p> <p>5.3怎样定义和引用二维数组125</p> <p>5.3.1怎样定义二维数组125</p> <p>5.3.2怎样引用二维数组的元素126</p> <p>5.3.3二维数组程序举例126</p> <p>5.3.4二维数组的初始化129</p> <p>5.4利用字符数组处理字符串数据130</p> <p>5.4.1怎样定义字符数组130</p> <p>5.4.2字符数组的初始化131</p> <p>5.4.3引用字符数组的元素132</p> <p>5.4.4字符串和字符串结束标志133</p> <p>5.4.5字符数组的输入输出方法135</p> <p>5.4.6有关字符处理的算法136</p> <p>5.4.7利用字符串处理函数139</p> <p>本章小结142</p> <p>习题143</p> <p>第6章利用函数进行模块化程序设计145</p> <p>6.1为什么要使用函数145</p> <p>6.1.1函数是什么145</p> <p>6.1.2程序和函数146</p> <p>6.2怎样定义函数147</p> <p>6.2.1为什么要定义函数147</p> <p>6.2.2怎样定义无参函数148</p> <p>6.2.3怎样定义有参函数148</p> <p>6.3函数参数和函数的值149</p> <p>6.3.1形式参数和实际参数149</p> <p>6.3.2函数的返回值150</p> <p>6.4函数的调用151</p> <p>6.4.1函数调用的一般形式151</p> <p>6.4.2调用函数的方式152</p> <p>6.4.3对被调用函数的声明和函数原型152</p> <p>6.5函数的嵌套调用155</p> <p>6.6函数的递归调用157</p> <p>6.6.1什么是函数的递归调用157</p> <p>6.6.2递归算法分析157</p> <p>6.6.3用递归函数实现递归算法160</p> <p>6.7数组作为函数参数164</p> <p>6.8函数应用举例——编写排序程序168</p> <p>6.9变量的作用域和生存期171</p> <p>6.9.1局部变量171</p> <p>6.9.2全局变量171</p> <p>6.9.3变量的存储方式和生存期172</p> <p>6.9.4作用域与生存期小结176</p> <p>6.10关于变量的声明和定义178</p> <p>本章小结179</p> <p>习题180</p> <p>第7章善于使用指针182</p> <p>7.1什么是指针182</p> <p>7.2变量的指针和指向变量的指针变量184</p> <p>7.2.1怎样定义指针变量184</p> <p>7.2.2怎样引用指针变量187</p> <p>7.2.3指针变量作为函数参数189</p> <p>7.3通过指针引用数组194</p> <p>7.3.1数组元素的指针194</p> <p>7.3.2指针的运算195</p> <p>7.3.3通过指针引用数组元素196</p> <p>7.3.4用数组名作函数参数200</p> <p>7.4通过指针引用字符串206</p> <p>7.4.1引用字符串的方法206</p> <p>7.4.2字符指针作函数参数209</p> <p>7.4.3对使用字符指针变量和字符数组的归纳212</p> <p>本章小结215</p> <p>习题219</p> <p>第8章根据需要创建数据类型221</p> <p>8.1定义和引用结构体变量221</p> <p>8.1.1怎样创建结构体类型221</p> <p>8.1.2怎样定义结构体类型变量223</p> <p>8.1.3引用结构体变量225</p> <p>8.2使用结构体数组228</p> <p>8.2.1定义结构体数组228</p> <p>8.2.2结构体数组应用举例230</p> <p>8.3结构体指针231</p> <p>8.3.1指向结构体变量的指针231</p> <p>8.3.2指向结构体数组的指针233</p> <p>8.3.3用结构体变量和结构体变量的指针作函数参数234</p> <p>8.4用指针处理链表237</p> <p>8.4.1什么是链表237</p> <p>8.4.2建立简单的静态链表239</p> <p>8.4.3建立动态链表240</p> <p>8.4.4输出链表243</p> <p>8.5使用枚举类型246</p> <p>8.5.1什么是枚举和枚举变量246</p> <p>8.5.2枚举型数据应用举例247</p> <p>本章小结250</p> <p>习题251</p> <p>第9章利用文件保存数据252</p> <p>9.1C文件的有关概念252</p> <p>9.1.1什么是文件252</p> <p>9.1.2文件名253</p> <p>9.1.3文件的分类253</p> <p>9.1.4文件缓冲区254</p> <p>9.1.5文件类型指针254</p> <p>9.1.6文件位置标记255</p> <p>9.2文件的打开与关闭256</p> <p>9.2.1用fopen函数打开文件256</p> <p>9.2.2用fclose函数关闭文件257</p> <p>9.3文件的顺序读写258</p> <p>9.3.1向文件读写一个字符258</p> <p>9.3.2向文件读写一个字符串260</p> <p>9.3.3对文件进行格式化读写263</p> <p>9.3.4按二进制方式对文件进行读写264</p> <p>9.4文件的随机读写264</p> <p>9.4.1文件位置标记的定位264</p> <p>9.4.2对文件进行随机读写266</p> <p>本章小结267</p> <p>习题269</p> <p>附录A常用字符与ASCII代码对照表270</p> <p>附录BC语言中的关键字271</p> <p>附录C运算符和结合性272</p> <p>附录DC语言常用语法提要275</p> <p>附录EC库函数280</p> <p>参考文献287</p>显示全部信息前 言
前言<br />前言<br />C语言是国内外广泛使用的一种计算机语言。学会使用C语言进行程序设计是计算机工作者的一项基本功。1991年,作者所著的《C程序设计》由清华大学出版社出版。该书出版后反映很好。许多读者说:“C语言原来是比较难学的,但自从《C程序设计》出版后,C语言变得不难学了”。该书被全国大多数高校选为正式教材,并被许多高校指定为研究生入学考试必读教材。该书已成为国内读者学习C语言的主流用书。20多年来,该书已先后出了5版,重印120多次,累计发行1400多万册,位居国内外同类书之首。作者到全国各高校和各企事业单位访问时,许多在校师生和已毕业参加工作的人士都说他们学过这本书,印象很深,作者在内心深切地感受到广大读者的殷切期望。各校师生普遍认为该书内容系统,讲解详尽,包含了许多其他教材中没有的内容,尤其是针对编程实践中容易出现的问题作了提醒和分析,被认为是学习C语言程序设计的理想教材。同时有的学校提出,由于各校情况不完全相同(例如,学校的类型不同、教学要求不同、安排的学时数不同、学生的基础不同),希望在保持原有的优点的基础上,能提供适用于不同要求的版本。作者和出版社征求了多方面的意见,进行了反复的研究,除了继续出版和完善《C程序设计》以外,还针对学时较少的学校,于2007年出版了《C程序设计教程》。该教材以《C程序设计》为基础,紧扣*基本的要求,适当减少内容,压缩篇幅,突出**。出版后受到广泛欢迎,认为内容适当,概念清晰,被教育部评为普通高等教育“十一五”**级规划教材,向全国各高校**。经过几年的教学实践,作者于2013年对《C程序设计教程》一书进行了修订。现在又进行一次修订,在修订的过程中,作者思考了以下几个方面的问题。1. 程序设计课程的作用与要求近年来,在讨论C程序设计课程改革时,有的老师主张要学深学透;有的认为不能要求太高,主要是打好基础;有的认为有一些了解、初识即可;有的则认为大学生毕业后由自己编程序的机会不多,因此可不必学,课程可以取消。这些引起人们深入思考:大学生要不要上程序设计课程?程序设计课程的目的和作用是什么?学习程序设计课程的要求是什么?程序设计课程的内容应该是什么?作者认为,学习程序设计能够使大学生更好地理解计算机和应用计算机。计算机的本质是“程序的机器”,程序和指令的思想是计算机系统中*基本的概念。只有懂得程序设计,懂得计算机是怎样工作的,才能较好地懂得计算机。通过学习程序设计,能使学生学习到用计算机处理问题的方法,培养学生提出问题、分析问题和解决问题的能力,并且具有编制程序的初步能力,能较好地应用计算机。即使将来不是计算机专业人员,由于学过程序设计,了解软件的特点和生产过程,也能与程序开发人员更好地沟通与合作,开展本领域中的计算机应用,开发与本领域有关的应用程序。对我国所有理工类学生都开设程序设计课程,并且把它作为进一步学习与应用计算机的基础,是十分必要的。2. 要不要学习C语言进行程序设计,必须用计算机语言作为工具,否则只是纸上谈兵。可供选择的语言很多,各有特点。C语言是基础而实用的语言,并不是每一种语言都具有此特点,有的语言实用,但不能作为基础语言(如FORTRAN),有的语言可以作为基础,但实际应用不多(如Pascal)。C语言功能丰富、表达能力强、使用灵活方便、应用面广、目标程序效率高、可移植性好,既具有**语言的优点,又具有低级语言的许多特点;既适于编写系统软件,又能方便地用来编写应用软件。C语言是多年来国内外使用*广泛的语言,国内外许多专家认为,C语言是*基本的通用语言,有了C语言的基础后,掌握任何一种语言都不困难。C语言被认为是计算机专业人员的基本功。有人认为有了C 语言以后,C语言就过时了,这是一种误解。C 语言是为设计大型程序应运而生的。将来从事系统开发的人员以及计算机专业学生需要学习C 语言或其他面向对象的语言。面向对象编程使用的是复杂的类层次结构与对象,适于处理大型的模块程序,但是在某些情况下并不比C语言程序更为有效。C语言作为传统的面向过程的程序设计语言,更适于解决某些小型程序的编程。在编写底层的设备驱动程序和内嵌应用程序时,往往是更好的选择。对复杂的问题,面向对象方法符合人们的思维方式。对简单的问题,面向过程方法符合人们的思维方式,而面向过程是*基本的。对初学者来说,学习C语言显然比学习C 语言容易得多,许多学校把C语言作为大学生的**门计算机语言,是比较合适的。有了C语言的基础,学习C 语言也是很容易的。目前,如果有些非计算机专业学生学习C 语言,其作用应当是了解面向对象的程序设计方法,为以后需要时进一步学习打下初步基础,要求不宜太高。本书选择C语言为学习程序设计使用的语言。3. 程序设计课程的性质和体系,正确处理算法与语法的关系关于C程序设计课程的性质,应该说,它既有基础的性质(了解计算机处理问题的方式,学习算法),又有应用和工具的性质(掌握语言工具,具有编程的初步能力,能具体应用),二者兼顾。因此,既要注意讲清概念,使学生建立正确的概念,又要培养学生实际处理问题的能力。程序设计有4个要素: ①算法——程序的灵魂; ②数据结构——加工的对象; ③语言——编程工具(算法要通过语言来实现); ④合适的程序设计方法。程序设计教学是否成功取决于能否将以上4个要素紧密结合。本教材自始至终把这四方面自然、有机地结合,全面兼顾。不是孤立地介绍语法,也不是全面系统地介绍算法。本书不是根据语言规则的分类和顺序作为教学和教材的章节和顺序,而是从应用的角度出发,以编程为目的和主线,由浅入深地介绍怎样用C语言处理问题。把算法和语法紧密结合,同步展开,步步深入。精心安排顺序,算法的选择由易到难,细心选择例子,使读者容易学习。在此基础上,构造了新的教学和教材体系。具体的做法是:在每一章中,首先举几个简单的例子,引入新的问题,接着介绍怎样利用C语言解决简单的问题,然后再循序渐进地介绍较深入的算法和程序。使学生在富有创意、引人入胜的编程中,学会算法,掌握语法,领悟程序设计的思想和方法,把枯燥无味的语法规则变成生动活泼的编程应用。多年的实践表明,这种做法是成功的。 建议教师在讲授时,以程序为**展开,着重讲清解题思路以及怎样用程序实现它,不要孤立介绍语法规定,教材中叙述的语法规定可以在介绍编写程序的过程中加以说明,或在简单介绍后请学生自己阅读,并通过上机实践掌握。4. 在程序设计课程中注意培养科学思维学习程序设计的一个重要作用是可以培养学生的科学思维能力。近年来,国内外有些专家提出要重视和研究计算思维,认为计算思维是运用计算机科学的基础概念进行问题求解、系统设计和理解人类行为的思维活动。计算思维是科学思维的组成部分。人们在学习和应用过程中已经认识到:计算机不仅是工具,而且是可以启发人们思考问题的科学方法。通过学习和应用计算机,人们改变了旧的思维方式和工作方式,逐步培养了现代的科学思维方式和工作方式,懂得现代社会处理问题的科学方法,这个意义比掌握工具更为深远。计算思维是信息时代中的每个人都应当具备的一种思维方式,要让思维具有计算的特征。计算机不仅为不同专业提供了解决专业问题的有效方法和手段,而且提供了一种独特的处理问题的思维方式。把计算机处理问题的方法和技术用于各有关领域,有助于提升各个领域的科学水平,开拓新的领域。积极在计算机的教学中引入跨学科元素,启迪跨学科计算思维,会对各个学科的发展产生深远的影响。 计算思维不是悬空的抽象概念,是体现在各个环节中的。算法思维就是典型的计算思维。学习程序设计就是培养计算思维的有效途径。计算思维的培养不是孤立进行的,不是依靠另开专门课程讲授的,而是在学习和应用计算机的过程中培养的。多年来,人们在学习和应用计算机过程中不断学习和培养了计算思维,正如学习数学培养了理论思维,学习物理培养了实证思维一样。对计算机的学习和应用越深入,对计算思维的认识也越深刻。 培养计算思维不是目的,正如学习哲学不是目的一样。学哲学的目的是认识世界、改造世界。培养计算思维的目的是更好地应用计算技术,推动社会各领域的发展与提高。要正确处理好培养计算思维与计算机应用的关系。 程序设计的各个环节都体现了计算思维。没有必要去声明或争论:这个问题是计算思维,那个问题属于其他什么思维。属于计算思维的就重视,否则就不重视,这是书生气十足的做法。只要有利于培养大学生科学思维,都应当大力提倡,大学生需要培养多种思维的能力。本教材注意在教学过程中努力培养学生的科学思维(包括计算思维)。在介绍每一个问题时,都采取以下步骤:提出问题→解题思路→编写程序→运行结果→程序分析→有关说明。在“解题思路”中,分析问题,介绍算法,建立数学模型。使读者首先把注意力放在处理问题的思路和方法上,而不是放在语法细节上。在确定算法之后,再使用C语言编��程序就顺理成章了。在“程序分析”中,再进一步分析程序的思路及其实现方法。这样,思路清晰,逻辑性强,有利于形成科学的思维方法。希望读者不仅要注重学习知识,更要注重学习方法,掌握规律,举一反三。5. 从实际出发,区别对待学习程序设计的人群中,有的是计算机专业学生,有的是非计算机专业的学生;有的是本科生,有的是专科(高职)学生;有的是**大学的学生,有的是一般大学的学生。情况各异,要求不同,必须从实际出发,制订切实可行的教学方案,对象不同,要求也应不同,并非越多越深越好。切忌脱离实际的一刀切。例如,对计算机专业学生,应有较高的要求,应作为基本功来要求。尤其是对算法的要求应当高一些,需要较系统学习各种算法,不仅会用现成的算法,还应当会设计一般的算法:熟练掌握语言工具;了解软件开发的方法和规范;掌握程序设计的全过程;具有一定的编程实践经验;能够举一反三,掌握几种计算机语言。*好能在学完本课程后独立完成一个有一定规模的程序。对一般大学非计算机专业的学生,多数人将来工作中不一定要求用C语言编程,本课程的目的不是培养熟练的程序员。学习程序设计的目的是学习计算机处理问题的方法,具有一定的编程知识和应用能力。对非计算机专业的学生,对算法的要求不能太高。算法选择典型的、难度不太大的,只要求掌握基本的算法和设计算法的思路,为以后进一步学习和应用打下基础。没有必要把语言的每一个细节都学透,而是围绕程序设计,使用语言工具中基本的、常用的部分,对初学者不常用的部分可暂时不学。有些部分概念很重要,但难度较大,初学时用得不多,但以后会用到,可作简单介绍,打下基础。在非计算机专业中不宜提“学深学透”的要求。要求是相对的,一切以实际条件为转移。对高职学生的要求应不同于本科生,更不应搬用**大学的做法,不宜在算法上要求太高,因为高职不是培养设计算法的人才的,而应培养切实掌握语言工具,具有较强的动手和实践能力,例如编码能力、调试能力。对基础较好、学生程度较高的学校,可以采取少讲多练,强调自学,有的内容课堂上可以不讲或少讲,指定学生自学。引导学生通过自学和实践掌握知识,尽可能完成一些难度较高的习题。全国各校的情况不同,学生的基础和学习要求也不尽相同,不可能都采用同一本教材。教材应当服务于教学,满足多层次多样化的要求。许多学校的老师认为《C程序设计》是一本经过长期教学实践检验的**教材,其内容与风格已为广大师生所熟悉,希望在《C程序设计》的基础上组织不同层次的教材,供不同对象选用。作者与清华大学出版社决定出版C程序设计的系列教材,目前已出版的有以下3种:(1) 《C程序设计(第五版)》。该书系统全面,内容深入,讲授详尽,包含了许多其他教材中没有的内容,尤其是针对编程实践中容易出现的问题作了提醒和分析,是学习C语言程序设计的理想教材。适合程度较高、基础较好的学校和读者使用。(2) 《C程序设计教程(第3版)》,即本书。它是在《C程序设计(第五版)》的基础上改编的,适当减少内容,突出**,紧扣*基本的要求,适合学时相对较少的广大高校使用。本书为普通高等教育**级规划教材,**给各校使用。(3) 《C语言程序设计(第3版)》。内容更加精练,要求适当降低,适合程度较好的高职院校使用。该书亦为普通高等教育**级规划教材和**级精品教材。6. 本次修订版的特点在本次修订中保持了本书概念清晰、通俗易懂的特点,体现了以下特点:(1) 按照C99标准进行介绍,以适应C语言的发展,使编写程序更加规范。例如:① 数据类型介绍中,增加了C99扩充的双长整型(long long int)、复数浮点型(float_complex,double_complex,long long _complex)、布尔型(bool)等,使读者有所了解。② 根据C99的建议,main函数的类型一律指定为int型,并在函数的末尾加返回语句“return 0;”。③ C99增加了注释行的新形式——以双斜线“//”开始的内容作为注释行,这本来是C 的注释行形式,现在C99把它扩充进来了,使编程更加方便。同时保留了原来的“/ …… /”形式,以使原来按C89标准编写的程序不加修改仍可使用。本书采用C99的注释新形式,读者使用更方便,而且符合发展需要。因此,本书的程序基本上采用下面的形式:return 0; //如函数正常执行,返回整数0}④ C99增加的其他一些具体内容,会在书中有关章节中专门注明,以提醒读者。由于C99是在C89的基础上增加或扩充一些功能而成的,因此C89和C99基本上是兼容的。过去用C89编写的程序在C99环境下仍然可以运行。C99所增加的许多新的功能和规则,是在编制比较复杂的程序时为方便使用和提**率而用的,在初学时可以不涉及,因此本书对目前暂时用不到的内容不作介绍,以免读者分心,增加学习难度。在将来进行深入编程时再逐步了解和学习。(2) 加强算法,强化解题思路。在各章中由浅入深地结合例题介绍各种典型的算法。对穷举、递推、迭代、递归、排序(包括比较交换法、选择法、起泡法)、矩阵运算、字符处理应用等算法作了详尽的介绍,对难度较大的链表处理算法的思路作了清晰说明,使读者逐步建立算法思维。介绍例题时,在给出问题后,先是进行问题分析,探讨解题思路,构造算法,然后才根据算法编写程序,而不是先列出程序再解释程序,从中了解算法。这样做,更符合读者认知规律,更容易理解算法,有利于培养计算思维。引导读者在看到题目后,先考虑算法再编程,而不是坐下来就写程序,以培养好的习惯。(3) 对指针作了更明确详尽的说明。指针是学习C语言的**,也是难点。不少读者反映难以掌握指针的实质和应用。作者在《C程序设计》和本书中,明确指出了“指针就是地址”,许多读者反映这是“画龙点睛,点出了问题的实质”,觉得一通百通,许多问题迎刃而解了。许多学校的师生反映,原来在学习指针时感到特别难懂,后来看了《C程序设计》后豁然开朗了。希望作者保持这一正确做法,并能对指针再作更详尽的说明。作者根据各校教学中的情况和一些师生提出的问题,在本次修订中对指针的性质作了进一步说明,指出: 我们所说的指针就是地址,这个地址不仅是在内存中的位置信息(即纯地址),而且包括在该存储单元中的数据的类型信息,并对此作了有力而明确的说明,使读者对指针的性质有进一步的认识。请读者阅读本书时加以注意。(4) 更加通俗易懂,容易学习。作者充分考虑到广大初学者的情况,精心设计体系,适当降低门槛,便于读者入门。尽量少用深奥难懂的专业术语,用通俗易懂的方法和语言阐述清楚复杂的概念,使复杂的问题简单化。没有学过计算机原理和高等数学的读者完全可以掌握本书的内容。本书采用作者提出的“提出问题→解决问题→归纳分析”的新的教学三部曲,先具体后抽象,先实际后理论,先个别后一般,而不是先抽象后具体,先理论后实际,先一般后个别。实践证明这样做符合读者的认知规律,读者很容易理解。在介绍每个例题时,都采取以下的步骤: 给出问题→解题思路→编写程序→运行结果→程序分析→有关说明,对一些典型的算法,还有算法分析,使读者更好理解。把算法与语言二者紧密而自然地结合,而且通过运行程序,看到结果,便于验证算法的正确性。学习时不会觉得抽象,而会觉得算法具体有趣,看得见,摸得着。本书便于自学。具有高中以上文化水平的人,即使没有教师讲解,也能基本上掌握本书的内容。这样就有可能做到:教师少讲,提倡自学,上机实践。考虑到教学的基本要求,本书适当降低难度,对以下几个问题进行了适当处理:① 简化输入输出格式。C语言的输入输出格式比较烦琐复杂,初学者往往感到难以掌握。本次修订时,只介绍*基本的格式(%d,%f,%e,%c,%s),能够进行输入输出就行,其他附表供查用。② 在函数一章中,简化一些初学者不常用的内容,如“内部函数和外部函数”,对存储类别的介绍也从简。③ 指针一章主要介绍一级指针,关于二级指针只介绍有关二维数组的内容。对“指向函数的指针”“返回指针值的函数”“指针数组和多重指针”“动态内存分配与指向它的指针变量”等较深入而初学者用得不多的内容不再介绍。④ 只介绍结构体,不介绍共用体。⑤ 链表处理(链表的建立、插入、删除和输出等)的内容,对于非计算机专业学生来说难度较大,且不必要,因此精简了。只对链表做很简单的介绍,有一定了解即可。⑥ 文件只作简单介绍,有初步概念即可。⑦ 由于许多学校把C语言的教学安排在一年级,而学生还未学完高等数学,因此本书不包括有关高等数学知识的例题。考虑到有部分读者在学习高等数学后可能对这方面的内容感兴趣,在习题部分列出有关的题目(如用二分法和牛顿迭代法求一元方程的根),并在《C程序设计教程(第3版)学习辅导》中给出介绍和程序,可供自学参考。⑧ 在各章节标题前加“”号的,是比较深入的内容,在教学时可以不讲,由学生自学参考。 相信经过修改后,本书会更加容易学习,读者的基本功会更扎实,效果会更好。7. 作者的心中永远要装着读者作者从1978年开始从事计算机基础教育和计算机普及工作,40年来一直奋斗在这个平凡而重要的岗位上,把自己的后半生贡献给了我国的计算机教育和计算机普及事业,对这个事业有着深厚的感情和深切的体会。我*大的愿望是“把计算机从少数计算机专家手中解放出来,成为广大群众手中的工具”,使广大群众轻松愉快、兴趣盎然地进入计算机的天地。经过40年的努力,这个愿望正在变成现实。我始终认为,作者心中要永远装着读者,处处为读者着想,和读者将心比心,善于换位思考。我在编写教材时,常常反问自己:“读者读到这里时会提出什么问题?”“怎样讲才能使读者更容易明白?”我常常用这样一句话来鞭策自己:“只有明白不明白的人为什么不明白的人才是明白人。” 写书不仅是简单地把有关的技术内容告诉读者,而且要考虑怎样写才能使读者容易理解。我写书,有一半的时间用来研究和处理技术方面的问题,还有一半时间用来考虑怎样讲才能使学生易于理解。有时为了找到一个好的例子或一个通俗的比喻,往往苦苦思索好几天,每一句话都要反复斟酌推敲。要善于把复杂问题简单化,而不能把简单问题复杂化。写一本书容易,写一本好书不容易,能讲一堂课很容易,要讲好一堂课并不容易,需要下很大的功夫。这就要求我们(作者和老师)要深入了解自己工作的对象,有的放矢,准确定位;要根据应用的需要,合理取舍,精选内容;要认真研究学习者的认识规律,采用他们容易理解的方法,深入浅出,通俗易懂。清华大学一位已故的院士说得好: “什么叫水平高?只有能用通俗易懂的方法和语言阐述清楚复杂概念的人,才是水平高。那些把概念搬来搬去的人,不能算水平高。”多年来,在广大师生的关心和支持下,我努力去做了,取得一些成绩。有人称我是计算机界的“平民作家”。我乐于接受并很珍惜群众送给我的这一称谓,这是对我的莫大鞭策。希望所有的教师和作者共同努力,把每一本书、每一门课程都做成精品,得到千万学生和读者的肯定和赞扬,这才是对我们辛劳的*高奖赏。为了帮助读者学习本书,作者还编写了一本《C程序设计教程(第3版)学习辅导》,提供本书中各章习题的参考答案以及上机实践指导。该书由清华大学出版社于2018年出版。南京大学金莹副教授、薜淑斌**工程师和谭亦峰工程师参加了本书的策划、调研、收集资料、研讨以及编写部分程序的工作。由于作者水平有限,本书肯定会有不少缺点和不足,热切期望得到专家和读者的批评和指正。<br />谭浩强谨识 2018年3月于清华园<br />显示全部信息免费在线读第3章选择结构程序设计接标题2接正文在顺序结构中,各语句是按排列的先后次序顺序执行的,是无条件的,不必事先作任何判断。但在实际中,常常有这样的情况: 要根据某个条件是否成立决定是否执行指定的任务。例如: 如果你在家,我去拜访你;(需要判断你是否在家) 如果考试不及格,要补考; (需要判断是否及格) **我们去郊游; (需要判断是否是**) 如果a b,输出a。 (需要判断a是否大于b)判断的结果应该是一个逻辑值: “是”或“否”,在计算机语言中用“真”和“假”表示。例如,当a b时,满足“a b”条件,就称条件“a b”为真,如果a≤b,不满足“a b”条件,就称条件“a b”为假。由于程序需要处理的问题往往比较复杂,因此,在大多数程序中都会包含条件判断。选择结构就是根据指定的条件是否满足,决定执行不同的操作(从给定的两组操作中选择其一)。3.1简单的选择结构程序先通过以下几个程序,初步了解怎样在C语言程序中用选择结构处理问题。【例3.1】输入两个实数,按代数值由小到大的顺序输出这两个数。解题思路: 有两个变量a和b,若a≤b,则两个变量的值不必改变,若a b,则把a和b的值互换,然后顺序输出a和b,即可实现题目要求。因此此题的算法是: 做一次比较,然后决定是否进行值的交换。关于两个变量互换值的方法,已在例2.8中介绍了。类似这样简单的问题可以不必先写出算法或画流程图,而直接编写程序。或者说,算法在编程者的脑子里,相当于在算术运算中对简单的问题可以“心算”而不必在纸上写出来一样。编写程序: #include stdio.h int main() {float a,b,temp; printf("please enter a and b: "); scanf("%f,%f", a, b); if(a b) {temp=a;a=b;b=temp;} printf("%7.2f,%7.2f\\n",a,b); return 0;}运行结果: please enter a and b: 3.6,-3.2↙-3.20,3.60【例3.2】输入a,b,c三个数,要求按由小到大的顺序输出。解此题的算法比上一题稍复杂一些。现在先用伪代码写出算法: beginif a b 将a和b对换(a是a,b中的小者)if a c 将a和c对换 (a是a,c中的小者,因此a是三者中*小者)if b c 将b和c对换 (b是b,c中的小者,也是三者中次小者)输出a,b,c的值end编写程序: 按以上算法编写程序。 #include stdio.h int main () { float a,b,c,temp; printf("please enter a,b,c: "); scanf("%f,%f,%f", a, b, c); if(a b) {temp=a;a=b;b=temp;}//实现a和b的互换 if(a c) {temp=a;a=c;c=temp;} //实现a和c的互换 if(b c) {temp=b;b=c;c=temp;} //实现b和c的互换 printf("%7.2f,%7.2f,%7.2f\\n",a,b,c); return 0; }运行结果: please enter a,b,c: 33.52,-27.65,100.45↙ -27.65, 33.52, 100.453.2选择结构中的关系运算第3.1节的程序中,在if语句括号中给出一个需要判别的条件,例如a b,a c,b c。这些“条件”在程序中是用一个表达式来表示的。类似这种表示判别条件的表达式还有: a b cbb-4ac 0'a' 'v'这种式子显然不是数值表达式,它包括了“ ”和“ ”这样的比较符号,这些式子的值并不是一个普通的数值,而是一个逻辑值(“真”或“假”)。例如,问对方: “你是中国人吗?”回答只有两个: “是”或“不是”,而不能回答: “3”或“4”。用来进行比较的符号称为关系运算符(或比较运算符,它用来比较运算符两侧的数据),上面这些表达式称为关系表达式。3.2.1关系运算符及其优先次序C语言提供6种关系运算符: ① (小于)② = (小于或等于)③ (大于)④ = (大于或等于)优先级相同(高)⑤ == (等于)⑥ != (不等于)优先级相同(低) 关于优先次序的说明: (1) 前4种关系运算符( , =, , =)的优先级别相同,后2种也相同。前4种高于后2种。例如,“ ”优先于“==”,而“ ”与“ ”优先级相同。图3.1(2) 关系运算符的优先级低于算术运算符。(3) 关系运算符的优先级高于赋值运算符。以上关系见图3.1。例如: c a b等效于c (a b)a b==c 等效于 (a b)==ca==b c 等效于 a==(b c)a=b c 等效于 a=(b c)3.2.2关系表达式用关系运算符将两个表达式(可以是算术表达式或关系表达式、逻辑表达式、赋值表达式、字符表达式)连接起来的式子,称关系表达式。例如,下面都是合法的关系表达式: a b b c(a=3) (b=5)'a' 'z'(a b) (b c)前面已说明,条件判断的结果是一个逻辑值(“真”或“假”)。同理,关系表达式的值也是一个逻辑值。例如,关系表达式“5==3”的值为“假”,“5 0”的值为“真”。在C99之前,C语言没有逻辑型数据(C 有逻辑变量和逻辑型常量,以True表示“真”,以False表示“假”)。在C的关系运算中,以“1”代表“真”,以“0”代表“假”。例如,当a=3,b=2,c=1时,则: 关系表达式“a b”的值为“真”,表达式的值为1。 关系表达式“(a b)==c”的值为“真”(因为a b的值为1,等于c的值),表达式的值为1。 关系表达式“b c a”的值为“假”,表达式的值为0。说明: 从本质上来说,关系运算的结果(即关系表达式的值)不是数值,而是逻辑值,但是由于C语言追求精练灵活,没有提供逻辑型数据(其他**语言如Pascal,FORTRAN,C 都允许定义和使用逻辑型数据,C99也增加了逻辑型数据,用关键字bool定义逻辑型变量)。为了便于处理关系运算和逻辑运算的结果,C语言以1代表“真”,以0代表“假”,并在编译系统中按此实现(这种规定只是C语言的特殊处理方法,不要误认为是所有计算机语言的普遍规则)。用C语言的人要注意这样的规定。由于用了1和0代表真和假,而1和0又是数值,所以在C程序中还允许把关系运算的结果(即1和0)看作和其他数值型数据一样,可以参加数值运算,或把它赋值给数值型变量。例如,若a,b,c的值为3,2,1。请分析下面的赋值表达式: d=a bd的值为1f=a b c f的值为0(因为" "运算符是自左至右的结合方向,先执行a b,得值为1, 再执行关系运算1 c,得值0,赋给f)这是C的灵活性的一种表现,允许把关系表达式作为一般数值来处理,对有经验的人,可以利用它实现一些技巧,使程序精练专业,但是对初学者来说,可能会不好理解,容易弄错。在学习阶段,还是应当强调程序的清晰易读,不要写出别人不懂的程序。3.3选择结构中的逻辑运算有时需要判断的条件不是一个简单的条件,而是一个复合的条件,如: 是中国公民,且在18岁以上才有选举权。这就要求同时满足两个条件: 中国公民和大于18岁。 5门课都及格,才能升级。这就要求同时满足5个条件。 70岁以上的老人和10岁以下儿童,入公园免票。这就要对入园者检查两个条件,即age 70或age 10,必须满足其中之一。以上问题仅用一个关系表达式是无法表示的,需要用一个逻辑运算符把两个关系表达式组合在一起才能处理。在BASIC和Pascal语言用AND,OR和NOT作为逻辑运算符,分别代表逻辑运算符“与”“或”“非”。例如: (a b) AND (x y)其中的AND是逻辑运算符,代表“与”,即运算符两侧的关系表达式(或其他逻辑量)的值都为“真”(二者的条件都满足)。上面表达式意思是: “a b”与“x y”两个条件都同时满足。如果已知a b和x y,则上面的表达式的值为“真”。3.3.1逻辑运算符及其优先次序在C语言中不直接用AND,OR和NOT作为逻辑运算符,而用其他符号代替。见表3.1。表3.1C语言逻辑运算符及其含义运算符含义举例说明 逻辑与a b 如果a和b都为真,则结果为真,否则为假‖逻辑或a‖b如果a和b有一个或一个以上为真,则结果为真,二者都为假时,结果为假!逻辑非!a如果a为假,则!a为真,如果a为真,则!a为假“ ”和“‖”是双目(元)运算符,它要求有两个运算对象(操作数),如(a b) (x y)和(a b)‖(x y)。“!”是一目(元)运算符,只要求有一个运算对象,如!(a b)。表3.2为逻辑运算的“真值表”。用它表示当a和b的值为不同组合时,各种逻辑运算得到的值。表3.2逻辑运算的真值表ab!a!ba ba‖b 真真假假真真真假假真假真假真真假假真假假真真假假怎样看这个表呢?以表中第2行为例,当a为真,b为假时,!a为假,!b为真,a b为假,a‖b为真。这是很简单的,也是*基本的。图3.2如果在一个逻辑表达式中包含多个逻辑运算符,如: !a b‖x y c。怎样确定它的运算次序呢?C规定按以下的优先次序: (1) !(非)→ (与)→‖(或),即“!”为三者中*高的。(2) 逻辑运算符中的“ ”和“‖”低于关系运算符,“!”高于算术运算符,见图3.2。例如: (a b) (x y)可写成a b x y(a==b)‖(x==y)可写成a==b‖x==y(!a)‖(a b)可写成!a‖a b3.3.2逻辑表达式用逻辑运算符将关系表达式或逻辑量连接起来的式子就是逻辑表达式。逻辑表达式的值是一个逻辑量“真”或“假”。前已说明: C语言编译系统在表示逻辑运算结果时,以数值1代表“真”,以0代表“假”。但是在判断一个逻辑量是否为“真”时,测定它的值是0还是非0,如果是0就代表它为“假”,如果是非0则认为它是“真”。因为逻辑量只有两种可能值,所以把被测定的对象划分为两种情况(0和非0),以便于处理。例如: (1) 若a=4,则!a的值为0。因为a的值为非0,被认作“真”,对它进行“非”运算,得“假”,“假”以0代表。(2) 若a=4,b=5,则a b的值为1。因为a和b均为非0,被认为是“真”,因此a b的值也为“真”,值为1。(3) a,b的值分别为4和5,则a‖b的值为1。因为a和b均为非0,即“真”。(4) a,b的值分别为4,5, 则!a‖b的值为1。因为!a为“假”,而b为“真”。(5) 4 0‖2的值为1。因为4 0为“假”而2为非0,故进行“或”运算结果为“真”。通过这几个例子可以看出,由系统给出的逻辑运算结果不是0就是1,不可能是其他数值。而在逻辑表达式中作为参加逻辑运算的运算对象(操作数)可以是0(“假”)或任何非0的数值(按“真”对待)。如果在一个表达式中不同位置上出现数值,应区分哪些是作为数值运算或关系运算的对象,哪些作为逻辑运算的对象。例如: 5 3 8 4-!0表达式自左至右扫描求解。首先处理“5 3”(因为关系运算符优先于逻辑运算符“ ”)。在关系运算符两侧的5和3作为数值参加关系运算,“5 3”的值为1(代表真)。再进行“1 8 4-!0”的运算,8的左侧为“ ”,右侧为“ ”运算符,根据优先规则,应先进行“ ”的运算,即先进行8 4-!0的运算。而4的左侧为“ ”,右侧为“-”运算符,而“-”优先于“ ”,因此应先进行“4-!0”的运算,由于“!”的级别*高,因此先进行“!0”的运算,得到结果1。然后进行“4-1”的运算,得到结果3,再进行“8 3”的运算,得0,*后进行“1 0”的运算,得0。实际上,逻辑运算符两侧的运算对象不但可以是0和1,或者是0和非0的整数,也可以是字符型、实型或指针型等数据。系统*终以0和非0来判定它们属于“真”或“假”。例如: 'c' 'd'的值为1(因为'c'和'd'的ASCII值都不为0,按“真”处理),所以1 1的值为1。可以将表3.2改写成表3.3的形式。表3.3逻辑运算的真值表ab!a!ba ba‖b非0非00011非000101假非01001假01100说明: 在计算机对逻辑表达式的求解中,并不是所有的逻辑运算符都被执行,只是在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符。例如: (1) a b c。只有a为真(非0)时,才需要判别b的值,只有a和b都为真的情况下才需要判别c的值。只要a为假,就不必判别b和c(此时整个表达式已确定为假)。如果a为真,b为假,不判别c,见图3.3。(2) a‖b‖c。只要a为真(非0),就不必判断b和c。只有a为假,才判别b。a和b都为假才判别c,见图3.4。图3.3图3.4也就是说,对 运算符来说,只有a≠0,才继续进行右面的运算。对‖运算符来说,只有a等于0,才继续进行其右面的运算。因此,如果有下面的逻辑表达式: (m=a b) (n=c d)当a=1,b=2,c=3,d=4,m和n的原值为1时,由于“a b”的值为0,因此m=0,而“n=c d”不被执行,因此n的值不是0而仍保持原值1。这点请读者注意。 熟练掌握C语言的关系运算符和逻辑运算符后,可以巧妙地用一个逻辑表达式来表示一个复杂的条件。 例如,要判别用year表示的某一年是否是闰年。闰年的条件是符合下面二者之一: ①能被4整除,但不能被100整除,如2016。②能被4整除,又能被400整除,如2000(注意,能被100整除,不能被400整除的年份不是闰年,如2100)。可以用一个逻辑表达式来表示: (year %4==0 year %100 !=0)||year %400==0当year为某一整数值时,如果上述表达式值为真(1),则year为闰年;否则year为非闰年。可以加一个“!”用来判别非闰年: !((year %4==0 year %100 !=0)||year %400==0)若此表达式值为真(1),year为非闰年。也可以用下面逻辑表达式判别非闰年: (year %4 !=0)||(year %100==0 year %400!=0)若表达式值为真,year为非闰年。请注意表达式中右边的一对括号内的不同运算符(%,!=, ,==)的运算优先次序。3.4用if语句实现选择结构 有了以上的基础,就可以顺利地利用选择结构进行编程了。在C语言中,可以用不同的方法实现选择结构(包括if语句、条件表达式、switch语句等),其中if语句是*基本的,用得*多。本节先介绍if语句。在if语句中包含一个逻辑表达式,用它判定所给定的条件是否满足,并根据判定的结果(真或假)决定选择执行哪一种操作(在if语句中给出两种可能的选择)。3.4.1if语句的三种形式 C语言提供了三种形式的if语句供用户选用。1. if(表达式) 语句例如: if(x y) printf("%d\\n",x);这种if语句的执行过程见图3.5(a)。图3.52. if(表达式)语句1 else语句2例如: if (x y)printf("%d\\n",x);elseprintf("%d\\n",y); 这种if语句的执行过程见图3.5(b)。3. if (表达式1)语句1else if(表达式2) 语句2else if(表达式3) 语句3else if(表达式m) 语句melse语句n流程图见图3.6。图3.6例如: if (number 500) cost=0.15;else if (number 300) cost=0.10;else if (number 100) cost=0.075;else if (number 50) cost=0.05;else cost=0;说明: (1) 3种形式的if语句中在if后面都有“表达式”,一般为逻辑表达式或关系表达式。例如: if(number 300 number =500) cost=0.10;在执行if语句时先对括号中的表达式求解,若表达式的值为0,按“假”处理,若表达式的值为非0,按“真”处理,执行指定的语句。假如有以下if语句: if(3) printf("OK");是合法的,执行结果输出“OK”,因为表达式的值为3,按“真”处理。由此可见,表达式的类型不限于逻辑表达式,可以是任意的数值类型(包括整型、实型、字符型、指针型数据等)。下面的if语句也是合法的: if('a') printf("%d",'a'); 执行时输出'a'的ASCII码97。(2) if语句中有内嵌语句,每个内嵌语句都要以分号结束。例如: if (x 0)print ("%f\\n",x);elseprintf("%f\\n",-x); 行末各有一个分号(;)分号是C语句中不可缺少的部分,即使是if语句中的内嵌语句也不能例外。如果无此分号,则出现语法错误。读者可以上机试验一下。(3) 不要误认为上面是两个语句(一个if语句和一个else语句)。它们都是属于同一个if语句。else子句不能作为独立语句单独使用,它只能是if语句的一部分,与if配对使用。(4) 在if和else后面可以只含一个内嵌的操作语句(如上例),也可以有多个操作语句,但应当用花括号“{}”将几个语句括起来成为一个复合语句。例如: if (a b c b c a c a b){s=0.5(a b c);area=sqrt(s(s-a)(s-b)(s-c));printf("area=%6.2f",area);}else printf("it is not a trilateral");注意在else上面一行的右花括号“}”外面不需要再加分号。因为{}内是一个完整的复合语句,不需另附加分号。3.4.2if语句的嵌套在if语句中又包含一个或多个if语句称为if语句的嵌套。一般形式如下: if()if() 语句1else 语句2内嵌ifelseif() 语句3else 语句4内嵌if应当注意if与else的配对关系。else总是与它上面的*近的未配对的if配对。假如写成: if()if()语句1elseif() 语句2else 语句3 内嵌if编程序者把**个else写在与**个if(外层if)同一列上,希望**个else与**个if对应,但实际上**个else是与第二个if配对的,因为它们相距*近。写成这样的锯齿形式并不能改变if语句的执行规则。这个if语句实际的配对关系表示如下: if()if()语句1elseif() 语句2else 语句3 内嵌if因此*好使外层if和内嵌if都包含else部分(如3.4.2节*早列出的形式),即: if()if()语句1elseif() 语句2else 语句3else语句4这样if的数目和else的数目相同,从内层到外层一一对应,不致出错。如果if与else的数目不一样,为实现程序设计者的企图,可以加花括号来确定配对关系。例如: if (){ if () 语句1} //内嵌ifelse 语句2 这时“{ }”限定了内嵌if语句的范围, { }内是一个完整的if语句。因此else与**个if配对。通过下面的例子可以具体地了解如何正确地使用if的嵌套。【例3.3】有一函数: y=-1(x 0)0(x=0)1(x 0)编程序,要求输入一个x值后,输出y值。解题思路: 先用伪代码写出算法: 输入x若 x 0,则y=-1若 x=0,则y=0若 x 0,则y=1输出y图3.7或 输入x若 x 0,则y=-1 否则 若 x=0,则y=0若 x 0,则y=1输出y也可以用流程图表示,见图3.7。编写程序: 按照上面的算法,有人用C语言写出以下几个不同的程序,请读者分析哪个是正确的。程序1: #include stdio.h int main() { int x,y; printf("enter x: "); scanf("%d", x); if(x 0) y=-1; else if(x==0) y=0; else y=1; printf("x=%d,y=%d\\n",x,y); return 0;}程序2: 将程序1的if语句(第6~10行)改为 if(x =0) if(x 0) y=1; else y=0; else y=-1;程序3: 将上述if语句改为 y=-1; if(x!=0) if(x 0) y=1; else y=0;程序4: 将上述if语句改为 y=0; if(x =0) if(x 0) y=1; else y=-1; 图3.8读者可以分别画出程序1~程序4的流程图,便可以判断出: 只有程序1和程序2是正确的。图3.7是程序1的流程图,显然它是正确的。图3.8是程序2的流程图,它也能实现题目的要求。程序3的流程图见图3.9,程序4的流程图见图3.10,它们是不能实现题目要求的。请注意程序中的else与if的配对关系,例如程序3中的else子句是和它上一行的内嵌的if语句配对,而不与第2行的if语句配对。图3.9图3.10为了使逻辑关系清晰,避免出错,一般把内嵌的if语句放在外层的else子句中(如程序1那样),这样由于有外层的else相隔,内嵌的else不会被误认为和外层的if配对,而只能与内嵌的if配对,这样就不会搞混,如像程序3和程序4那样写就很容易出错。3.5用条件表达式实现选择结构有时,在if语句中,在被判别的条件为“真”或“假”时,都用一个赋值语句向同一个变量赋值,例如: if(a b)max=a;else max=b;当a b时将a的值赋给max,当a≤b时将b的值赋给max。可以看到无论a b是否满足,都是向同一个变量赋值。此时可以用条件表达式来处理,使程序更简练。 上面的if语句可以用以下的语句代替: max=(a b)?a:b;其中,赋值号“=”右侧的“(a b)?a: b”是一个“条件表达式”。它是这样执行的: 如果(a b)条件为真,则条件表达式的值为a;否则取值b。然后把此值赋给max变量。 条件表达式的一般形式为表达式1? 表达式2: 表达式3图3.11