欢迎光临
免费的PDF电子书下载网站

C程序设计教程(第3版) PDF下载

编辑推荐

本书为普通高等教育“十一五”*规划教材,面向初、中级读者,内容精练,实例题目经典实用、综合性强,着重提高编程应用开发能力。被多所高校用作教材。尽管随着计算机技术的飞速发展,高级程序设计语言的种类越来越多,但是C语言仍然是*适合作为学习程序设计思想的入门语言。本书在内容的编排上,更多地考虑了初学者的需求。本书主要内容包括:C语言的基础知识、结构化程序设计、模块化程序设计、数组、指针、结构和文件。全书的内容从易到难,循序渐进,列举了大量能够解决实际问题的实例,并有一个贯穿始终的例子,将一个小程序逐渐扩充成一个比较大的程序。同时,特意安排了一些与信息安全方向有关的小例子,增加趣味性。*后一章还讨论了两个实例,帮助读者了解和掌握编写实用的能解决实际问题的C程序的方法。本书主要是为初学程序设计语言的高校学生量身定做的,也可作为C语言自学者的教材或参考书。 ;

内容简介

尽管随着计算机技术的飞速发展,高级程序设计语言的种类越来越多,但是C语言仍然是*适合作为学习程序设计思想的入门语言。本书在内容的编排上,更多地考虑了初学者的需求。 本书主要内容包括:C语言的基础知识、结构化程序设计、模块化程序设计、数组、指针、结构和文件。 全书的内容从易到难,循序渐进,列举了大量的能够解决实际问题的实例,并有一个贯穿始终的例子,将一个小程序逐渐扩充成一个比较大的程序。同时,特意安排了一些与信息安全方向有关的小例子,增加趣味性。 *后一章还讨论了两个实例,帮助读者了解和掌握编写实用的能解决实际问题的C程序的方法。 本书主要是为初学程序设计语言的高校学生量身定做的,也可作为C语言自学者的教材或参考书。

作者简介

暂无

C程序设计教程(第3版) PDF下载

目录

 ;目录

第1章C语言概述 1

1.1程序设计语言 1

1.1.1低级语言 2

1.1.2高级语言 3

1.2通过实例认识C程序的结构 4

1.2.1问候界面 4

1.2.2计算里约奥运会中国军团新人的人数 5

1.2.3计算有线电视n年的费用 7

1.3C语言的标准和编译器 8

1.3.1C语言的标准 8

1.3.2常用的C语言编译器 9

1.4程序的调试 9

1.4.1调试步骤 9

1.4.2在Visual C 6.0环境下调试第一个程序 10

习题 13第2章C语言基础知识 15

2.1标识符、变量与常量 15

2.1.1标识符 15

2.1.2变量 17

2.1.3常量 18

2.2C语言的数据类型 19

2.2.1为什么要讨论数据类型 19

2.2.2C语言的数据类型种类 22

2.2.3整型数据 23

2.2.4字符型数据 29

2.2.5浮点型数据 35

2.3运算符和表达式 38

2.3.1表达式与简单语句 38

2.3.2算术运算符 39

2.3.3赋值运算符 41

2.3.4增1 减1运算符 42

2.3.5位逻辑运算符 43

2.3.6逗号运算符 45

2.3.7求字节数运算符 46

2.3.8不同数据类型数据间的混合运算 47

2.3.9赋值表达式的类型转换 50

2.4指针类型与指针运算符 55

2.4.1指针概念和指针变量的定义 55

2.4.2指针运算符&;和的使用 56

2.5典型错误分析 59

习题 60第3章结构化程序设计 65

3.1结构化程序设计 65

3.1.1结构化程序设计思想的产生 65

3.1.2结构化程序设计的3种基本结构 67

3.2语句与分程序 70

3.3顺序结构程序设计 72

3.4关系运算符与逻辑运算符 74

3.4.1关系运算符 74

3.4.2逻辑运算符 76

3.5选择结构程序设计 78

3.5.1问题提出与程序示例 78

3.5.2if语句的3种形式 79

3.5.3嵌套的if语句 90

3.5.4switch语句 94

3.5.5条件运算符 98

3.5.6选择结构程序举例 100

3.6循环结构程序设计 104

3.6.1问题提出与程序示例 104

3.6.2while语句 106

3.6.3do while语句 110

3.6.4for语句 113

3.6.5多重循环 115

3.6.6break语句在循环语句中的用法 118

3.6.7continue语句 120

3.6.8循环结构程序举例 123

3.7典型错误分析 131

习题 137第4章模块化程序设计 147

4.1模块化程序设计思想 147

4.2函数的定义、声明与调用 150

4.2.1函数基础 150

4.2.2函数的定义形式 151

4.2.3函数的返回值 152

4.2.4函数声明 152

4.2.5函数调用 154

4.3函数的参数传递 157

4.3.1形参和实参的关系 158

4.3.2普通变量作为函数的形式参数 158

4.3.3指针变量作为函数的形式参数 159

4.4程序举例 162

4.5函数的递归调用 165

4.6变量的存储类别 168

4.6.1自动变量与外部变量 168

4.6.2静态变量 177

4.6.3寄存器变量 179

4.7预处理命令 180

4.7.1宏定义 180

4.7.2文件包含 184

4.7.3条件编译 186

4.8典型错误分析 187

习题 190第5章数组和指针 197

5.1一维数组 197

5.1.1问题提出与程序示例 197

5.1.2一维数组的定义 198

5.1.3一维数组的引用 198

5.1.4一维数组的初始化 200

5.1.5程序举例 201

5.1.6数组名作为函数的参数 205

5.2指针与一维数组 212

5.2.1指针值的算术运算 212

5.2.2指针方式和数组方式对数组元素的操作 216

