新書推薦:
《
人民币国际化报告2024:可持续全球供应链体系与国际货币金融变革
》
售價:HK$
87.4
《
道德经新注 81幅作者亲绘哲理中国画,图文解读道德经
》
售價:HK$
143.4
《
清俗纪闻
》
售價:HK$
98.6
《
镜中的星期天
》
售價:HK$
76.2
《
世界前沿技术发展报告2024
》
售價:HK$
188.2
《
可转债——新手理财的极简工具
》
售價:HK$
65.0
《
新加坡教育:神话与现实
》
售價:HK$
96.3
《
“口袋中的世界史”第一辑·冷战中的危机事件
》
售價:HK$
291.2
|
編輯推薦: |
本书介绍的内容非常全面。不仅支持多种操作系统,而且所讲解的语法、程序设计方法、库函数和编程规范上非常全面的,具有指南和手册的特点。重点突出: 本书采用加黑加粗加框的方式突出核心重点部分内容,方便查找与阅读,并且提供了非常明显的注意事项、说明和小甜点等内容,加强记忆。编程规范: 本书的内容基于C语言国际标准,中文术语遵循国家标准,总结了众多公司的编程规范,并经过了多种操作系统以及不同版本VC平台的验证。简洁易懂: 采用简明的方式揭示相关概念的本质之处,通过翔实的例程展现C语言及其程序设计的特点和核心思想,从而在较短的时间内掌握较多的知识。
|
內容簡介: |
本书讲解C语言程序设计知识及其编程方法,包括C语言的基础语法、结构化程序设计、静态数组、动态数组、字符串、结构体、共用体、枚举、函数、指针、单向链表、双向链表、类型别名、预处理命令、文件处理、编程规范、程序测试、自动测试、常用库函数与宏定义等内容。本书的内容不仅可以用在微软公司的Windows系列操作系统及其VC平台,而且也适用于Linux和Unix系列操作系统。本书的内容与章节编排以读者学习与认知过程为基础,与公司的实际需求相匹配。内容力求简洁,每章都附有习题,而且在附录中包含图、表、例程以及函数、运算符和宏的页码索引,采用特殊字体突出中心词,包含有注意事项、说明和小甜点等内容,希望使读者在轻松阅读的过程中迅速了解与掌握C语言程序设计的知识和方法,并应用到实践中。本书内容丰富易学,而且提供了大量的例程,既可以作为计算机专业和非计算机专业的基础教材以及C语言相关考试的辅导教材,也可以作为需要使用C语言的工程人员和科技工作者的自学参考书。
|
關於作者: |
雍俊海从1991年9月到2000年9月就读于清华大学计算机系,分别获得学士、硕士和博士学位,同时辅修了应用数学专业。从2000年10月到2002年9月在美国肯塔基大学计算机系做博士后。现为清华大学软件学院教授、博导和学术委员会主任,计算机辅助设计、图形学与可视化研究所所长,全国计算机辅助设计与图形学专业委员会副主任,全国技术产品文件标准化技术委员会委员,国际期刊《Computers & Graphics》的Associate Editor,《软件学报》责任编委和《计算机辅助设计与图形学学报》编委。曾任IEEE形状造型国际会议程序委员会联合主席、CADGraphics 2013国际会议联合主席以及CADGraphics 2015国际会议程序委员会联合主席等。多年来一直坚持科研工作为我国国民经济服务的理念,提出了*几何Hermite曲线等曲线、曲面和实体表示、设计与编辑方案,设计并编写了大量代码,努力提升我国在计算机辅助设计、图形学和增强现实领域的科技水平及国际竞争力。负责的多项软件产品以及参与编写的多项国家标准已经在企业得到应用实施和推广。在《CAD》、《CAGD》、《ACM TOG》和《IEEE T PAMI》等国内外期刊与会议上发表160多篇学术论文。曾获全国杰青、全国优秀博士论文奖、国际Elsevier Outstanding Service Award、计算机动画国际会议*论文奖和教育部自然科学一等奖等荣誉。编写的教材《Java程序设计教程》入选*规划教材并获教育部普通高等教育精品教材和首届中国大学出版社图书奖一等奖等奖励。另外,还编写了生动有趣的个人科研科普专著《清华教授的小课堂:魔方真好玩》,减少了复原魔方所需的转动次数。
|
目錄:
|
第1章 绪论... 1
1.1 C语言简介... 1
1.2 开发C语言程序... 4
1.2.1 第一个C语言例程... 4
1.2.2 在Microsoft Windows下开发程序... 8
1.2.3 在Linux或Unix下开发程序... 12
1.3 小结... 16
1.4 习题... 17
第2章 数据和运算... 18
2.1 标识符和关键字... 18
2.2 数据类型... 22
2.2.1 有符号整数系列类型和无符号整数系列类型... 23
2.2.2 字符类型... 26
2.2.3 枚举类型... 27
2.2.4 浮点数类型... 28
2.3 变量和字面常量... 39
2.3.1 变量... 39
2.3.2 有符号整数系列类型和无符号整数系列类型字面常量... 43
2.3.3 字符类型字面常量... 45
2.3.4 枚举类型字面常量... 46
2.3.5 浮点数类型字面常量... 47
2.4 数据的输入和输出... 48
2.4.1 函数printf 48
2.4.2 函数scanf和scanf_s 54
2.4.3 字符输入函数getchar和字符输出函数putchar 64
2.5 运算... 66
2.5.1 算术运算... 67
2.5.2 关系运算... 75
2.5.3 逻辑运算... 76
2.5.4 位运算... 76
2.5.5 赋值类运算... 80
2.5.6 条件运算... 81
2.5.7 其他运算... 82
2.6 小结... 83
2.7 习题... 84
第3章 控制结构... 86
3.1 选择结构... 86
3.1.1 if语句和if-else语句... 87
3.1.2 switch语句... 91
3.2 循环结构... 94
3.2.1 for语句... 94
3.2.2 while语句... 96
3.2.3 do-while语句... 98
3.2.4 continue语句... 99
3.2.5 break语句... 101
3.3 小结... 104
3.4 习题... 105
第4章 结构化程序设计... 108
4.1 函数基础... 108
4.1.1 函数定义与调用... 108
4.1.2 形式参数个数可变的函数... 114
4.1.3 主函数main. 117
4.2 多个源程序文件... 123
4.3 函数递归调用... 130
4.4 结构化程序设计实现... 142
4.5 小结... 148
4.6 习题... 148
第5章 静态数组... 150
5.1 一维数组... 151
5.2 多维数组... 163
5.3 字符数组与字符串... 172
5.4 小结... 194
5.5 习题... 195
第6章 结构体和共用体... 196
6.1 结构体(struct)... 196
6.2 共用体(union)... 208
6.3 小结... 215
6.4 习题... 215
第7章 指针... 216
7.1 指针类型与变量... 216
7.2 动态数组... 222
7.3 指针运算... 229
7.4 函数返回值... 230
7.5 单向链表和双向链表... 241
7.6 函数指针与函数自动测试... 270
7.7 小结... 278
7.8 习题... 278
第8章 关键字typedef和const以及预处理命令... 280
8.1 类型别名定义typedef 280
8.2 常量属性const 285
8.3 预处理命令... 288
8.3.1 宏定义#define与取消宏定义#undef 289
8.3.2 条件编译... 295
8.3.3 文件包含#include. 298
8.4 小结... 304
8.5 习题... 304
第9章 文件处理... 306
9.1 文件操作基本框架... 306
9.2 以文本形式读写文件... 316
9.3 以二进制数据流形式读写文件... 324
9.4 文件整体信息与处理... 327
9.5 错误处理... 328
9.6 文件处理程序示例... 330
9.7 小结... 349
9.8 习题... 349
第10章 编程规范、程序调试与测试... 351
10.1 程序编写规范... 352
10.1.1 命名规范... 352
10.1.2 排版规范... 358
10.1.3 语句... 362
10.1.4 文件组织... 369
10.2 程序编译与调试... 376
10.2.1 程序编译与链接... 376
10.2.2 设置断点与查看即时信息... 382
10.2.3 断言assert 389
10.2.4 编写调试日志文件程序... 392
10.3 程序测试... 396
10.4 小结... 434
10.5 习题... 435
第11章 其他常用函数和宏... 437
11.1 数学库... 437
11.1.1 指数与对数类函数... 437
11.1.2 三角函数... 446
11.1.3 反三角函数... 449
11.1.4 双曲函数... 452
11.1.5 其他数学类函数... 454
11.2 标准库... 458
11.2.1 伪随机数生成函数... 458
11.2.2 程序退出函数以及注册函数... 459
11.2.3 环境变量值的获取函数... 462
11.2.4 查找与排序函数... 463
11.2.5 整数绝对值和除法运算函数... 467
11.3 时间获取与处理函数... 469
11.3.1 在时间库中的时间获取函数... 469
11.3.2 在时间库中的时间处理函数... 471
11.3.3 在时间库中的时间格式输出函数... 476
11.3.4 在VC平台下的高精度计时函数... 481
11.4 小结... 487
11.5 习题... 487
附录A 图的索引....................................................................................................... 490
附录B 表的索引....................................................................................................... 492
附录C 例程索引....................................................................................................... 494
附录D 函数、运算符与宏索引.................................................................................. 496
参考文献..................................................................................................................... 502
|
內容試閱:
|
现代科学技术正在迅猛地发展着,计算机信息技术在其中发挥着巨大的作用,并已渗透到各行各业,推动着相关行业的迅速发展。合理利用计算机及其软件可以迅速提升人们生活与工作的效率。因此,如何尽快地掌握计算机知识,学好一门计算机语言,并用来解决人们在生活与工作中的实际问题,是一个有着迫切需求的问题。本书希望能在这方面为读者安上智慧的翅膀,越过学好一门计算机语言的种种障碍,尽情享受学好一门计算机语言的乐趣。C语言是迄今为止人类发明的最为成功的计算机语言之一,应用非常广泛,同时也是很多其他计算机语言的基础。例如,C语言是在C语言基础上发展起来的计算机语言,而Java语言和C#语言则是在CC语言的基础上发展起来的语言。无论如何发展与变革,C语言本身依然不断展示出其巨大的自身优势,数十年来一直在开发商业软件所采用的计算机语言当中名列前茅,深受人们青睐。C语言程序常常以短小精悍并且运行效率高著称。这实际上也体现出了C语言强大的表达能力和处理实际问题的能力。无论国内还是国外,C语言程序设计目前通常是计算机或软件专业学生学习的第一门计算机语言课程。这说明C语言是一门相对比较容易入门的计算机语言。它容易上手,而且可以迅速用来解决实际问题;具有很大的灵活性,可以支持结构化程序设计,可以用来培养严谨的编程思维习惯;具有很好的通用性,容易理解,可以构成学习其他计算机语言的基础。我从1991年进入清华大学计算机系就开始学习C语言程序设计,积累了大量的笔记。2002年我从美国留学回国并回到清华大学工作,那时便答应我的学生开始着手编写本书。因为工作的原因,编写的过程时断时续。也许因为自己过于追求完美,写起来非常缓慢,我从VC(Visual C,简称VC)6.0、VC 2003、VC 2005、VC 2008、VC 2010、VC 2012、VC 2015、Linux的gcc和Unix的gcc等逐个平台进行实验,并反反复复地进行修改。在此期间,随着时间的流逝,两次出台了新的C语言国际标准,让我又改变了本书的写法。其实,因为工作的原因,C语言与自己朝夕相处,要重现其完美是一件非常难的事。正所谓亲近无伟人。在描述与自己朝夕相处的C语言的程序设计时,我一方面常常担心是否遗漏了什么;另一方面又担心过于烦琐,破坏了C语言的简洁之美。时间便在这样反反复复之中流逝而去。好在最后终于成稿了,可以暂时松一口气了,也可以给学生一个交待了。我希望本书能够给读者带来尽可能多的益处。对于学习而言,首先最重要的应当是对学习方法的引导。学习每门课程都有其内在的学习规律。顺应其规律,采用正确的学习方法,一般会产生良好的学习效果。学习首先应当是学以致用。为此,我常常利用各种机会调研软件公司对程序设计的实际需求。如果能够从应用出发进行学习,那么应当会提高学习的效率。另外,学习过程的关键应当是实践,课本是实践的一种辅助工具。为此,本书比较详细地讲解了在VC平台以及Linux和Unix操作系统下进行C语言程序设计实践的方法,努力降低进行C语言实践的难度,希望读者能够很快入门并进行C语言程序设计实践。在本书每章的后面都有习题。对于书中的习题,都没有提供答案,是因为我真诚希望这些习题能够给读者增加一些自主性思考和实践练习的机会。自主性思考意味着应当通过自己的思考去理解C语言并求解问题,同时应当不拘泥于某一种答案,即可以采用多种不同的方法求解相同的问题,从而快速掌握C语言及其程序设计方法。不过,本书提供了大量的例程及其详细的讲解,读者可以进行模仿。同时,希望读者能够经常总结实践过程的收获,享受其中的成就感,即使无法最终求解问题。本书还讲解了C语言所有常用的库函数、运算符与宏,在一定程度上体现出了C语言程序设计手册或指南的特点。为了方便读者查找本书知识点和中心内容,通过加黑加粗加框的方式,强调各部分内容的中心词以及各个基本概念或定义的核心词,并提供了非常明显的注意事项、说明和小甜点等内容,而且在附录中添加了图、表、例程以及函数、运算符和宏的页码索引。此外,本书在鲁棒编程、高效编程和规范编程等方面也形成了一定的特色。本书既可以作为计算机专业和非计算机专业的基础教材,也可以作为需要使用计算机的工程人员和科技工作者的自学参考书。本书在编写与出版的过程中得到了许多朋友的帮助,其中,读者、选修我所负责的课程的学生以及我所负责的清华大学计算机辅助设计、图形学与可视化研究所里的同事与学生,都起到了非常重要的作用。他们的建议和批评意见是本书发生变化的最重要的外在因素,并且他们当中的很多人也参与了本书的校对工作。本书也凝聚了他们的劳动结晶。这里一并对他们表示诚挚的谢意。真诚希望读者能够轻松并且愉悦地掌握C语言程序设计,也希望自己能做得更好。欢迎广大读者特别是讲授此课程的老师对本书进行批评和指正。真诚欢迎各种建设性意见。 、 雍俊海 于清华园2017年3月3日
IIC程序设计III前言
控 制 结 构 C语言的控制结构只有3类:顺序结构、选择结构和循环结构。顺序结构是最简单的程序结构。在顺序结构中,程序从前到后按顺序依次执行各条语句或语句块,不跳过也不重复任何语句或语句块。在C语言当中,不含语句块的每条语句通常以分号;作为结束标志。最简单的语句可以只包含一个分号,该语句称为空语句。空语句不执行任何操作。有时采用空语句来延长程序的运行时间。被大括号{ }括起来的一条或多条语句通常称做语句块。下面给出顺序结构代码示例。 double a = 5.1; double b = 7.2; double c = a b2; printf"%g和%g的平均值是%g。\n", a, b, c; 输出: 5.1和7.2的平均值是6.15。↙本章将依次介绍选择结构和循环结构。在选择结构中,程序依据条件选择相应的分支执行语句或语句块。选择结构包括if语句、if-else语句和switch语句,这些语句也可以统称为选择语句。在循环结构中,程序不断重复执行指定的语句或语句块,直到循环结束。循环结构包括for语句、while语句和do-while语句。组成循环结构的for语句、while语句和do-while语句也可以统称为循环语句。选择语句和循环语句实际上都是复合语句,即在这些语句的组成部分当中还会包含语句、语句块或语句组,其中语句组也是由一条或多条语句组成。语句块与语句组的区别在于是否被一对大括号{ }括起来。在选择结构和循环结构中,还可能包含break语句和continue语句,其中break语句用来中断执行switch语句或循环结构,continue语句只能用于循环结构并使得程序直接进入下一轮的循环。3.1 选择结构选择结构的特点是根据不同的条件选择执行不同的程序代码。选择结构包括if语句、if-else语句和switch语句。其中if语句只有一个分支,当且仅当在满足if条件时,才执行在if语句中的语句或语句块。if-else语句包含两个分支。如果满足if条件,则执行if分支的语句或语句块;否则,执行else分支的语句或语句块。switch语句可以包含多个分支。switch语句根据一个整数系列类型表达式的值,选择执行相应的分支。3.1.1 if语句和if-else语句if语句和if-else语句统称为条件语句。if语句的格式是: if 表达式 语句或语句块其中,表达式必须是数值类型的表达式,可以是定点数,也可以是浮点数,称为if条件表达式。在if语句当中的语句或语句块只能是单条语句或一个语句块,称为if分支语句或语句块。如图3-1(a)所示,只有当if条件表达式不等于0时,才会执行if分支语句或语句块。
图3-1 if语句和if-else语句流程图在流程图中,小圆圈表示流程图片断的连接点,即上面流程图连接入其他流程图组成更大流程图的连接点;菱形表示条件判断,而且将依据判断结果执行不同的分支;矩形表示正常的代码执行;箭头表示程序运行的路径。下面给出if语句代码示例。 int studentScore = 95; if studentScore90 printf"成绩优秀!\n"; 结果输出: 成绩优秀!↙ 1 2 3在上面第2行代码中,因为studentScore = 95,所以if条件表达式studentScore90成立。这样,上面第3行代码if分支语句printf"成绩优秀!\n";就会被执行,结果输出成绩优秀!↙。如果将上面第1行代码换为int studentScore = 85;,那么if条件表达式studentScore90不成立,这样上面第3行代码就不会被执行,结果什么也没有被输出。下面给出另外一个if语句代码示例。 int a = 10; int b = 5; if ab { printf"a=%d\n", a; 结果输出: a=10↙ printf"b=%d\n", b; 结果输出: b=5↙ printf"a比b大。\n"; 结果输出: a比b大。↙ } if结束 1 2 3 4 5 6 7 8在这个示例当中,if分支部分是一个语句块。通过语句块使得if分支部分可以包含多条语句。: 在if分支语句块当中,作为语句块标志的一对大括号{ }是不能去掉的。如果去掉,则if分支语句块就变为if分支语句,而且这条if分支语句就是原语句块的第一条语句。例如,在上面的代码示例中,如果去掉其中第4行和第8行代码,则在第3行之后的代码变为 if ab printf"a=%d\n", a; 只有当ab,才会输出a的值 printf"b=%d\n", b; 无论a是否大于b,均会输出b的值 printf"a比b大。\n"; 无论a是否大于b,均会输出: a比b大。↙
这时,最后两行代码printf"b=%d\n", b;和printf"a比b大。\n";并不隶属于if语句。因此,无论a是否大于b,均会输出b的值以及a比b大。↙。这显然是有问题的。if-else语句包含两个分支。if-else语句的格式是: if 表达式 语句1或语句块1 else 语句2或语句块2其中,表达式称为if条件表达式,必须是数值类型的表达式,可以是定点数,也可以是浮点数。if下方的语句1或语句块1称为if分支语句或语句块,else下方的语句2或语句块2称为else分支语句或语句块。这里的语句1和语句2均只能是单条语句,语句块1和语句块2也只能是一个语句块。如图3-1(b)所示,只有当if条件表达式不等于0时,才会执行if分支语句或语句块;否则,执行else分支语句或语句块。下面给出if-else语句代码示例。 int studentScore = 85; if studentScore=60 printf"通过考试!\n"; else printf"考试没通过,请继续努力!\n"; 1 2 3 4 5上面代码示例将输出通过考试!↙。在if语句和if-else语句当中的分支语句仍然可以是if语句或if-else语句。但这时,需要注意if和else在同一个语句块中的最近配对原则。: if和else的最近配对原则:在同一个语句块中,else部分总是按照if-else语句格式与最近的未配对的if部分配对,构成if-else语句。如果else部分无法与if部分配对构成符合if-else语句格式的语句,那么将出现编译错误。根据这一原则,如果在if-else语句当中的if分支语句或语句块仍然是一条if语句,那么该if语句代码的编写应当采用语句块的形式;否则,该if语句将与else部分配对成为if-else语句。下面给出具体的示例代码进行说明。这里给出示例代码,说明if和else最近配对原则可能出现的问题,以及如何避免可能出现的错误。具体的代码如下。 int month = 12; int day = 30; if month==12 { if day==31 printf"这是一年的最后一天!\n"; } else printf"这不是一年的最后一个月!\n"; 1 2 3 4 5 6 7 8 9虽然第5行的if比第3行的if离第8行的else更近一些,但第5行的if与第8行的else不在同一个语句块中。因此,上面代码第8行的else只会与第3行的if相配对,而不会与第5行的if相配对。上面代码第4~7行是一个语句块,只包含一条if语句。在if-else语句格式中,允许其中的if分支语句或语句块是一条语句。那么,能否去掉第4行和第7行代码,即去掉作为语句块标志的一对大括号{ }? 在去掉这两行代码之后,语法仍然是正确的。这时,上面的代码变为 int month = 12; int day = 30; if month==12 if day==31 printf"这是一年的最后一天!\n"; else printf"这不是一年的最后一个月!\n"; 1 2 3 5 6 8 9运行上面的代码,将会输出这不是一年的最后一个月!↙。为什么会这样? 为什么12月份会不是一年的最后一个月? 我们分析一下修改之后的代码。根据if和else最近配对原则,在修改之后的代码中,上面代码第8行的else会与第5行的if相配对。这样,修改之后的代码实际上等价于 int month = 12; int day = 30; if month==12 { if day==31 printf"这是一年的最后一天!\n"; else printf"这不是一年的最后一个月!\n"; } 1 2 3 4 5 6 7 8 9这样,对于12月份,只要日期不是31,就会输出这不是一年的最后一个月!↙。对于其他月份,反而什么都不会输出。将if day==31 printf"这是一年的最后一天!\n";部分按语句块的形式编写,就不会出现这种与预期不相符的逻辑。总之,在if-else语句当中的if分支语句或语句块仍然是一条if语句的正确语句格式是: if 表达式1 { if 表达式2 语句1或语句块1 } else 语句2或语句块2如果if-else语句的else分支语句仍然是一条if-else语句,则通常写成 if 表达式1 语句1或语句块1 else if 表达式2 语句2或语句块2 else 语句3或语句块3这个过程可以有限次重复下去,形成如下的语句格式: if 表达式1 语句1或语句块1 else if 表达式2 语句2或语句块2 else if 表达式n 语句n或语句块n else 语句n 1或语句块n 1下面给出代码示例。 int studentScore = 85; if studentScore=90 printf"成绩优秀!\n"; else if studentScore=80 printf"成绩良好!\n"; else if studentScore=70 printf"成绩中等!\n"; else if studentScore=60 printf"成绩合格!\n"; else printf"考试没通过,请继续努力!\n"; 1 2 3 4 5 6 7 8 9 10 11上面的代码对成绩进行分类。如果分数大于或等于90分,则成绩优秀;如果分数介于80和89之间,则成绩良好;如果分数介于70和79之间,则成绩中等;如果分数介于60和69之间,则成绩合格;如果分数低于60,则考试没通过,需要继续努力。3.1.2 switch语句switch语句也常称为分支语句。switch语句的格式如下。 switch 表达式 { case 常数1: 语句组1 case 常数2: 语句组2 case 常数n: 语句组n default: 语句组n 1 }上面switch语句第一行的表达式称为switch表达式,它必须是整数系列类型的表达式。在switch语句的一对大括号{ }内是一系列的case分支和一个default分支。每个case分支在关键字case和空格之后紧接着一个常数,这个常数的数据类型必须与switch表达式相匹配,称为case常数。在同一条switch语句当中,各个case常数必须各不相等;否则,无法通过编译。在case常数之后是冒号,然后是case分支语句组。default分支在同一条switch语句中最多出现一次,也可以不出现。在default分支中的语句组称为default分支语句组。case分支语句组和default分支语句组均由一条或多条语句组成,而且每个case分支语句组和default分支语句的最后一条语句通常是break语句。如果在这些分支语句组的中间出现break语句,那么在break语句之后的语句实际上将不会起作用。当然,这些分支语句组也可以不含break语句。如图3-2所示,在执行switch语句时,首先计算switch表达式的值,然后依次将该表达式的值与各个case常数进行匹配。如果该表达式的值刚好等于某个case常数,则进入该case分支,执行相应的case分支语句组。如果该case分支语句组不含break语句,则会继续执行下一个case分支或default分支的语句组,直到执行到break语句或整个switch语句结束。如果switch表达式的值与任何一个case常数都不相等,并且switch语句含有default分支,则执行default分支语句组。
图3-2 switch语句流程图下面给出一个switch语句示例。 char grade = ''A''; switchgrade { case ''A'': printf"百分制成绩: 90~100。\n"; break; case ''B'': printf"百分制成绩: 80~89。\n"; break; case ''C'': printf"百分制成绩: 60~79。\n"; break; case ''D'': printf"百分制成绩: 0~59。\n"; break; default: printf"无效成绩。\n"; } switch结束 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18在这个示例中,因为变量grade的值是''A'',所以程序会进入case ''A''分支,执行该case分支语句组,输出百分制成绩: 90~100。↙。因为该case分支语句组的最后一条语句是break语句,如上面第6行代码所示,所以switch语句运行到这里就自动结束了。我们还可以修改上面第1行代码,改变grade的值,从而执行switch语句的不同case分支或执行default分支的语句组。下面给出一个不含break语句的switch语句应用示例。 int month = 5; int dayRemain = 0; switchmonth { case 1: dayRemain= 31; case 2: dayRemain= 28; case 3: dayRemain= 31; case 4: dayRemain= 30; case 5: dayRemain= 31; case 6: dayRemain= 30; case 7: dayRemain= 31; case 8: dayRemain= 31; case 9: dayRemain= 30; case 10: dayRemain= 31; case 11: dayRemain= 30; case 12: dayRemain= 31; } switch结束 printf"距离年终还剩余%d天。\n", dayRemain; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30这个示例假设某一年2月份总共是28天,希望统计从month这个月开始到年终还剩余多少天。在这个示例中,因为变量month的值是5,所以程序会进入case 5分支,执行该case分支语句组,统计5月份的天数,使得dayRemain= 31。因为该case分支语句组不含break语句,所以程序会进入该switch语句的下一个case分支,即case 6分支,继续统计6月份的天数,使得dayRemain=31 30=61。这个过程不断继续下去,直到最后一个case分支,即case 12分支,程序统计了最后一个月的天数,该switch语句才执行结束。这时,程序已经统计了从5月份到12月份的总天数,得到dayRemain=245。因此,运行上面第30行代码将输出距离年终还剩余245天。。:(1)在switch语句中,switch表达式必须是定点数类型的表达式。(2)在switch语句中,case常数必须是定点数类型的常数,不能是浮点数类型的常数。(3)在同一条switch语句当中,所允许的case分支的总个数总是有限的。C语言标准规定,在同一条switch语句中,case分支的个数不能超过1023。不过,实际所允许的case分支个数依赖于C语言支撑平台。3.2 循环结构循环结构非常适合发挥计算机的强大运算能力。循环结构的特点是不断重复执行位于在循环体内的程序代码,直到不满足循环条件。有限性是正常计算机程序的基本特点。因此,对于正常的循环结构,应当设计合理的循环条件使得循环最终能够在有限的步骤之后结束。循环结构包括for语句、while语句和do-while语句。下面分别介绍这些循环语句。3.2.1 for语句for语句是C语言的3种循环语句之一。for语句的格式是 for 初始化表达式; 条件表达式; 更新表达式 循环体其中,循环体一般是一条语句或一个语句块。如图3-3所示,在执行for语句时,初始化表达式只会被计算一次。初始化表达式通常用来初始化循环所需要的变量,因此通常由一个或多个赋值运算表达式组成。如果是多个赋值运算表达式,则采用逗号分隔开。
图3-3 for语句流程图下面给出采用for语句实现计算从1到100之和的示例。 int i, n, sum; for i=1, n=100, sum=0; i#include
int mainint argc, char* args[ ]{int i, k, number, sum, n;for i=1, k=0, sum=0, n=5; i 在VC平台中,应将scanf改为scanf_sif number 统计正整数个数} for循环结束if k0printf"正整数的平均值是%g。\n", sumdoublek;else printf"没有输入正整数。\n";system"pause"; 暂停住控制台窗口return 0; 返回0表明程序运行成功} main函数结束 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21可以对上面的代码进行编译、链接和运行。下面给出一个运行的结果示例。请输入第1个整数: 12↙请输入第2个整数: ?1↙请输入第3个整数: 13↙请输入第4个整数: ?2↙请输入第5个整数: 14↙正整数的平均值是13。请按任意键继续...例程进一步说明:如果去掉第11行的代码,则上面第13行和第14行的代码将都不会起作用。上面第11行和第12行代码的共同作用,使得0和负整数不会进入统计,即当输入的是0或负整数时,上面第13行和第14行的代码都不会被执行。上面第16行代码通过if k0使得第17行的运算sumdoublek不会出现除数为0的情况。3.2.5 break语句C语言标准规定break语句只能用在switch语句和循环语句中。break语句的写法如下。 break;第3.1.2小节已经介绍了在switch语句中的break语句。因此,这里只介绍在循环语句中的break语句。如图3-7所示,当执行循环语句遇到break语句时,程序会立即自动结束整个循环语句的运行。: break语句通常作为条件语句if语句或if-else语句的一部分出现在循环语句的循环体中。如果直接将break语句作为一条独立的语句放入循环语句的循环体中,则在break语句之后的循环体语句将都不起作用。例程3-2 接受以0或负整数为结束标志的多个正整数输入,并计算其中正整数的平均值例程。例程功能描述:该例程依次接受整数的输入。若输入的是正整数,则继续输入;若输入的是0或负整数,则表示输入结束。对于输入的所有正整数,统计并输出这些正整数的平均值。例程解题思路:设计整数类型的变量n,用来统计输入的正整数的总个数。设计整数类型的变量number,用来保存输入的整数。设计整数类型的变量sum,用来保存正整数之和。因为需要接受多个整数的输入,所以需要采用循环语句。这里采用for循环语句。因为无法提前知道输入的正整数的总个数,所以for语句的条件表达式为1,即这个for语句并不通过for语句条件表达式来结束循环,而是利用break语句结束循环。在for语句的循环体内,接受整数的输入。如果输入的是正整数,则统计已经输入的正整数的总个数,并计算已经输入的正整数的和。一旦发现输入的是0或负整数,则调用break语句,立即结束for循环语句。在结束for语句之后,变量n的值已经是输入的正整数的总个数,变量sum已经是输入的所有正整数之和。因此,这时可以计算平均值。在计算平均值时,可以考虑将整数运算转化成为双精度浮点数运算,以提高计算精度。例程由一个源程序文件C_MultiplePositiveNumberAverage.c组成,具体的程序代码如下。
图3-7 包含break语句的循环语句流程图 文件名: C_MultiplePositiveNumberAverage.c;开发者: 雍俊海行号#include #include
int mainint argc, char* args[ ]{int n, sum, number;for n=0, sum=0; 1;{printf"请输入第%d个整数: ", n 1;scanf_s"%d", &number;if number0printf"正整数的平均值是%g。\n", sumdoublen;else printf"没有输入正整数。\n";system"pause"; 暂停住控制台窗口return 0; 返回0表明程序运行成功} main函数结束 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21可以对上面的代码进行编译、链接和运行。下面给出一个运行的结果示例。请输入第1个整数: 5↙请输入第2个整数: 6↙请输入第3个整数: 7↙请输入第4个整数: 8↙请输入第5个整数: -1↙正整数的平均值是6.5。请按任意键继续...例程进一步说明: 如果去掉第11行的代码,则上面第13行和第14行的代码将都不会起作用。上面第11行和第12行代码的共同作用,使得一旦发现输入的是0或负整数,则立即结束for循环语句。上面第16行代码通过if n0使得第17行的运算sumdoublen不会出现除数为0的情况。: 如果出现多重嵌套的循环语句,即在循环语句的循环体内仍然含有循环语句,则当遇到break语句时,只是立即结束该break语句所在的那一层的循环语句,而不会结束其外层的循环语句(当然,这个前提是存在外层的循环语句)。图3-8给出了break语句在两重嵌套循环语句中的运行示例。如图3-8所示,在两重嵌套循环语句中,如果break语句出现在外层循环语句中,则一旦运行到这条break语句,则立即会结束这两重嵌套循环语句的运行;如果break语句出现在内层循环语句中,则一旦运行到这条break语句,只是结束内层循环语句的运行,然后继续执行在外层循环体内并且在内层循环语句之后的语句,即整个外层的循环语句仍然会继续运行。下面给出程序片断示例。 int i, k; for i=0; i=0if x0 y=1; else y=-1; printf"x=%d, y=%d", x, y; 1 2 3 4 5 6习题3.6 下面程序片断是否含有语法错误?如果没有,请写出其运行结果的输出 内容。 char ch=''B''; switch ch { case ''A'': case ''a'': printf"优秀"; break; case ''B'': case ''b'': printf"良"; default: printf"再接再厉"; } 1 2 3 4 5 6 7 8 9 10 11 12 13习题3.7 下面程序片断是否含有错误?如果没有,请写出其运行结果的输出内容。 double a=6; switcha { case 6: printf"Saturday。\n"; break; case 7: printf"Sunday。\n"; break; default: printf"Unknown。\n"; break; } switch语句结束 1 2 3 4 5 6 7 8 9 10 11 12 13习题3.8 下面程序片断是否含有错误?如果没有,请写出其运行结果的输出内容。 int a = 6; switcha { case 6.0: printf"Saturday。\n"; break; case 7.0: printf"Sunday。\n"; break; default: printf"Unknown。\n"; break; } switch语句结束 1 2 3 4 5 6 7 8 9 10 11 12 13习题3.9 请找出并更正下面程序片断的错误。 char ch=0; char sum=0;while ch5; { ch; sum =ch; } printf"sum=%d", sum; 1 2 3 4 5 6 7 8 9习题3.10 请总结break语句的用法。习题3.11 请总结continue语句的用法。思考题3.12 能否写出不含分号的C语言语句?思考题3.13 能否写出不以分号结尾的C语言语句?习题3.14 请编写程序,接受输入10个整数,计算并输出其平均数。习题3.15 请编写程序,接受输入1个正整数,计算并输出不超过这个正整数的所有水仙花数。这里水仙花数是一个正整数,它的各个十进制位的立方和等于它本身。例如,1是水仙花数,因为1=13。再如,153是水仙花数,因为153=13 53 33。习题3.16 请编写程序,接受一系列整数的输入,其中输入的最后一个整数是0。要求计算并输出除了整数0之外其他输入的整数的最大值和最小值。习题3.17 请编写程序,接受3个正整数y、m和d的输入。请判断y年m月d日是否是一个合法日期。如果是一个合法的日期,则输出这一天是星期几;否则,请输出字符串这是一个无效的日期。????????106C程序设计107第3章 控制结构
|
|