• 1. C语言程序设计
  • 2. 教材分析 本书内容共有11章,可分为三部分。 第1、2章为第一部分,为初学者的入门知识,使读者对c语言编写程序的步骤、方法和程序结构及算法描述有一个大致的了解。 第3~第5章为第二部分,是程序设计的基础部分,使读者详细了解c语言的基本数据类型和表达式以及c语言的控制结构。掌握了第一、二部分的内容,读者可以完成简单的程序设计。 第6章~第11章为第三部分,讲述了模块化程序设计的概念和实现的方法,为程序设计提供了更多、更方便的途径,为进行综合程序设计奠定了基础。每一个章节里都有详细的程序范例来说明程序的设计思想、语句的概念、作用、含义和使用方法,使学生能够由浅入深系统地学习c语言的知识,同时掌握一定的编程方法。   
  • 3. 成绩考核成绩考核方法: 期末成绩=平时成绩20%+期末考试80%; 注:平时成绩包括:上课情况、作业情况、上机作业完成情况等。
  • 4. 学习C的忠告上机实践(编程)!!! (Try!!!)
  • 5. C语言程序设计教程第1章 引言 第2章 程序的简单算法制定 第3章 基本程序语句 第4章 选择结构 第5章 循环结构 第6章 函数与编译预处理 第7章 数组 第8章 指针 第9章 构造数据类型 第10章 文件 第11章 位运算
  • 6. 《C语言程序设计》课程的任务 1. 指导学生掌握 C 程序设计语言的基础知识; 2.培养学生综合分析并编制程序解决实际应用问题的能力; 3.培养学生契而不舍的解决问题的精神以及认真的学习态度。 通常我们把设计、书写及检查调试程序的过程称为程序设计。应当指出,简单的程序设计应包括以下几个部分: 确定数据结构 确定算法 编写代码 调试并运行 整理并写出文档资料
  • 7. 第一章 引 言1.1 C语言的特点 1.2 简单的C语言程序介绍 1.3 C语言程序的结构 1.4 C程序设计语言的执行
  • 8. 1.1 C语言的特点C语言有9种控制语句,32个关键字。 运算符丰富。共有34种运算符 数据结构类型丰富。 具有结构化的控制语句 语法限制不太严格,程序设计自由度大。 C语言允许直接访问物理地址,能进行位操作,可以直接对硬件进行操作。 生成目标代码质量高,程序执行效率高。 C语言编写的程序可移植性好。
  • 9. 1.2 简单的C语言程序介绍/*ex101.c-在屏幕上输出This is a C program. */ #include void main( ) { printf(“This is a C program.\n”); }
  • 10. ①注释 /*ex101.c-在屏幕上输出This is a C program. */ C程序中的“/* … */”之间的内容称为注释,是程序编写者给程序阅读者留下的一些说明(注释),以帮助阅读者理解程序。编译器不对注释进行编译,只将它们当作空白看待。 本程序的第1行中的注释为“ex101.c”,是说明本书编写时将这个程序保存在文件ex101.c中。
  • 11. ②库函数与文件包含命令include #include 库函数:系统提供的标准函数,程序可直接使用; 使用库函数必须将其有关说明信息写入程序。为了用户方便,系统定义库函数时,把一类相关库函数的说明信息,分别写在一些文件中。本例中使用了库函数printf ,其有关说明信息写在文件stdio.h中。所以在程序的开始加入了#include 使用C语言的库函数,要在程序前面加上类似#include 的预处理命令
  • 12. ③ main函数任何C程序都必须有且只能有一个主函数main(),它是程序的入口,也是程序的出口。其中,main是函数名,()内可以包含一些参数;{ }的内容称为函数体,其包含若干条C程序语句;不同语句之间用分号分隔;一般情况下,每个程序都由一至多个函数组成; 表示main函数没有返回值函数名函数体语句void main( ) { printf(“This is a C program.\n”); }演示ex101
  • 13. ④语句 printf(“This is a C program.\n”);C语言的主函数体由一些语句组成。每个语句由一个分号结束。如本例中,主函数的一个语句: printf (“This is a C program.\n”); 说明: 函数printf是系统提供的一个库函数,printf函数的功能是向显示器 输出一段信息,具体内容括在双引号内; 参数中的“\n”代表一个命令:输出完这行字符后换行,不是要求显示的文字。
  • 14. 例2 写出以下程序的运行结果写出以下程序的输出结果 #include void main( ) { printf(“Hello\n”); printf(“world!\n”); } 演示 ex102
  • 15. 例3 四则运算编程#include int add(int x,int y); main() {int a,b,c; scanf("%d %d",&a,&b); c=add(a,b);/*函数调用语句*/ printf("c=%d",c);} int add(int x,int y) {return(x+y);}演示ex103 演示ex104 讨论减、乘、除的编程输入函数 Scanf()函数说明函数定义
  • 16. 1.4 C程序设计语言的执行对于C语言程序来说,这一过程一般分为4步: 第1步:编辑源程序; 第2步:编译; 第3步:链接; 第4步:执行;
  • 17. (整个过程如下图)filename.c编 辑(edit)编辑器filename.obj预处理编 译(compile)编译器filename.exe库函数和 其他目标模块链 接(link)链接器出错出错执 行(excute/run)结果出错出错调试debug
  • 18. 编 译编译就是把用C语言描述的程序翻译成计算机可以直接理解并执行的机器语言命令组成的程序。C语言的编译过程分为两个阶段:首先是编译预处理,系统要先扫描程序,处理所有预处理命令,如把文件包含命令要求的文件包含(嵌入)到程序中。然后才开始编译。编译后得到的文件称为目标文件。目标文件就是用机器语言描述的文件。C语言的目标文件的后缀为.obj。目标文件的主文件名,一般与源程序文件名相同。 在编译过程中,还要对源程序中的语法和逻辑结构进行检查。编译任务是由称做编译器(compiler)的软件完成的。程序在编译过程中,也可能发现错误。这时要重新进入编辑器进行编辑。
  • 19. 链 接链接是将与当前程序有关的、已经有的几个目标模块链接在一起,形成一个完整的程序代码文件。这些已经有的目标模块有: · 库函数:如前面使用的printf; · 对于大的程序,常常分成几个模块,分别编写、编辑和编译,形成不同的目标模块。 经正确链接所生成的文件才是可执行文件。可执行文件的文件名后缀为.exe(有的系统为.out)。完成链接过程的软件称为链接器(linker)。 程序在连接过程中,也可能发现错误。这时也要重新进入编辑器进行编辑。
  • 20. 执 行链接后得到的可执行文件名,对操作系统来说,相当于一条命令。在操作系统提供的命令界面上打入这个命令,就可以开始执行这个程序。
  • 21. C语言的集成开发环境Turbo c 2.0 Turbo c++(选用)Vc++等 (1)打开Turbo c++运行环境。界面如图:
  • 22. 从图可以看到在集成环境的上部,有一行“主菜单”,其中包括下面10个菜单项: File Edit Search Run Compile Project Options Debug Window Help 分别代表:文件操作、编辑、查找、运行、编译、项目文件、选项、调试、窗口、帮助等功能。用户可通过以上菜单项来选择使用Turbo C集成环境所提供的各项主要功能。 (2)编辑源程序。 在File菜单下选择NEW子菜单项命令,系统的光标处于等待输入C源程序状态。输入完源程序后,选择File菜单下选择Save as子菜单项命令进行保存,在随后弹出的保存文件对话框中,输入文件名*.c后按“↙” (3)编译源程序 选择Compile主菜单项并在其下拉子菜单中选择Compile 命令,则进行编译。若源程序无语错误,生成可执行文件EXE;若源程序有语法错误,在Message窗口显示错误信息,此时没有生成可执行文件,应回到第2步,修改程序的错误,直到无语法错误、生成可执行文件。 返回
  • 23. (4) 连接程序 在Compile菜单中,选择Link子菜单项命令,程序将被连接成可执行程序。 注:按F9键,可一次完成编译和连接。 (5) 执行程序。选择Run子菜单命令,或按快捷键Ctrl+F9。 (6) 看结果。程序运行后看结果必须选择File菜单下的DOS Shell命令 或者按快捷键Alt+F5,才能看到运行的结果。 如程序未得到预期的结果,应回到第2步,修改程序的错误。 (7) 退出Turbo C++,File---Quit菜单命令或按Alt+X。
  • 24. 总结:简单C语言程序设计步骤分析问题,设计解决方案 了解和编写C语言程序代码上机调试(编辑、编译、链接、执行)理论课的主要内容 实验课的主要内容 上述每个步骤都可能出现很多错误,具体有三种错误:语法错误、逻辑错误、运行错误。总之,出现错误就要进行调试。
  • 25. 作 业1、在屏幕上输出如下图形:    ****   *  *  *  *25 **** 要求:写出程序,并上机调试,尽量保证程序能够得到正确结果。复习本讲内容(第一章),预习教材第二章。
  • 26. 第二章 程序的简单算法制定2.1 结构化程序的算法制定 2.2 结构化程序的算法描述 2.3 算法制定的范例
  • 27. §2.1 结构化程序的算法制定1利用计算机处理问题简述
  • 28. §2.1 结构化程序的算法制定例2.1 从键盘输入3个数,找出其中最小的那个数。 分析:1、需变量的个数----3个 2、先比较a,b的值,把小的存在min中。 3、再用min与c比较,把数值小的存放在min中。 如果 a
  • 29. 【例】让某学生解方程 ax2+bx+c=0 求解过程: ①分析问题 这是一个一元二次方程(代数问题,须中学代数知识) ②确定处理方案 用求根公式 ③确定解题步骤 确定a、b、c的值 求出b2 -4ac的值 如果 b2 -4ac>0(双实根) X1=…… X2=…… 如果 b2 -4ac=0(单实根) X1=X2=…… 如果 b2 -4ac<0(双复根) X1=…… X2=…… ④根据上述步骤计算 ⑤写出答案,整理、分析结果
  • 30. §2.2 结构化程序的算法描述什么是算法 为解决一个问题所采取的方法和步骤称为算法。 算法的特性 有穷性、确定性、有零个或多个输入、有一个或多个输出、有效性。 算法有两个很重要的方面: (1)按什么顺序或步骤执行 (2)用什么语句来实现
  • 31. §2.2 结构化程序的算法描述自然语言 特点:易懂、冗长、易产生歧义 流程图 N-S结构化流程图 PAD图 伪代码 计算机语言
  • 32. 伪码语句示例之一 if student’s grades greater than or equal to 60 display ” Passed” else display ”Failed”伪码语句示例之二 如果学生成绩大于或等于60 显示”及格” 否则 显示 ”不及格”C语言源程序段示例 if (grade>=60) printf(“Passed!”); else printf(“Failed”);算法可采用自然语言、流程图、N-S图、PAD图、伪代码等方法来描述。 示例:根据学生成绩输出评定结果。一、算法(algorithm)
  • 33. 二、算法与流程图——传统流程图特点: 直观形象; 使用流线。 缺点: 占面积大,使用流线任意转移,易出现“乱麻”现象,造成编程与阅读程序困难。
  • 34. 二、算法与流程图——N-S结构化流程图 77年美学者I.Nassi和B.Scheiderman提出。 特点 ①取消流线 ②不允许流程任意转移,只能从上而下顺序执行 ③规定三种基本结构的流程图单元,由这些基本结构象搭积木似的组成各种算法(结构化设计)。 优点 算法清晰,流程不会无规律乱转移。
  • 35. 二、算法与流程图————三种基本结构通常情况下,程序中的语句是以所编写的顺序一句接一句地执行,这种执行方法称为“顺序执行”。许多C语句能够让程序员指定不按编写顺序执行下一条执行语句,这种执行方法称为“控制转移”。 Bohm和Jacopini的研究证实,所有的程序都能够只用三种控制结构编写,即 ◆顺序结构 ◆选择结构(selection structure) ◆循环结构(repetition structure) 顺序结构是C语言的基本结构,除非指示转移,否则计算机自动以语句编写的顺序一句一句地执行C语句。 任何C语言程序都是由七种控制结构(顺序结构、三种选择结构和三种循环结构)构成的。
  • 36. 二、算法与流程图————三种基本结构顺序结构 A块、B块顺序执行(每块代表一个或一组操作)
  • 37. 二、算法与流程图——三种基本结构选择结构 条件p成立时执行a块(否则执行b块) if 选择结构 条件为真时执行某个指定的操作,条件为假时跳过该操作(单路选择) if…else选择结构 条件为真时执行某个指定的操作,为假时执行另一个指定的操作(双路选择) switch选择结构 根据表达式的值执行众多不同操作中的某个指定的操作(多路选择)
  • 38. 二、算法与流程图——三种基本结构循环结构 分当型和直到型两类。 当型 先判断,只要条件为真就反复执行A块,为假则结束循环。 直到型 先执行A块,再判断条件是否为真,为真则继续执行循环体,为假则结束循环。 C语言提供了三种循环结构,即while循环结构,do…while循环结构和for循环结构。
  • 39. §2.2.3 PAD图PAD(Problem Analysis Diagram)另一种被广泛使用的一种算法的图形表示法。 PAD图可以看成是二维的,它能展现算法的层次结构。(顺序结构很简单,在此未画图。)
  • 40. §2.3 算法制定范例例2.4 把从键盘输入的大写字母转换成小写字母,输出结果。 问题: 1、描述算法 2、根据算法编写C程序 3、运行检查程序是否正确。 演示ex202
  • 41. §2.3 算法制定范例例2.5 已知实数a和b,计算u的值:u=(r+s)2。其中,当a
  • 42. 开始输入a,ba
  • 43. 输入实数a,ba
  • 44. 输入实数a,ba
  • 45. /*例2.5*/ #include main() { float a,b,r,s,u; printf("请输入变量a、b的值:"); scanf("%f %f",&a, &b); if(a
  • 46. 小结: 本章主要介绍了程序算法的制定方法:自然语言、流程图、N-S图和PAD图。通过用这些方法表示解题思路。 作业: 用流程图、 N-S图和PAD图描述问题的算法: 从键盘输入3个整数a,b,c,输出其中的最大的数。
  • 47. 第三章 基本程序语句C语言的数据类型简介 几个基本概念 C语言的三种基本数据类型 基本运算符和表达式 C基本语句 数据的输出 数据的输入 简单程序设计举例
  • 48. 3.1 C语言的数据类型简介 字符型(char) 整型(short,int,long,unsigned) 单精度型(float) 实型 双精度型(double) 枚举类型(enum) 数组类型([ ]) 构造类型 结构体类型(struct) 共用体类型(union) 指针类型(*) 空类型(void)基本类型数据类型C语言的数据结构
  • 49. 3.2 几个基本概念3.2.1 标识符 1.标识符概念:是用来标识名称的,可以用来标识变量名、符号常量名、函数名、类型名、数组名、文件名等。C语言规定标识符只能由字母、数字和下划线组成,且第一个字符必须是字母或下划线。如:Day ,month ,student ,name_1 ,s2 ,_12 ,_t13 注意: C语言中大写字母和小写字母被认为是两个不同的字符,大写字母‘A’与小写字母‘a’则表示不同的标识符。 采用“见名知义”的原则
  • 50. 3.2 几个基本概念3.2.1 标识符 2.标识符的分类 关键字(代表固定含义,不能另做他用。书P21) 分为三类 预定义标识符(有特定含义,包括C语言库函数名 和变异预处理命令允许另做他用,但标识符失去原义) 用户标识符(用户自己定义,不能使用关键字,可 以使用预定义标识符,建议不要使用预定义标识符)
  • 51. 3.2 几个基本概念3.2.2 常量 在程序运行中,其数值不能被改变的量 1.直接常量:是在程序中直接引用的数据 2.符号常量:符号常量是用标识符来代表一个数据 符号常量的定义形式: #define 符号常量标识符 常量数据 例如: #define PI 3.14159
  • 52. 3.2 几个基本概念3.2.3 变量 变量是指以标识符为名字,其值可以改变的量。 1、定义形式:类型标识符 变量名1 [,变量名2,变量名3...]; 例如: int a,b,c ; float x,y; char c1,c2; 或 int c1,c2; 自己设定,满足标识符的规定。如:int, float,char;不可省变量分为整型、实型、字符型等。
  • 53. 3.2 几个基本概念3.2.3 变量 2、变量初始化 在说明变量的同时给变量一个初始值。 int a=5, b=3; √ int a,b,c; a=b=c=3; √ int a=b=c=3; 例如注意:在同一程序块中,变量不能被重复定义;使用变量时必须“先定义,后使用”。
  • 54. 3.3 C语言的三种基本数据类型3.3.1 整型数据 1、整型常量: (1) 十进制形式: 与数学上的整数表示相同; 例如: 12, -100, 0 (2) 八进制形式: 在数码前加数字0; 例如: 012=1*81+2*80=10(十进制) (3) 十六进制形式: 在数码前加0X(数字0和字母X)。 例如: 0x12=1*161+2*160=18(十进制) * 八进制的数码范围为0~7; 018  * 十六进制的数码除了数字0~9外, 还使用英文字母a~ f (或A~ F)表示10~15。 如:0x1e √ 注意!
  • 55. 3.3 C语言的三种基本数据类型2、整型变量 (1)整型变量分类 根据数据所占的二进制位数分为:int、short、long; 同样存储长度的数据又分unsigned、signed; 故可组合出六种类型。 (2)整型数据的存储方式 数据在内存中是以二进制形式存储的。 C语言中,一个int型数据通常用两个字节存放,其中最高位用来存放整数的符号,若最高位为0则表示该数为正数,若最高位为1则表示该数为负数。 如:int i=-1; 则存放形式为:1111111111111111
  • 56. 3.3 C语言的三种基本数据类型3、值域:变量允许存放的数值范围 由机器中数据的存储长度决定。 VC 6.0 所支持的整型数据 类型名称所占位数数值范围signed [int]8*4-2147483648~2147483647[signed] short [int] 8*2-32768~32767[signed] long [int]8*4-2147483648~2147483647unsigned [int]8*40~4294967295unsigned short[int]8*20~65535unsigned long [int]8*40~4294967295
  • 57. 3.3 C语言的三种基本数据类型例3.1:P24 思考:运行结果是否正确,说明理由!#include main() {int a,b,c,d; unsigned u,v; a=1;b=3;c=6;d=-7; u=a+b;v=c+d; printf("u=%d,v=%u\n",u,v);}
  • 58. 3.3 C语言的三种基本数据类型3.3.2 实型数据 1、实型常量: (1) 十进制小数形式:由数字和小数点组成; 例如: 3.4 , 4. , .3 (2) 指数形式:“十进制小数”+“ e(或E)”+“十进制数整数”。 例如: 12.5e-6 表示12.5×10-6 。 规范化指数形式: 小数点不能单独出现; 0.√ .0 √ .  e或E的两边必须有数,且其后面必须为整数; 如: 6E0.2  e5  2、实型变量(分类和值域): 关键字 字节数 取值范围 精度(位) float 4 3.4×10-38 ~ 3.4×1038 7 double 8 1.7×10-308 ~ 1.7×10308 15 注意
  • 59. 3.3 C语言的三种基本数据类型3.3.3字符型数据 1、常量: (1) 用单引号括起来的一个字符;如:‘A’、‘1’、‘?’等。 (2) 用单引号括起来的由反斜杠(\)引导的转义字符。 字符形式 功能 \n 换行 \t 横向跳格 \b 退格 \r 回车 \\ 反斜杠字符 \’ 单引号字符 \ddd 8进制数表示的ASCII码对应的字符 \xhh 16进制数表示的ASCII码对应的字符 例如:字符A的ASCII码为: 65D(十进制)=41H(十六进制)=101Q(八进制) ∴字符A可以表示为‘A’、’\x41’、’\101’。
  • 60. #include main() {char c1='a',c2='b',c3='c',c4='\101',c5='\116'; printf("a%c b%c\tc%c\tabc\n",c1,c2,c3); printf("\t\b%c %c",c4,c5);}转义字符的应用演示ex304
  • 61. 3.3 C语言的三种基本数据类型2、变量的分类和值域: 分类: char 和 unsigned char; 值域: 每个字符型数据在内存中占一个字节;包括ASCII字符表中的所有字符(可显示字符和非显示字符)。 3、字符串常量: 是用一对双引号括起来的字符序列。 如:“SHANGHAI”,“FGHijk”,“CHINA”。 字符串常量的存放: 每个字符均以其ASCII码存放,且在最后加一个“空字符” ‘\’’√ ‘\\’ √ ‘’’  ‘\’  ‘a’与“a”的区别。注意
  • 62. 3.4 基本运算符和表达式 3.4.1 C运算符简介 按操作功能运算符大致可分为算术运算符、关系运算符、逻辑运算符、按位运算符以及其它运算符如赋值运算符、条件运算符、逗号运算符等。 表达式是由操作数和运算符组成的序列。 算术运算符 + - * / % 关系运算符 > < == >= <= != 逻辑运算符 ! && ‖ 位运算符 《 》 ~ | ∧ & 赋值运算符 = 条件运算符 ?: 逗号运算符 , 指针运算符 * 和 & 求字节数运算符 sizeof 强制类型转换运算符 分量运算符 • → 下标运算符 [ ] 其它运算符号
  • 63. 3.4 基本运算符和表达式 3.4.2算术运算符和算术表达式 1、 基本的算术运算符 +(加):3+4、 +3 -(减):3-5、 -5 *(乘):3*5 /(除):5/2的值为2;5.0/2的值为2.5; %(取余):5%3的值为2; -5%3的值为-2; 5%(-3)的值为2; -5%(-3)的值为-2; 12.3%3 × 若a能被b整除,则有:a%b==0 整型数据相除,结果整型。5/3为1 求余运算两侧为整型数据 参与运算的数有一个是实型,则结果为实型
  • 64. 3.4 基本运算符和表达式 2.算术表达式 用算术运算符和括符将操作数连接起来的式子。 优先级:() *、/、% +、- 结合性:从左至右; 表达式的值: 数值型(int、long、unsigned、double); 例如: 已知: float a=2.0; int b=6,c=3; 求解: a*b/c-1.5+ ‘a’+(b-5)=?
  • 65. double float long unsigned int char,short float a=2.0; int b =6,c =3; a*b/c -1.5 +’a’ + (b-5)12.0/314.0 - 1.52.5 + 97(int)99.5 + 1100.5(double)
  • 66. 3.4 基本运算符和表达式 3.4.3 赋值运算符和赋值表达式 1、赋值运算符 = 2、赋值表达式:用赋值运算符将变量和表达式连接起来的式子 一般形式为: <变量> 赋值运算符 <表达式> 优先级: 赋值运算符的优先级比算术运算符低。 结合性:自右至左(右结合性)。 求值规则: 先计算“=”右边表达式的值,再将其值赋给左边的变量。 表达式的值:赋值号左边变量的值即为赋值表达式的值。 例如: (1) x=(y=12)/4 y值为12,x值为3,表达式的值为3 (2) x=y=12/4 y值为3,x值为3,表达式的值为3 (3) x=(y=12/4) y值为3,x值为3,表达式的值为3 (4) (x=y)=12/4 
  • 67. 3.4 基本运算符和表达式 3、复合赋值运算符 *=、/=、 %=、 +=、 -=等 注意: 复合运算符是一个运算符,但功能上,是两个运算符功能的组合。 例如: (1) a+=b 相当于 a=a+b a*=b 相当于 a=a*b a*=b+c 相当于 a=a*(b+c) 而不是 a=a*b+c (2) 设a=12,计算表达式a+=a-=a*12和a+=a-=a*=12的值
  • 68. 3.4 基本运算符和表达式 4.赋值时的类型转换 实型数据赋给整型(字符型)变量:去掉小数部分; 如:int f=23.457; 变量f的值为23。 整型(字符型)数据赋给实型变量: 补足有效位。 字符型数据赋给整型变量:将字符数据(8位)放到整型变量的低8位中,高8位进行“符号扩展”。 一个int、short、long、unsigned型数据赋给一个char 型变量:截取低8位赋给字符型变量。 带符号的整型数据(int型)赋给long型变量:进行符号扩展。 带符号的long型数据赋给int型变量时,只截取低16位赋给int变量。 unsigned int 型数据赋给long int变量:高位补0。 int 型数据赋给unsigned int变量:内存情况不变,但若是负数,其符号位也作为数值赋给unsigned 型变量。
  • 69. 3.4 基本运算符和表达式 5、自增与自减运算符 单目运算符,运算对象是变量,不是表达式或者常量 ++i,--i:先使变量i的值增1(或减1),再使用变量i的值作为整个表达式的值来参加其它的运算; i++,i--:先使用变量i的值进行其它运算,再使变量i的值增1(或减1)。 (1) i++; ++i; (2) i=3; j=i++; (3) i=3; j=++i;等价于 i=i+1;j=i;i++; 所以i的值为4,j的值为3。i++;j=i; 所以i的值为4,j的值为4。例如:
  • 70. 3.4 基本运算符和表达式 5、自增与自减运算符 结合性:自右至左。 如: i = 2; j = -i++; 等价于:j=-(i++); 即: j=-i; i++; “++”与”-“是同优先级 所以i的值为3,j的值为-2。 注意 “++”或“--”自增与自减运算符的使用。 设i=3,k=(i++)+(i++)+(i++),k=? 设i=3,k=(i++)+(++i)+(++i), k=? 设i=3,j=4,k=i+++j,k=? 设i=3; printf(“%d %d”,i,-i++);结果为?
  • 71. 3.4 基本运算符和表达式 3.4.4 关系运算符和关系表达式 1. 6种关系运算符:< <= >= > == != 2. 关系表达式:用关系运算符将表达式连接起来的式子 ★ 优先级: (< <= >= >)>( == != ) ★ 结合性:自左至右; ★ 表达式的值: 若为真,则结果为1; 若为假,则结果为0。 3>5 的值为 0; 3<4>2 的值为 0; 3+(4<3)*4的值为 3; 3+4<3*4 的值为 1; X=6>3 的值为1; ‘a’<‘h’的值为1 算术运算符优先级高于关系运算符 关系运算符优先级高于赋值运算符例如
  • 72. 3.4 基本运算符和表达式 3.4.5 逻辑运算符和逻辑表达式 1. 3种逻辑运算符:&& || ! 逻辑量:可以是整型、实型、字符型和指针类型, 0——假 非0——真; 如:0,0.0,‘\0’,NULL都代表假。 2. 逻辑表达式:用逻辑运算符将表达式连接起来的式子 ★优先级: !>&&>|| ★结合性:自左至右; ★表达式的值: 若为真,则结果为1; 若为假,则结果为0。
  • 73. 3.4 基本运算符和表达式 int a=5; float b=3.5; !a (0) !(a < b) (1) a && b (1) !a&&b (0) !a&&!b (0) !(a&&b) (0) a || b (1) !a||b (1) !a||!b (0) !(a||b) (0) (a < b) && (a > 0) (0) (a < b) || (a > 0) (1)例如结论: &&:只要有一个为假,结果则为假; ||:只要有一个为真,结果则为真;
  • 74. ! 高 算术运算符 关系运算符 &&和|| 赋值运算符 低 4 - 01 && 28 < 41015 > 3 && 2 || 8 < 4 - !5
  • 75. 3.4 基本运算符和表达式 注意: 在逻辑表达式的求解中,并不是所有的逻辑运算符都被执行,只是在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符。 例如: (1)a = 0; b = 1; c = a++ && ( b = 3 ); 结果: a为1,b为1,c为0。 (2)a = 1; b = 1; c=0; d = --a || b-- || (c = b+3 ); 结果: a为0,b为0,c为0,d为1。
  • 76. 3.4 基本运算符和表达式 逻辑表达式一般用于控制语句中的条件: 例如: (1) n是小于m的偶数: (2)year是闰年: (能被4整除但不能被100整除或能被400整除) n
  • 77. 3.4 基本运算符和表达式 3.4.6 条件运算符 1、条件运算符 ?和: ,它们与三个操作数组成三目运算。 2、形式为: <表达式1> ? <表达式2>:<表达式3> 3、求值规则和表达式的值: 真(非0),求解表达式2 求解表达式1 条件表达式的值 假(0),求解表达式3例如: int max, a=5, b=3; max=a>b?a:b a
  • 78. 又如: --a == b++ ? a++ : b++ (a=a-1;)4 == 3(b=b+1;)?a++:b++ a为4 b为4 0 4(b=b+1;) 表达式值为4 b为5 ∴ a值为4,b值为5,条件表达式的值为4。 4、 优先级: 逻辑>条件>赋值 验证:printf("%d %d\n",--a==b++?a++:b++,b ); 运行结果:4 5
  • 79. 3.4 基本运算符和表达式 5、 结合性:自右至左; y = x>10 ? x/10 : x>0 ? x: -x; 等价于: y = x>10 ? x/10 :(x<0? x: -x); 思考:当x的值为15时,表达式的结果为: 当x的值为5时,表达式的结果为:15
  • 80. 3.4 基本运算符和表达式 3.4.7逗号运算符: , 形式: 逗号表达式1,逗号表达式2,…,逗号表达式n 求值规则: 从左至右依次计算各表达式的值; 优先级: 最低; 结合性:自左至右; 表达式的值:最后一个表达式的值。
  • 81. 3.4 基本运算符和表达式 例如: a b y 表达式 y=a=4,b=5,a+b; 4 5 4 9 y=(a=4,b=5,a+b); 4 5 9 9 y=(a=4,b=5),a+b; 4 5 5 9 y=a=(4,b=5),a+b; 5 5 5 10 注意: C语言常用逗号作为分隔符, 例如: int a=3,b=4,c=5; printf(“%d,%d,%d”,(a,b,c)); × printf(“%d,%d,%d”,a,(a,b,c),c); 结果为3,5,5
  • 82. 3.4 基本运算符和表达式 3.4.8 强制类型转换运算符 强制类型转换:指将表达式的类型强制转换为指定的类型, 其一般形式为: (类型名)表达式 其作用:将表达式的结果的类型强制转换为类型名所指的类型。 例如 (int)(3.4+2.8) 的值为6 强制类型转换时,得到所需类型的中间变量,而原来变量的类型不会改变。 注意:
  • 83. 3.4 基本运算符和表达式 例如: int a=2,b=5; float x=4.4; 则有: 表达式 结果 b/a 2 (float)b/a 2.5 (float)(b/a) 2.0 (int)x%a+x 4.4 (int)x%(a+x) 不合法
  • 84. 3.5 C基本语句 C语言的语句可分为以下四类: 简单语句(包括输入/输出语句) 空语句 复合语句 流程控制语句
  • 85. 3.5 C基本语句 3.5.1简单语句 1. 表达式语句就是一个表达式加上一个分号。 如:a++; x=1; 函数调用语句由函数调用表达式加分号构成。 printf(“%d”,a); 3. 空语句 用一个分号表示,其一般形式为: ;
  • 86. 3.5 C基本语句 C 语言有丰富的标准函数库, 可提供各类函数供用户调用,完成预先设定好的操作. #include #include main() { int a = 2 , b = 4; float x , y; x = a / 2 + sqrt( b ); /*x=3.0 */ a++ ; /*a=3 */ y = x * a ; /*y=9.0 */ printf(“x=%6.2f, y= %6.2f ”, x, y); }
  • 87. 3.5 C基本语句 常用标准库函数求数学函数值: fabs(x) (求x的绝对值)、pow(x,y)(计算x的y次幂)、 sin(x) 、cos(x) 、 exp(x) (求ex ) 、log(x)(求lnx)等。调用标准库函数要注意以下几点: 在程序中要包含相应的头文件 例如: 要使用标准的输入/输出函数printf()等需包含头文件 #include 要使用数学函数sqrt()等需包含头文件 #include 调用规则: 函数名(参数表)
  • 88. 3.5 C基本语句 3.5.2 复合语句 用一对花括号{}将多条语句组合在一起,在语法上相当于一 条语句。 1、一般形式: { [内部数据说明;] 语句1; …… 语句n; } 注意: (1)在复合语句中说明的变量,是局部变量, 仅在复合语句中有效。 (2)复合语句的 } 之后,不能有分号。
  • 89. 3.5 C基本语句 复合语句(程序块) 示例【例3.3】 main( ) { int x=1; { int x=2; { int x=3; printf(“x=%d”, x); } printf(“x=%d”, x); } printf(“x=%d”, x); }
  • 90. 3.6 数据的输出1.格式输出函数 printf( ) 格式: printf( “……”,输出项1,输出项2,… ,输出项n ); 例:printf( “x=%d,y=%f\n” , x , x+3 );格式控制 (用双引号括起来,控制输出项的格式和输出一些提示信息 )输出表列 (用逗号分隔的数据组,可选项)格式控制分为两个部分: 普通字符—原样输出(转义字符按表3-4输出) 格式说明—%+格式字符 (替换输出)
  • 91. 格式说明的一般形式: % - 0 m.n l(或h) 格式字符 - 左对齐输出 0 数字前的空位填0 m 输出域宽(长度,包括小数点) 如数据的位数小于m,则左端补以空格 如数据的位数大于m,则按实际位数输出 n 输出精度(小数位数) l 或 h 长度修正符 l 长整型及双精度 注:long型的数据宜用%ld,double型宜用%lf h 表示短整型 如 %hd %hx3.6 数据的输出
  • 92. 格式字符(规定了输出的数据形式): %d 输出十进制整数 %x 以十六进制无符号形式输出整数 %o 以八进制无符号形式输出整数 %u 以无符号十进制数形式输出整数 %f 输出小数形式浮点数(double型用%lf ) %s 输出字符串 %c 输出单字符3.6 数据的输出【例1】求运行结果。 main() { int a=30; printf("%d,%o,%x,%u,%c",a,a,a,a,a); }结果: 30,36,1e,30,▲
  • 93. 结论: 格式字符与对应输出项类型要一致,否则正确的运算结果不能得到正确的显示结果。3.6 数据的输出 【例】若float y=1234.9999;printf(“%d”,y);则输出结果为何? printf函数使用注意事项: 在格式控制字符串中,格式说明与输出项从左到右在类型上必须一一对应匹配。 在格式控制字符串中,格式说明与输出项的个数应该相同。 如果要输出百分号(%),则在格式控制串中用两个连续的百分号(%%)来表示。 在调用printf函数时,输出项有自增(自减)运算时,计算输出项的顺序从右至左。
  • 94. 3.6 数据的输出【例】 .格式输出函数示例程序 #include main() {int i = 97; char ch = ’a’; printf (“i=%d,%c\n”, i, i );  } 输出结果: i =97,a 两个输出项都是变量i , 但以不同的格式输出,一个是输出的整型数,一个输出的是字符a. 其格式是由%d与%c控制的.
  • 95. 3.6 数据的输出字符输出函数 格式: putchar(c) 其中 c为字符型或整型的常量、变量及其表达式 功能: 每次向屏幕输出一个字符供显示。【例】求以下程序运行结果 #include main() { char x='a'; putchar(x); putchar('b'); putchar(x+2); putchar('b'+2); }结果:abcd
  • 96. 1.格式输入函数scanf() 格式: scanf( “……”,&变量名1,&变量名2,… , &变量名n ); 例: scanf( “ %d,%d,%d ” , &a, &b, &c );3.7 数据的输入格式控制 (需要输入数据的类型)地址列表 (简单变量要用&开头)格式说明的一般形式: % * m l (或h) 格式字符 & —求地址的运算符 &a 表示该变量所占空间的首地址 * —抑制字符(“虚读”,即读入数据后不送给任何变量)
  • 97. 注意: scanf( )函数没有输出功能(即不会向屏幕显示任何字符) 也不能规定小数位数(m.n) 典型错误: scanf( “a=%d,b=%d,c=%d \n”,&a,&b,&c); scanf( “ %5.2f “,&x ); 3.7 数据的输入正确语句: printf( “ Input a,b,c=“); scanf( “%d, %d, %d”, &a, &b, &c); scanf( “%5f “, &x);scanf()注意事项
  • 98. 字符输入函数 格式: getchar( ) 功能: 从键盘上读入一个字符,getchar( )包含在stdio.h中。 3.7 数据的输入【例一】 #include main() { char a,b; a=getchar(); b=getchar(); printf(“a=%c,b=%c\n”,a,b); } 运行时,如果—— 输入:Student 输出结果为 a=S,b=t
  • 99. 例3.13 输入圆的半径,输出圆的周长和面积。 分析: 1.定义实型变量r、l、s用于存放半径、周长、面积; 2.调用输入函数,输入r: 3.分别利用周长公式和面积公式求出l、s; 4.调用输出函数输出l、s。3.8 程序举例
  • 100. 例3.10输入圆的半径,输出圆的周长和面积#include void main() {float r,l,s; scanf(“ %f ”,&r); /*输入一个浮点数据,存入地址&r */ l = 2 * 3.14159 * r; /*计算周长,赋值给l */ s = 3.14159 *r * r; /*计算面积,赋值给s */ printf(“\n l=%8.4f”,l); /*周长占8个字符宽,4位小数*/ printf(“\n s=%8.4f”,s); /*输出面积,数据共占8个字符宽,4位小数*/ }3.8 程序举例
  • 101. 3.8 程序举例例3.12从键盘输入一个学生的3门课程的成绩,求其平均并输 出,保留一位小数。例3.11从键盘输入一个小写字母,用大写形式输出该字母。例3.13 从键盘输入两个整数给两个变量x和y,交换变量x和y的值,然后输出。
  • 102. 程序流程控制第三章 顺序结构程序设计1第四章 选择结构程序设计2第五章 循环结构程序设计3几种控制语句4
  • 103. 顺序结构程序设计顺序结构:自顶向下顺序执行语句 例:交换两个数的值34x3t①②③ybefore :x=3,y=4; after :x=4,y=3;#include main() { int x=3,y=4,t; printf(“before :x=%d,y=%d\n”,x,y); t=x; x=y; y=t; printf(“after:x=%d,y=%d\n”,x,y); }
  • 104. 例:从键盘输入一个小写字母,输出其对应的大写字母及其相应的ASCII码值。 程序如下: #include main() { char ch1,ch2; ch1=getchar(); ch2=ch1-32; printf("\n letter:%c,ASCII=%d",ch1,ch1); printf("\n letter:%c,ASCII=%d",ch2,ch2); } scanf(“%c”,&ch1);运行结果为: a↙ letter:a,ASCII=97 letter:A,ASCII=65
  • 105. 第四章 选择结构程序设计if语句: 1.单分支if语句 2.双分支if语句 3.多分支if语句 选择结构有两种:switch 语句按给定条件进行判断,按判断后的不同情况进行不同处理。
  • 106. 形式二(一般形式): 格式:if (expression) statement1 else statement2 执行过程: if语句常用的两种形式 形式一(缺省形式): 格式:if (expression) statement 执行过程:表达式语句非00例:if (x>y) printf(“%d”,x);表达式语句1语句2非00例:if (x>y) max=x; else max=y;if语句(条件分支语句)
  • 107. 【例4-1】在两个数中取大数。main() { int num1,num2,max; printf("\n input two numbers: "); scanf("%d%d",&num1,&num2); max=num1; if(maxnum2) printf("max=%d\n",num1); else printf("max=%d\n",num2); }
  • 108. 如:if(a==b&&x==y) printf(“a=b,x=y”); if(3) printf(“OK”); if(‘a’) printf(“%d”,’a’);   if(s=2) printf(“hello”); if(s=2,s<0) printf(“false”); else要与if配对使用 if后面的表达式类型任意 语句可以是复合语句 同一个条件的多种表达方式 如:if(x)  if(x!=0) if(!x)  if(x==0)例 考虑下面程序的输出结果: #include main() { int x,y; scanf(“%d,%d”,&x,&y); if(x>y) x=y; y=x; else x++; y++; printf(“%d,%d\n”,x,y); }Compile Error!说明:错误信息: misplaced else in function main如:if(a
  • 109. #include main() { int x,y; printf("Enter integer x:"); scanf("%d",&x); y=x>=0?2*x+1:0; printf(“when X=%d,f(x)=%d\n”,x,y); }运行:Enter integer x:10 when X=10,f(x)=21 Enter integer x:-1 when X=-1,f(x)=0 例 求分段函数的值 if(x>=0) y=2*x+1; else y=0;îíì³+<=)0(12)0(0)(xxxxf
  • 110. #include main() { int x,y; printf("Enter integer x:"); scanf("%d",&x); if(x) y=1; else y=-1; printf(“when X=%d,y=%d\n“,x,y); }运行:Enter integer x:10 when X=10,y=1 Enter integer x:0 when X=0,y=-1 例 if(x!=0)îíì=-1!==)0()0(1xxy
  • 111. 多分支if语句:if-else if其格式为: if(表达式1) 语句1 else if(表达式2) 语句2 …… else if(表达式n) 语句n else 语句n+1
  • 112. 【例3-3】将学生成绩由百分制转化为等级制。规则如下:  ⑴ 85分(含)以上为A级。 ⑵ 70分(含)以上且85分以下为B级。 ⑶ 60分(含)以上且70分以下为C级。 ⑷ 60分以下为D级。main() { float score; printf("\n please input a score:"); scanf("%f",&score); if(score>=85) printf("the score %f is A \n",score); else if(score>=75) printf(" the score %f is B \n",score); else if(score>=60) printf("the score %f is C \n",score); else printf("the score %f is D \n",score); }程序运行结果如下: please input a score:89↙ the score 89.000000 is A
  • 113. if语句嵌套例: #include “stdio.h” main() { int x=4,y=5,z=2,max; max=x; if(z>y) if(z>x) max=z; else if(y>x) max=y; printf(“max=%d”,max); }结果?
  • 114. 缺省{ }时,else总是和它上面离它最近的未配对的 if 配对 if(…)if(…)if(…)else…...else…...else…...if ~ else 配对原则:
  • 115. main() { int x=100,y=10,a=30,b=20,k1=10,k2=6; if(a>b) if(b!=10) if(!k1)x=1; else if(k2) x=10; else x=20; printf("x =%d\n",x); }运行结果: x=10
  • 116. 例: if (a==b) if(b==c) printf(“a==b==c”); else printf(“a!=b”);修改: if (a==b) { if(b==c) printf(“a==b==c”); } else printf(“a!=b”); 实现if ~ else 正确配对方法:加{ }实现if ~ else 正确配对方法注意:书写格式不能代替程序逻辑
  • 117. if语句嵌套一般形式:if (expr1) if (expr2) statement1 else statement2内嵌ifif (expr1) { if (expr2) statement1 } else statement2 内嵌ifif (expr1) statement1 else if(expr3) statement2 else statement3内嵌ifif (expr1) if (expr2) statement1 else statement2 else if(expr3) statement3 else statement4内嵌if内嵌if
  • 118. main() {int x,y; printf(”\n input x :”); scanf(”%d”,x); if(x<0) y=-1; else {if(x= =0)y=0; else y=1; } printf(”x=%d,y=%d\n”,y); }
  • 119. #include main() { int x,y; printf("Enter integer x,y:"); scanf("%d,%d",&x,&y); if(x!=y) if(x>y) printf("X>Y\n"); else printf("XY Enter integer x,y:12,12 X==Y 例 输入两数并判断其大小关系
  • 120. switch语句(开关语句) 一般形式: 执行过程:switch(<表达式>) { case <常量表达式1>: <语句序列1> case <常量表达式2>: <语句序列2> ……. case <常量表达式n>: <语句序列n> default: <语句序列n+1> } <表达式>的值与某一case后面的<常量表达式>值匹配时,则执行此case后面的所有的<语句序列>,直至遇到break语句或switch的结束“}”,否则,执行default后的<语句序列>。一般是一个整数表达式(或字符表达式)
  • 121. 说明: case后面是常量表达式,且值必须互不相同 case和常量表达式之间要有空格 case后可包含多个可执行语句,且不必加{ } 常量表达式起语句标号作用,跳出必须用break语句 多个case可共用一组执行语句 switch可嵌套 完全可以用if语句或if语句的嵌套来实现。 如: switch(z) { …… case ‘A’: case ‘B’: case ‘C’: printf(“score>60\n”); break; case ‘F’: …….. }如: switch(z) { case 1: case 2: …….. case 2: ……. }如: switch(z) { …… case ‘A’: i++; k--; printf(“A\n”); break; case ‘F’: …….. }例 switch(score) { case 5: printf(“Very good!”); case 4: printf(“Good!”); case 3: printf(“Pass!”); case 2: printf(“Fail!”); default : printf(“data error!”); }运行结果:score为5时,输出: Very good! Good! Pass! Fail! data error!如: int x=3,y=7; switch(z) { ……… case x+y: …….. }
  • 122. 【例】输入1—7中的数字,将其转换成相应的星期英文单词。 main() { int num; scanf(”%d”,&num); switch(num) { case 1:printf(”Monday\n”); break; case 2:printf(”Tuesday\n”); break; case 3 :printf(”Wednesday\n”); break; case 4:printf(”Tursday\n”); break; case 5:printf(”Friday\n”);break; case 6:printf(”Saturday\n”);break; case 7:printf(”Sunday\n”);break; default:printf(”error\n”); } }若无break?
  • 123. 【例4-6】编写程序测试是数字、空白、还是其他字符。 main() { int c; switch(c) { case ‘0’: case ‘1’ : case ‘2’ : case ‘3’ : case ‘4’ : case ‘5’ : case ‘6’ : case ‘7’ : case ‘8’ : case ‘9’ : printf(”this is a digit\n”); break; case ‘ ’ : case ‘\n’ : case ‘\t’ : printf(”this is a blank\n”); break; default: printf(”this is a character\n”); break; } }
  • 124. 补充举例:路程s越远,每公里运费越低。 折扣的标准如下: s<250km 没有折扣 250≤s<500 2%折扣 500≤s<1000 5%折扣 1000≤s<2000 8%折扣 2000≤s<3000 10%折扣 3000≤s 15%折扣 设每公里每吨货物的基本运费为p,货物重为w,距离为s,折扣为d,则总运费f 的计算公式为: f=p*w*s*(1-d)折扣的“变化点”都是250倍数 分析折扣变化的规律:若s为整型,则c与折扣d的关系为: c=0 d=0 c=1 d=2% c=2、3 d=5% c=4、5、6、7 d=8% c=8、9、10、11 d=10% c=12、13、14、… d=15%若c=s/250,则折扣d如下: c<1 d=0 1≤c<2 d=2% 2≤c<4 d=5% 4≤c<8 d=8% 8≤c<12 d=10% 12≤c d=15%运输公司对用户计算运费:
  • 125. 若s为整型,则c与折扣d的关系为: c=0 d=0 c=1 d=2% c=2、3 d=5% c=4、5、6、7 d=8% c=8、9、10、11 d=10% c=12、13、14、… d=15%结论:c=s/250; switch (c) { case 0: d=0; break; case 1: d=2; break; …… case 8: case 9: case 10: case 11: d=10; break; default: d=15; }蓝色部分程序段能否改为:main( ) { int c,s; float p,w,d,f; scanf(“%f%f%d”,&p,&w,&s); if (s>=3000) c=12; else c=s/250; switch (c) { case 0:d=0; break; case 1:d=2; break; case 2: case 3:d=5; break; case 4:case 5:case 6: case 7:d=8; break; case 8:case 9:case 10: case 11:d=10; break; case 12:d=15; break; } f=p*w*s*(1-d/100.0); printf(“%15.4f\n”,f); }程序:?能
  • 126. 练习: 输入一个由两个数据和 一个算术运算符组成的表达式,根据运算符完成相应运算,并输出结果。#include main() {int a,b; char c; scanf("%d%c%d",&a,&c,&b); switch(c) {case '+':printf("a+b=%d",a+b);break; case '-':printf("a-b=%d",a-b);break; case '*':printf("a*b=%d",a*b);break; case '/':if(b!=0)printf("a/b=%d",a/b); else printf("b=0");break; delfault:printf("error");}}
  • 127. 作业:第四章课后习题 P65—P70 上机:练习
  • 128. 4种循环语句whilefordo-while循环是指使用一定条件对同一个程序段重复执行若干次。循环结构又称重复结构,可以完成重复性、规律性的操作。第五章 循 环 结 构goto
  • 129. goto 语句一般格式: goto 语句标号 由if ……goto 构成循环 例4-1: main() {int x=0,y=0; star: if (x<=3) {y=x+1; x=x+1; goto star;}printf(“%d”,y);}分析输出结果。
  • 130. 一般形式:while(<表达式>) <语句>执行流程: while语句循环体:被重复执行的部分表达式循环体假(0)真(非0)while
  • 131. 特点:先判断表达式,后执行循环体 说明: 循环体有可能一次也不执行 循环体可为任意类型语句 下列情况,可退出while循环 条件表达式不成立(为零) 循环体内遇break,return,goto while语句特点和说明while(<表达式>) <语句>
  • 132. 例4-2: main() { int count=1; while(count<5) { printf(”good morning!\n”); count+ +; } }good morning! good morning! good morning! good morning!
  • 133. #include main() { int n=9; while(n>6) { n--; printf(“%d”,n); } }876main( ) { int n=9; while(n>6) n--; printf(“%d\n”,n); }6
  • 134. 例4-3:用while循环求sum=1+2+3+……+100 #include main() { int sum=0; int i=1; while(i<=100) { sum+=i; i++; } printf(“sum=%d",sum); }循环初值循环终值循环变量增值循环条件循环体如何求sum=1*2*3*……*100 ?
  • 135. 【例5-13】猴子吃桃问题。猴子第一天摘下若干桃子,当即吃掉一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃掉前一天剩下的一半零一个。到第10天早上再想吃时,就只剩一个桃子了。问第一天共摘了多少个桃子?迭代法设第n天为xn个,第n+1天为xn+1 则:xn+1= xn/2-1 可得递推公式: xn=(xn+1+1)*2 1≤n≤9 x10=1 n=10 即: x10=1 x9=(x10+1)*2=4 x8=(x9+1)*2 =10 …… x1=(x2+1)*2=1534算法分析:倒推#include main() { int p2=1,p1; int n=9; while(n>0) { p1=2*(p2+1); p2=p1; n--; }  printf(“the total is %d\n”,p1); }
  • 136. #include main() { int n=0; long t=1; printf(“ n n! \n”); while(n<8) { n++; t*=n; printf("%d %ld \n",n,t); } }运行结果: n n! 1 1 2 2 3 6 4 24 5 120 6 720 7 5040 8 40320 求n!(n=1~8)
  • 137. do-while语句 一般形式: do <语句> while(<表达式>);执行流程: do循环体expr假(0)真(非0)while“ ; ”不能少
  • 138. expr循环体假(0)真(非0)循环体while循环 特点:先执行循环体,后判断表达式 说明: 至少执行一次循环体 do~while可转化成while结构do~while语句特点和说明do <语句> while(<表达式>);main() { int x=3; do { printf(“%d”,x-=2); }while(x>=0); }1-1x=x-2; printf(“%d”,x);
  • 139. 求1+2+3+……100#include main() { int sum=0,i; i=1; do{ sum=sum+i; i++; }while(i<=100); printf(”sum=%d\n”,sum); }#include main() { int sum=0; int i=1; while(i<=100) { sum=sum+i; i++; } printf(“sum=%d",sum); }
  • 140. main( ) { int i=1,s=0; while(i<1) { s=s+i; i=i+1; } printf("s=%d\n",s); }s=0main() { int i=1,s=0; do { s=s+i; i=i+1; } while(i<1); printf("s=%d\n",s); }s=1do-while与while的区别
  • 141. 一般形式: for([表达1] ;[表达式2] ;[表达式3]) <语句> 执行流程: expr2循环体假(0)真(非0)forexpr1expr3for语句 一般应用形式: for(初始化表达式;条件表达式;修正表达式) <语句>
  • 142. 说明: for语句中expr1, expr2 ,expr3 类型任意,都可省略,但分号;不可省 for语句可以转换成while结构表达式1; while(表达式2) { <语句> 表达式3; }for语句for([表达1] ;[表达式2] ;[表达式3]) <语句>
  • 143. 形式1: #include main( ) { int i=0; for(i=0;i<10;i++) putchar(‘a’+i); }运行结果:abcdefghij形式2: #include main( ) { int i=0; for(;i<10;i++) putchar(‘a’+i); }形式3: #include main( ) { int i=0; for(;i<10;) putchar(‘a’+(i++)); }形式4: #include main( ) { int i=0; for(;i<10;putchar(‘a’+i),i++) ; }例: for语句形式的多样性
  • 144. main() {int i; for(i=0;i<10;i++) { i++; printf(“%d”,i); } }main() { int i; for(i=1;i<5;i++) ; printf(“%d”,i); }513579空语句
  • 145. 求1+2+3+……100main() { int sum=0,i;  for(i=1;i<=100;i++) sum=sum+i;  printf(”sum=%d\n”,sum); }
  • 146. 几种循环的比较……… while(表达式) 语句; ……… do 语句 while(表达式);循环控制条件循环条件初始化循环修改条件也可在for前也可在循环体内for(表达式1;表达式2;表达式3) 语句
  • 147. 几种循环的比较123循环体的执行:先判断条件,循环体可能一次也不执行。while(表达式) 语句; 后判断条件,循环体至少执行一次.do 语句 while(表达式);for循环功能强,两者界限不清,使用较随意。for(表达式1;表达式2;表达式3) 语句界限不清……界限不清
  • 148. 小结 循环控制有两种方法:计数法和标志法。 能确定循环次数时,采用计数法,用for语句比较清晰; 不能确定循环次数时,采用标志法,设法找出循环终止条件,用while或do-while语句来实现。 用while与do-while语句能实现的程序,用for语句未必可以实现。 while语句是先判断后执行,do-while语句是先执行后判断。在循环体至少执行一次的情况下两者等价。
  • 149. #include main( ) { int i ,s; s=0; i=1; while(i<=100) { s = s + i; i++; } printf("s=%d\n",s); }计算s=1+2+3+…+100#include main( ) { int i,s; s=0; i=1; do { s = s + i; i++; }while(i<=100); printf("s=%d\n",s); }#include main( ) { int i, s=0; for(i=1; i<=100;i++) s = s + i; printf("s=%d\n",s); } i=1; for( ;i<=100; ) { s=s+i; i++; }
  • 150. main( ) { int i; for(i=1;i<5;i++) ; printf(“i=%d\n”,i); } main( ) { int x=3; do { printf(“%d\n”,x-=2); } while(x>=0); } 去掉分号,结果是?
  • 151. 例:求Fibonacci数列第40项。又叫兔子繁殖问题(Fibonacci提出的) main( ) { int n,m; long f1=1,f2=1,f3; printf(“%ld %ld ”,f1,f2); for (m=3;m<=40;m++) { f3=f1+f2; f1=f2; f2=f3; printf(“%d ”,f3); } printf(“\n”); }设有一对新生兔子,从第3个月开始,每个月都生一对兔子。按此规律,若所有兔子都不死,问一年后共有多少对兔子?迭代法算法分析:月:1 2 3 4 5 6 7 8 1--1—1—1—1—1—1--1 1 1--1 1—1--1 1 1—1—1--1 1 1--1 1—1—1—1—1 1 1--1 1—1—1 1 兔: 1 1 2 3 5 8 13 21f1 f2 1 1 f3=f1+f2 2 f1 f2 f3=f1+f2 3 f1 f2 f3=f1+f2 5 f1 f2 f3=…初始条件终止条件迭代公式思考:f1=f2和f2=f3能否对换位置?不
  • 152. 例:打印出所有的水仙花数。一个3位数,其各位数字的立方和等于它本身。分析: 百位数i=m/100; 十位数:j=m/10%10; 个位数k=m%10; 判断m==i^3+j^3+k^3 main() { int i,j,k,m;  for(m=100;m<1000;m++)  {   i=m/100;   j=m/10%10;   k=m%10; if(m= =i*i*i+j*j*j+k*k*k) printf("%5d",m); }  }穷举法计数法
  • 153. 统计从键盘输入一行字符的个数.main() { int count=0; while( getchar()!='\n‘ ) count++; printf("%d",count); }标志法: 循环终止条件
  • 154. main( ) { int x,max,i; scanf(“%d”,&x); max=x; for (i=2;i<=10;i++) { scanf(“%d”,&x); if (x>max) max=x; } printf(“max=%d\n”,max); }依次输入10个数,找出最大数。分析: 输入x1 x1 max 输入x2 若x2>max则x2 max 输入x3 若x3>mx则x3 max 输入x4……打擂方式
  • 155. 有一个分数序列2/1,3/2,5/3,8/5,21/13……求该数例前20项之和main() { int n,t; float a=2,b=1,s=0; for(n=1;n<=20;n++)  {  s=s+a/b;  t=a; a=a+b; b=t;  } printf("sum is %9.6f\n",s); }分析: 每项用a/b表示,从第2项开始: 每项的分子a是前一项的分子与分母之和, 分母是前一项的分子。
  • 156. 例题:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数 #i nclude "stdio.h" main() { char c;  int letters=0,space=0,digit=0,others=0;  printf("please input some characters:\n");  while((c=getchar())!='\n')  {  if(c>='a'&&c<='z'||c>='A'&&c<='Z')    letters++;  else if(c==' ')    space++;    else if(c>='0'&&c<='9')        digit++;      else        others++; } printf("all in all:char=%d space=%d digit=%d others=%d\n",letters,space,digit,others); }
  • 157. 循环的嵌套:循环体本身包含循环语句 三种循环可互相嵌套,层数不限 外层循环可包含两个以上内循环,但不能相互交叉(1) while() { …… while() { …… } …... }(2) do { …… do { …… }while( ); …... }while( );(3) while() { …… do { …… }while( ); ……. }(4) for( ; ;) { …… do { …… }while(); …… while() { …… } …... }内循环外循环内循环循环的嵌套
  • 158. for(i=1;i<5;i++) { j=1; while(j<4) { printf(i=%d,j=%d\n",i,j); j++; } }     for(j=1;j<4:j++) printf((i=%d,j=%d\n",i,j);i=1,j=1 i=1,j=2 i=1,j=3 i=2,j=1 i=2,j=2 i=2,j=3 i=3,j=1 i=3,j=2 i=3,j=3 i=4,j=1 i=4,j=2 i=4,j=3
  • 159. 形状 形状main( ) { int i,j; for (i=1;i<=9;i++) printf(“%4d”,i); printf(“\n”); for (i= 1;i<=9;i++) printf(“%c”,‘-’); printf(“\n”); for (i=1;i<=9;i++) { for (j=1;j<=9;j++) printf(“%4d”,i*j); printf(“\n”); } }P71例12:打印九九乘法表 形状1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 … …打印表头 9个数字打印虚线打印 表体…… for (i=1;i<=9;i++) { for (j=1; j<=i; j++) printf(“%4d”,i*j); printf(“\n”); }打印 表体for (i=1;i<=9;i++) { for (j=0;j<=i-1;j++) printf(“%4c”,‘ ’); for (j=i; j<=9; j++) printf(“%4d”,i*j); printf(“\n”); }打印 表体打印 空格
  • 160. 例:百马百担有100匹马,驮100担货,大马驮3担,中马驮2担,两匹小马驮1担。问有大、中、小马各多少?算法分析:main( ) { int a,b,c; for (a=0;a<33;a++) for (b=0;b<50;b++) { c=100-a-b; if (3*a+2*b+c/2.0==100) { printf(“a=%d ”,a); printf(“b=%d ”,b); printf(“c=%d\n”,c); } } }设大、中、小马各为a、b、c,则: 3a+2b+c/2=100 a+b+c=100 可得: 0≤a<33 0≤b<50 0≤c≤200穷举法若问有几种解决方法,则应如何修改程序?用变量k作为计数器,在if语句中增加“k++;”语句
  • 161. 例:打印图形。12345678901****************算法分析:第1行:1个*,6个空格,换行 第2行:3个*,4个空格,换行 第3行:5个*,1个空格,换行 第4行:7个*,0个空格,换行 第i(1~4)行:2i-1个*,8-2i个空格,换行main( ) { int i,j; for (i=1;i<=4;i++) { for (j=1;j<=2*i-1;j++) printf(“*”); for (k=1;k<=8-2*i;k++) printf(“ ”); printf(“\n”); } }2i-1个*8-2i个空格换行
  • 162. 补充举例:打印图形。1234567891011*************************算法分析:第1行:1个空格,5个*号,换行 第2行:2个空格,5个*号,换行 第3行:3个空格,5个*号,换行 第4行:4个空格,5个*号,换行 第5行:5个空格,5个*号,换行第i(1~5)行:i个空格,5个*号,换行main( ) { int i,j; for (i=1;i<=5;i++) { for (j=1;j<=i;j++) printf(“ ”); for (j=1;j<=5;j++) printf(“*”); printf(“\n”); } }i个空格5个*号换行循环语句嵌套时,当外层循环变量取1个值时,内层循环变量要取遍所有值
  • 163. 补充举例(续):打印图形。12345678901***************1234567890112233344445555512345678901***************算法分析:第1行:5个空格,1个*_,换行 第2行:4个空格,2个*_,换行 第3行:3个空格,3个*_,换行 第4行:2个空格,4个*_,换行 第5行:1个空格,5个*_,换行第i(1~5)行:6-i个空格,i个*_,换行main( ) { int i,j; for (i=1;i<=5;i++) { for (j=1;j<=6-i;j++) printf(“ ”); for (j=1;j<=i;j++) printf(“*_”); printf(“\n”); } }6-i个空格i个*_换行算法分析:第1行:5个空格,1个1_,换行 第2行:4个空格,2个2_,换行 第3行:3个空格,3个3_,换行 第4行:2个空格,4个4_,换行 第5行:1个空格,5个5_,换行第i(1~5)行:6-i个空格,i个i_,换行main( ) { int i,j; for (i=1;i<=5;i++) { for (j=1;j<=6-i;j++) printf(“ ”); for (j=1;j<=i;j++) printf(“%d_”,i); printf(“\n”); } }6-i个空格i个i_换行算法分析:第1行:1个空格,5个*_,换行 第2行:2个空格,4个*_,换行 第3行:3个空格,3个*_,换行 第4行:4个空格,2个*_,换行 第5行:5个空格,1个*_,换行第i(1~5)行:i个空格,6-i个*_,换行main( ) { int i,j; for (i=1;i<=5;i++) { for (j=1;j<=i;j++) printf(“ ”); for (j=1;j<=6-i;j++) printf(“%d_”,i); printf(“\n”); } }i个空格6-i个*_换行
  • 164. 流程控制语句流程 控制 语句选择结构 (条件语句)双分支结构多分支结构if( )…else语句else if语句 switch语句循环结构while( )…语句 do…while( )语句 for( )…语句流程 转向 语句条件转向语句无条件 转向语句goto语句中止循环或switch语句:break 跳过其后语句返回循环开始:continue 函数返回语句:return( )while ( ) { …… break; …… } ……break;while ( ) { …… continue; …… } ……continue; …… goto er; …… er …… …… ……goto 标号;几种控制语句
  • 165. 判断一个正整数m>3是否为素数main( ) { int n,m; scanf("%d",&m); for (n=2;n<=m-1;n++) if (m%n==0) break; if (n>m-1) printf("the %d is a primer\n",m); else printf("the %d is not a primer\n",m); } 例:验证素数 素数是除了1和它自身外,再也找不到能被它整除的数。 即:若m不能被2到m-1中所有整数整除,则n为素数。 已证明只要从2判断到m/2或 即可。算法分析:求100~200间的全部素数?也可用m/2或sqrt(m)
  • 166. 与break语句退出循环不同的是,continue语句只结束本次循环,忽略循环体中剩下的语句,接着进行下一次循环的判断,如果满足循环条件,继续循环,否则退出循环。 例:输出100以内的偶数 main() {int i; for(i=1;i<=100;i++) { if(i%2!==0) continue; printf("%d ",i); } }本次循环结束, 循环体中剩余语句被忽略,执行达式3.进入下一循环. continue做if的内嵌语句if(i%2= =0) printf("%d ",i);continue语句
  • 167. 例:打印3-100内的素数。main( ) { int n,m; scanf(“%d”,&m); for(m=3;m<=100;m++) { for (n=2;n
  • 168. #include main() { int i,s; s=0; for(i=1;i<=10;i++) { if(i%2==0) continue; if(i%10==7) break; s=s+i; } printf("s=%d\n",s); }阅读下面程序,写出运行结果 结果:S=9
  • 169. return和gotomain() { int sum =0,i=1; Loop:if(i<=100) { sum=sum+i; i++; goto Loop; } printf(“sum=%d\n”,sum) }int max(int a,int b) { int max; if(a>b) max=a; else max=b; return max; } main() { int a,b; scanf(“%d%d”,&a,&b); printf(“MAX is %d\n”,max(a,b)); }
  • 170. main() { int x,y,z; x=2; y=7; z=5; switch(x>0) { case 1: switch(y<10) { case 1: printf("^");break; case 0: printf("!");break; } case 0: switch(z==5) { case 0: printf("*");break; case 1: printf("#");break; default: printf("%%");break; } default:printf("&"); } printf("\n"); } 思考运行结果是什么?
  • 171. 小结 前五章主要讲了C语言的基础知识,3种基本的数据类型和几种运算符及表达式,C语言中3种基本的结构以及简单的编程思想。 要求:通过这几章的学习,要求学生掌握C的编程思想以及算法的制定,同时要求掌握调试程序的方法
  • 172. 第 6 章 函 数6.1 函数的概述与分类 6.2 函数定义 6.3 函数的调用 6.4 标识符的作用域 6.6 函数应用举例
  • 173. 6.1 函数的概念与分类 C程序设计的基础工作是函数的设计和编制。C程序完全由函数组成。除语言本身提供的库函数外,用户还可根据需要定义任意多个自己的函数,这些函数可以同main函数放在一个源文件中;也可以分放在不同的源文件中,单独进行编译,形成独立的模块(.obj),然后将若干obj文件链接在一起,形成一个可执行文件(.exe)。
  • 174. C函数分类 除main函数外, 其它为系统函数、自编函数。 系统函数:由系统提供,放在不同的头文件中,用 户可调用。 例如:sin(x), scanf(“%d”,&x) 。 自编函数:由用户按语法规则编写。 注意:自编函数若与系统函数同名,则系统 函数不能用。
  • 175. 4-1 . c 4-2. c z1( ) z5( ) z2( ) z4( ) main( ) z3( ) 所有的函数都是独立的。即函数不能嵌套,不附属于另一个函数,书写的顺序任意。4-2.c 4-2.obj4-1.c 4-1.obj编译编译连接4-1. exe执行C函数之间的关系
  • 176. main ( )a()b()c()d()x() 1) DOS调用main函数;main函数调用其它函数;其它函数可相互调用。 2) 执行时从main()开始,调用其他函数后,仍然返回main(),最后从main()结束 。C函数执行过程
  • 177. 6.2 函数定义 按照规定的格式,将一个子任务编写成一个 函数。函数的定义例如:编写一个求平均分的函数就是平均分函数 的定义。
  • 178. 完成一个子工作的程序模块后有两种可能: (1)通过执行函数得到一个明确的执行结果,该 结果需要回送到调用函数中。 例如:调用求绝对值函数abs(-10),可得到具体 的函数值10。(2)仅完成某个功能,不需回送到执行的具体结 果。 例如: 执行输出函数printf(“**********”)的结 果是显示10个*。
  • 179. 函数类型 函数名(类型 形参1,类型 形参2,…) { 说明部分 语句部分 }函数定义的格式 说明: 1. 类型符表示函数的返回值类型: 若无返回值:类型符void ; 若有返回值:函数名前有类型符,且利用 return语句将函数值返回调用函数。
  • 180. 2. return语句: return 表达式; 或 return(表达式); 编写函数时,若求函数值,就要用return,若函数类型为void,则不用return语句。 功能:return语句先计算表达式的值,再将该值作为函数运算的结果回送给调用者。如果函数类型与return语句中表达式类型不一致,系统以函数类型为准,返回时自动进行类型转换。格式:
  • 181. 1)return语句只能返回一个结果,若有多个处理结果需返回调用函数,要采用其他方法。 2)若没有return语句,就一直执行到函数体的末尾 },然后返回调用函数。 3)流程从调用函数中的哪条语句转移到被调函数,返回时仍回到该语句。即从哪里出,还返回到哪里。 特点:
  • 182. void print( ) // void类型,不能有return语句 { int i ; for( i=1; i<=10; i++) printf(“*”); } int f ( int n) 函数首部 { int y=1,i; for(i=1;i<=n;i++) y=y*i; return(y); }函数体例如:
  • 183. void output( int n) { int i; for( i=1; i<=n; i++) printf("*"); printf("\n"); } void main( ) { int n; output( 10 ); n=20; output( n ); n=30 ; output( n+5 ); }例程6-1:没有return,执行到函数末尾从哪里出去,返回到哪里,每次返回的位置不一样
  • 184. int max( int x, int y ) { if(x>y) return(x); else return(y); } viod main() { int a,b,c; printf(“input a ,b:”); scanf(“%d%d”,&a,&b); c=max(a,b); printf(“max is %d\n”,c); } 例程6-2: 求两数中较大者。
  • 185. 3. 每个参数前要有类型符,若无参数,( )不能省略 float ave( int x , y ) { } float ave( int x, int y , char c ) { }
  • 186. 6.3 函数的调用 执行一段子程序并带回计算的结果;或完成 子程序中的操作。 函数的入口:函数首部 函数的出口:retrun语句,函数最后的 } 注意:不能利用goto插入到函数内,或break中断函数。见P.82-83。
  • 187. 按函数在程序中出现的位置来 分,共有3种。1. 函数语句: 因为 void类型不需返回值,把函数调用作为一个独立的语句,仅完成一定的操作。 函数名(实参表);例如: scanf(“%d”, &x); printf(“%d”, x);函数调用的形式
  • 188. void p2( int n) { int i ; for( i=1; i<=n; i++) printf( “*”); } void p1( ) { printf( “ 显示10个*\n ” ) ; } void main( ) { p1( ); p2( 10 ); }例程 6-3:
  • 189. 2. 函数表达式: 作为表达式,出现在允许表达式出现的地方,要 求带回一个确定的值,以参加表达式的运算。 int f( int n) void main( ) { int j ; int y=1 ; { int s; for(j=1;j<=n;j++) s=1+f(2)+f(3)+f(4)+f(5); y=y*j; printf(“s=%ld\n”’, s ); return(y); } } 例程 6-4 :
  • 190. 3. 函数参数: 函数调用作为一个函数的参数,即嵌套调用。 例如: m=max ( a, max( b, c) ); s=sum( 10, sum( 100 , 28 ) ) ; 见P.84-85 例6.7,例6.8
  • 191. 函数的提前声明 虽然C语言中的函数,放置顺序任意,但必须符合先声明后使用的原则。系统函数: 利用#include命令调入。放在程序的最前面。 用户函数: 在程序中的位置应遵循“先定义,后使用”的原 则,否则要提前声明。
  • 192. 函数的提前声明: 将被调函数的首部置于调用函数的说明部分。例程6-5: 用函数求平均分。 P.86 例6.9,例6.10
  • 193. 函数参数的传递 C程序是由函数组成的,每个C函数是独立的程序模块。 决不允许利用goto等转向跳跃语句,将数据从函数外插入函数内执行,这样破坏了函数的独立性及模块的结构化,同时函数返回时也找不到返回点。 但是函数之间有时需要一定的联系,例如:将A函数的数据传递到B函数中。
  • 194. 函数之间的联系工作,通过参数的传递来完成。函数参数的作用: 参数用来在独立的函数之间传递数据,建立函 数间的联系,根据参数的功能,有两类参数。 位置:出现在函数调用的( )中。 格式:函数名(实参1,实参2,……实参n) 实参的形式:表达式、函数、变量、数。 功能:将调用函数中的数据传递到被调函数中。 1. 实际参数(实参):
  • 195. 2. 形式参数(形参): 位置:在被调函数首部( )中说明的各量。 格式:类型 变量1,类型 变量2,……类型 变量n 功能:其作用是接收调用函数传递过来的实参值, 所以形参只能是变量(存储单元形式)。 例如:int f( int x, int, n, float y)形式参数{ }每个变量名前要有类型
  • 196. 说明: 1)多个参数间用逗号分隔,实参与形参在个数 类型、顺序上,必须一一对应或赋值兼容。 2)函数被调用时,才临时分配单元给形参, 函数执行完毕,这些单元被释放。 这样程序中占用的固定单元较少,执行速度快,不需考虑变量名的重用,便于多人编程。 需要接收外来数据的变量安排为形参,否则安排为普通变量。
  • 197. 3)实参仅用来传递数据或地址,不再分配存储单元,用户函数的调用同系统函数。 例如: sin(x); sin( int x); ave(n); ave( int 10 );
  • 198. void output( int n) { int i; for( i=1; i<=n; i++) printf("*"); printf("\n"); } 例程 6-6:void main( ) { int n; output( 10 ); n=20; output( n+5 ); output( n ); } 每次调用output函数时,分配给n的存储单元地址可能不同。实参传数据给形参,可以是表达式,但先计算后传递先分配单元,再接收数据。 故只能是变量,有类型符声明不要写成 output(int n); 变量n已分配
  • 199. P.89 例6.11函数之间数据的传递方式:1. 将实参传给形参,有二种方式: 复制式传递数据方式 传送地址方式 (数组和指针中介绍) 复制式传递数据方式 当调用函数时,实参将数据传给了形参后,它们之间没有任何联系,即单向按值传送。
  • 200. 由于实参和形参不在同一个函数,分配存储单元的时间不同,所以实参和形参不管是否同名,亦不同存储单元,所以在被调函数中,无论形参如何变化都不会影响实参值,处理的结果利用return语句带回。 从前面介绍的很多例程中,可看出复制式传递数据方式的特点:不同函数中的同名变量不同存储单元。 由于每个参数只能传递一个数据,当需要传递的数据较多时,显得很不方便。
  • 201. #include void main() { int a=15,b=25; void swap(int a, int b); printf("1.a=%d b=%d\n",a,b); swap(a,b); printf("4.a=%d b=%d\n",a,b); } void swap(int a, int b) { int t; printf("2.a=%d b=%d\n",a,b); t=a;a=b;b=t; printf("3.a=%d y=%d\n",a,b); } 例程 6-7:局部变量的值传递。
  • 202. 2. 利用全局变量可在每个函数中使用不释放内存单元的特点。 在函数外部说明的变量是全局变量。从声明的位置开始,以下的所有函数中都是有效的,即多个函数都可使用、改变它的值。 全局变量的使用增加了函数间的联系,但却降低了函数的独立性。因此在模块化设计方法中不提倡过多地使用全局变量。
  • 203. int i ; // 全局变量可在2个函数中使用 void print( ) { for( i=1; i<=10; i++) printf(“*”); } int f ( int n) { int y=1; for(i=1;i<=n;i++) y=y*i; return(y); }例程 6-8:全局变量应用
  • 204. 函数不能嵌套定义,但可以嵌套调用。a( ) { : : 调用b : : }b( ) { : : : : : }main { : : 调用a : : }函数的嵌套调用见P.91 例6.12
  • 205. 递归: 一个函数直接或间接地调用自身。 1. 直接递归调用:函数直接调用本身 2. 间接递归调用:函数间接调用本身函数的递归调用
  • 206. 直接调用: int f( int x ) { int y, z; … z=f (z); … }间接调用: int f1 ( int x ) { int y, z; … z=f2 (y); … } int f2 ( int t) { int a, b; … a=f1 (b); … }以下表示了递归的概念.
  • 207. 采用递归算法的优点: 可将复杂问题变得较简单。 缺点: 系统要自动安排一系列的内部操作,因此通常使效率降低,对硬件要求高,且并不是所有的问题都可以用递归来实现,必须有条件限制,否则回无限执行。
  • 208. 一个问题采用递归方法来解决时,必须符合以下二个条件: 1. 可以把一个问题转化为一个新的问题,而这个新问题的解决方法仍与原问题的解法相同,只是所处理的对象有所不同,但它们也只是有规律的递增或递减。 2. 必须有一个明确的结束条件。否则递归将无休止地进 行下去。
  • 209. n!=1 (n=0, 1) 结束条件 n(n–1)! (n>1) 每次计算方法相同例如: 求n!1. 从数学上定义见P.93 例6.13,6.14
  • 210. 6.4 标识符的作用域与存储方式变量的作用域变量的生命期被称为变量的作用域。 变量声明的方式不同,位置不同,其作用域也不同。C语言中的变量,按作用域范围可分为两种,即局部变量和全局变量。
  • 211. 局部变量 凡在函数(含main 函数)内或{ }内定义的变量 称为局部变量。生命期: 局部变量仅在函数内或{ }内有效。说明: 1) 不同的函数可具有同名的变量, 它们所占内存单元不同, 互不影响。形参为局部变量。 2)在复合语句中说明的变量仅在{ }内有效。
  • 212. 全局变量 在所有函数之外说明的变量为全局变量。生命期: 自说明的位置开始至文件结尾全部有效。 int p=1, q=5; //p,q可在f1,f2,main中使用 float f1( int a) { int b, c; } // b,c只能在f1中使用 char c1, c2; // c1,c2可在f2,main中使用 char f2( int c, y ) { int i, j ; } // i,j只能在f2中使用 void main() { }例如:
  • 213. 1. 因为可在多个函数中使用,相当于这些函数的公共变量。于是, 当一个函数对其值进行改变后, 另一个函数使用该变量的值亦相应改变。 优点:可将某函数的结果带到另一个函数中 缺点:始终占据内存单元;通用性差。2. 当全局和局部变量同名时, 局部变量有效。说明:见P.98 例6.18-20
  • 214. 变量的存储类别表达了在程序运行期间一个变量存在的空间、时间。 C系统给每个C程序在内存中分配一片区域用来存放程序和数据。程序区 静态存储区 动态存储区存放数据,变量值内存分配变量的存储方式
  • 215. 变量又可分为四种具体形式2. 静态变量(static)4. 寄存器型变量(register ,已不用)3. 外部变量(extern)1. 自动型变量(auto)
  • 216. 静态存储变量: 用 static 说明的变量或全局变量。 存放在静态存储区, 在程序整个运行过程中, 始终占据 固定的内存单元, 到程序执行完毕才释放 。注意: 1、用static声明的变量,程序运行中仅在第一次调用时赋初值,以后调用不再赋初值,而是使用上一次调用的值(因为存储单元不释放)。 2、若不赋初值, 则系统置初值0 。
  • 217. #include int fac ( int n) { static int f=1; f=fn; return(f); } void main ( ) { int i; for (i=1; i<=5; i++) printf ("%d!=%d\n", i, fac( i ) ); } 例程6-9: 求n!
  • 218. 每一次调用fac(i), 输出一个i ! ,同时保留这个i !的值以便下次再乘(i+1)。运行结果为: 1!=1 2!=2 3!=6 4!=24 5!=120
  • 219. 动态存储变量: 用 auto 说明或缺省。存放于 动态存储区, 函数调用时临时分配的单元,调用 结束,释放这些单元。在程序执行过程中,这种 分配和释放是动态的。 在一个程序中几次调用同一函数,分配给函 数中局部变量的存储空间可能不同。
  • 220. 外部变量(extern) 若一个程序分成2个文件保存,在B文件中要用A文件中的全局变量,则在B文件中将该变量声明成外部变量,这样就可在B文件中,引用在A文件中说明并赋值的全局变量。例6-10:// 1.c文件 int x; void main() { void f(); x=10; f(); }// 2.c 文件 #include void f() { extern int x; printf("x=%d\n", x ); }
  • 221. 说明: 若被调函数和调用函数不在同一文件,必须 在调用函数中对被调函数声明,或作为全局量。 // 1.c文件 int n=100; void f(); void main() { // void f(); f( ); }// 2.c 文件 #include void f() { extern int n; int i,s=0; for(i=1;i<=n;i++) s+=i; printf("s=%d\n",s); }例6-11:
  • 222. 一个C程序由一个或多个源程序文件组成。每个源程序文件中有若干个函数。最后将若干个文件组成一个C程序执行。多文件操作方法一: 利用#include命令,将另一个文件的内容包含进来;编译、连接、执行等操作同单文件。 注意:文件要放在同一个文件夹中。
  • 223. 例如: #include “a2.c” #include ”a3.c” void main( ) { … }方法二: 利用 vc 的projectc工程。
  • 224. 数组:一种数据类型数据类型基本类型 构造类型 指针类型 空类型整型 实型 字符型数组 结构 联合 枚举单精度型 双精度C语言的数据类型第7章 数 组
  • 225. 引言 整型int、字符型char、实型float、double是简单变量,相互之间无 任何联系,要表示数学上的矢量、矩阵、下标变量等比较困难。例如 一个班级30个学生,求某门课的平均分数 float a0,a1,a2,a3,...,a29,average; …….. average=(a0+a1+a2+a3+a4+...+a29)/30average=0; average= average+a0; average= average+a1; average= average+a2; ……. average= average+a29; average= average/30;average= average+ai; i=0,1,2,…,29
  • 226. 程序得到简化 float a[30],average=0; …….. for(i=0;i<30;i++) average=average+a[i] average=average/30其中 a是数组名,a[i]是数组元素,i是数组的下标,若改用数组 average= average+a[i]; i=0,1,2,…,29数组由许多元素组成 每个元素对应一个存储单元 数组元素有共同的名,访问数组元素通过下标实现 用下标表示数组元素之间的联系。
  • 227. §7.1 一维数组7.1.1 一维数组的定义和引用 1.定义 格式 类型名 数组名[数组长度]其中 类型名 定义数组元素的类型 数组名 按标识符规则取名 数组长度 表示该数组的元素个数,及 元素的下标范围0~数组长度-1之间操作 定义数组名、全体元素的类型、元素的个数、数组元素的 下标取值范围,分配相应的内存单元例 int a[10]; float f[5]; 表示 a是数组名,有10个元素,下标取值在0~9之间,即a[0],a[1], a[2]~a[9],全部为整型。 f是数组名,有5个元素,下标取值在0~4之间,即f[0],f[1], f[2], f[3],f[4],全部为实型。
  • 228. 2.引用格式 数组名[下标]其中 数组名在说明部分已定义过 下标可以是整型常量、变量、表达式,下标值必须在定 义的取值范围 ,即0~数组长度-1之间例 int a[10],k=3; a[0]=a[1]+a[k]-a[2*3];数组元素的使用方法与同类型的变量相同例 scanf("%d", &a[i]); temp = a[i]; a[i]= a[k]; a[k] = temp; printf("%d ",a[i]);其优点,数组的下标是可变的
  • 229. 例 void main() {int i,a[10]; for (i=0;i<=9;i++) a[i]=i; for (i=9;i>=0;i--) printf("%3d",a[i]); }输出 9 8 7 6 5 4 3 2 1 0i a[i]=i 0 a[0]=0 1 a[1]=1 … 8 a[8]=8 9 a[9]=9i a[i] 9 a[9]9 8 a[8]8 … 0 a[0]0注数组使用之前必须先定义 只能引用单个的数组元素,不能一次引用整个数组 数组元素下标不要越界例 int a[9]; a[1]=2*a[9]; 错误(语法不错)
  • 230. 例7-2 求Fibonacci(斐波那契)数列的前20个数 1, 1, 2, 3, 5, 8, 13, ... 用f数组存放。 #include "stdio.h" void main() {int i, f[20];f[0]=1;f[1]=1; for(i=2;i<20;i++) f[i]=f[i-2]+f[i-1]; for(i=0;i<20;i++) {printf("%d ",f[i]); if((i+1)%5==0) printf("\n"); } }7.1.2 使用一维数组编程 f[0]=1 f[1]=1 i=2 f[2]=f[0]+f[1]=1+1=2 i=3 f[3]=f[1]+f[2]=1+2=3 i=4 f[4]=f[2]+f[3]=2+3= 5 i=5 f[5]=f[3]+f[4]=3+5= 8 …… i=19 f[19]=f[17]+f[18]=6765f[0]=1 i=0 f[1]=1 i=1 f[i]=f[i-2]+f[i-1] 2≤i≤19 1 1 2 3 5 8 13 … f[0] f[1] f[2] f[3] f[4] f[5] f[6]
  • 231. 例7-3 输入n个互异的整数,将它们存入数组中,再输入1个数x,然后在数组中找x。如果找到,输出相应的下标,否则输出“Not Found”。算法将x与数组元素依次比较。 无序数据序列的查找(遍历算法) #include "stdio.h" void main() {int i,n,a[20]; scanf("%d",&n); for(i=0;i=n) printf(" Not Found\n"); }输入数组a输入xi=0,n-1,1x==a[i]ii>=n输出iNot Found0110停
  • 232. 例7-4 输入一个正整数n(1x10min=xi=a[index] a[index]=a[0] a[0]=imin>a[i]10min=a[i]i=1,n-1,1iindex=imin=a[0]index=0输入a,b,c,dmin=amin>b10min=b输出min停min>c10min=cmin>d10min=d
  • 233. #include "stdio.h" void main() {int i,index=0,n,a[10]; scanf("%d",&n); for(i=0;ia[i])index=i; printf("%d %d\n", index,a[index]); i=a[index];a[index]=a[0];a[0]=i; for(i=0;ia[i] index=i a[index] 0 1 6>31 1 3 1 2 3>11 2 1 2 3 1>80 2 4 1>90a[index]>a[i]10i=1,n-1,1iindex=iindex=0i=a[index] a[index]=a[0] a[0]=i输出 2 1 1 3 6 8 9
  • 234. 例7-1 选择法排序 对n个数小到大排序 算法 (1)在n个数(a[0]~a[n-1])中找到最小数,将它与a[0]交换。 (2)在未排序的n-1个数(a[1]~a[n-1])中找到最小数,将它与a[1]交换。 …… (n-1)未排序的2个数(a[n-2]~a[n-1])中找到最小数,将它与a[n-2]交换如 2 6 1 8 7 4 5 确定第1最小1与a[0]对换1 6 2 8 7 4 5 确定第2小值2与a[1]对换1 2 6 8 7 4 5 确定第3小值4与a[2]对换1 2 4 8 7 6 5 确定第4小值5与a[3]对换1 2 4 5 7 6 8 确定第5小值6与a[4]对换1 2 4 5 6 7 8 确定第6小值
  • 235. 把思路用流程图描述 n个数先存入a数组a[0]~a[n-1]中n个数 (a[0]~a[n-1]) 中找最小数,与 a[0] 交换n-1个数 (a[1]~a[n-1]) 中找最小数,与 a[1] 交换2个数 (a[n-2]~a[n-1]) 中找最小数,与 a[n-2] 交换…index]a[j]
  • 236. #include "stdio.h" void main() {int i,j,n, index; float a[10],t; scanf("%d",&n); for(i=0;i
  • 237. 7.1.3 一维数组的初始化 在定义数组的同时即给数组元素赋值 格式 类型名 数组名[数组长度]={常量表达式序列} 其中 常数表达式序列:常数表达式1,常数表达式2,...即初值操作 将常数表达式序列的初值依次赋值于数组各元素如 int a[10] ={0,1,2,3,4,5,6,7,8,9}; 经过定义初始化后 a[0]=0,a[1]=1,...a[9]=9注当定义数组的长度省略,则数组个数由初值个数决定 如 int a[]={1,2,3,4,5}; 即为 int a[5]; a[0]=1,a[1]=2,a[2]=3,a[3]=4,a[4]=5
  • 238. 注 ANSI C 规定只有静态存储的数组才能初始化 static int a[10] ={0,1,2,3,4,5,6,7,8,9};但一般的C编译系统允许自动型数组也能初始化 auto int a[10] ={0,1,2,3,4,5,6,7,8,9};省略auto的,即为自动型static型与auto型区别存储单元分配: static分配固定存储空间 auto动态分配存储空间存储单元缺省值:static为0 auto为随机值例 static int a[5]; a数组的5个元素全为0 auto int b[5]; b数组的5个元素均是不定值
  • 239. 注 当数组指明的元素个数大于初值个数时,初值只赋予数组开 始若干个元素,余下部分为相响应类型的缺省值。例 static int a[10]={0,1,2,3,4}; 即为 a[0]=0,a[1]=1,a[2]=2,a[3]=3,a[4]=4;a[5]~a[9]=0 int b[10]={0,1,2,3,4}; 即为 b[0]=0,b[1]=1,b[2]=2,b[3]=3,b[4]=4;b[5]~b[9]=不定值实际上,TC或VC b[5]~b[9]仍为0
  • 240. #include void main() {int num[26]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,91,97}; int i,j,m,line=0; for(i=6;i<=100;i+=2) for(j=0;j<26;j++) for(m=j;m<26;m++) if(num[m]+num[j]==i) {line++; printf("%d=%d+%d ",i,num[j],num[m]); if(line%5==0) printf("\n"); }} 例验证哥德巴赫猜想:任何一个大于6的偶数均可表示为两个素数之和。例如6=3+3,8=3+5,…,18=7+11。要求将6~100之间的偶数都表示成两个素数之和,打印时一行打印5组。
  • 241. §7.2 二维数组7.2.1 二维数组定义和引用 1.定义 格式 类型说明符 数组名[数组长度1] [数组长度2]与一维数组比较,多了一个下标,一般称前个下标为行, 第二个称为列例 float a[3][4]; 定义了 a数组 3行4列 12个元素 均为实型 a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3] 数组元素在内存排序,按行存放1 2 3 4 5 6 7 8 9 10 11 12 a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3]
  • 242. 多维数组定义 格式 类型说明符 数组名[数组长度1] ...[数组长度n]n个数组长度为n维数组例 float a[2][3][4]; 定义了 a数组为三维 2*3*4个元素 均为实型 a[0][0][0] a[0][0][1] a[0][0][2] a[0][0][3] a[0][1][0] a[0][1][1] a[0][1][2] a[0][1][3] a[0][2][0] a[0][2][1] a[0][2][2] a[0][2][3] a[1][0][0] a[1][0][1] a[1][0][2] a[1][0][3] a[1][1][0] a[1][1][1] a[1][1][2] a[1][1][3] a[1][2][0] a[1][2][1] a[1][2][2] a[1][2][3] 多维数组元素在内存排序,靠右的维数先变,依次向左变化1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
  • 243. 2. 二维数组元素的引用格式 数组名[下标1] [下标2] 多维数组 数组名[下标1] [下标2]...[下标n]其中 数组名在说明部分已定义过 下标可以是整型常量、变量、表达式,各下标值必须在定 义的取值范围,即0~定义下标的数组长度-1如 float a[3][4]; a[1][2]=a[2][3]/2;
  • 244. 例7-6 定义32的二维数组a,数组元素的值由下式给出 a[i][j]=i+j (0≤i≤2,0 ≤j≤1) 将该数组元素按矩阵的形式输出#include "stdio.h" void main() {int i,j,a[3][2]; for(i=0;i<3;i++) for(j=0;j<2;j++) a[i][j]=i+j; for(i=0;i<3;i++) {for(j=0;j<2;j++) printf("%4d",a[i][j]); printf("\n"); } }输出: 0 1 1 2 2 37.2.2 使用二维数组编程0 1 1 2 2 30 0 a[0][0]=0+0=0 0 1 a[0][1]=0+1=1 1 0 a[1][0]=1+0=1 1 1 a[1][1]=1+1=2 0 a[2][0]=2+0=2 2 1 a[2][1]=2+1=3i j a[i][j]=i+j
  • 245. #include "stdio.h" void main() {char a[3][2],i,j; for(i=0;i<3;i++) for(j=0;j<2;j++) a[i][j]=i+j; for(i=0;i<3;i++) for(j=0;j<2;j++) printf("%d ",a[i][j]); printf("\n"); for(j=0;j<6;j++) printf("%d ",a[0][j]); }输出 0 1 1 2 2 3 0 1 1 2 2 3说明: 行下标*列长度+列下标<行长度*列长度a[0][0]=0 a[0][1]=1 a[1][0]=1 相同于 a[0][2] a[1][1]=2 a[0][3] a[2][0]=2 a[0][4] a[2][1]=3 a[0][5]如a[0][5], 0*2+5<3*2
  • 246. 例7-5 将1个3*2的矩阵存入1个3*2的二维数组中,找出最大值以及它的行下标和列下标,并输出该矩阵。算法 遍历矩阵全部元素,比较,找出最大值设 row 记录最大值的行下标 col 记录最大值的列下标 a[row][col] 就是最大值void main( ) { int col, i, j, row;int a[3][2]; for(i=0;i<3;i++) for(j=0;j<2;j++) scanf("%d", &a[i][j]); row = col = 0; for(i = 0; i < 3; i++) for(j = 0; j < 2; j++) if(a[i][j] > a[row][col]) {row = i; col = j; } printf("max=a[%d][%d]=%d\n",row,col,a[row][col]); }
  • 247. 例7-7 输入一个正整数n(1 b[j][i] i=0,1,…n-1 j=0,1,…n-1#include "stdio.h" void main() {int i,j,n,a[6][6],b[6][6]; scanf("%d",&n); for(i=0;i
  • 248. 转置(行列互换)即为对角线为界a[i][j] <=> a[j][i] for(i=0;i a[1][0] a[0][2] <=> a[2][0] a[1][2] <=> a[2][1]遍历上三角阵for(i=1;i=j
  • 249. #include "stdio.h" void main() {int i,j,n,t,a[6][6]; scanf("%d",&n); for(i=0;i a[j][i] ,程序得到简化
  • 250. 7.2.3 二维数组的初始化 两种形式 1.按顺序赋初值 格式 类型说明符 数组名[数组长度1][数组长度2] ={常量表达式序列} ;操作 将常数表达式序列的初值依次赋值于数组各元素,数组元素 按行排序(内存单元排序)例 int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};即 a[0][0]=1 a[0][1]=2 a[0][2]=3 a[0][3]=4 a[1][0]=5 a[1][1]=6 a[1][2]=7 a[1][3]=8 a[2][0]=9 a[2][1]=10 a[2][2]=11 a[2][3]=12
  • 251. 2.分行赋初值 格式 类型说明符 数组名[数组长度1][数组长度2] ={{常量表1},{常量表2},...,{常量表n}} ;操作 将常数表1赋值于数组第一行元素, 将常数表2赋值于数组第 二行元素,..., 将常数表n赋值于数组第n行元素例 int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; 获得同上结果注 (1)方法比较, 后者优越,一行数据对一行数组元素,界限清楚;特 别当行尾有零元素不必在初值表中列出例int a[3][3]={{1,2,5},{0,0,0},{4,5,0}};简化为 int a[3][3]={{1,2,3},{},{4,5}};
  • 252. 注 (2)数组元素赋初值时,定义第一维的长度可以缺省例 int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12}; 即 int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; 又例 int a[][4]={{0,0,3},{},{0,10,0}}即
  • 253. 例7-8 定义一个函数day_of_year(year,month,day)计算并返回year、month和day是该年的第几天。 例如,调用day_of_ year(2000,3,1)返回61, 2000年是闰年 调用day_of_year(1999,3,1)返回60 , 1999年不是闰年显然,对1~month-1的月天数累加,再加上当月的day。但2月的天数根据是否闰年取29天或28天用数组tab[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31}};存放显然 非闰年使用tab[0][k] 闰年使用tab[1][k] 其中 k代表月份
  • 254. 程序int day_of_year(int year,int month,int day) {int k,leap,s=0; int tab[2][3]={ {0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31}}; leap=(year%4==0&&year%100!=0)||year%400==0; for(k=1;k
  • 255. §7.3 字符串与数组在C语言中,字符串的存储和运算可以用一维字符数组来实现。7.3.1 一维字符数组一维字符数组用于存放字符型数据。它的定义、初始化和引用与其他类型的一维数组一样。例 char c[10]; c[0]='I'; c[1]=' '; c[2]='a'; c[3]='m'; c[4]=' '; c[5]='h'; c[6]='a'; c[7]='p'; c[8]='p'; c[9]='y'; 定义 c数组名,包含10个元素,是字符型在内存存放1.定义printf("I am happy\n");
  • 256. 2.初始化例 char c[10]={'I',' ','a','m',' ','h','a','p','p','y'}; 注 (1)初值的个数不能超过元素的个数 如 char a[5]={'I',' ','a','m',' ','h','a','p','p','y'}; 不允许 (2) 初值的个数少于元素的个数,将数值赋于前面的数组元素 余下元素以字符\0充填 如 char c[11]={'I',' ','a','m',' ','h','a','p','p','y'}; c: I am happy\0\0 ASCII为0的字符,作为字符串的结束等价于 char c[11]={'I',' ','a','m',' ','h','a','p','p','y','\0'}; char c[11]={'I',' ','a','m',' ','h','a','p','p','y',0}; 注:在字符数组'\0'与0等价
  • 257. (3)当数组长度缺省,由初值个数决定数组元素的个数 如 char c[ ]= {'c',' ','p','r','o','g','r','a','m'}; 自动定义c数组9个元素,即 c[9]3.引用例main() {char c[10]={'I',' ','a','m',' ','h','a','p','p','y'}; int i; for(i=0;i<10;i++) printf("%c",c[i]);/*putchar(c[i]);*/ printf("\n"); }(4)多维数组的初始化 如 char c[2][3]={{'a','b','c'},{'1','2','3'}}; 格式 数组名[下标]
  • 258. 7.3.2 字符串字符串 “字符序列”每个字符串后都有字符串结束标志'\0' ,控制字符串的操作例 printf("this is a C program.\n");例 char c[10]={'I',' ','a','m',' ','b','o','y','\0'}; c是字符串2.字符串初始化 C语言用字符数组存放字符串,字符串可以赋初值于字符数组例 char s[10]={"Happy"}; 或 char s[10]="Happy"; 或 char s[ ]="Happy"; char s[10]={'H','a','p','p','y'}; 自动加上'\0' 但char s[5]={'H','a','p','p','y'}; 或char s[]={'H','a','p','p','y'}; s不是字符串1.字符串定义注 字符串不能在语句中对数组赋值 如 char s[10]; s="Happy"; 不允许 而只能 s[0]='H';s[1]='a'; s[2]='p';s[3]='p'; s[4]='y';s[6]='\0'; 或用库函数 strcpy(s, "Happy"); 该库函数在string.h
  • 259. 3.字符串的输入和输出printf()的%s的输出 例 char c[ ]="I am happy"; printf("%s\n",c); 输出 I am happy注 输出的对象是地址,字符数组仅写数组名 遇到'\0',输出结束,而'\0'不作输出(1)字符串输出用putchar()或printf()的%c的输出void main() {int i=0;char c[11]={"I am happy"}; while(c[i]!='\0') putchar(c[i++]);/*或 printf("%c",c[i++]);*/ }
  • 260. (2)字符串输入用getchar()或scanf()的%c的输入void main() {int i=0;char c[20]; while((c[i]=getchar())!='\n') i++; c[i]= '\0'; /*使c成为字符串*/ printf("%s\n",c); }void main() {int i=0;char c[20]; scanf("%c",&c[0]); while(c[i]!='\n') {i++; scanf("%c",&c[i]); } c[i]='\0'; /*使c成为字符串*/ printf("%s\n",c); }
  • 261. 注 输入的对象是内存地址。字符数组仅写名空格符是输入字符串的结束符 例 char str1[5],str2[5],str3[5]; scanf("%s%s%s",str1,str2,str3); 输入数据 How are you? 得 str1="How" str2="are" str3="you?"输入字符个数少于定义的字符数组元素的个数,系 统自动在输入的字符串后加上\0结束符,因此定义字符数组 数组长度>=字符个数+1 scanf()的%s的输入 例 char ch[6];scanf("%s",ch); 输入 China 得 ch="China\0"
  • 262. 例7-11 输入一个以回车结束的字符串(少于80个字符),统计其中数字字符的个数。 分析:由于字符串少于80个字符,数组长度就取其上限80,以'\n'作为输入结束符。#include "stdio.h" void main() {int i=0,count=0;char str[80]; while((str[i]=getchar())!='\n') i++; str[i]='\0'; for(i=0;str[i]!='\0';i++) if(str[i]<='9'&&str[i]>='0') count++; printf("count=%d\n",count); }i: 0 1 2 3 4 5 输入:9b465str输出: count=4#include "stdio.h" void main() {int i=0,count=0;char str[80]; scanf("%s",str); for(i=0;str[i]!='\0';i++) if(str[i]<='9'&&str[i]>='0') count++; printf("count=%d\n",count); }/*输入一行中不能有空格*/
  • 263. 4.字符串有效长度与字符数组的长度例 #include "stdio.h" #include "string.h" void main() {char s[10]="Happy"; int l1,l2; l1=strlen(s);l2=sizeof(s); printf("s=%s l1=%d l2=%d\n",s,l1,l2); l1=strlen("Happy");l2=sizeof("Happy"); printf("s=%s l1=%d l2=%d\n",s,l1,l2); }运行 s=Happy l1=5 l2=10 s=Happy l1=5 l2=6字符串有效长度:字符串的字符的个数,不包括'\0'strlen():计算字符串有效长度 sizeof():计算字节数注: '\0'赋值数组元素,将改变字符串长度如上例 s[3]='\0'; 则 s的有效长度为3字符数组的长度:字符数组定义的长度,数组元素的个数
  • 264. 例7-9 输入一个以回车结束的字符串(少于10个字符),它由数字字符组成,将该字符串转换成整数后输出。例 123451×104 +2×103+3×102+4×101+5×10012345即为多项式计算5.字符串应用——进制转换a0xn-1+a1xn-2+… +an-3x2 +an-2x+an-1 x表示数进制改写为 (… ((a0x+a1)x+ a2)x +…+an-2)x+an-1 如 12345(((1×10+2)×10+3)×10+4)×10+5(a0xn-2+a1xn-3+… +an-3x1 +an-2)x+an-1 ((a0xn-3+a1xn-4+… +an-3)x +an-2)x+an-1 ……程序为: d=0; for(i=0;i
  • 265. 算法(a[n]=getchar())!='\n'n=0n++d=0i=0,n-1,1d=d*10+a[i]-'0'i输出d10#include "stdio.h" void main() {int n=0,i; long d=0; char a[10]; while((a[n]=getchar())!='\n') n++; a[n]='\0'; for(i=0;a[i]!='\0';i++) d=d*10+a[i]-'0'; printf("%ld\n",d); }由于a[i]是字符 转成数值 a[i]-’0’ 进制 x=10 ,则程序为: d=0; for(i=0;i
  • 266. 7.4 数组作为函数参数1.形参是变量,实参可以是数组元素,形参与实参结合是单值传递#include "stdio.h" void main() {int a[10],b[10],i,j,n=0,m=0; scanf("%d",&j); for(i=0;in) printf("a>b\n"); else if(my)flag=1; else if(x
  • 267. 2.形参是数组,实参应为数组名例有一维数组x内放10个学生的成绩,求平均成绩程序float average(float a[10]) {int i; float aver=a[0]; for(i=1;i<10;i++) aver= aver +a[i]; aver= aver/10; return(aver); }#include "stdio.h" void main() {float x[10],aver;int i; for(i=0;i<10;i++) scanf("%f",&x[i]); printf("\n"); aver=average(x); printf("average= %f",aver); } aver= aver/10;数组名数组
  • 268. 注 (1)数组名是数组内存的首地址,数组的虚实结合是地址传递,把实参数组的起始地址传递形参数组,两个数组共占一段内存单元 如 形参a [10]与实参x[10]结合 xaa [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]起始地址存储单元x [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]由此可见实际实参数组在运行,因而函数执行完毕实参数组的内 容可能被改变。利用这点可以使函数返回更多的值。
  • 269. 例 编一函数,用选择法对数组(10个元素)小→大排序void sort(int x[10],int n) {int i,j,k,t; for(i=0;i
  • 270. (2)形、实参数组的类型一致,否则编译出错(3)形参可以是可调数组,不确定数组元素的个数 一维数组 省略定义元素大小 多维数组 只能省略第一维定义元素大小 如 void sort(int a[],int n) 、int fun(float b[][3][4])函数的形参省略维数定义数组适应程序的通用性例 编一函数,用选择法对数组小→大排序void sort(int x[100],int n) {int i,j,k,t; if(n>100)exit(1); for(i=0;i
  • 271. 例 有一个3×4矩阵,求其中的最大元素max_value(int a[][4],int n) {int i,j,k,max; max=a[0][0]; for(i=0;imax)max=a[i][j]; return(max); } main() {static int b[3][4]={{1,3,5,7},{2,4,6,8},{15,17,34,12}}; printf("max_value is %d\n",max_value(b,3)); }
  • 272. 4.形参、实参的数组元素个数、维数可以不一致,原因是编译不检 查,只是起始地址的传递。原则上实参数组元素个数≥形参数组 元素个数。void print(int a[],int n) {int i; for(i=0;i
  • 273. 作业:第7章作业 下载http://www.ccea.zju.edu.cn/clearn/ 实验:第7次实验
  • 274. 折半法(二分法)查数 对已排序数据序列(小到大或大到小)的查找算法:值区间不断折半缩小,直到找到要查的数例 a[9]={1,2,3,6,8,9,10,12,14}0 1 2 3 4 5 6 7 8 要求查 x=2a的有值区间0~8 折半 (0+8)/2=4 a[4]=8 不是 a的区间分为 0~3 5~8 判别有值区间 0~3 a的有值区间0~3 折半 (0+3)/2=2 a[2]=2=x 是
  • 275. 折半法流程输入数组a输入x top=0, mid=0 bot=N-1 x>a[bot]||x
  • 276. #define N 10 #include "stdio.h" void main() {int a[N],top=0,bot=N-1,mid=0,x,i; for(i=0;i=a[0]&&x<=a[N-1]) while(top<=bot) {mid=(top+bot)/2; if(x==a[mid]) break; else if(x