5.2.3指向一组空间首地址的指针作为函数参数2175.3动态的一维数组 218

5.3.1空指针 218

5.3.2存储器申请与释放 219

5.4字符数组与字符串函数 221

5.4.1字符数组 221

5.4.2字符数据的输入与输出 223

5.4.3指针与字符串 225

5.4.4程序举例 226

5.4.5字符串函数 229

5.5二级指针 231

5.6指针数组与命令行参数 233

5.6.1指针数组 233

5.6.2命令行参数 237

5.7二维数组 238

5.7.1二维数组的定义 239

5.7.2二维数组的引用 240

5.7.3二维数组的初始化 241

5.7.4程序举例 242

5.7.5用指针方法操作二维数组 247

5.8典型错误分析 248

习题 253第6章结构体等构造数据类型 262

6.1结构体 262

6.1.1问题提出与程序示例 262

6.1.2结构体的声明和定义 263

6.1.3结构体成员的引用 266

6.1.4结构体的初始化 268

6.2结构体与数组 268

6.2.1结构体包含数组 268

6.2.2结构体数组 269

6.3结构体与指针 271

6.3.1指向结构体的指针 271

6.3.2用结构体类型指针建立链表 274

6.4结构体与函数 276

6.4.1结构体数据作为函数的参数 276

6.4.2返回指向结构体的指针的函数 277

6.5联合体与枚举 279

6.5.1使用联合体与枚举的目的 279

6.5.2联合体与枚举的声明 279

6.5.3联合体变量与枚举变量的定义 280

6.5.4联合体变量成员的引用 281

6.5.5枚举变量的使用 282

6.5.6指向联合体变量的指针 284

6.5.7联合体变量与函数 284

6.5.8使用联合体与枚举的程序举例 285

6.6类型定义 287

6.7程序举例 288

6.8典型错误分析 291

习题 294第7章文件 301

7.1文件概述 301

7.1.1问题提出与程序示例 301

7.1.2文件“流” 302

7.1.3文件操作的特点 303

7.1.4缓冲文件系统 303

7.2文件的打开与关闭 304

7.2.1文件类型指针 304

7.2.2文件的打开 304

7.2.3文件的关闭 306

7.3文件的读写操作 306

7.3.1fputc函数与fgetc函数 307

7.3.2fprintf函数与fscanf函数 311

7.3.3fread函数与fwrite函数 315

7.3.4fgets函数和fputs函数 319

7.4文件的定位操作 320

7.4.1文件的顺序存取和随机存取 320

7.4.2rewind函数 320

7.4.3fseek函数 321

7.4.4ftell函数和feof函数 323

习题 323第8章案例 326

案例1学生试卷分数统计 326

案例2通信录管理系统 332附录AASCII码与字符对照表 339附录B运算符的优先级和结合性 341附录Cprintf函数的转换说明模式 343

前沿

前言本教材是在前两版的基础上,总结了教学过程中的经验,征询了部分专家的意见,并考虑了读者和学生的需求,经过进一步修订而成的。主要的修订内容包括: ;(1) 选用了一些新的案例。这些案例不但更适合初学者,也更有实际意义。例如,增加了一些与信息安全概念相关的小程序,加密、解密和信息隐藏等;又例如,将所缴税的计算方法已经修改为最新的,即2013年开始实施的计算方法;增加了一些有关奥运会的例子,将前一版有关奥运会的案例中的相关数据全部改为里约奥运会的数据。希望读者学习起来更感兴趣。(2) 将“函数说明”的提法修改为“函数声明”,全局变量等存储类别的“变量说明”修改为“变量声明”,对结构体类型的“说明”也修改为对结构体类型的“声明”。(3) 摒弃了“字符串变量”的提法,直接采用更准确的术语“字符数组”。(4) 将大部分程序的架构改为“int main( ) {… return 0; }”。(5) 尽量符合 C99 的标准,例如注释符全部改为“//”。本书由林小茶和陈昕共同编写,除了共同讨论全部章节的写作思想和内容,陈昕主要负责每章典型错误分析和第8章部分程序的编写。最后,借此次本书再版的机会,向使用本书作为教材和学习参考书的教师和读者表示衷心的感谢,并殷切希望您对本书的内容和编写方法提出宝贵的意见和建议。由于编者水平有限,疏漏在所难免,请广大读者批评指正。

作者2015年1月

免费在线读

第3章结构化程序设计结构化程序设计的3种基本结构是: 顺序、选择和循环。结构化程序设计的3种基本结构可以用流程图和NS结构图来描述,在用C语言编写程序之前,使用流程图和NS结构图描述程序功能是值得提倡的方法。在前面的章节中已经出现了许多程序,这些程序中的结构都是结构化程序设计思想中的顺序结构,通过大量的实例,读者一定对顺序结构的程序设计有了比较感性的认识。本章首先介绍结构化程序设计思想,然后分别讨论3种基本结构的程序设计方法。由于顺序结构比较简单,所以,重点是选择和循环结构。3.1结构化程序设计随着计算机软硬件的飞速发展,程序设计已经由最初的追求时间和空间效率演变为追求程序的清晰度。以现在的观念看,一个好的程序首先应该具有良好的可读性,以方便检测、修改和维护。3.1.1结构化程序设计思想的产生结构化程序设计思想的产生与20世纪60年代“软件危机”的出现有着密切的关系。计算机系统发展的初期(20世纪60年代中期以前),硬件通常用来执行一个单一的程序,而这个程序又是为具体应用而专门编写的。那时,通用硬件是很平常的事情,但是软件的通用性却是很有限的,而且那时的软件通常是规模比较小的程序,编写者和使用者往往都是同一人,软件往往带有强烈的个人色彩。早期的软件开发也没有什么系统的方法可以遵循,程序设计的自由度相当大。程序设计是程序员在头脑中完成的过程,除了源代码,没有任何文档对软件进行说明。 ;从20世纪60年代中期到70年代中期,软件开始作为一种产品被广泛使用,于是出现了“软件作坊”式的开发方法,一些程序员根据使用者的需求专职写软件。这种软件开发方法基本上仍然沿用早期的个体化软件开发方式,但随着计算机的日益普及,软件规模和数量急剧膨胀,软件需求日趋复杂,维护的难度越来越大,开发成本越来越高,而失败的软件开发项目却屡见不鲜,最终导致“软件危机”的出现。“软件危机”的出现,迫使人们围绕软件项目的开发,开展了有关开发模型、方法以及支持工具的研究。研究的主要成果就是开发了一些结构化程序设计语言(例如Pascal语言和Ada语言),并提出了结构化程序设计的思想。结构化程序设计思想的产生与是否在程序设计中使用goto语句的争论有很大的关系。为了说明问题,先来看一个带有goto语句的实例。这里要解决的问题是: 输入中国队在里约奥运会的金牌数、银牌数和铜牌数,计算并输出奖牌总数。按照顺序结构程序设计的方法,先读入3个数,再计算它们的和,最后输出计算结果。程序如下:#include "stdio.h"int main(){int gold,silver,bronze,sum;//变量定义scanf("%d%d%d",&; gold,&; silver,&; bronze);//接收输入sum=gold silver bronze; //计算奖牌总数printf("sum=%d\n",sum);//输出}如果用goto语句,可以编写下面的程序解决求和问题。#include "stdio.h"int main(){int gold,silver,bronze,sum; //变量定义scanf("%d%d%d",&; gold,&; silver,&; bronze); //接收输入goto s1;//跳转到s1语句s2: printf("sum=%d\n",sum);//输出goto s3;//跳转到s3语句s1: sum=gold silver bronze; //计算奖牌总数goto s2;//跳转到s2语句s3:return 0;}本程序也能完成求奖牌总数的功能,执行步骤是: 程序首先执行接收用户输入的语句,然后执行goto语句转到s1指示的语句求奖牌总数,接着又执行了goto语句转到s2指示的语句输出奖牌总数,输出奖牌总数以后,还要执行goto语句转到s3指示的程序结束处。不难看出,这是一个从结构上看非常混乱的程序,尽管它也能完成求奖牌总数的操作,但这个程序比顺序结构的程序可读性要差得多,跳来跳去的,所以不是一个好的程序。注意: 这个程序没有实用价值,只是为了说明加入goto语句后会导致程序结构的混乱。关于goto语句的讨论始于1968年。那一年,著名的计算机科学家Edsger W.Dijkstra发表了一篇批评goto语句的短文《Goto语句看来是有害的》,从而引发了震动程序设计界的对goto语句的长期论战。直到1974年Donald Knuth发表论文《带有Goto语句的结构化程序设计》,才结束这场论战。关于goto语句的讨论促进了关于程序结构化概念以及程序设计方法学的产生和发展。而在1966年,Corrado Bhm和Guiseppe Jacopini.就证明了只要有顺序、选择和循环3种形式的控制结构,就足以导出其他各式各样的程序结构,从而在理论上奠定了结构化程序设计的基础。1971年,Niklaus Wirth发表了“通过逐步求精方式开发程序”,首次提出了“结构化程序设计”(Structured Programming)的思想。这个概念的重点是: 不要求一步就编制成可执行的程序,而是要分若干步进行,也就是逐步求精。第一步编出的程序抽象程度最高,第二步编出的程序抽象程度有所降低……最后一步编出的程序即为可执行的程序。用这种方法编程,似乎较复杂,实际上优点很多,可使程序易读、易写、易调试、易维护,也易于保证程序的正确性及验证其正确性。结构化程序设计方法又称为“自顶向下”法或“逐步求精”法。人们已经改变了早期对软件的一些不正确看法,以前被认为是优秀的但是常常很难被别人看懂的程序已经被人遗忘。现在人们对优秀程序的看法是: 程序不但要功能正确,性能优良,还要容易看懂、容易使用、容易修改和扩充。 ;3.1.2结构化程序设计的3种基本结构结构化程序设计的3种基本结构是: 顺序结构、选择结构和循环结构。结构化程序设计思想要求任何一个程序,不论是简单的还是复杂的,都由这3种基本结构组合而成。(1) 顺序结构顺序结构就是一组逐条执行的可执行语句,按照书写顺序,自上而下执行。(2) 选择结构(分支结构)选择结构是一种先对给定条件进行判断,并根据判断的结果执行相应命令的结构。(3) 循环结构循环结构是指多次重复执行同一组命令的结构。具有循环结构的程序一般必须指定循环的终止条件,以便对程序的循环进行有效的控制,以免进入无限循环(或称死循环)的状态。结构化程序设计的3种结构可以用流程图来表示,直观形象,易于理解。常用的流程图有两种,一种是传统的流程图,另一种是NS结构图,是专门为结构化程序设计而设计的,又称“盒图”。下面我们给出3种基本结构的流程图,并以生活中的例子来说明其用法。顺序结构的流程图如图3.1所示,其中,(a)是传统流程图,(b)是NS图。两个流程图都表示了先执行A操作,再执行B操作的流程。现在用流程图来描述这样一件事: 从银行保险库中取贵重首饰。必须先到银行保险库门前,通过门禁系统对指纹的检查,然后进入保险库,用钥匙打开保险柜,取出首饰后要重新锁好保险柜,最后离开银行保险库。这个过程可以用流程图描述,如图3.2所示。选择结构的流程图如图3.3所示。选择结构的含义是: 如果条件P成立(P为真),执行A;否则,也就是条件P不成立(P为假),执行B。图3.1顺序结构的流程图图3.2“取贵重首饰”的流程图

图3.3选择结构的流程图之一下面接着使用“取贵重首饰”的例子来说明选择结构。在银行保险库门口,门卫要检查有效证件,如果进入者持有合法的有效证件,就允许其进入,否则拒绝其进入。据此,可以画出流程图,如图3.4所示。图3.4选择结构的流程图之二循环结构一般有两种,当型循环和直到型循环。当型循环的含义是: 当条件P成立(P为真)时,反复执行A,P条件不成立(P为假)结束循环,流程图如图3.5所示。直到型的含义是: 反复执行A,直到P条件不成立(P为假),也就是说,条件成立时一直执行A,流程图如图3.6所示。图3.5当型循环结构的流程图之一图3.6直到型循环的流程图之一

一般情况下,称条件P为循环条件或循环表达式,而将动作A称为循环体。生活中也经常遇到需要重复做的事情。例如,回家时忘了带钥匙或者拿着很多东西,需要按门铃通知屋里的人来开门,可以用图3.7和图3.8来描述。图3.7当型循环结构的流程图之二图3.8直到型循环的流程图之二

用当型循环来描述回家按门铃的情况可以这样理解: 首先要看看门是不是开着的,(也许刚好没锁,或是家里有人)如果门开着,不用按门铃,直接进屋;如果门没开,就要一直按门铃,等到门开了,才停止按门铃,可以进屋了。直到型与当型循环略有不同,不论门是否开着,首先要按门铃,然后再看看门是否开了,若没开,一直按门铃,直到门开了为止。也就是说,直到型循环不用先判断条件P,要先做完一次循环的动作,才判断条件;而当型循环要先判断条件,条件为真时,做循环的动作,如果条件为假,结束循环,如果第一次判断条件就为假,循环的动作就一次也不用做。直到型循环可以用当型循环的变形来替代,图3.9描述的就是与图3.8功能相同的当型循环结构,也就是,在当型循环之前,先做一次与循环体动作相同的动作,然后再判断循环条件,这样就与直到型循环思想完全一样了。因此,直到型循环可以用当型循环来替代。这里还要强调一个概念,就是循环次数。循环次数是指循环动作做了几次。有些程序的流程在程序真正执行之前是无法知道循环次数的,例如按门铃的次数就无法确定,也许一次、也许两次,如果家里根本就没有人,这样就构成了无限循环(或称死循环),永远不会有人给你开门了(只好想别的办法了)。而另一些程序的流程在程序真正执行之前就知道循环次数,例如,一个厨师要做100个月饼,流程如图3.10所示,也就是把做一个月饼的动作做100次。做月饼的循环次数是固定的,就是100次。图3.9与3.8功能相同的当型循环结构的流程图图3.10做100个月饼的流程图

循环结构是程序设计的重中之重,重复计算可以说是计算机的优势。1 1就不用麻烦它了,而计算1! 2! 3! 4! … 100!是它的强项。3.2语句与分程序在讨论相关的概念之前先来看一个程序,程序的功能是输出100以内的正偶数,每行输出10个数。注意,该程序的细节不需要理解,只是通过它掌握一些概念。输出结果如下:24681012141618202224262830323436384042444648404244464850【例3.1】输出100以内的正偶数,每行输出10个数。#include"stdio.h"//第1行int main() //第2行{int x;//第3行x=1; //第4行for(;x<;=100;x ) //第5行{if(x%2==0)//第6行printf("%4d",x); //第7行if(x%20!=0)//第8行;//第9行else //第10行printf("\n"); //第11行}//第12行return 0;//第13行} //第14行例3.1中首先定义了一个变量x,第4~11行是C程序的执行部分。执行部分由执行语句构成,执行语句大致包括表达式语句、函数调用语句、控制语句、复合语句(或称分程序)和空语句等。1. 表达式语句程序3.1中的第4行“x=1;”就是表达式语句。表达式语句是在一个符合C语言语法的表达式后面加一个分号,这是最简单的可执行语句。又例如: i;x=y;有一点要注意,有效的表达式语句一般都要包含赋值运算,不做任何赋值运算的表达式语句往往是没有意义的。例如,表达式“y<;<;3”表示将y左移3位,如果在这个表达式加上分号,即“y<;<;3;”,这就是一条毫无意义的语句,因为运算结果没有存放到任何存储单元中。2. 函数调用语句程序3.1中的第7行“printf("%4d",x);”就是函数调用语句。由函数名、实际参数以及分号构成。在语句“printf("%4d",x);”中,printf是函数名,"%4d",x是实际参数。函数名既可以是C语言提供的库函数名,也可以是用户自己定义的函数名。3. 控制语句程序3.1中的控制语句有for语句和if语句。控制语句是能够改变程序的顺序结构的语句,也可以说是用于控制程序流程的语句。C语言的控制语句比较丰富,与选择结构有关的语句有if,switch和break语句,与循环语句有关的语句包括while,dowhile,for,continue以及break语句,另外,还有两个特殊的语句goto和return,尽管编写好的程序不提倡使用goto语句,但是C语言仍然提供了对goto语句的支持。return 语句用于函数的返回,在很多情况下都可以省略。4. 复合语句和分程序结构复合语句是用“{”和“}”把数据说明语句和若干个有序的执行语句组合在一起而构成。程序3.1包含了两个复合语句,第3~14行是一个复合语句,第6~12行是第2个复合语句。其一般格式为{[数据说明];[语句];}复合语句在语法上相当于一个简单语句,在程序中可以作为一个独立语句来看待,因此又称为分程序。复合语句的执行按在其中的语句顺序执行。由于在程序中,每个简单语句都可以用复合语句来代替,而复合语句的每个执行语句又可以是控制语句或简单语句,这样,C语言的语句就形成了一种层次结构,原则上可以不断地扩大这种层次。复合语句中的每个说明语句和执行语句都必须带分号,而在花括号的后面不用加分号。用复合语句代替多个简单语句是C语言的特征之一。其优点是: 使用灵活,并可以在分程序中说明局部变量。5. 空语句C语言中有一个很特殊的语句,即空语句。顾名思义,空语句就是什么也不存在的语句,只有一个分号:;程序3.1的第9行就是一个空语句。在此的含义是: 如果x模20的结果不等于0,则什么都不做。尽管空语句不会有任何命令执行,但仍然是一个有用的语句。常用于循环语句中,使循环体为空。如果没有空语句,当循环体内没有任何语句时,就无法表示了。例如,“for(sum=0,i=0;i<;=9;i ,sum=sum i);”中的循环体是空语句。注意: 程序3.1为了解释一些概念,编写的程序不简练。比较好的编写方法如下:#include"stdio.h"int main(){int x;//变量定义for( x=1;x<;=100;x )//循环从x从1~100{if(x%2==0)//如果x能被2整除 ;printf("%4d",x); //输出x ;if(x%20==0) //如果x能被20整除printf("\n");//换行} ;return 0;}3.3顺序结构程序设计顺序结构程序设计就是将语句按照正确的逻辑规则由上而下地书写C的语句。就像取贵重首饰的过程一样,通过证件的检查,才能打开保险柜,然后取首饰。如果把这3个动作调换一下,是不符合现实情况的。因为如果未通过证件的检查,就不能打开保险柜,当然也就不能取到首饰。顺序程序设计的步骤可以归纳如下:(1) 用预处理命令包含文件或进行宏定义(不是必需的,根据具体情况)。(2) 定义变量(分配内存空间)。(3) 为变量赋初值(可以用赋值语句或输入函数)。(4) 计算。(5) 输出结果(用输出函数)。【例3.2】编写程序输入长方形的长和宽,求长方形的面积和周长并输出,用浮点数据处理。#include"stdio.h"int main(){double length,width,area; //定义变量printf("请输入长方形的长:"); //提示用户输入长方形的长scanf("%lf",&;length);//接收输入printf("请输入长方形的宽:"); //提示用户输入长方形的宽scanf("%lf",&;width); //接收输入area=lengthwidth; //计算长方形的面积printf("长方形的面积=%lf",area);//输出长方形的面积printf("长方形的周长=%lf",2(length width)); //输出长方形的周长return 0;}编写程序要养成良好的习惯,一般在接收数据的语句之前,要显示一些信息提示用户应该做什么,因此,本程序在接收用户输入长方形的长和宽两个数据之前,都显示了明确的提示信息。本例中,定义了一个存储长方形的面积的变量area,但是并没有定义存储长方形的周长的变量,而是通过表达式的值输出了长方形的周长。也就是说,对于计算结果可以存储到内存中,也可以不存储,直接输出。【例3.3】编写程序,输入x和y,交换它们的值,并输出交换前后x和y的值。//----------------------- swap x and y ------------------#include "stdio.h"int main(){int x,y,temp;printf("请输入两个整数:");//提示用户输入两个整数scanf("%d%d",&;x,&;y); //接收输入printf("交换以前x=%3d y=%3d\n",x,y); //输出交换以前x和y的内容 ;temp=x;x=y;y=temp;printf("交换以后 x=%3d y=%3d",x,y); //输出交换以后x和y的内容 ;return 0;}程序运行情况:请输入两个整数:4 6↙交换以前 x=4 y=6交换以后 x=6 y=4本程序利用第3个变量temp来完成交换工作。先将x赋值给temp,再将y赋值给x,由于x的值已经存放于temp中,最后将temp(原先是x的值)赋值给y,这样就完成了交换。注意这3条语句的顺序不能随便交换,请读者自己举例说明为什么。3.4关系运算符与逻辑运算符不论是选择结构还是循环结构,都需要对一个特定条件进行判断,是否满足条件与下一步的动作有密切的关系。以做100个月饼为例,只要做的月饼不够100个,就要继续做下去,一旦做够了100个,就不用再做了。“不够100个”就是一个条件。在C语言中,条件用表达式来表示,表示条件的表达式中最常用的运算符是关系运算符和逻辑运算符。3.4.1关系运算符【例3.4】编写程序,接收用户输入的x和y,输出这两个数中大的那个数。//------------------------比较大小 ---------------------#include "stdio.h"int main(){int x,y;//变量定义printf("请输入两个整数:");//提示用户输入两个整数scanf("%d%d",&;x,&;y); //接收输入if(x>;y)//如果x大于yprintf("max=%d\n",x);//输出xelse //否则 ;printf("max=%d\n",y); //输出yreturn 0;}尽管尚未讨论ifelse 语句的语法,但是,只要有一定的英语基础(再加上中文注释),是不难看懂程序的。程序首先接收用户输入的两个整数,然后将两个数中大的那个数输出。在该程序中,x>;y是比较x和y的大小,“>;”是关系运算符。比较两个数值的大小的运算就称为关系运算。比较两个数值的大小的运算符就是关系运算符。关系运算符包括有大于(>;)、大于或等于(>;=)、小于(<;)、小于或等于(<=)、等于(==)、不等于(!=)。由关系运算符连接起来的表达式就是关系表达式。程序中的x>y是关系表达式。还可以举出一些关系表达式的例子。例如,x>=0,x==y,x!=y以及3>2等。那么,关系表达式的计算结果是什么呢?从方便理解的角度讲,关系表达式的结果只有两种可能,成立或不成立,只不过在C语言中,关系表达式表示的关系成立时,表达式的值为整数1;关系表达式表示的关系不成立时,表达式的值为整数0。也就是说,在C语言中,系统计算一个关系表达式的值时,得到的解只有两种可能的值: 整数1和整数0。例如,如果变量x的内容为6,那么,x>=0是成立的,则表达式x>=0的值是1;而x<0不成立,表达式x<0的值是0。又例如,表达式3>2表示“3大于2”,这是一个永远都正确的表达式,因此,3>2的值是1;而表达式3<2表示“3小于2”,肯定是不正确的,3<2的值是0。如果有调用函数printf输出关系表达式的结果,应该使用%d控制输出格式。“printf("%d%d ",3>2,3<2);”语句执行的结果是10。注意: 许多高级语言中关系表达式的结果是用一种特殊的数据类型——“逻辑型”来表示的。例如在Pascal中,关系表达式表示的关系成立时,表达式的解为逻辑值True(真);关系表达式表示的关系不成立时,表达式的解为逻辑值False(假)。这时,逻辑型的数值只有两种值(真或假)。但是C语言的基本数据类型中没有逻辑型,所以,关系表达式的值用整数1表示逻辑真,整数0表示逻辑假。6个关系运算符中的“!=”和“==”的优先级小于其余4个运算符。关系运算符的优先级小于算术运算符,大于赋值运算符。关系运算符的结合性均为自左至右。【例3.5】输入10 8 6,判断下列程序的运行结果。//-----------------------比较大小 --------------------#include "stdio.h"int main(){int x,y,z; //变量定义printf("请输入两个整数:"); //提示用户输入两个整数scanf("%d%d%d",&x,&y,&z); //接收输入if(x>y>z) //错误语句 printf("最大值=%d\n",x);//输出xreturn 0;}运行程序,输入10 8 6,但是程序的执行结果是无任何输出。为什么没有输出10呢?原因是什么呢?因为表达式x>y>z的计算过程是: 先计算x>y,由于x的值为10,y的值为8,则x>y相当于表达式10>8,10>8是成立的,结果为1,接下来计算1>z,由于z的值是6,1>6不成立,导致x>y>z的计算结果是不成立的,也就是说,x>y>z不能表示“x大于y并且大于z”,正确表示“x大于y并且大于z”需要使用逻辑表达式x>y&&y>z。&&是C语言的逻辑与运算符。3.4.2逻辑运算符第2章讨论过二进制的“与、或、非”运算,称其为位逻辑运算。如果将“与、或、非”运算的思想应用于逻辑值(逻辑真和逻辑假)就称为逻辑运算。逻辑运算与关系运算是有密切联系的,逻辑表达式的计算结果是逻辑真和逻辑假。C语言用非零整数(包括1) 表示真,而用0表示假。例如,x大于y并且大于z的正确表示是x>=y&&y>=z其中,&&是逻辑与运算符。C语言中的逻辑运算符有3个,逻辑与&&、逻辑或||和逻辑非!,其中,逻辑与和逻辑或是双目运算符,逻辑非是单目运算符。逻辑运算的规则与二进制的位逻辑是相似的。逻辑运算的规则见表3.1。表3.1逻辑运算的规则AB!A!BA&&BA||B逻辑真逻辑真逻辑假逻辑假逻辑真逻辑真逻辑真逻辑假逻辑假逻辑真逻辑假逻辑真逻辑假逻辑真逻辑真逻辑假逻辑假逻辑真逻辑假逻辑假逻辑真逻辑真逻辑假逻辑假表达式x>=y&&y>=z的值是如何计算的呢?按照运算符的优先级,首先计算x>=y,再计算y>=z,再将这两个结果做与运算。假设,x,y和z的值分别是10,8和6,则x>=y的值是逻辑真,y>=z的值也是逻辑真,按照表3.1,逻辑真与逻辑真做“与”运算仍然是逻辑真,此时x>=y&&y>=z的值就是逻辑真了。【例3.6】输入10 8 6,判断下列程序的运行结果。//----------------------比较大小 ----------------------#include "stdio.h"int main(){int x,y,z;//变量定义printf("请输入两个整数:"); //提示用户输入两个整数scanf("%d%d%d",&x,&y,&z); //接收输入if(x>y&&y>z) //正确printf("最大值=%d\n",x); //输出xreturn 0;}程序的输出是: 最大值=10,结果是正确的!如果用户输入的是8106,则程序不会有任何输出。需要说明的是,C语言系统对任何非0值都认定为逻辑真,而将0认定为逻辑假。也就是说如果一个表达式参与逻辑运算,只要这个表达式的解为非0,则系统就认为这个表达式的结果是逻辑真。但是要注意,系统逻辑运算的结果仍然只有两个: 1(逻辑真)和0(逻辑假)。尽管表达式3&&2不是提倡的写法,但是它确实是一个C语言编译器能够识别的写法。这是因为3和2都是非0值,按照规则,逻辑真&&逻辑真的计算结果为逻辑真,逻辑真表示为整数1,也就是说,3&&2的计算结果是1,当然除了考试,谁也不会这样写程序。逻辑运算符经常与关系运算符一起使用,再举个例子,考试成绩应该在0~100分,数学表达方式是0≤score≤100,而C语言表达式是((score>=0)&&(score<=100))。注意,为了正确表示运算符号的优先级,可以将&&运算符号前后的表达式用圆括号括起来。用逻辑运算符将关系表达式或逻辑量连接起来的式子叫逻辑表达式。(score>=0)&&(score<=100)和3&&2都是逻辑表达式。逻辑运算符中逻辑非(!)的优先级最高,然后是逻辑与(&&),最后是逻辑或(||)。与其他运算符相比,逻辑非(!)的优先级高于算术运算符(当然也高于关系运算符)和赋值运算符,而逻辑与(&&)和逻辑或(||)的优先级高于赋值运算符,但是低于算术运算符和关系运算符。逻辑非(!)是单目运算符,其结合性是自右至左;逻辑与(&&)和逻辑或(||)的结合性是自左至右。在此,同样要强调,如果将算术、关系、逻辑等运算符混合用于一个表达式时,应该使用圆括号表示运算的先后顺序。还有一个问题要特别引起注意的是: 在C语言中,如果逻辑运算符的左操作数已经能够确定表达式的最终解,则系统不再计算右操作数的值。例如: 对于表达式x==1 && y==0,若x此时不为1,在检测x==1以后,系统就不会再检测y==0。因为x==1的结果是逻辑假,逻辑假与任何数进行逻辑与操作结果都会是逻辑假。这是C编译为了提高速度做的代码优化。但是,一定要注意避免使用带有副作用的表达式。例如,对于表达式x==y ||x=0的计算,若x==y成立,则表达式的值为真,不需要继续做x=0了。但是,若x==y不成立,由于x=0是个赋值表达式,表达式的结果很可能是错误的。假设该表达式计算以前,x值为1,y的值为0,x==y的计算结果是0,这时需要执行赋值运算x=0,表达式的结果仍然是0,而这时的x和y的值均为0,又满足了x==y,这不是产生了矛盾吗?书写表达式的原则是: 不要在一般的表达式中夹杂赋值运算。当多种运算符在一个表达式中混合使用时,要注意运算符的优先级,防止记错运算符优先级的最好方法是加圆括号。编写“好看”的程序,一定要注意有好的习惯,在表达式中间加圆括号是一个好的方法。3.5选择结构程序设计结构化程序设计的3种基本结构中的选择结构的基本思想是: 程序可以根据不同的情况采取不同的动作。就像我们走到一个十字路口,要根据交通标志灯来确定自己是否过马路,所谓“红灯停,绿灯行”。在C语言中,能实现选择结构程序设计的语句有if条件语句和switch多分支语句,本节通过几个简单的程序初步讨论使用选择结构的程序。3.5.1问题提出与程序示例假设某社区要举行围棋比赛,根据报名情况决定比赛的方式。第1种是只分一组进行比赛,要求参加比赛的必须成年(大于等于18岁);第2种是分两组进行比赛,一组是成年人,另一组是儿童;第3种是分四组进行比赛,一组是儿童(小于18岁),一组是青年(18~45岁),第3组是中年(45~55岁),第4组是老年(55岁以上)。现在要编写3个程序,对不同的分组情况进行处理。【例3.7】编写程序,输入报名者的岁数,如果大于等于18岁,允许参加比赛(只分一组)。//-------------------比赛报名处理1------------------------#include "stdio.h"int main(){int age;//定义整型变量记录岁数printf("请输入年龄 (0<=年龄<=150): ");scanf("%d",&age);//接收岁数if(age>=18)//判断岁数是否大于等于18printf("允许参加\n"); //如果是输出“允许参加”return 0;}本例使用的是if形式的选择结构。而对于分两组进行比赛的处理方式是: 如果报名者的岁数大于等于18岁,参加“成人”组比赛;否则参加“儿童”组比赛。【例3.8】编写程序,输入报名者的岁数,如果大于等于18岁,分在“成人”组;否则分在“儿童”组。//------------------比赛报名处理2------------------------#include "stdio.h"int main(){int age;//定义整型变量记录岁数printf("请输入年龄 (0<=年龄<=150): ");scanf("%d",&age);//接收岁数if(age>=18) //判断岁数大于等于18printf("参加成人组\n"); //参加成人组elseprintf("参加儿童组\n ");//参加儿童组return 0; }本例使用的是if else 形式的选择结构。【例3.9】编写程序,输入报名者的岁数,小于18岁分儿童组,18~45岁分在青年组,45~55岁分在中年组,55岁以上的分老年组。//--------------------比赛报名处理3------------------------ #include "stdio.h"int main(){int age;//定义整型变量记录岁数printf("请输入年龄 (0<=年龄<=150): ");scanf("%d",&age);//接收岁数if(age<18)printf("参加儿童组\n");//岁数小于18参加儿童组else if(age<45)printf("参加青年组\n");//岁数小于45输出参加青年组else if(age<55)printf("参加中年组\n");//岁数小于55输出参加中年组else printf("参加老年组\n");//参加老年组return 0;}本例使用的是else if 形式的选择结构。注意: 在例3.7、例3.8和例3.9中都有信息提示,要求用户输入一个正确的岁数,这样才能保证程序的正确执行,如果用户输入的不是一个正确的岁数,比如-10岁,这3个程序是不能给出正确结果的,因为程序没有判断输入数据的合法性,而是假设用户的输入是合法的,这个问题将在后面解决。3.5.2if语句的3种形式〖*4/5〗1. if形式 if形式是比较单一的选择,当条件满足时,执行规定的语句;条件不满足时,就什么也不用做。if 形式是最简单的条件语句。if 形式的语法格式为if(表达式)语句1;下一条语句;if形式的流程图和NS图如图3.11所示。if语句中的表达式一般称为条件表达式。图3.11if形式的流程图if形式表示的选择结构属于单分支结构。因为只有条件为真时做动作,而条件为假时不做动作。if 形式的功能是: 检测表达式,如果表达式的值为非0(真),则执行语句1,然后执行下一条语句;如果表达式的值为0(假),直接执行下一条语句。【例3.10】使用if形式编写程序: 输入x,求出并输出x的绝对值。图3.12求绝对值求x的绝对值的数学公式是:y=xx≥0-xx<0y是x的绝对值,如果x大于等于0,x的绝对值就是x自己;否则,x的绝对值就是x的负值。首先画出NS流程图,如图3.12所示。#include "stdio.h"//-------------------abs(x)----------------------------------int main(){int x;//变量定义printf("请输入一个整数:"); //提示scanf("%d",&x);//接收输入if(x<0) //如果 x小于0x=-x; //x取负 printf("|x|=%d\n",x); //输出结果return 0;}运行情况1:请输入一个整数:-5↙|x|=5运行情况2:请输入一个整数:5↙|x|=5初学者要注意:if(x<0)x=-x;不能写成if x<0x=-x;图3.13保持a>bif x<0一句将不能通过编译。这意味着if后面的条件表达式必须用圆括号括起来,千万不能省略。【例3.11】使用if形式编写程序: 若a>b将两个数的位置调换;否则保持不变,见图3.13。#include "stdio.h"//-------------------swap a and b------------------------int main(){int a,b,temp;//变量定义printf("请输入两个整数:"); //提示scanf("%d%d",&a,&b); //接收输入if(a>b)//如果 a小于b{temp=a;//a与b做交换a=b;b=temp;}printf("%d,%d\n",a,b);//输出a和b return 0;}运行情况:请输入两个整数: 6 4↙4,6注意: 不能将上述程序中的if形式写成如下的方式:if(a>b)temp=a;a=b;b=temp;这段程序不能满足题目的要求。在这个程序段中,如果a>b的条件成立时,只执行了一条语句“temp=a;”,而后面两条语句无论a>b是否成立,都是要执行的。也就是说,如果a>b条件成立,先执行语句“temp=a;”,然后从if的分支出来以后,会执行语句“a=b;”和“b=temp;”,因此a>b条件成立时,能够满足交换a和b的要求;但是,如果a>b条件不成立,直接从if语句出来执行语句“a=b;”和“b=temp;”,执行的结果是破坏了a和b原来的内容,与题目的要求不符,因为题目要求a>b条件不成立时,不做交换,保持不变。通过本例题,必须理解: if形式语法中的语句1既可以是单个语句,也可以是复合语句。使用单个语句时,语句结束符分号“;”一定要写,超过一条语句就必须使用复合语句,使用复合语句时需要用花括号{}将一组带分号的语句括起来。【例3.12】请判断下面程序的执行结果,并解释该程序的功能。#include "stdio.h"int main(){int a=10,b=20,x;x=a;if(a

b&&a>c)//如果a>b并且a>c printf("%d最大\n",a); //输出a if(b>a&&b>c)//如果b>a并且b>c printf("%d最大\n",b); //输出b if(c>a&&c>b)//如果c>a并且c>b printf("%d最大\n",c); //输出creturn 0;}在本例中,if后面的条件表达式不但使用了关系运算符,还使用了逻辑运算符,这两种运算符都是最常用的。尤其出现比较复杂的运算时,通常都会将关系运算符和逻辑运算符混合使用。需要注意的是,与其他高级语言不同,C语言对条件表达式的语法要求并不十分严格,在C语言中,条件表达式还可以是一般的表达式,甚至是一个常量或一个变量,例如,if(x)和if(checkstate())都是正确的,只要x或checkstate()的值为非0,则条件表达式即为真。另外,还要请读者注意,由于只学习了if形式的语法,本程序不是效率最高的编写方法。#include "stdio.h"//-------------------求3个数中的最大数------------------------int main(){int a,b,c,max; //变量定义printf("请输入三个整数:"); //提示scanf("%d%d%d",&a,&b,&c); //接收输入max=a;//假设a最大if(b>max)//如果b大 max=b;//b存储到max中 if(c>max)//如果b大 max=c;//c存储到max中 printf("%d最大\n",max);//输出maxreturn 0;}本程序的思想对于初学者来说是非常重要的,比较3个数中谁最大,不妨先假设第1个最大,并将其存入变量max,接着,用b与max相比,b大的话,就用b覆盖max,然后用c与max相比,c大的话,就用c覆盖max。这个算法不但执行效率高,用max空间存放最大值的思想也非常重要。2. if else形式if形式是单分支结构,只允许在条件为真时指定要执行的语句,而if else形式是双分支结构,不但允许条件为真时指定要执行的语句,还允许在条件为假时指定要执行的语句。if else 形式的语法是if(表达式)语句1;else 语句2;下一条语句;if else形式功能是: 检测表达式,如果表达式的值为非0(真),则执行语句1,然后执行下一条语句;如果表达式的值为0(假),执行语句2,再执行下一条语句。if else形式的流程图和NS图如图3.14所示。注意: 使用if else形式时,条件表达式的设计要准确,要保证非此即彼,满足条件时,执行语句1,不满足时执行语句2。【例3.14】将输入字符的大写字符转换成小写字符输出,小写字符原样输出,如图3.15所示。图3.14if形式的流程图图3.15大写字母转化为小写字母

#include "stdio.h"//-------------------lowercase--------------------------int main(){int c;//变量定义c=getchar();//接收输入if(c>=A && c<=)//若字母大写putchar(c 32);//输出小写elseputchar( c);//输出原字符 return 0;}解决这个问题时,首先要考虑如何判断输入的字符是大写还是小写字符,可以观察一下ASCII码表,从中可以看出,A~的ASCII码值是连续的,a~z的 ASCII码值也是连续的,因此如果一个字符的ASCII码值为A~,说明这个字符是大写字母。因此条件表达式(c>=A && c<=)成立,表示c中存储的字符是大写字母。第二点要考虑如何将大写转换成小写,同样要观察一下ASCII码表,可以发现A的ASCII码值是65,a

C程序设计教程(第3版) pdf下载声明

本pdf资料下载仅供个人学习和研究使用,不能用于商业用途,请在下载后24小时内删除。如果喜欢,请购买正版

pdf下载地址

版权归出版社和作者所有,下载链接已删除。如果喜欢,请购买正版!

链接地址:C程序设计教程(第3版)