C语言程序设计教程第二版第二版全套电子课件完整版ppt整本书电子教案最全教学教程整套课件

上传人:工**** 文档编号:569718540 上传时间:2024-07-30 格式:PPT 页数:510 大小:4.30MB
返回 下载 相关 举报
C语言程序设计教程第二版第二版全套电子课件完整版ppt整本书电子教案最全教学教程整套课件_第1页
第1页 / 共510页
C语言程序设计教程第二版第二版全套电子课件完整版ppt整本书电子教案最全教学教程整套课件_第2页
第2页 / 共510页
C语言程序设计教程第二版第二版全套电子课件完整版ppt整本书电子教案最全教学教程整套课件_第3页
第3页 / 共510页
C语言程序设计教程第二版第二版全套电子课件完整版ppt整本书电子教案最全教学教程整套课件_第4页
第4页 / 共510页
C语言程序设计教程第二版第二版全套电子课件完整版ppt整本书电子教案最全教学教程整套课件_第5页
第5页 / 共510页
点击查看更多>>
资源描述

《C语言程序设计教程第二版第二版全套电子课件完整版ppt整本书电子教案最全教学教程整套课件》由会员分享,可在线阅读,更多相关《C语言程序设计教程第二版第二版全套电子课件完整版ppt整本书电子教案最全教学教程整套课件(510页珍藏版)》请在金锄头文库上搜索。

1、2024/7/30121世纪高职高专新概念教材C语言程序设计教程(第二版)2024/7/302第第1 1章章 语言概述语言概述教学目的教学目的:掌握掌握C语言的程序结构程序结构,函数结构函数结构,源程序书写规则书写规则,以及TC+3.0的基本操作基本操作。了解了解C语言的特点和语句。2024/7/303教学内容教学内容:1.1 发展简史和特点发展简史和特点1.2* 程序结构与函数结构程序结构与函数结构1.3* 源程序书写规则源程序书写规则1.4 C语言的语句语言的语句1.5* TC+3.0基本操作基本操作本章要点本章要点2024/7/3041.1 1.1 发展简史和特点发展简史和特点 1语言的

2、诞生与发展语言的诞生与发展贝尔实验室贝尔实验室贝尔实验室贝尔实验室于70707070年代年代年代年代初研制出来。80年代初,美国国家标准化协会(ANSI),制定了ANSI C标准(俗称标准标准C C),1989年再次做了修订(称新新标准标准C C) 。微机上广泛使用的语言编译系统有MSCMSC、TCTC 、BCBC:基本部分相同,但存在一些差异。本课程以ANSI CANSI C新标准新标准来介绍,上机环境选择TC TC +3.0+3.0。2024/7/3052C语言的特点语言的特点C语言兼有汇编和高级语言的优点:(1) 汇编汇编语言:可以直接操纵硬件操纵硬件。(2) 高级高级语言:可读性可读性

3、和可移植性良好可移植性良好。返回返回2024/7/3061.21.2* * 程序结构与函数结构程序结构与函数结构1.2.1 程序结构程序结构 1最简单的程序:仅由一个main( )函函数数(又称主函数)构成。案例案例1.1 仅由main()函数构成的语言程序。 #include “stdio.h”#include “conio.h”void main( ) printf(“This is a C program.n”); getch(); 程序运行结果:This is a C program. 2024/7/3072一般化结构:由一个main()函函数数和若干个其其它它函数函数结合而成。案案例

4、例1.2 由main()函数和1个max()函数构成的语言程序。 #include “stdio.h”#include “conio.h”void main( ) int num1, num2; printf(“Input the first integer number: ”); scanf(“%d”, &num1); printf(“Input the second integer number: ”); scanf(“%d”, &num2); printf(“max = %dn”, max(num1, num2); getch(); 2024/7/308int max( int x, i

5、nt y) return( xy ? x : y ); 程序运行情况: Input the first integer number: 6 Input the second integer number: 9 max = 92024/7/309案案例例1.3 交换案例1.2中main( )函数和max( )函数的位置。源程序略。程序运行情况: Input the first integer number: 6 Input the second integer number: 9 max = 9思考思考:案例1.3说明了什么?2024/7/30103说明:函数函数是语言程序的基本构成单位。(1)

6、main()函数: C语言程序总是从main( )函数开始执行(不论其在程序中的位置),止于主函数结束。(2)其它其它函数:通过被main( )函数直接或间接调用而执行。习惯习惯:将主函数main()放在最前头。2024/7/3011 1.2.2 函数结构函数结构 任何函数(包括主函数main()都是由函函数数说说明明和函数体函数体两部分组成:函数类型 函数名( 函数参数表 ) 说明语句部分; 执行语句部分; 函数说明函数说明函数体函数体2024/7/30121语法符号约定语法符号约定 . 可选(即可以指定,也可以缺省)前面的项可以重复 | 多(含2)中选1 2024/7/30132 2函数说

7、明:函数说明:由函数类型函数类型(可缺省)、函数名函数名和函数函数参数表参数表(可缺省)组成。案例1.2中函数max()的函数说明如下: int max ( int x , int y )函数参数表的一般格式为:数据类型数据类型 形参形参,数据类型数据类型 形参形参2 2 函数类型函数名函数参数表2024/7/30143 3函数体函数体:在函数说明的下面、最外层最外层1对大括大括号号(必须配对使用)括起来的部分。案例例1.2中中main( )函数的函数体如下:void main( ) int num1, num2; printf(“Input the first integer number:

8、 ”); scanf(“%d”, &num1); printf(“max = %dn”, max(num1, num2); 变量定义变量定义可执行语句可执行语句2024/7/3015一般由两部分构成:(1)数数据据说说明明部分:由变变量量定定义义、自定义类型定义、自定义函数说明、外部变量说明等组成。(2)可可执执行行语语句句部分:一般由若干条可执行语句构成。注注意意:函数体中的变变量量定定义义语语句句,必须在所有可执行语句之前。2024/7/3016下面程序中 “int max;”的位置非法:#include “stdio.h”#include “conio.h”void main() int

9、 x , y;/*变量定义语句*/ x = 3; y = 6; /*可执行的赋值语句*/ int max; max = x y ? x : y ; printf(“max = %dn”, max); getch(); 思考思考:如何解决?返回返回变量定义语句出现在可执行的赋值语句之后2024/7/30171除字符串常量中的字符外,一律使用半角字符半角字符。例如,字母、数字、标点符号等。2所有语句都必须以分号“;”结束,函数的最后一个语句也不例外。3允许1行行内写几几条条短语句,也允许将1条条很长的语句分写在几行几行上。1.31.3* * 源程序书写规则源程序书写规则2024/7/3018案例例

10、1.2中的主函数main( ),也可写成如下格式:void main() int num1, num2; printf(“Input the first integer number: ”); scanf(“%d”, &num1); printf(“Input the second integer number: ”); scanf(“%d”, &num2); printf(“max=%dn”, max(num1, num2); 2024/7/3019 4允许使用注释注释: /* */(1) “/*”和“*/” 必必须须成成对对使使用用,且“/”和“*”、以及“*”和“/”之间不能有空格,否则

11、都出错。技技巧巧:必须配对使用的符号(例如注释符号、函数体的花括号、圆括号等等),可连续输入这些起止标识符,通过插入来完成内容的编辑。2024/7/3020(2) 注释可以单占1行,也可跟在语句的后面。(3) 如果1行写不下,可另起1行继续写。(4)注释中允许使用汉字。在非中文操作系统下,看到的是一串乱码,但不影响程序运行。 返回返回2024/7/30211.4 C1.4 C语言的语句语言的语句按照语句功功能能(或构成)的不同,将语言的语句分为五类。1. 控制语句控制语句(条,为三种条,为三种)(1) 选择选择结构控制语句:if( ), switch( )(2)循循环环结构控制语句:dowhi

12、le() , for(), while( ) , break , continue(3) 其它其它控制语句:goto , return2024/7/3022 2. 函函数数调调用用语语句句由一次函数调用加一个分分号号(语句结束标志)构成。例如,printf(This is a C function statement.) ;3. 表达式语句表达式语句由表达式后加一个分号分号构成。最典型的是赋值语句:num = 5 ;/*赋值语句*/4. 空语句空语句仅由一个分号分号构成。例如: ;2024/7/30235. 复复合合语语句句由大括号括起来的若干条语句构成。main() /*右括号后不需要分号!

13、*/ 复合语句的性质复合语句的性质: (1)在语法上和单单一一语语句句相同,即单一语句可以出现的地方,也可以使用复合语句。(2)允许嵌套,即复合语句中也可出现复合语句。2024/7/3024C语言的控控制制语语句句9条:用于实现选选择择结构、循循环环结构和其它控制其它控制。输入输出输入输出(I/O)操作,均由标准库函数标准库函数来实现。所以学习C语言,不仅要学习这9条控制语句,而且要学习并掌握常用标准库函数的使用。返回返回不是C语言的组成部分2024/7/30251.5* TC+3.0的基本操作的基本操作1. 运行一个语言程序的一般过程 2. TC+的启动、退出与命令菜单 3. 选择工作目录4

14、. 新建一个语言源程序 5. 编译、连接、运行、查看结果 、新建下一个返回2024/7/30261. 运行一个语言程序的一般过程运行一个语言程序的一般过程 TC+是一个集源程序编辑、编译、连接、运行与调试于一体、 用菜单驱动的集成开发环境。(1) 启动启动TC,进入TC集成开发环境。(2) 选择工作目录工作目录 存放用户文件的目录。(3) 新建新建 (或编辑编辑)源程序。(4) 编译编译。成功,转下一步;失败,返回(3) 。2024/7/3027(5)连连接接。成功,转下一步;失败,根据系统的错误提示,进行相应修改,再重新连接。(6)运运行行。如果出现逻辑错误,则返回(3),重新修改源程序,再

15、编译、连接和运行。(7)退出退出TC集成环境,结束本次程序运行。返回2024/7/30282. TC+的启动、退出与命令菜单的启动、退出与命令菜单 (1)启动Turbo C + : 双击桌面图标图标 双击主程序文件名主程序文件名TC.EXE (在TC+3.0下的文件夹BIN中)。首次启动TC+的初始画面如图1-3所示:2024/7/3029(2)命令菜单的使用鼠标 / 键盘:F10激活,F10Esc关闭。(3)退出Turbo C 菜单法:File | Quit 快捷键法:Alt + X (先按下Alt键并保持,再按字母键,然后同时放开)返回2024/7/30303 3选择工作目录选择工作目录

16、存放用户文件的目录。选择并执行File | Change Dir.项,系统弹出一个“Change Directory”窗口,如图1-4所示:在“Directory Name”下的文本框中输入工作目录,或者在“Directory Tree”下的目录树中选择工作目录(C:TC30CASE),然后单击“OK”按钮。返回2024/7/30314. 新建一个语言源程序新建一个语言源程序 (File | New)选择并执行File | New项,系统给出一个空白编辑窗口,如图1-5所示:2024/7/3032常用编辑操作:常用编辑操作:F2键(或File | Save)将当前编辑的文件存盘,然后继续编辑。

17、这是一个良好的习惯!F1键激活活活动动窗窗口口(或状态)的在在线线帮帮助助,Esc返回原窗口(或状态)。F1查询库库函函数数的在在线线帮帮助助信息:将光标移到需要查询函数名的首字符上,然后键入F1即可。返回 Ctrl2024/7/30335. 编译、连接、运行单个源程序文件 :F9 / Run | Run6. 查看结果: Alt+F5 / Windows | User Screen 7. 新建下一个源程序:File | New。返回2024/7/3034本本 章章 要要 点点1 1、C C语言有多种版本,本课程以语言有多种版本,本课程以ANSI CANSI CANSI CANSI C新标准新标

18、准新标准新标准为蓝本介绍为蓝本介绍 。2 2、C C语言的特点:语言的特点:兼有汇编汇编汇编汇编和高级语言高级语言高级语言高级语言的优点。3 3、C C语言程序的语言程序的一般结构由一个main()main()main()main()函数函数函数函数和若干个其它函数其它函数其它函数其它函数结合而成。2024/7/30354 4、C C语言函数的结构语言函数的结构函数类型 函数名(函数参数表) 函数说明函数说明函数说明函数说明 说明语句部分; 执行语句部分; 函数体函数体函数体函数体 2024/7/30365 5、源程序书写规则(1) 除字符串常量中的字符外,一律使用半角字半角字符符。(2) 所

19、有语句必须以分号分号分号分号“ “ ;” ”结束;(3) 注释: /* /* /* /* */ */ */ */。2024/7/30376、TC的基本操作基本操作基本操作基本操作(1) 启动、退出与命令菜单 (2) 新建(或编辑)(3) 编译、连接、运行(4) 查看结果返回返回2024/7/3038 第第2 2章章 数据类型、运算与表达式数据类型、运算与表达式教学目的:教学目的:掌握掌握变量变量命名规则与定义、整型整型数据值域、字字符符(串串)常量常量的表达与存储,赋值运算赋值运算以及运算符的结合性结合性;了解了解常量及其表达、实型数据分类,自增、自减运算等 。2024/7/3039教学内容教

20、学内容:2.1 程序设计概述程序设计概述2.2 数据类型数据类型2.3* 常量和变量常量和变量2.4* 整型数据整型数据2.5 实型数据实型数据2.6* 字符型数据字符型数据2.7 算术运算与算术表达式算术运算与算术表达式2.8* 赋值运算与赋值表达式赋值运算与赋值表达式2.9 自增、自减与逗号运算简介自增、自减与逗号运算简介本章要点本章要点本章作业与上机实践本章作业与上机实践2024/7/30402.1 2.1 程序设计概述程序设计概述一个程序应包括对数据的描述和对数据处理的描述。1对数据的描述数据结构数据结构C C语言提供的数据结构,以语言提供的数据结构,以数据类型数据类型的形式出现的形式

21、出现。2024/7/30412对数据处理的描述算法算法著名计算机科学家沃思沃思提出一个经典公式: 数据结构数据结构 + 算法算法 = 程序程序在软件工程中,除了数据结构和算法外,还必须编制相关文档文档。 返回返回2024/7/30422.2 2.2 数据类型数据类型C C语语言言提提供供的的数数据据结结构构,以以数数据据类类型型形形式式出出现现。常用的有以下3类6种:1. 基本类型:整型、实型(浮点型)、字符型等。2. 构造类型:数组、结构类型等。3. 指针类型。C语言中的数据,有常常量量和变变量量之分,它们分别属于某种数据类型。返回返回2024/7/30432.32.3* * 常量和变量常量

22、和变量2.3.1 常量常量1. 概念在程序运行过程中,其值不其值不能被改变变的量。2. 分类(通过书写形式书写形式来判别)(1)整型常量:1,7,12(2)实型常量:3.14,9.80(3)字符(串)常量:a,1 / ”ABC”,”中国北京”(4)符号常量:PI(3.14)。2024/7/30442.3.2* 变量变量1. 概念在程序运行过程中,其其值值可可以被改变变的量。2. 两个要素(1)变变量量名名:每个变量都必须有一个名字,变量命名遵循标识符标识符命名规则。(2)变变量量值值:在程序运行过程中,变量值存储在内存内存中。在程序中,通过变量名变量名来引用。2024/7/3045. 标识符命

23、名规则标识符命名规则(1)有有效效字字符符:只能由大写字母、小写字母、数字和下划线组成,且以字母或下划线开头。注注意意:在C语言中,同一字母的大小写,被认为是两个不同的字符。关键字中,除个别外,绝大多数也是如此。思思考考:在C语言中,变量名total与TOTAL、ToTaL、tOtAl等是同一个变量吗?2024/7/3046(2) 有有效效长长度度:随系统而异;但,超超长长部部分分被被舍弃舍弃。思思考考:假设某系统标识符的有效长度为8,则student_name和student_number是一回事吗?(3) C语言的关键字关键字不能用作标识符名。2024/7/30474. 标识符命名的软件工

24、程软件工程要求见名知义见名知义所谓“见名知义”是指,通过标识符名名就知道标识符所代表的含义义。方法:英文单词英文单词(或缩写) ,或汉语拼音字头汉语拼音字头。例如,name/xm(姓名)、sex/xb(性别)、age/nl(年龄)、salary/gz(工资)。比较比较:a、b、c、d与上述4个变量名的可读性?2024/7/30485. 变量的定义与初始化变量的定义与初始化在语言中,变量必须先定义、后使用先定义、后使用。变量初始化初始化定义定义变量的同时赋初值时赋初值的操作。 存存储储类类型型 数数据据类类型型 变变量量名名=初初值值,变变量量名名2 2=初值初值22;例如,float radi

25、us, length, area ;例如,float radius = 2.5 = 2.5 ; 返回返回2024/7/30492.42.4* * 整型数据整型数据2.4.1* 整型变量整型变量1分类根据占用内存字节数内存字节数的不同,分为4种。常用的有:(1) 基本基本整型(int)(简称为整型)(2) 长长整型(long int)一般:long型(字节) int型(字节) 。2024/7/30502 2值域值域可使用sizeof( sizeof( 类型类型| |变量变量 ) )运算符,求得某种整型(变量)占用的内存字节数n 。其值域值域如下: 有有符号整型变量的值域为:-2n*8-1 ( 2

26、n*8-1 - 1); 无无符号整型变量的值域为:0 ( 2n*8 1 )。例如,在16位系统(如IBM-PC)中, sizeof( int ) = 2,即int变量占用字节字节,其值域为-22*8-1(22*8-1-1),即-32768 32767。2024/7/3051思考思考:假设被处理数据的取值范围为-1000至+100,000的整数,那么对应的变量应定义为什么类型?2024/7/30522.4.2 整型常量整型常量1表示形式三种(十、八、十六进制),最常用的是十进制:10,36。2024/7/30532分类(1)基基本本整型:在16位机中,用2字节存储,其值域与int变量一样。(2)

27、长长整型(在数值后面加“L L| |l l”)对超出int型值域的整型常量,应使用长整型常量表示。例如,long n = 100000L;2024/7/30543赋值规则一个整型常常量量,可以赋给值值域域它的整型变量变量,即:基本整型常量 int、long型变量;长整型常量 long 型变量。返回返回2024/7/30552.5 2.5 实型数据实型数据2.5.1 实型变量分类实型变量分类1单精度型(float):一般占字节(32位) 。2双精度型(double):一般占8个字节。2024/7/30562.5.2 实型常量实型常量实型常量即实数(浮点数),有两种表达形式:(1)十进制小数十进制

28、小数形式:3.14,9.8。 (2)指数指数形式:尾数尾数 E(e) E(e) 整型指数。整型指数。例如,3.0+5。实型常量不分float型和double型,可以赋给一个实型变量(float或double型)。返回返回2024/7/30572.62.6* * 字符数据字符数据2.6.1 字符常量字符常量1. 定义用一对单引号单引号括起来的单个字符单个字符。例如,A、等。2. 转义字符以反斜杠反斜杠“ ”开头的字符常量。常用转义字符参见表2-1,最常用的是n。注意注意:如果反斜杠反斜杠或单引号单引号本身作为字符常量,必须使用转义字符: 、 。2024/7/30582.6.2 字符变量字符变量(

29、char) 一般占用1字节内存单元,用于存储字符常量。1变量值的存储将一个字符常量字符常量存储到一个字符变量字符变量中,实际上是将该字符的ASCII码码值 (无符号整数)存储到内存单元中。例如:char ch1= a ; /*给字符变量赋值*/2024/7/30592特性字符数据字符数据与整型数据整型数据之间通用因为字符数据在内存中存储,与整数一样:A: 0100000165:00000000, 01000001具体:(1) 输出:字符 + 整数(ASCII码值)(2) 允许参与算术运算(ASCII码值)2024/7/30602.6.3 (字符字符)串常量串常量1用一对双引号双引号括起来的若干

30、若干字符称为(字符字符)串串常量常量。2字符串中的字符个数字符个数称为字符串长度(简称串长串长)。例如, “Good morning.”、“A”、 “ ” (一对紧连的双引号) ,串长分别为13 (空格也是一个字符) 、1和0(长度为0的字符串称为空串空串)。2024/7/3061注意注意:如果反斜杠反斜杠和双引号双引号作为字符串中的有效字符,则必须使用转义字符转义字符。例如:C: msdos v6.22 C:msdosv6.22I say: Goodbye! I say:Goodbye! 2024/7/30623串常量的存储由系统在字符串的末尾末尾自动添加一个00作为字符串的结束标志。例如,

31、字符串“CHINA”,在内存中的实际存储如下:CHINA0返回返回2024/7/30632.7 2.7 算术运算与算术表达式算术运算与算术表达式1. 1. 算术运算符算术运算符+、-(减法/取负)、*、/、%(求余数)C语言规定:两个整数相除,其商为整数整数相除,其商为整数,小数部分被舍弃。例如,5 / 2 = 2,-5 / 2 = -2-5 / 2 = -2。2024/7/30642. 表达式和算术表达式表达式和算术表达式(1)表达式用运运算算符符和括括号号,将运运算算对对象象(常量、变量和函数等)连接起来的、符合语言语法规则的式子。例如, ( x + y ) / 2 1。(2)算术表达式表

32、达式中的运算符运算符都是算术算术运算符运算符。例如,3 + 6 * 9。2024/7/30653求表达式的值求表达式的值(1)优先级优先级:高低。例如,先乘除后加减: a b * c。(2)如果某个操作数两侧运算符的优先级相同,则按结合性结合性进行: 左左结结合合性性(先左后右的结合方向)运算符:操作数先与左边左边的运算符结合。例如, 1 - 2 + 3:先执行“1 - 2”,再“+ 3” 。2024/7/3066 右右结结合合性性(先右后左的结合方向)运算符:操作数先与右边右边的运算符结合。例如, a = b = 1:先执行“b = 1”,再执行“a = (b = 1)” 。说说明明:除单单

33、目目、赋赋值值和条条件件运算符是右右结结合合性性外,其它运算符都是左结合性。详见附录B。2024/7/30674. 数据类型转换数据类型转换(1) 不同类型数据间混合运算时,系统“先转换、先转换、后运算后运算”先将数据自动转换自动转换成同一类型,然后再运算。转换规则如图2-5所示:1) 必须的转换。2) 不同类型的转换方向。例如,int型与double型混合运算,则int型double型,结果为double型。2024/7/3068(2) 语言也允许强制转换强制转换: (目标数据类型) ( 被转换表达式 )(double) (a) / (double) a(float)5 / 2 = ?(fl

34、oat)(5 / 2) = ?注注意意:原表达式类型并不发生变化。例如,(double)a。返回返回单个对象时,括号可缺省2024/7/30692.82.8* * 赋值运算与赋值表达式赋值运算与赋值表达式1. 赋值运算赋值运算 变量 = = 表达式 例如,x = 5,y = (float)5 / 2 注意注意:如果“表达式”类型与变量不一致,则系统将“表达式” 的值转换成变量的数据类型,再赋值。思考思考:假设有“float num=2.5;”,则执行“num = (int)num”后,num的值等于多少?赋值运算符2024/7/30702. 复合赋值运算复合赋值运算 变量变量 双目运算符双目运

35、算符 = = 表达式表达式 变量变量 = = 变量变量 双目运算符双目运算符 ( ( 表达式表达式 ) )例如:x += 3 x = x + 3y *= x + 6y = y * ( ( x + 6 ) ) /*不是y = y * x + 6*/单个对象时,圆括号才可缺省,否则可能出错。2024/7/30713. 赋赋值值表表达达式式由(复合)赋赋值值运运算算符符,将一个变量和一个表达式连接起来的表达式。(1)一般格式:变量 ( (复合复合) )赋值运算符赋值运算符 表达式(2)赋值表达式的值被被赋赋值值变变量量的的值值,就就是是赋值表达式的值赋值表达式的值。例如,赋值表达式“a = 5”,变

36、量a的值“”就是赋值表达式的值。返回返回2024/7/30722.9 2.9 自增、自减与逗号运算自增、自减与逗号运算2.9.1 自增自增(+)、自减、自减(-)运算运算1. 作用:使单个单个变量的值增增(+ +) 、减减(-)。2. 用法及其运算规则2024/7/3073(1)前置前置运算 + +变量、-变量运算规则:运算规则:先增减、后运算先增减、后运算,即先使变量的值增(减),然后再以变化后的值参与其它运算。例如:num1 = + num2; num2 = num2+1;/*先增减先增减*/ num1 = num2;/*后运算后运算*/2024/7/3074(2)后置后置运算变量+ +、

37、变量-运算规则运算规则:先运算、后增减先运算、后增减,即变量先参与其它运算,然后再使变量的值增(减)。例如:num1 = num2-; num1 = num2;/*先运算先运算*/ num2 = num2 1;/*后增减后增减*/注注:自增/减单独运算时,前置与后置等价。num+; + num; num-; - num;2024/7/3075案例案例2.4自增、自减运算的用法与运算规则示例。 #include “stdio.h”#include “conio.h”void main() int x = 6, y; printf(x = %dn, x); y = +x; /*前置运算*/ pri

38、ntf(y = +x: x = %d, y= %dn, x, y); y = x-; /*后置运算*/ printf(y = x-: x = %d, y= %dn, x, y); getch(); 程序运行结果:2024/7/3076x = 6y = +x: x = 7, y = 7y = x-: x = 6, y = 7思思考考:如果将“y = +x;” 改为“y y = = x+;x+;”,“y = x-;” 改为“y y = = -x;-x;”,程序运行结果会如何?注注意意:自增、自减运算符,只能用于单个变量,不能用于常量常量和表达式表达式。例如,5+、-(a+b)等都是非法的。2024

39、/7/30772.9.2 逗号运算逗号运算(,)及其表达式及其表达式1.一般形式:表达式1, 表达式2, , 表达式n2.求解过程:自左至右,依次计算各表达式的值,最后1个 “表达式表达式n n” 的值的值即为整个逗号表达式的值逗号表达式的值。例如:(1) a = 3 * 5, a * 4 :?(2) (a = 3 * 5, a * 4), a + 5 :?2024/7/3078(1) a = 3 * 5, a * 4 :先求解a = 3 * 5,得a=15;再求a * 4 = 60,所以逗号表达式的值=60。(2) (a = 3 * 5, a * 4), a + 5 :先求解a = 3 *

40、5,得a=15;再求a * 4=60;最后求解a + 5=20,所以逗号表达式的值=20。返回返回2024/7/3079本本 章章 要要 点点标识符命名规则标识符命名规则:有效字符、有效长度+关键字英文字母大小写敏感,见名知义整型变量整型变量:不同类型整型变量,占用的内存字节数不同,其值域值域不同。2024/7/3080字符型数据字符型数据:字符常量常量:单引号,单个字符;转义字符:反斜杠“ ”,反斜杠和单引号本身:,。字符变量变量:1B,ASCII码值。字符串常量串常量:双引号,若干字符;存储时,系统自动在串尾添加一个0 。2024/7/3081运算运算整数相除整数相除:商为整数。赋值表达式

41、的值赋值表达式的值:被赋值变量的值。前置运算规则前置运算规则:先增减、后运算后置运算规则后置运算规则:先运算、后增减返回返回2024/7/3082本章作业与上机实践本章作业与上机实践作业:1,3,4,6上机实践: (1)掌握TC+下开发C语言程序的基本操作。 (2)自己设计方案,验证作业6。 (3)自己设计方案,找出用字符形式输出一个256的数值,会得到什么结果?返回返回2024/7/3083第第3 3章章 顺序结构程序设计顺序结构程序设计数据处理的一般过程是:输入输入 处理 输出输出。在C语言中,输入输出操作是由编译系统提供的库函数库函数来实现。教学目的教学目的:掌握掌握printf() 、

42、scanf()函数,以及顺序结构程序设计。2024/7/3084教学内容教学内容:3.1* 格式化输出格式化输出printf()函数函数3.2* 格式化输入格式化输入scanf()函数函数3.3 顺序结构程序设计顺序结构程序设计本章要点本章要点本章作业与上机实践本章作业与上机实践2024/7/30853.13.1* * 格式化输出格式化输出printf()printf()函数函数3.1.1 printf()函数的一般格式函数的一般格式 案例案例3.13.1 已知圆半径radius=1.5,求圆周长(2r)和圆面积(r2) 。2024/7/3086#include “stdio.h”#inclu

43、de “conio.h”void main( ) float radius = 1.5, length, area, pi=3.14; length = 2 * pi * radius; area = pi * radius * radius; printf(“radius = %fnradius = %fn”, radius); printf(“length = %7.2f, area=%7.2fnlength = %7.2f, area=%7.2fn”, length, area); getch(); radius = 1.500000length = 9.42, area = 7.072

44、024/7/3087printf()printf()函数的一般格式: printf(printf(格式字符串格式字符串 ,输出项表,输出项表);1 1格式字符串(1)格式指示符格式指示符: % % 标志标志宽度宽度.精度精度F|N|h|LF|N|h|L类型类型例如,%7.2f%7.2f。各类常用指示符,参见表3-1至表3-5。2024/7/3088在表3-1中,最常用的标志字符是“-” :左对齐,右端补空格。缺省时为右对齐,左端补空格。在表3-2中,最常用宽度字符“n”:指定输出域的宽度。若超长,则按实际宽度输出;若不足,则补空格。在表3-3中,最常用精度字符“ .n”:指定保留的小数位数(实

45、数,超长则4舍5入),或截取左起的前n个字符(字符串)。在表3-4中,最常用的长度长度字符“l”:长整型。2024/7/3089在表3-5 中,最常用的数据类型类型转换字符如下表所示: 数据类型数据类型类型转换字符类型转换字符功功 能能整 数d 带符号十进制整数十进制整数实 数f十进制小数十进制小数形式(默认6位小数)字 符c输出1个字符字符s输出1个字符串字符串2024/7/3090(2)转义字符。转义字符。特点:通常是产生一个控制操作。例如,转义字符n,输出时产生一个“换行”操作。 (3)普通字符普通字符除格式指示符和转义字符之外的其它字符。特点:原样输出原样输出。例如,“radius=”

46、、“length=”、“area=”、“,”。2024/7/30912输出项表如果不止1个,则相邻2个之间用逗号逗号分开。下面的用法都是合法的:(1)printf(I am a student.n);(2)printf(%d,3+2);(3)printf(a=%f b=%5dn, a, a+3);2024/7/30923.1.2 常用的类型转换字符常用的类型转换字符输出不同类型数据,要使用不同类型转换字符。2024/7/30931类型转换字符类型转换字符d以带符号的以带符号的十进制整数十进制整数形式输出。形式输出。案例案例3.2 类型转换字符d的使用。#include “stdio.h”#in

47、clude “conio.h”void main() int num1=123; long num2=123456; printf(num1=%d,num1=%5d,num1=%-5d,num1=%2dn, num1,num1,num1,num1); printf(num2=%ld,num2=%8ld,num2=%5ldn, num2,num2,num2); printf(num1=%ldn,num1); getch(); 2024/7/3094程序运行结果如下:num1=123,num1=123,num1=123,num1=123num2=123456,num2=123456,num2=12

48、3456num1=16908411(1)格式指示符,必须与输出项的数据类型一致,否则会引起输出错误。(2)对于整整数数,还可用%o%o(八进制无符号形式)、 %x%x(十六进制无符号形式)、 %u%u(十进制无符号形式)输出。类型匹配错误,输出结果是随机的。2024/7/30952类型转换字符类型转换字符f以以小数小数形式输出实数。形式输出实数。案例案例3.3 类型转换字符f的使用。#include “stdio.h”#include “conio.h”void main( ) float f = 123.456; double d1,d2; d1 = 1111111111111.111111

49、111; d2 = 2222222222222.222222222; printf(%f, %12f, %12.2f, %-12.2f, %.2fn, f, f, f, f, f ) ; printf(d1 + d2 = %fn, d1 + d2); getch(); 2024/7/3096程序运行结果如下:123.456001,123.456001,123.46,123.46,123.46d1+d2=3333333333333.333010提示提示:对于实数也可使用%e%e,以标准指数形式标准指数形式输出;或使用%g%g,让系系统统根据数值的大小,自自动动选选择择%f或%e格式、且不输出无意

50、义的零。2024/7/30973 3类型转换字符类型转换字符c c输出输出1 1个个字符字符( (占占1 1列宽度列宽度) )案例案例3.4 类型转换字符c的使用。#include “stdio.h”#include “conio.h”void main() char c=A; int i=65; printf(c= %c, %5c, %dn, c, c, c ); printf(i = %d, %c, i, i); getch(); 程序运行结果如下: c = A, A, 65 I = 65, A2024/7/30984类型转换字符类型转换字符s输出一个输出一个字符串字符串。案例案例3.5

51、类型转换字符s的使用。#include “stdio.h”#include “conio.h”void main() printf(%s, %5s, %-10s,Internet,Internet,Internet); printf(%10.5s, %-10.5s, %4.5sn,Internet,Internet,Internet); getch(); 程序运行结果如下:Internet,Internet,Internet,Inter,Inter,Inter 注意注意:系统输出字符(串),不输出单引号和双引号。2024/7/30993.1.3 使用说明使用说明1格格式式指指示示符符,必须按从

52、左到右的顺序,与输出项表中的每个数据数据一一对应,否则出错。例如,printf(str = %s, f = %d, i = %fn, Internet, 1.0 / 2, 3 + 5, CHINA);是错误的。2类型转换字符的紧紧前前字字符符不是“%”时,将作普通字符处理(原样输出)。例如,“printf(”c = %c, f = %fn“, c, f);”中的第一个c和f,都是普通字符。2024/7/301003类型转换字符x、e、g,大小写均可。大写时,输出数据中包含的字母也大写。其它类型转换字符,必须小写。例如,%f不能写成%F。返回返回2024/7/301013.23.2* * 格式化

53、输入格式化输入scanf()scanf()函数函数3.2.1 一般格式一般格式 案例案例3.63.6 已知圆柱体的底半径radius=1.5,高high = 2.0 ,求其体积(r2 h) 。2024/7/30102#include “stdio.h”#include “conio.h”void main() float radius, high, pi=3.14159, vol; radius=1.5; high=2.0; vol = pi * radius * radius * high; printf(“vol = %7.2fn”, vol); getch(); 思考思考:使用赋值语句给

54、出初值的方式的局限性?2024/7/30103 案案例例3.73.7 已知圆柱体的底半径为radius、高为high,求其体积。#include “stdio.h”#include “conio.h”void main() float radius, high, vol, pi=3.1415926; printf(Please input radius & high: ); scanf(scanf(%f%f%f%f, , &radius, &high&radius, &high);); vol = pi * radius * radius * high; printf(radius=%7.2f

55、, high=%7.2f, vol=%7.2fn, radius, high, vol); getch(); Please input radius & high: 1.52.0radius=1.50,high=2.00,vol=14.142024/7/30104给计算机提供数据,可以使用:(1)赋值语句。只能解决1 1个个特定的问题。例如,案例3.6。(2)输入函数scanf() 。能解决1 1类类特定的问题。例如,案例3.7。显然,采用scanf( scanf( ) )函函数数,使得程序具有更好的适应性适应性。2024/7/30105scanf( )函数的一般格式: scanf(scanf

56、(格式字符串格式字符串, , 输入项首地址表输入项首地址表););(1)格式字符串 格式指示符格式指示符:与printf()函数的相似; 普通字符普通字符:必须原样输入。2024/7/30106(2)输入项首地址表可以是变量首地址变量首地址、数组名数组名,或者指针变量指针变量。变量首地址的表示: & &变量名变量名相邻2个输入项首地址,用逗号分开。地址运算符2024/7/301073.2.2 数据输入操作数据输入操作(假设num1=12、num2=36)1默认分隔符默认分隔符空格、 Tab键、回车如果不指定分隔符(例如逗号、冒号),则使用默认分隔符。例如,scanf(%d%d,&num1,&n

57、um2);正确的输入操作为: 1236 或者:12 362024/7/301082普通字符普通字符务必原样输入。(1) scanf(%d , ,%d,&num1,&num2); 正确的输入操作为:12 , 36(2) scanf(num1=%d , num2=%dn,&num1,&num2); 正确的输入操作为: num1=12 ,num2=36n 提示提示:scanf()格式字符串中,没有转义字符转义字符概念。比较(1)、(2)两种设计方式的优缺点?2024/7/30109比较(1)、(2)两种设计方式的优缺点?(1) 仅输入数据,输入量小,但人机交互性差(用户不知道该输入什么,以及输入给谁

58、)。(2) 同时输入说明和数据,人机交互友好性好,但输入量大。思思考考:如何改进设计,既保持良好的人机交互性,又不增加输入量?2024/7/30110提高人机交互性的设计思路提高人机交互性的设计思路:先用printf()函数输出提示信息,再用scanf()函数进行数据输入。scanf(num1=%d,num2=%dn,&num1,&num2);printf(num1=); scanf(%d,&num1);printf(num2=); scanf(%d,&num2);2024/7/301113使用 “%c”输入时,空空格格和转转义义字字符符均作为有效字符被输入。例如:scanf(%c%c%c,&

59、ch1,&ch2,&ch3);printf(ch1=%c,ch2=%c,ch3=%cn,ch1,ch2,ch3);思思考考:假设输入“ABC”,printf()输出的内容是什么?输出结果输出结果:ch1= A,ch2=,ch3= B返回返回2024/7/301123.3 3.3 顺序结构程序设计顺序结构程序设计顺序结构程序一般包括两部分:1程序开头的编译预处理命令编译预处理命令。如果要在程序中使用标准库函数,则必须使用编译预处理命令#include,将相应的头文件包含进来。2024/7/301132函数体主要包括:(1)变量定义语句;(2)输入语句;(3)运算语句;(4)输出语句。 3 执行流

60、程执行流程:各语句是按照物理位置物理位置次序,被顺序执行,且每个语句都会被执行到。2024/7/30114案例案例 输入3个整数,求它们的和及平均值。#include “stdio.h”#include “conio.h”void main() int num1,num2,num3,sum; float aver; printf(Please input three numbers:); scanf(%d, %d, %d, &num1, &num2, &num3); sum = num1 + num2 + num3;/*求累计和*/ aver = sum / 3.0; /*求平均值*/ pri

61、ntf(num1=%d,num2=%d,num3=%dn, num1, num2, num3); printf(sum=%d, aver=%7.2fn,sum, aver); getch(); 2024/7/30115案例案例3.113.11 设计一个进行加、减、乘、除和求余数运算练习的程序。对程序功能的基本要求如下:(1) 使用菜单驱动;(2) 随机产生运算所需的2个操作数(0-99);(3) 程序自动判断用户的计算结果是否正确。由于所学内容的限制,本案例的设计要求将在本章,以及随后的第4 第7章中分阶段逐步实现并完善。本案例首先实现设计要求(1) 。 2024/7/30116/*功能:菜单

62、程序段*/#include stdio.h#include conio.hvoid main() char options; clrscr( );/*清屏。函数原型在conio.h中*/2024/7/30117 printf( 加、减、乘、除和求余数运算练习程序 n); printf(n); printf( + (Addition) + / a n); printf( - (Subtraction) - / s n); printf( * (Multiplication) * / m n); printf( / (Division) / / d n); printf( % (Remainder

63、) % / r n); printf( E x i t e n); printf(n); printf( Please choose one option: ); scanf(%1c , &options); getch(); 2024/7/30118程序运行情况如下: 加、减、乘、除和求余数运算练习程序 + (Addition) + / a - (Subtraction) - / s * (Multiplication) * / m / (Division) / / d % (Remainder) % / r E x i t e Please choose one option: _返回返回

64、2024/7/301191. printf()1. printf()函数 printf(printf(格式字符串格式字符串 ,输出项表,输出项表);本本 章章 要要 点点(1)格式指示符格式指示符 % % 标志标志宽度宽度.精度精度F|N|h|LF|N|h|L类型类型 (2)转义字符转义字符(3)普通字符普通字符原样输出原样输出。2024/7/301202. scanf()函数 scanf(scanf(格式字符串格式字符串, , 输入项首地址表输入项首地址表););(1)格式指示符格式指示符(2)普通字符普通字符:原样输入。&变量名变量名2024/7/301213. 源程序书写风格源程序书写风

65、格顺序程序段顺序程序段左对齐左对齐顺序程序段中的所有语句(包括说明语句),一律与本顺序程序段的首行左对齐左对齐。4. .良好的人机交互性良好的人机交互性提示输入/输出数据的含义(1)输入:printf(姓名:姓名:); scanf(%s, name);(2)输出:printf(姓名:姓名:%sn, name);返回返回2024/7/30122本章作业与上机实践本章作业与上机实践作业作业:2,3,6上机实践上机实践:验证本章作业。返回返回2024/7/30123第第4 4章章 选择结构程序设计选择结构程序设计选择结构程序设计,要解决两个问题:(1)选择条件如何表示:关系关系/ /逻辑表达式逻辑表

66、达式(2)实现选择结构语句: ifif、switchswitch语句语句教学目的教学目的:掌握掌握关系和逻辑运算,if语句、switch语句,选择结构程序设计。2024/7/30124教学内容教学内容:4.1 关系运算及其表达式关系运算及其表达式4.2 逻辑运算及其表达式逻辑运算及其表达式4.3* if语句语句4.4* switch语句语句4.5 选择结构程序设计选择结构程序设计本章要点本章要点本章作业与上机实践本章作业与上机实践2024/7/301254.1 4.1 关系运算及其表达式关系运算及其表达式关系运算将两个数据进行比较,判定是否符合给定的关系。例如,“a ba b”中的“ ”,表示

67、一个大于大于关系:如果a=5、b=3,则大于关系成立关系成立;如果a=2、b=3,则大于关系不成立关系不成立。2024/7/301264.1.1 关系运算符及其优先次序关系运算符及其优先次序1关系运算符 (小于), = (大于), =(大于等于)=(等于), !=!=(不等于)2与其它种类运算符的优先关系算术算术运算符 关系关系运算符 赋值赋值运算符思考思考:在混合运算时,如何增强程序可读性可读性(明确运算的优先关系)?不是 “= ”2024/7/301274.1.2 关系表达式关系表达式1概念用关关系系运运算算符符,将两个表达式连接起来的式子。例如:a b,a = b ,a + b c -

68、d2关系表达式的值逻辑真 / 逻辑假如果关系成立关系成立,则表达式的值为逻辑真逻辑真;如果关系不成立关系不成立,则表达式的值为逻辑假逻辑假。语言没有逻辑型数据,用整整数数表示“逻逻辑辑真真”,用整数整数表示“逻辑假逻辑假”。2024/7/30128假设num1=3,num2=4,num3=5,则:(1) num1 num2 := 0(2) (num1 num2) != num3: = 1(3) num1 num2 num3 := 1思思考考:任意改变num1或num2的值,会影响整个表达式的值吗?为什么?x(1,100):1x=0) & (x10) ,(x5) ,! (x= =0), (yea

69、r%4= =0) & (year%100!=0) | | (year%400= =0)2024/7/301302. 运算规则(1)&:当且仅当两个运算对象的值都为“逻辑真”时,结果为“逻辑真”,否则为“逻辑假”。运算口诀:运算口诀:同时为真同时为真才为才为真真,否则为假,否则为假。(2) | :当且仅当两个运算对象的值都为“逻辑假”时,结果为“逻辑假”,否则为“逻辑真”。运算口诀:运算口诀:同时为假同时为假才为才为假假,否则为真,否则为真。2024/7/30131(3) ! :当运算对象的值为“逻辑真”时,结果为“逻辑假”;当运算对象的值为“逻辑假”时,结果为“逻辑真”。运算口诀:运算口诀:取

70、反取反。2024/7/301324.2.2 逻辑表达式逻辑表达式1. 概念用逻逻辑辑运运算算符符,将若干表达式连接起来的式子。例如,逻辑表达式(year%4= =0) & (year%100!=0) | (year%400= =0),判断year是否闰年。2逻辑表达式的值逻辑真 /逻辑假2024/7/301333非逻辑值运算对象的真/假判定和非逻辑运算的对对象象要求是逻逻辑辑值值,而语言中没有逻辑型数据。C语言约定: ,判定为“逻辑假逻辑假”非逻辑值运算对象= 非非,判定为“逻辑真逻辑真”2024/7/30134假设num=12,则:(1)!num: = (2) (num = 1) & (nu

71、m 31) := 1。2024/7/301354说明(1)运算对象的数据类型:除整型外,也可以是实型、字符型等其它任何类型数据。(2)子子表表达达式式计计算算:只有在必须计算下一个子表达式才能求解时,才计算;否则,不再计算。换句话说:对于逻逻辑辑与与运算,如果第第1个个对对象象被判定为“逻辑假假”,系统不再计算第2个对象(因为无论真假,都不影响整个表达式的结果)。2024/7/30136对于逻逻辑辑或或运算,如果第第1个个对对象象被判定为“逻辑真真”,系统不再计算第2个对象。思思考考:假设n1、n2、n3、n4、x、y的值分别为1、2、3、4、1、1,求解表达式“(x = n1 n2) & (

72、y = n3 n4)”后,x、y的值=?2024/7/30137答案: x=,y=1分析:(1) n1 n2: = 0(2) x = n1 n2 :x = 0(3) (x = n1 n2) := 0(4) &:(y = n3 n4) 不再计算,y保持原值,即y=1。返回返回2024/7/301384.3.3* * if if语句语句案例案例4.14.1 输入3个整数num1、num2、num3,求最大值。算法设计要点:算法设计要点:(1) 任取一个数预置为max(最大值);(2) 用其余的数num依次与max比较:如果num max,则max num 。比较完所有的数后,max中的数就是最大值

73、。 2024/7/30139#include “stdio.h”#include “conio.h”void main() int num1, num2, num3, max; printf(“Please input three numbers:”); scanf(“%d,%d,%d”, &num1, &num2, &num3); max = num1; if (num2 max) max = num2;/* max = maxnum1, num2 */ if (num3 max) max = num3; printf(The three numbers are:%d,%d,%dn,num1

74、,num2,num3); printf(max=%dn,max); getch(); 2024/7/30140 案例案例4.24.2编写一程序, 判断一个年份year(4位十进制数)是否闰年。闰年的条件是:能被4整除、但不能被100整除,或者能被400整除。2024/7/30141算法设计要点算法设计要点:(1)如果X能被整除,则余数为,即如果X % Y = ,则表示能被整除。(2)根据闰年的条件可知:“能被4整除、但不能被100整除” 表示为:(year % 4 = 0) & (year % 100 != 0);“能被400整除” 表示为:year % 400 = 0;两个条件之间是逻辑或的

75、关系:( (year % 4 = 0) & (year % 100 != 0) | (year % 400 = 0)。 2024/7/30142#include stdio.h#include conio.hvoid main() int year; printf(Please input a year:); scanf(%d, &year); if (year % 4 = 0) & (year % 100 != 0) | | (year % 400 = 0)/*闰年*/ printf(%d is a leap year.n, year); else/* 非闰年*/ printf(%d is

76、not a leap year.n, year); getch(); 2024/7/30143 1if语句的一般格式 if ( 表达式表达式 ) 语句组语句组1; else 语句组语句组2; 必须用“(”和“)”括起来if语句的一部分,必须与if配对使用。语句组仅由一条语句构成时,也可不使用复合语句形式(即去掉花括号)2024/7/301442if语句的执行流程(1)缺省else子句( 图4.1 )当“表达式”的值:非非0 0(逻辑真) ,执行语语句句组组1 1;否否则则,直接转向执行下下一条一条。例如,案例4.1。2024/7/30145(2)指定else子句(图4.2 )当“表达式”的值:

77、非非0(逻辑真),执行语语句句组组1,然后跳过语语句句组组2,转向下一条语句;否否则则,执行语语句句组组2。例如,案例4.2。2024/7/30146 3if语句的嵌套匹配原则 (1) if语句的嵌套在“语句组1”或(和)“语句组2”中,又包含有if语句的情况。(2)else子句与if的匹匹配配原原则则:与在它上上面面、距距它它最近最近、且尚未匹配尚未匹配的if配对。建议建议:将内嵌的if语句,一律用花括号括起来。2024/7/301474说明(1)if后面的“表表达达式式”:除关关系系(逻逻辑辑)表达式外,也允许是整型、实型、字符型等其它类型的数据。(2)在语句组1和语句组2中,每个语语句句

78、后后面面的的分分号不可少号不可少!例如: if (num1 num2) max = num1 ; else max = num2 ;返回返回2024/7/301484.44.4* * switch switch语句语句 案例案例4.44.4 将1个百分制成绩score,按下列原则输出其等级:score=90,A;80=score90,B;70= score80,C;60score70,D;score60,E。#include stdio.h#include conio.hvoid main() int score, grade; printf(“Input a score(0100): ”);

79、 scanf(“%d”, &score); grade = score / 10; /*将成绩整除10,转化成case标号*/ 2024/7/30149switch (grade) case 10: case 9: printf(grade=An); break; case 8: printf(grade=Bn); break; case 7: printf(grade=Cn); break; case 6: printf(grade=Dn); break; case 5: case 4: case 3: case 2: case 1: case 0: printf(“grade=En”);

80、break; default: printf(“The score is out of range!n”); getch(); 2024/7/301501一般形式一般形式switch( 表达式表达式 ) case 常量表达式常量表达式1:语句组1;break; case 常量表达式2:语句组2;break; . case 常量表达式n:语句组n ;break; default:语句组n +1; 2024/7/301512执行流程执行流程指定指定breakbreak语句语句2024/7/30152(1)当 “表表达达式式”的值,与某个case后面的“常常量量表表达达式式”的值相同时,就执行该ca

81、se后面的语语句句(组组);当执行到break语句时,转向执行switch语句的下一条下一条。(2)如果没没有有任何一个case后面的“常量表达式”的值,与“表达式”的值匹匹配配,则执行default 后面的语句语句(组组)。然后,再执行switch语句的下一条。2024/7/301533执行流程执行流程缺省缺省break语句语句case后面的常常量量表表达达式式仅起语句标标号号作用,并不进行条件判断条件判断。缺省break语句时,系统一旦找到入口标号,就从此标号开始执行,不再进行标号判断,其执行流程如下图所示:2024/7/301542024/7/30155思思考考: 如果去掉案案例例4.4

82、4.4程序中所有break语句,输入成绩75,输出如何?输出:grade=C grade=D grade=E The score is out of range!2024/7/301564 4说明说明(1) “表达式”的类型:int、char和枚举型。(2)每个case后面“常常量量表表达达式式”的值,必须各各不不相同相同,否则会出现相互矛盾的现象。(3)各case及default子句次序,不影响执行结果。(4)多个case子句,可共用同一语句(组)。在案例案例4.44.4中,case 10和case 9,case 5case 0。返回返回2024/7/301574.54.5* * 选择结构程

83、序设计选择结构程序设计案案例例4.74.7 已知某公司员工的保底薪水为500,某月所接工程的利润profit(整数)与利润提成的关系如下(单位:元): profit1000没有提成; 1000profit2000提成10%; 2000profit5000提成15%; 5000profit10000提成20%;10000profit提成25%。2024/7/30158算法设计要点:算法设计要点:将利利润润profit与提提成成的关系,转换成某些整整数数与提提成成的关系。分析本题可知,提成比例的变化点,都是1000的整数倍,如果将利润利润profit整除整除1000,则当: profit1000

84、对应0、11000 profit2000 对应1、22000 profit5000 对应2、3、4、55000 profit10000 对应5、6、7、8、9、1010000profit 对应10、11、12、思考:如何解决相邻两个区间的重叠问题?思考:如何解决相邻两个区间的重叠问题?2024/7/30159最简单的方法:利润profit先减减1 1(最小增量),然后再整除1000即可: profit -1 -1 1000 对应0 1000profit -1 -1 2000 对应1 2000profit -1 -1 5000 对应2、3、4 5000profit -1 -1 10000 对应5

85、、6、7、8、910000profit -1-1 对应10、11、12、2024/7/30160#include stdio.h#include conio.hvoid main() long profit; int grade; float salary = 500; printf(Input profit: ); scanf(%ld, &profit); grade = (profit 1) / 1000;/*将(利润-1)/1000*/2024/7/30161 switch( grade ) case 0: break;/*profit1000 */ case 1: salary +=

86、profit*0.1; break;/*1000profit2000 */ case 2: case 3: case 4: salary += profit*0.15; break; /*2000profit5000 */ case 5: case 6: case 7: case 8: case 9: salary += profit*0.2; break;/*5000profit10000 */ default: salary += profit*0.25;/*10000profit */ printf(salary=%.2fn, salary); getch(); 2024/7/30162

87、 案例案例4.8 加、减、乘、除和求余数运算练习程序。对程序功能的基本要求如下:(1)使用菜单驱动;(2)随机产生运算所需的2个操作数(0-99);(3)程序自动判断用户的计算结果是否正确。在第3章参考程序实现设计要求(1)的基础上,本章实现设计要求(2)和(3),形成练习程序的第2版。 2024/7/30163#include stdio.h#include conio.h#include stdlib.h#include time.hvoid main() char options; /* options存储用户选择的运算符 */ int n1, n2, result; /* 函数rand

88、omize( )为随机函数random( )提供不同的 随机种子,函数原型在stdlib.h和time.h中*/ randomize(); n1 = random(100); n2 = random(100);/*产生2个0-99的随机整数*/ clrscr();/*清屏。函数原型在conio.h中*/ /*菜单程序段*/2024/7/30164printf( Please choose one option: ); scanf(%1c , &options);fflush(stdin);/*清空键盘缓冲区*/printf(nn);/*空1行*/* */switch(options) case

89、 e: break;/*exit*/ case +: case a:/*加法运算*/ printf(%2d + %2d = , n1, n2); scanf(%d , &result); if (result = n1 + n2) /*计算正确*/ printf(nGreat! Your answer is correct.); else /*计算不正确*/ printf(nSorry! Correct answer: %2d + %2d=%d, n1, n2, n1 + n2); break; 2024/7/30165 default: printf(Sorry! Incorrect opt

90、ion.); /*incorrect option*/ /*switch()*/ getch(); /*main()*/2024/7/30166程序运行情况举例如下(菜单,略): (1)Please choose one option: + 17 + 95 = 112 Great! Your answer is correct. (2)Please choose one option: * 32 * 24 = 628 Sorry! Correct answer: 32 * 24 = 768 返回返回2024/7/30167本本 章章 要要 点点1. 语言用整数整数表示“逻辑真逻辑真”,用整数整

91、数表示“逻辑假逻辑假”,所以关系表达式关系表达式还可以参与其它其它种类的运算运算。2. 非逻辑运算对象的真假判定:,则判定为“逻辑假逻辑假”;非非,则判定为“逻辑真逻辑真”。子表达式计算子表达式计算:只有在必须计算下一个子表达式才能求解时,才计算;否则,不再计算。2024/7/301683. if ( 表达式表达式 ) 语句组语句组1; else 语句组语句组2; else子句与if的匹配原则匹配原则:与在它上面上面、距它最距它最近近、且尚未匹配尚未匹配的if配对。建议建议:将内嵌的if语句,一律用花括号括起。2024/7/301694. switch( 表达式表达式 ) case 常量表达式

92、常量表达式1:语句组;break; case 常量表达式2:语句组;break; . case 常量表达式n:语句组;break; default:语句组;break; 2024/7/301705良好的源程序书写风格良好的源程序书写风格缩排与注释缩排与注释(1) 缩排缩排if和switch语句中的语句组,向右缩进右缩进3-4个字符,形成阶梯状;复合语句内的顺序程序段,段内左对段内左对齐齐。(2) 注释注释必要的注释,可有效地提高程序的可读性可读性,从而提高程序的可维护性可维护性。2024/7/30171在语言源程序中,注释可分4个层次:在函数体内对语句语句/程序段程序段的注释。在函数之前对函数

93、函数的注释;在源(程序)文件开始处,对源(程序)文件的注释。对整个程序的注释。2024/7/30172 顺序结构在每个顺序程序段程序段之前,注释其功能功能。除很复杂的处理外,一般没有必要每条语句都加以注释。2024/7/30173 选择结构一般地,要在选择结构语句选择结构语句前面,说明其功能功能;在每个分支条件语句行分支条件语句行的后面,说明该分支的含义含义。/*(说明功能)*/if (条件表达式) /*条件成立时的含义*/ else/*入口条件含义*/ 2024/7/30174/*(说明功能) */switch(表达式) case 常量表达式1: /*入口值的含义*/ 语句组; case 常

94、量表达式n: /*入口值的含义*/ 语句组; default: /*入口值的含义*/ 语句组; 如果条件成立时(或入口值)的含义很明确,也可不再注释。返回返回2024/7/30175本章作业与上机实践本章作业与上机实践作业作业:2,4 ,6,8 上机实践上机实践:验证本章后3个作业题。返回返回2024/7/30176第第5 5章章 循环结构程序设计循环结构程序设计教学目的教学目的:掌握掌握for、break与continue语句,循环结构程序设计;了解了解while语句、do-while语句等。2024/7/30177教学内容教学内容:5.1 循环语句概述循环语句概述5.2* for语句和语句

95、和while语句语句5.3 直到型循环直到型循环do-while语句语句5.4* break语句与语句与continue语句语句5.5* 循环结构程序设计循环结构程序设计本章要点本章要点本章作业与上机实践本章作业与上机实践2024/7/301785.1 5.1 循环语句概述循环语句概述C语言提供了3条循环语句:(1)forfor语句(2)当型循环语句whilewhile(3)直到型循环语句do-whiledo-while从功能上说,while可完全被for语句代替。2024/7/30179说明:关于说明:关于gotogoto语句语句结构化程序设计方法,主张限制使用goto语句。因为滥用goto

96、语句,将会导致程序结构无规律、可读性差。返回返回2024/7/301805.25.2* * for for语句和语句和whilewhile语句语句在3条循环语句中,for语句最最为灵活灵活,不仅可用于循环次数已经确定的情况,也可用于循环次数虽不确定、但给出了循环继续条件的情况。 案例案例5.2 求1100的累计和。2024/7/30181#include “stdio.h”#include “conio.h”void main( ) int i, sum=0; for( i = 1; i = 100; i+) sum += i;/*累加*/ printf(sum=%dn,sum); getch

97、(); 2024/7/301821for语句的一般格式 forfor(循环变量赋初值;循环条件;循环变量增值) 循环体;循环体; 表达式可以部分或全部缺省,但其间的分号不能省略。仅有1条语句,可缺省大括号2024/7/301832for语句的执行流程2024/7/30184(1)求解“循环变量赋初值”表达式。(2)求解“循环条件”表达式: 循环条件表达式= (3)执行循环体语句组,并求解“循环变量增值”表达式,然后转向(2)。(4)执行for语句的下一条语句。非0,执行(3)0,转至(4)2024/7/30185案例案例5.3 求n的阶乘n!(n!=1*2*n)。#include “stdio

98、.h”#include “conio.h”void main() int i, n; long fact=1; /*初始化累乘器fact为1*/ printf(“Input n: ”); scanf(“%d”, &n); for(i=1; i=n; i+) /*实现累乘*/ fact *= i; printf(%d ! = %ldn, n, fact); getch(); 2024/7/30186程序运行情况如下: Input n: 5 5 ! = 1202024/7/301873说明(1)“循环变量赋初值循环变量赋初值”表达式:也可以是与此无关的其它表达式其它表达式(如逗号表达式)。例如,f

99、or( sum=0; i=100; i+) sum += i; for( sum=0, i=1; i=100;i+) sum += i;(2)“循环条件循环条件”表达式:除关系(逻辑)表达式)表达式外,也允许是数值(字符)表达式表达式。2024/7/30188(3) 循环体循环体:仅由1条语句条语句(简单简单或复合复合)构成。例如: for( i = 1; i = 100; i+) sum += i ; for( i = 1; i = n; i+) fact *= i ; for() ;循环体为空语句。2024/7/301894while语句(1)一般格式: while(while(循环条件循

100、环条件) ) 循环体;循环体; (2)执行流程2024/7/301901)求解“循环条件”表达式。如果其值为非非0 0,转2)2);否则否则,转3)3)。2)执行循环体语句组,然后转1)。3)执行while语句的下一条。思考思考:从执行流程上看, while与for的关系?参考:参考:w whilehile是forfor的一种简化形式简化形式(缺省“循环变量赋初值”和“循环变量增值”表达式)。2024/7/30191案例案例5.4 用while语句求1100的累计和。#include “stdio.h”#include “conio.h”void main() int i=1,sum=0; w

101、hile( i=100 ) sum += i;/*实现累加*/ i+;/*循环控制变量i增1*/ printf(“sum=%dn”,sum); getch(); 思考思考:对于计数循环, while和for,哪个更简洁?2024/7/301925循环嵌套(1)循环嵌套循环体内,又包含另一个完整的循环结构。(2)for语句和while语句允许嵌套,do-while语句也不例外。 返回返回2024/7/301935.3 5.3 直到型循环直到型循环do-whiledo-while语句语句1一般格式 do 循环体; while(循环条件) ;2执行流程(右图)分号不能缺2024/7/30194(1)

102、执行循环体语句组;(2)计算“循环条件”表达式:如果为非非0 0(真),则转向(1)(1)继续执行;否则否则,转向(3)(3)。(3)执行do-while的下一条语句。特点特点:先执行,后判断。3适用环境适用环境:先执行1次循环体,再判断条件是否成立的情况。除此之外,do-while语句能实现的,for语句也能实现,而且更简洁。2024/7/30195案例案例5.5 用do-while语句求解1100的累计和。#include “stdio.h”#include “conio.h”void main() int i=1, sum=0; do sum += i; i+; while( i = 1

103、00 );/*循环条件:i=3),即从第3个数开始,每个数等于前2个数之和。数据结构数据结构:(1)设置2个简单变量f1、f2。(2)设置40个简单变量f1、f2、f40。 (3)设置一个数组f40。2024/7/30203算法设计要点算法设计要点:f1+f2f3,f1不再使用,所以可以用f1来存储f3的值,即f1+f2f3(f1) ;f2+f3(f1) f4 ,f2不再使用,所以可以用f2来存储f4的值,即f2+f3(f1) f4(f2)。2024/7/30204#include “stdio.h”#include “conio.h”void main() long int f1=1, f2

104、=1; int i=1; for( ; i = 20; i+ ) printf(“%15ld%15ld”, f1, f2); if( i % 2 = = 0 ) printf(“n”); f1 += f2; f2 += f1; /*计算下2个数*/ getch(); 为什么不是40?条件成立的含义?2024/7/30205案例案例5.7 输出10100之间的全部素数。 n是素数的条件:除1和n之外,不能被2(n-1)之间的任何整数整除。算法设计要点算法设计要点:(1)判断n是否是素数涉及数n能否被另一个数m(2(n-1)整除,可通过判断它们整除整除的余数余数是否为0来实现。(2)在判断某数n是

105、否是素数的算法外面,再套一个for循环即可。2024/7/30206#include “stdio.h”#include “conio.h”void main() int n=11, m, counter=0; for( ; n=100; n += 2) /*外循环:提供1个整数n*/ for(m=2; m= n ) /*n是素数*/ printf(“%6d”,n); /*输出*/ counter+; /*计数器加1*/ if(counter % 10 = = 0) /*输出10个数*/ printf(“n”); /*换1行*/ getch(); 为什么从11开始?增量为2有什么好处?2024

106、/7/30207案例案例5.8 加、减、乘、除和求余数运算练习程序(第3版)。对程序功能的基本要求如下:(1)使用菜单驱动;(2)随机产生运算所需的2个操作数(0-99);(3)程序自动判断用户的计算结果是否正确。在上一章中,实现了上述基本要求。但存在一个问题:运行1次,只能进行1种运算的1次练习;如果想继续练习,只能重新运行。显然,这样做很麻烦。在本案例中,将通过循环控制语句实现:运行1次,可以进行多种运算的多次练习,形成练习程序的第3版。2024/7/30208算法设计要点:算法设计要点:在上一章参考程序的主体结构(菜单显示、运算选择、输入运算结果及对结果的判断等)外,再加一层循环即可。

107、参考程序,详见教材5.5、案例5.8。返回返回2024/7/30209本本 章章 要要 点点1、for语句(1)格式:for(变量赋初值;循环条件;循环变量增值) 循环体; (2)执行流程2、break与continue的功能2024/7/302103、良好的源程序书写风格循环语句的缩排与注释(续)(1)缩排(续) :循环体向右缩进3-4个字符。(2)注释(续):for语句/*/*功能功能* */ /for() /*循环条件的含义含义*/ 注注:循环嵌套时,还应说明每层循环各控制什么。返回返回2024/7/30211本章作业与上机实践本章作业与上机实践作业作业:3,7,9 上机实践上机实践:验

108、证本章作业。返回返回2024/7/30212数组最简单的构造类型。教学目的教学目的:掌掌握握数组的定定义义、引引用用与应应用用,字符数组的整整体体操作操作。了解了解常用字符串处理函数字符串处理函数。第6章 数 组2024/7/30213教学内容教学内容:6.1 1维数组维数组6.2 2维数组维数组6.3 字符数组与字符串字符数组与字符串6.4 常用的字符串处理函数常用的字符串处理函数6.5 应用举例应用举例本章要点本章要点本章作业与上机实践本章作业与上机实践2024/7/302146.1 1维数组6.1.1 定义与引用案例6.1 从键盘上输入某学科竞赛组6名成员的成绩(整数),求平均成绩、并找

109、出最高分和最低分。 2024/7/30215算法设计要点:(1)平均成绩= (score0+score5) / 6;(2)将第1个人的成绩预置为最高分max和最低分min;(3)用其余5人的成绩依次与max和min比较:如果某人成绩 max,则更新max;如果某人成绩min,则更新min。 2024/7/30216#include stdio.h#include conio.h#define N 6/*定义符号常量N(分数个数)*/void main() int scoreN, loop, sum, max, min; /*输入N个成绩*/ printf( Please input %d sc

110、ores(departed by space): , N); for( loop = 0; loop N; loop+) scanf(%d, &scoreloop);2024/7/30217 /*求分数合计、最高分和最低分*/ sum = max = min = score0;/*预置累计和、最高、最低分*/ for(loop = 1; loop max) max = scoreloop; if (scoreloop min) min = scoreloop; /*输出结果*/ printf(n average = %4.1f, max = %d, min = %dn, (float)sum

111、/ N, max, min); getch();2024/7/30218程序运行情况举例:Please input 6 scores (departed by space): 64 72 85 80 90 78average = 78.2, max = 90, min = 642024/7/302191定义与存储数组必须先定义、后使用。数据类型 数组名常量表达式,数组名2常量表达式2;(1) “数据类型”是指数组元素的数据类型。(2) 数组名,必须遵循标识符命名规则;存放的是一个地址常量,它代表整个数组的首地址。(3) “常量表达式” 可以是常数和符号常量、不能包含变量,其值指数组元素个数(又

112、称数组长度) 。语法规则所要求的,不是可选项的描述符。2024/7/30220(4)数组元素下标,从0开始顺序编号,按下标顺序占用一段连续的存储单元,如右图所示。数组名0数组名1数组名n-12024/7/302212数组元素引用 数组名下标表达式(1) “下标表达式”可以是任何非负整型数据,合法取值范围是0-(元素个数-1)。注意:在引用数组元素时,系统并不检验下标是否越界。例如,上例中引用score10,其下标已经越界,但系统并不提示出错。2024/7/30222(2) 1个数组元素,就是1个简单变量,具有和相同类型变量一样的属性,可以对它进行赋值和参与各种运算。(3) 数值数组(整型/实型

113、)作为1个整体,不能参加数据运算,只能对单个的元素进行处理。2024/7/30223 6.1.2 初始化 数据类型 数组名常量表达式初值表;例如: float score5, ratio4=0.1,0.2,0.2,0.5; ratio0、ratio1 、ratio2 、ratio3,被分别赋予初值0.1、0.2、0.2、0.5。 说明:允许只给部分元素赋初值。例如,float score5=75,80,85,90; 返回2024/7/302246.2 2维数组6.2.1 定义与引用案例6.2 输出一个3行4列(记作3*4)矩阵A的转置矩阵A。矩阵A的转置矩阵A是指,矩阵A的第0、第1和第2行各

114、元素,转换成转置矩阵A的第0、第1和第2列元素。 2024/7/30225数据结构设计要点:对于一个3*4的矩阵A而言,最简单的数据结构莫过于用一个3*4的2维数组来存储其各元素;转置矩阵A是一个4*3的矩阵,所以再设计一个4*3的2维数组来存储其各元素。算法设计要点:基于2维数值数组的处理,一般使用2层嵌套循环来实现:外层循环控制行,内层循环控制列。2024/7/30226#include stdio.h#include conio.h#define ROW 3/*定义行数符号常量ROW 为3*/#define COL 4/*定义列数符号常量COL 为4*/void main() int l

115、oop1, loop2; /*定义并初始化3*4矩阵A*/ int array1ROWCOL = 1,2,3,4, 5,6,7,8, 9,10,11,12; /*定义转置矩阵A (4*3) */ int array2COLROW;2024/7/30227 /*求转置矩阵A (4*3)*/ for(loop1 = 0; loop1 ROW; loop1+) /*外循环:控制行*/ for(loop2 = 0; loop2 COL; loop2+) /*内循环:控制列*/ array2loop2loop1 = array1loop1loop2; /*输出转置矩阵A (4*3)*/ for(loop

116、1 = 0; loop1 COL; loop1+) for(loop2 = 0; loop2 ROW; loop2+) printf(%dt, array2loop1loop2); printf(n);/*每输出1行,换行*/ getch(); 2024/7/30228程序运行情况如下: 1 5 9 2 6 10 3 7 11 4 8 122024/7/302291定义与存储数据类型 数组名行常量表达式列常量表达式,数组名2行常量表达式2列常量表达式2;说明:2维数组元素在内存中的排列顺序为“按行存放”,即先顺序存放第0行各列元素,再存放第1行各列元素,以此类推。例如,数组a34 在内存中存放

117、顺序如下图所示:2024/7/30230第0 0列第1列第2列第3列第0 0行a00a01a02a03第1行a10a11a12a13第2行a20a21a22a232024/7/302312引用 数组名行下标表达式列下标表达式(1) 行/列下标表达式都应是整型表达式或符号常量,且都应在合法范围内。例如,对于数组a34,行下标的合法范围为02,列下标的合法范围为03。(2) 2维数组元素,具有和相同类型简单变量一样的属性,可以对它进行赋值和参与各种运算。2024/7/302326.2.2 初始化按行初始化数据类型 数组名行常量表达式列常量表达式 第0行初值表,第1行初值表,最后1行初值表 ;赋值规

118、则:将“第0行初值表”中的数据,赋给第0行元素;将“第1行初值表”中的数据,赋给第1行元素;以此类推。每行的赋值规则,与1维数组相同。2024/7/30233例如:int score34 = 78,85,83,65, 88,91,89,93, 72,65,54,75 ; 说明:与1维数组一样,允许只给2维数组的部分行,和行中的部分元素赋初值。例如, int array34=1,5,6; 返回2024/7/302346.3* 字符数组与字符串C语言没有专门的字符串变量,字符串的存储必须通过字符数组来实现。1维字符数组用于存储1个字符串(每个元素存放1个字符),2维字符数组用于同时存储多个字符串(

119、每一行存储1个字符串)。2024/7/30235对于字符数组的处理有两种方式:逐个字符方式和整体方式。逐个字符处理方式与数值数组一样,整体处理方式只有字符数组才被允许。 6.3.1 字符数组的逐个字符操作 6.3.2* 字符数组的整体操作返回2024/7/302366.3.1 字符数组的逐个字符操作案例6.3 密码输入程序。设计要求:以星号“*”代替密码字符显示, 6密码长度12。 2024/7/30237#include stdio.h#include conio.h#define MIN 6/*密码最小长度*/#define MAX 12/*密码最大长度*/void main() int

120、loop; char password13;/*为密码字符串预留1个结束标志位*/ printf(n Please input the password (612 characters): );2024/7/30238 for( loop = 0; loop MAX; loop+) passwordloop = getch(); printf(*);/*以星号代替密码字符显示*/ if(passwordloop=x0d)/*回车,结束密码输入*/ if( loop MIN ) /*长度6,提示重输*/ printf(n The length of the password is less th

121、an 6, press any key to continue); getch();/*暂停,按任意键继续*/ printf(n Please input the password again (612 characters): ); loop = -1; /*执行“loop+”后,使下标复位为0*/ 2024/7/30239 else /*密码长度在611之间*/ passwordloop = 0; /*置密码串结束标志*/ break; if( loop = MAX -1)/*密码长度达到最大值MAX*/ passwordloop = 0;/*置密码串结束标志*/ /*for循环尾*/ /

122、*main()函数尾*/2024/7/30240程序运行情况举例:Please input the password (612 characters): *The length of the password is less than 6, press any key to continuePlease input the password again (612 characters): *2024/7/30241总结:字符数组的定义、逐个字符引用和初始化,均与数值数组类似。说明:逐个字符输入输出时,使用“%c”格式符。输入时,无需输入定界符;输出时,系统也不输出定界符。返回2024/7/30

123、2426.3.2* 字符数组的整体操作C语言规定:以0作为字符串结束标志。因此可以对字符数组采用整体操作。案例 字符数组的整体输入与输出。 main( ) char name9; printf(“Whats your name?n”); scanf(“%s”, name); printf(“Welcome, %s !n, name); 数组名name,代表该数组首地址。所以不能再加&。结束标志占用1B,因此在说明字符数组长度时,至少为串长+1。2024/7/30243说明:(1)用scanf( )函数整体输入,或用printf( )函数整体输出一个字符串时,类型转换符必须使用“%s”。(2)在

124、scanf( )函数的输入项首地址表,或printf( )函数的输出项表中,直接使用数组名。2024/7/302441维字符数组整体初始化:数据类型 数组名长度=串常量,数组名2长度2=串常量2;2维字符数组的整体初始化:数据类型 数组名行数m列数n= 串常量0,串常量1,串常量m-1 ;返回2024/7/302456.4 常用的字符串处理函数字符串处理函数的原型,均在头文件string.h中。1输入字符串gets()函数2输出字符串puts()函数3字符串比较strcmp()函数4拷贝字符串strcpy()函数5字符串连接strcat()函数6求字符串长度strlen()函数7将大写字母转换

125、成小写strlwr()函数8将小写字母转换成大写strupr()函数返回2024/7/302461输入字符串gets()函数(1)调用方式:gets(字符数组)(2)函数功能:从键盘上读取1个字符串(可以包含空格),并将其存储到字符数组中去。gets()读取的字符串没有长度限制,编程者要保证字符数组有足够大的空间,用于存放输入的字符串。 与scanf()的区别: gets()输入的字符串中允许包含空格,而scanf()函数不允许。返回2024/7/302472输出字符串puts()函数(1)调用方式:puts(字符数组)(2)函数功能:将字符串输出到显示器,并用n取代结束标志0。字符串中允许包

126、含转义字符。与printf()的区别: puts()1次只能输出1个字符串,而printf()可以1次能输出多个。返回2024/7/302483字符串比较字符串比较strcmp()函数函数(1)调用方式:strcmp(字符串1 ,字符串2)其中,“字符串”可以是串串常常量量,也可以是1维维字字符数组符数组。(2)功能:比较两个字符串的大小。如果:字符串字符串1 = 字符串字符串2,返回值等于0; 字符串字符串1 字符串字符串2,返回一个正正整数。2024/7/30249如果一个字符串是另一个字符串从头开始的子子串串,则母串母串为大。不能使用关系运算符“”来比较两个字符串,只能用strcmp()

127、 函数来处理。返回2024/7/302504拷贝字符串拷贝字符串strcpy()函数函数(1)调用方式:strcpy(字符数组, 字符串)(2)函数功能:将“字符串”完整地复制到“字符数组”中(原有内容被覆盖)。字符数组必须足够大,以便容纳复制(连同结束标志0一起复制)过来的字符串。不能用赋值运算符“”将一个字符串直接赋值给一个字符数组,只能用strcpy( )函数来处理。返回2024/7/302515字符串连接字符串连接strcat()函数函数(1)调用方式:strcat(字符数组, 字符串)(2)函数功能:把“字符串”连接到“字符数组”中的字符串尾端,并存储于“字符数组”中。要保证“字符数

128、组”定义得足够大;否则,会因长度不够而产生问题。连接前两个字符串都有结束标志0,连接后,只在目标串的最后保留一个0。返回2024/7/302526求字符串长度求字符串长度strlen()函数函数(1)调用方式:strlen(字符串)(2)函数功能:求字符串(常量或字符数组)的实际长度(不包含结束标志)。返回2024/7/302537将大写字母转换成小写strlwr()函数(1)调用方式:strlwr(字符串)(2)函数功能:将字符串中的大写字母转换成小写,其它字符(包括小写字母和非字母字符)不转换。返回2024/7/302548将小写字母转换成大写strupr()函数(1)调用方式:strup

129、r(字符串)(2)函数功能:将字符串中小写字母转换成大写,其它字符(包括大写字母和非字母字符)不转换。返回2024/7/302556.5 应用举例案例案例6.5 从键盘上任意输入6个整数,要求按升序输出。冒泡法排序的基本思路冒泡法排序的基本思路:通过相邻两个数之间的比较和交换,使较小的数逐渐从底部移向顶部,较大的数逐渐从顶部移向底部,就像水底的气泡一样逐渐向上冒,故而得名。假设有6个数(36、24、85、48、90、60),顺序存储在数组array6中,采用冒泡法排序的过程下图所示:2024/7/30256 array0 array1 array2 array3 array4 array5 3

130、6 24 85 48 90 60 24 36 85 48 90 60 24 36 48 85 90 60 24 36 48 85 60 90 24 36 48 60 85 902024/7/30257算法设计要点:从上述实例可知,冒泡法排序算法的关键是:(1)比较轮数:6个数需要比较5轮,可以证明n个数需要n-1轮。(2)每轮比较的最后一个元素的下标:轮轮 次次待比较数据个数待比较数据个数最后一个元素的下标最后一个元素的下标165 ( = 6 1 )254 ( = 6 2 )343 ( = 6 3 )432 ( = 6 4 )521 ( = 6 5 )2024/7/30258设轮次为m、一共n

131、个数排序,通过上表可以推导出每轮比较的最后一个元素的下标为n - m。2024/7/30259/*功能:冒泡法排序*/#include stdio.h#include conio.h#define N 6/*定义符号常量N(数据个数)*/void main() int arrayN;/*定义1个1维整型数组array,共有N个元素*/ int loop1, loop2, temp;/*定义循环变量和用于元素交换的临时变量*/ /*输入N个数*/ printf(Please input %d numbers(departed by space): , N); for(loop1 = 0; loo

132、p1 N; loop1+) scanf(%d, &arrayloop1);2024/7/30260 /*冒泡法排序*/ for(loop1 = 1; loop1 = N - 1; loop1+)/*控制比较轮数*/ for(loop2 = 0; loop2 arrayloop2 + 1)/*交换两数*/ temp = arrayloop2; arrayloop2 = arrayloop2 + 1; arrayloop2 + 1 = temp; 2024/7/30261 /*输出排序结果*/ printf(nthe result of sort: ); for(loop1=0; loop1 n2

133、 ? n1 : n2); /*/void main( void ) int max(int n1, int n2);/*对被调用函数进行说明*/ int num1,num2; printf(input two numbers: ); scanf(%d%d, &num1, &num2); printf(max=%dn, max(num1, num2); 对函数的注释2024/7/302763、说明说明(1)函数定义不允许嵌套不允许嵌套。一个函数的定义,可以放在程序中的任意位置,但不能在另一个函数的函数体内,即不能嵌套定义。例如:main( ) int max() (2)空函数函数体为空的无参函数

134、: 函数类型函数类型 函数名函数名( ( void void ) ) 2024/7/302777.1.2 函数调用与返回1、对被调用函数的说明和函数原型(1) 函数说明的一般格式 在新标准中,采用函数原型方式,对被调用函数进行说明: 函数类型 函数名(形参表);2024/7/30278(2) 函数说明的两种方式 谁调用谁说明:函数说明语句放在调用函数的函数体中。例如,在案例7.1主函数main()中:void main( void ) int max( int n1, int n2); 对被调用函数进行说明2024/7/30279预先统一说明函数说明通常放在所有函数定义体之前。在这种方式下,所

135、有调用函数都无需再对自定义函数进行说明。例如,在案例7.1中,可以将对max()函数的说明放在程序文件开始处:void main( void ) int max(int n1, int n2); 2024/7/30280显然,对于被多个函数调用的自定义函数而言,采用预先统一说明方式进行说明,可以有效地减少函数说明次数。 注意: 如果被调用函数的定义体,出现在调用函数之前,可以缺省说明。2024/7/302812、函数调用 函数名(实参表) 例如,在案例7.1的主函数中: printf(, max (num1, num2) );注意:调用有参函数,必须提供实参(常量/变量/表达式/函数) 。调用

136、时,实参必须具有确定的值,且与形参个数相等、类型匹配。2024/7/30282(1) 调用方式 语句方式无返回值函数的调用,可作为一条独立的语句。例如,printf()、scanf ()等库函数的调用,均作为一条独立的语句。 表达式方式有返回值函数作为表达式的一项,以函数返回值参与表达式的运算。例如,“max = max(x, y)”是一个赋值表达式,把max()函数的返回值赋予变量max。2024/7/30283(2) 断点与函数调用的返回断点被调用函数执行完毕,返回调用函数后继续执行的位置。调用函数中的断点位置分两种情况: 语句调用方式:断点为函数调用语句的下一条语句。例如,案例7.1中的

137、语句调用“printf();”,其断点为该语句的下一条语句“getch();” 。2024/7/30284 表达式调用方式:断点为函数调用所在的表达式。例如,在案例7.1中,“printf(, max(num1, num2) );”语句中的表达式调用“max(num1, num2)”:其断点为该表达式调用所在的表达式“max(num1, num2)”(在本例中,“max(num1, num2)”函数调用既是表达式调用,本身又构成一个简单表达式)。2024/7/302857.1.3 参数传递发生函数调用时,根据参数值的性质不同,将参数传递分为两种:(1) 值传递参数值是一个一般数据(整形、实型、

138、字符型数据等)。系统把实参值复制1份给形参;被调用函数结束时,形参值不能传回给实参。(2) 地址(引用)传递参数值是一个地址。2024/7/30286执行案例7.1时的参数传递:int max( int n1, int n2) return ( n1 n2 ? n1 : n2); main( ) int max(int n1, int n2); int num1,num2; printf(input two numbers: ); scanf(%d%d, &num1, &num2); printf(max=%dn, max(num1, num2); 2024/7/30287(1)形参变量只有在

139、被调用时,才分配内存单元;调用结束时,立即被释放。因此,形参只有在该函数内有效。调用结束,返回调用函数后,则不能再使用该形参变量。(2)实参和形参占用不同的内存单元,即使同名也互不影响。2024/7/302887.1.4 小结1函数定义不允许嵌套。2调用有参函数时,实参的个数和类型,必须与形参匹配。3 函数调用的两种方式与断点位置(1) 语句方式:断点为函数调用语句的下一条语句。(2) 表达式方式:断点为函数调用所在的表达式。2024/7/302894参数传递分两种:(1) 值传递:单向传递。(2) 地址(引用)传递。返回2024/7/302907.2 函数的嵌套调用和递归调用7.2.1 函数

140、的嵌套调用 案例7.3 计算 = 1!+2!+ + n!(n1,20的整数,从键盘输入)。算法设计要点:本案例可以设计2个函数:factor( )用于求n!;sum( )通过调用factor( )来实现求。程序框架如下(完整程序详见教材7.2.1): 2024/7/30291void main( ) sum( num );/*调用函数sum( )*/ void sum(int num) sum += factor (loop); /*求累计和*/ long factor (int num) /*求num的阶乘*/ 2024/7/30292在案例7.3中,主函数main()调用求和函数sum(

141、),sum( ) 又循环调用求阶乘的函数factor( )。一般地说,函数的嵌套调用是指,在执行被调用函数时,该函数又调用其它函数的情形。 注意:被调用函数执行完毕后,将返回到调用函数的断点继续执行。简言之,谁调用,返回到谁的断点继续执行。2024/7/302937.2.2 函数的递归调用案例7.4 用递归法计算n!(1! = 1,n! = (n-1)! * n (n2))。算法设计要点:(1) 根据计算n!的递归定义可知,为了计算n!,必须首先计算(n-1)!;以此类推,直至1!(1! = 1)。(2) 依据1!求2!=1!*2,再依据2!求3!=2!*3;同理,依据(n-1)!求n!= (

142、n-1)!*n。2024/7/30294long factor( int num ) long fact; if( num 1) fact = factor( num 1 ) * num; else fact = 1; return( fact ); 以num = 5为例,其执行过程详见教材7.2.2。递归调用自己2024/7/30295语言允许函数直接(或间接)地调用它自己,称为递归调用;这种函数称为递归函数。例如,案例7.4中的函数factor()就是一个递归函数。防止递归调用无终止地进行的常用办法:添加1个继续(或终止)递归调用的条件判断。例如,案例7.4中函数factor( )中的“i

143、f( num 1)” 。返回2024/7/302967.3 内部函数和外部函数 C语言程序中的函数,是通过被调用而执行的,所以一个函数需要被其它函数调用。但是,当一个程序由多个源文件组成时,在一个源文件中定义的函数,能否被其它源文件中的函数调用呢?语言据此将函数分为内部内部函数函数和外部外部函数函数。2024/7/302977.3.1 内部函数内部函数(又称静态函数又称静态函数) 如果在一个源文件中定义的函数,只能被本源文件中的其它函数调用,这种函数称为内部函数。1定义static 函数类型函数类型 函数名函数名(形参表形参表) 2 特点:只能被本文件本文件中的函数所调用。3 好处:不用担心与

144、其它源文件中的函数同名,因为即使同名也没关系。2024/7/302987.3.2 外部函数如果在某源文件中定义的函数,可被同一程序中所有源文件中的函数调用,这种函数称为外部函数。 1定义:extern 函数类型 函数名( 形参表 ) 2特点:允许被所有源文件中的函数所调用。3调用其它源文件中的外部函数时,需要对其进行说明:extern 函数类型 函数名(形参表),函数名2(形参表2 );2024/7/30299案例7.5 将加、减、乘、除和求余数运算练习程序(第3版)的源文件组织形式改为:实现加、减、乘、除和求余数运算的程序段,均作为1个独立的函数、存储在1个独立的源文件中。程序框架如下(完整

145、程序详见案例源代码):2024/7/30300/*外部函数说明*/extern void addition(int n1, int n2);extern void subtraction(int n1, int n2);extern void multiplication (int n1, int n2);extern void division(int n1, int n2);extern void remainder(int n1, int n2);void main() 2024/7/303017.3.3 多个源文件的编译和连接在软件工程项目中,采用结构化方法进行程序设计与编程,通常会产

146、生多个源文件(例如源程序文件、数据结构定义文件等)。那么,如何将这些源文件编译、连接成一个统一的可执行文件呢?一般有两种方法:2024/7/30302(1)分别编译、一并连接C编译程序是以源文件为编译单位。当一个程序中的函数和数据结构分放在多个源文件中时:先将各文件分别编译,再通过link命令产生一个可执行文件(.exe) 。 (2)集中编译、连接利用编译预处理命令#include,将其它源文件包含到主函数main( )所在的源文件的开头;然后直接编译该文件即可。 2024/7/30303例如,在案例7.5中的主函数main()所在的源文件case75_1.c的开头添加如下几行:/*将其它各源

147、文件包含进来*/#include case75_2.c#include case75_3.c#include case75_4.c#include case75_5.c#include case75_6.cvoid main( ) 返回2024/7/303047.4* 内部变量与外部变量 语言中的变量,定义位置不同,其作用域也不同,据此将变量分为内部变量和外部变量。7.4.1 内部变量1、内部变量在函数内(函数说明+函数体)定义的变量。2、作用域只在该函数范围内有效。所以内部变量也称“局部变量”。2024/7/30305例如,在案例7.4中,主函数main( ) 中定义的变量num就是内部变量

148、,它仅在主函数main()中才能使用;求阶乘的factor( )函数,函数说明中的形参变量num,以及函数体中定义的变量fact,均属内部变量,都只能在factor( )函数中使用。 说明:在不同的函数中,允许使用同名内部变量。它们代表不同的对象,互不干扰。例如,在案例7.4中,主函数main()中的内部变量num,与函数factor()中的内部变量num同名。2024/7/30306案例 内部变量的应用。void main( ) void sum(int num); int num = 100; printf(“num_main()=%dn”, num); /*调用前实参的值*/ sum(

149、num ); /*调用函数*/ printf(num_main()=%dn, num); /*调用后实参的值*/ getch(); void sum(int num) int i; printf(num_sum()=%dn, num); /*改变前的形参值*/ for(i=num-1; i=1; i-) num += i; /*改变形参的值*/ printf(num_sum()=%dn, num); /*改变后的形参值*/ 2024/7/303077.4.2 外部变量1、外部变量在函数外部定义的变量。2、作用域:从外部变量的定义位置开始,到本文件结束为止。外部变量不从属于任何一个函数,可被作用

150、域内的所有函数使用,所以外部变量又称全局变量。2024/7/30308案例7.6 设计一个函数cuboid(int length, int width, int height)(3个参数依次为长方体的长、宽、高),用于求长方体的体积及正、侧、顶三个面的面积。算法设计要点:函数cuboid (int length, int width, int height)本身只能返回1个值(本案例选定体积),正、侧、顶三个面的面积就只能通过外部变量来进行数据共享。 参考程序框架如下:2024/7/30309long area1, area2, area3; /*定义3个外部变量,用于数据共享*/long c

151、uboid (int length, int width, int height);/*函数说明*/void main( ) volume = cuboid (length, width, height); printf(n volume = %ld, area1 = %ld, area2 = %ld, area3 = %ld , volume, area1, area2, area3); 2024/7/30310long cuboid (int length, int width, int height) long volume; volume = length * width * heig

152、ht;/*计算体积*/ area1= length * width; /*计算3个面的面积*/ area2= width * height; area3= length * height; return( volume);/*返回体积值*/ 2024/7/303113、说明(1)外部变量的作用域:从定义点到本文件结束。为方便使用,建议:将外部变量的定义放在文件开头,如 案例7.6所示。(2)在同一源文件中,允许外部变量和内部变量同名。在内部变量的作用域内,外部变量不起作用。2024/7/30312(3)外部变量可实现函数之间的数据共享,但又使这些函数依赖这些外部变量,因而使得这些函数的独立性降

153、低。注:从模块化程序设计观点来看,这是不利的。因此不是非用不可时,不要使用外部变量。2024/7/30313案例 内部、外部变量的同名应用。int len=3, width=4, high=5;int vs(int len, int width) int vol; vol = len * width * high;/*引用外部变量high*/ return v; main() int len=5; printf(len=%d, width=%d, high=%d , vol=%d, len, width, high, vs(len, width); len = ? width = ?len =

154、 ? 2024/7/303147.4.3 小结1内部变量在函数内(函数说明+函数体)定义的变量,其作用域:只在该函数范围内有效。不同函数中的同名内部变量,互不干扰。2外部变量在函数外部定义的变量,其作用域:从外部变量的定义位置开始,到本文件结束为止。允许内部、外部变量同名。在内部变量的作用域内,外部变量不起作用。返回2024/7/303157.5 变量的存储特性 语言中的变量,不仅有类型特性,还有存储特性:(1)动态存储方式:自动内部变量(auto)、寄存器变量(register)(2)静态存储方式:静态内部变量(static)、外部变量(extern) 。2024/7/303167.5.1

155、内部变量的存储1动态存储自动内部变量(简称自动变量)(1)定义:auto 数据类型 内部变量表;(2)存储特点:作用域:局限于定义它的函数内。生存期:函数被调用时,分配存储空间;调用结束就释放。初始化:定义而不初始化,其值是不确定的。如果初始化,则每次调用都要重新赋一次初值。2024/7/303172静态存储静态内部变量(1)定义: static 数据类型 内部变量表;(2)存储特点作用域:不变(只在本函数内有效,其它函数不可引用)。生存期:扩展到整个程序(即函数调用结束也不释放)。初始化:定义但不初始化,则系统自动初始化:(整型和实型)或0(字符型);每次调用它们所在的函数时,不再重新赋初值

156、,只是保留上次调用结束时的值!2024/7/30318 案例7.7 输出14的阶乘,并展示自动变量与静态内部变量的存储特性。void main() int num = 1; for(; num n2?n1:n2); 2024/7/30330(2)对文件的注释在文件开始处,至少应说明:/*文件名:xxx */*函数清单: xxx */*简要说明: xxx */*设计者: xxx */*完成日期: xxx */返回2024/7/30331本章作业与上机实践作业:6 ,7 ,9上机实践:验证本章作业。返回2024/7/30332第第9 9章章 指指 针针指针是语言的重要概念和特色。使用指针,可以使程

157、序更加简洁、紧凑、高效。教学目的教学目的:掌握掌握指针指针的概念,指针变量指针变量的概念、定义与应用,指向1维数组维数组(字符串)的指针变量应用,指针数组与带参主函数带参主函数;了解了解返回指针值的函数指针值的函数等。2024/7/30333教学内容教学内容:9.1 指针和指针变量的概念指针和指针变量的概念9.2* 指针变量的定义与应用指针变量的定义与应用 9.3* 1维数组的指针与列指针变量维数组的指针与列指针变量 9.4 字符串的指针和指向字符串的指针变量字符串的指针和指向字符串的指针变量9.5 指针数组与主函数指针数组与主函数main()的参数的参数9.6 返回指针值的函数返回指针值的函

158、数本章要点本章要点本章作业与上机实践本章作业与上机实践2024/7/303349.19.1* * 指针和指针变量的概念指针和指针变量的概念1内存地址内存地址内存中存储单元的编号编号。(1)内存中拥有大量的存储单元(1字节)。为了方便管理,必须为每一个存储单元编号存储单元的“地址”。每个存储单元,都有一个惟一的地址。(2)在地址所标识的存储单元中,存放数据数据。类比类比:住址(宿舍编号)与人。2024/7/303352变变量量地地址址系统分配给变量的内存单元的起起始地址始地址。假设有如下程序:void main( ) int num; scanf(%d, &num); printf(num=%d

159、n, num); 且系统分配给变量num的2个存储单元为 3000 和3001,则起始地址起始地址3000就是变量num在内存中的地址地址。2024/7/303363 3变量值的存取变量值的存取通过变量在内存中的地址地址进行系统存取变量num的方式可以有两种:33000num(1)直接访问直接访问直接利用变量的地址进行存取用变量名num查找符号表(编译程序建立),取出其起始地址3000;然后访问num(将数据送入/取出),如右图所示。2024/7/30337(2)间接访问间接访问通过另一变量访问num的值语言规定:在程序中,可以定义一种特殊的变量(称为指针变量指针变量),用来存放其它变量的地址

160、。假设:定义了1个指针变量num_p,它被分配到4000、4001单元,通过赋值语句“num_p =num;”获得num的地址3000,如下图所示:2024/7/30338通过指针变量num_p,存取变量num的过程如下:首先找到指针变量num_p的地址(4000),取出其值3000(num 的地址); 然后存取num的值(3)。3000330004000numnum_p2024/7/30339(3) 两种访问方式的比较 类比类比:某人甲(系统)找某人乙(变量)办事甲直接去找乙办事(即直接访问直接访问)。甲委托丙( (指针变量指针变量) )去找乙办事。2024/7/303404 4指针与指针变

161、量指针与指针变量(1)指指针针即地址,变量的地地址址称为该变量的指指针针。(2)指指针针变变量量专门用于存储其它变变量量地地址址的变量。例如,变量num_p是一个指针变量,其值是变量num的地址。返回返回2024/7/303419.29.2* * 指针变量的定义与应用指针变量的定义与应用 9.2.1 指针变量的定义与相关运算指针变量的定义与相关运算案例案例9.1 指针变量的定义与相关运算示例。#include stdio.h#include conio.hvoid main( ) int num_int=12, *p_int; float num_f=3.14, *p_f; char num_

162、ch=p, *p_ch; p_int = &num_int; p_f = &num_f; p_ch = &num_ch; 指向int型数据的指针变量p_int 使p_int指向变量num_int2024/7/30342 printf(“num_int=%d, *p_int=%dn”, num_int, *p_int); printf(“num_f=%4.2f, *p_f=%4.2fn”, num_f, *p_f); printf(“num_ch=%c, *p_ch=%cn”, num_ch, *p_ch); getch(); 程序运行结果: num_int=12, *p_int=12 num_

163、f=3.14, *p_f=3.14 num_ch=p, *p_ch=p访问p_int所指向的变量2024/7/303431、指针变量的定义指针变量的定义数据类型数据类型 * *指针变量指针变量,* *指针变量指针变量2 2;例如, 案例9.1中的语句:int num_int=12, *p_int ;特特别别说说明明:定义而未初始化的指针变量(例如p_int)是悬空的。使用悬悬空空指指针针变变量量,很容易破坏系统,导致系统瘫痪。指针变量的定义标识符2024/7/303442、取地址运算取地址运算 : 变量名变量名例 如 , 案 例 9.1中 的 &num_int、 &num_f、&num_ch的

164、结果,分别为对应变量的地址(num_int、num_f、num_ch)。注注意意:指指针针变变量量只能存存放放相同数据类型变量的地地址址。例如, 案例9.1中的指针变量p_int、p_f、p_ch,只能接收int型、float型、char型变量的地址,否则出错。2024/7/303453、指针运算:指针运算: * *指针指针变量名变量名*p_int、*p_f、*p_ch ,分别输出各自所指向的变量num_int、num_f、num_ch的值。 案案例例9.2 使用指针变量求解:输入2个整数,按升序(从小到大排序)输出。2024/7/30346#include stdio.h#include c

165、onio.hvoid main() int num1, num2; int *num1_p=&num1, *num2_p=&num2, *pointer; printf(“Input the first number: ”); scanf(“%d”, num1_p); printf(“Input the second number: ”); scanf(“%d”, num2_p); printf(“num1=%d, num2=%dn”, num1, num2); if( *num1_p *num2_p )/*num1num2:交换指针*/ pointer= num1_p; num1_p= nu

166、m2_p; num2_p=pointer; printf(“min=%d, max=%dn”, *num1_p, *num2_p); getch(); 悬空指针使num1_p指向num1本身是地址,不能再加&。2024/7/30347算算法法思思路路:交换指指针针变变量量num1_p 、num2_p的值,而不是变量num1和num2的值(保持原值),最后通过指针变量输出处理结果。假设输入的数据为9和6,则指针变量num1_p和num2_p交换前后的指向,如下图所示:2024/7/303489.2.2 指针变量作函数参数指针变量作函数参数1、指针变量:形参形参 + 实参实参。2、指针变量作实参时

167、,是地址传递地址传递,即将指针变量的值(一个地址) ,传递给被调用函数的形参(必须是一个指针变量)。2024/7/30349案例案例9.39.3 使用函数调用方式改写案例案例9.29.2,要求函数参数为指针变量。#include stdio.h#include conio.hvoid exchange( int *pointer1, int *pointer2 ) int temp; temp=*pointer1; *pointer1=*pointer2; *pointer2=temp; 2024/7/30350void main() int num1, num2; int *num1_p=&

168、num1, *num2_p=&num2; printf(“Input the first number: ”); scanf(“%d”, num1_p); printf(“Input the second number: ”); scanf(“%d”, num2_p); printf(“num1=%d, num2=%dn”, num1, num2); if( *num1_p *num2_p ) /* num1num2*/ exchange( num1_p, num2_p ); /*指针变量作实参*/ printf(“min=%d, max=%dn”, num1, num2); getch();

169、 2024/7/30351算算法法思思路路:通过指针变量num1_p 、num2_p,交换它们所指向的变变量量num1和num2的值,最后通过变量num1和num2输出结果。假设输入的数据为9和6,则调用函数exchange()之前、之时、结束时和结束后的情况,如图9-4所示:2024/7/303522024/7/30353形形 参参 指指 针针 变变 量量 pointer1(num1)和 pointer2 (num2),在函数调用开开始始时才分分配配存储空间,函数调用结束结束后立即被释放释放。结结论论:地地址址传传递递时,形形参参指针变量不可改变实实参参指针变量,但可以改变它所指向的变变量量

170、的的值值,通过不变的实参指针变量将变化的值保留下来。 返回返回2024/7/303549.39.3* * 1 1维数组的指针与列指针变量维数组的指针与列指针变量 9.3.1 预备知识预备知识9.3.2 使用列指针变量引用数组的元素使用列指针变量引用数组的元素 9.3.3 数组作函数参数数组作函数参数返回返回2024/7/303559.3.1 预备知识预备知识1、基本概念数组指针数组指针数组数组在内存中的起始地址起始地址,用数组名数组名表示。数组元素指针元素指针数组元素数组元素在内存中的起始地址起始地址。2024/7/303562、指向数组的指针变量的定义int array10, *pointe

171、r = array (或或&array0);int array10, *pointer;pointerarray;数组名数组在内存中的起始地址(与第1个元素的地址相同)2024/7/30357(1) pointer + i和array + i都是指针,均指向元素arrayi,即: pointer + i = array + i = &arrayi 。(2) *( pointer + i )和*( array + i ) 均访问元素 arrayi。(3)指向数组的指针变量,可以当作数组名用。例如,pointeri *(pointer+i)。注注:pointer pointer + + 1 1使指

172、针指向数组的下下一一个个元元素素,而不是内存下一个存储单元。2024/7/303583、数组元素的引用方法(1)下标法:arrayi,直观。(2)指针法:*pointer,目标程序占用内存少、速度快。返回返回2024/7/30359案例案例9.5 使用指向数组的指针变量来访问数组元素。#include stdio.h#include conio.hvoid main() int array10, *pointer = array, i; printf(“Input 10 numbers: ”); for(i=0; i10; i+) scanf(“%d”, pointer+i) ; printf

173、(“array10: ”); for(i=0; i10; i+) printf(“%d ”, *(pointer+i) ) ; printf(“n”); getch(); 使用指向数组的指针变量输入。 使用指向数组的指针变量输出9.3.2 使用列指针变量引用使用列指针变量引用1维数组的元素维数组的元素 2024/7/303601指向数组的指针变量,可以指向数组后面的内存单元,虽然没有实际意义。例如,*(pointer+10),程序照样运行。2对指向数组的指针变量(px和py),进行算算术术运算和关系关系运算的含义:2024/7/30361(1) 算术算术运算: px n:将指针从当前位置向前(

174、+)或回退(-)n个个元素元素(不是n个字节)。px+/+px和px-/-px是pxn的特例(n=1)。 px - py:两指针之间的元元素素个个数数,不是地址之差。2024/7/30362(2) 关关系系运算:两个指针所指地址的前后关系:前者为小,后者为大。例如,如果指针px所指地址在指针py所指地址之前,则px =a&c=A&c=Z ? 1 : 0); 2024/7/303662、数组名作为函数的形参和实参数组名作实参时,传递的是数组指针,属于地址传递,对应的形参必须是同一数据类型的数组名(指针变量)。案例 已知某个学生5门课程的成绩,求平均成绩。2024/7/30367#include

175、stdio.h#include conio.hfloat aver( float a , int n);void main( void ) float score5 = 70,75,80,85,90; printf(average = %5.2fn, aver( score, 5 ) ); float aver( float a , int n) float sum = a0; int i=1; for( ;i= a) & (stri = z) )/*小写字母*/ stri -= 32;/*转换成大写*/ 思考:1、程序输出结果? 2、 LwrToUpr ( char str )可以改为Lwr

176、ToUpr ( char *str )吗?函数体如何修改?函数体是否必须修改?2024/7/30371调用开始开始时:0.egaugnaLCstringstr调用结束结束时: 0.EGAUGNALCstrstring返回返回2024/7/30372第第9 9章章 指指 针针指针是语言的重要概念和特色。使用指针,可以使程序更加简洁、紧凑、高效。教学目的教学目的:掌握掌握指针指针的概念,指针变量指针变量的概念、定义与应用,指向1维数组维数组(字符串)的指针变量应用,指针数组与带参主函数带参主函数;了解了解返回指针值的函数指针值的函数等。2024/7/30373教学内容教学内容:9.1 指针和指针变

177、量的概念指针和指针变量的概念9.2* 指针变量的定义与应用指针变量的定义与应用 9.3* 1维数组的指针与列指针变量维数组的指针与列指针变量 9.4 字符串的指针和指向字符串的指针变量字符串的指针和指向字符串的指针变量9.5* 指针数组与主函数指针数组与主函数main()的参数的参数9.6 返回指针值的函数返回指针值的函数本章要点本章要点本章作业与上机实践本章作业与上机实践2024/7/303749.4 9.4 字符串指针和指向字符串的指针变量字符串指针和指向字符串的指针变量 第6章指出:1维字符数组用于存储1个字符串(每个元素存放1个字符),2维字符数组用于同时存储多个字符串(每一行存储1个

178、字符串)。对于字符数组的处理有两种方式:逐个字符方式和整体方式。字符串在内存中的起始地址称为字符串的指针字符串的指针,可以定义一个字符指针变量字符指针变量指向一个字符串。 2024/7/303759.4.1 字符串的表示与引用字符串的表示与引用字符串的表示:字符数组数组 + 字符指针变量指针变量;字符串的引用:逐个逐个引用 + 整体整体引用。1、逐个逐个引用案例案例9.8 使用字符指针变量表示和处理字符串。2024/7/30376#include stdio.h#include conio.hvoid main() char *string = “I love Beijing. ” ; for

179、( ; *string != 0; string+) printf(“%c”, *string); printf(“n”); getch(); 思考思考:(1) 在for()之后,再重复上述for(),输出结果如何?(2) 将for()改为:for( i=0; *(string + i ) != 0; i+) printf(“%c”, *(string+i);,再重复之,输出结果如何?等价于:char *string;string=I love Beijing.;用串常量首地址串常量首地址初始化string。存储在由系统自动开辟的内存块中,并在串尾添加一个结束标志0。2024/7/303772

180、、整体引用整体引用案例案例9.9 采取整体引用的办法,改写案例案例9.8。#include stdio.h#include conio.hvoid main() char *string = ”I love Beijing.”; printf(“%sn”, string); getch(); 思考思考:重复上述printf( ),输出结果如何?系统首先输出string指向的当前字符,然后自动使string+1(不是string+),指向下一个字符;重复上述过程,直至遇到0。2024/7/303783、字符指针变量与字符数组之比较字符指针变量与字符数组之比较(1)存储内容不同存储内容不同字符指指

181、针针变变量量,存储的是字符串串首首地地址址;字字符符数数组组,存储的是字符串本身串本身(数组名表示字符串首地址)。(2)字符指指针针变变量量的值,是可可以以改改变变的;数数组组名名代表数组的起始地址地址,是一个常量常量,是不能被改变的。2024/7/30379(3) 赋值方式不同赋值方式不同char *pointer, char_array20;pointer = “This is a example.”;/*合法*/char_array = This is a example.; /*非法*/2024/7/303809.4.2 字符串指针作函数参数字符串指针作函数参数案例案例9.10 编写1

182、个自定义函数void string_copy(char *str_from, char *str_to),实现字符串的复制。#include stdio.h#include conio.h void string_copy(char *str_from, char *str_to) int i = 0; for(; ( *(str_to + i) = *(str_from + i) != 0; i+) ; 循环体为空语句先复制、后判断先复制、后判断。0 复制吗?2024/7/30381void main() char array_str120 = I am a teacher.; char a

183、rray_str220; string_copy(array_str1, array_str2); printf(array_str2 = %sn, array_str2); getch(); 返回返回数组名作实参2024/7/303829.59.5* * 指针数组与主函数指针数组与主函数main()main()的形参的形参9.5.1 指针数组指针数组1、概念数组的每个元素都是1个指针。指针数组指针数组比较适合用于指向多个字符串多个字符串,使字符串处理更加方便、灵活。2、定义:数据类型数据类型 * *数组名数组名 元素个数元素个数 注意注意:行指针变量定义格式“数据类型 ( (*行指针变量)

184、)元素个数”。2024/7/30383案例案例9.11 有若干计算机图书,请按字母顺序,从小到大输出书名。解题要求:使用排序函数void sort(char *name, int count)完成排序,在主函数中进行输入输出。算法设计要点:算法设计要点:选择法排(升)序的基本思想:每次从剩余的数(或字符串)中选择1个最小的,存入这些数的首位置处。2024/7/30384下面以5种计算机图书书名BASIC(位序0)、FORTRAN(位序1)、PASCAL(位序2)、C(位序3)和FoxBASE(位序4)为例,说明选择法排(升)序的基本思路: (1) 从5个书名字符串中,选择最小的BASIC串,存

185、入本次比较的5个字符串的首位置(位序0)处(由于BASIC本来就存储在位序0处,所以保持不变)。2024/7/30385(2) 从剩余的4个串中,选择最小的C串,存入本次比较的4个字符串的首位置处(位序1),同时将FORTRAN交换C原来的存储位置(位序3)上。(3)以此类推,依次选出最小串FORTRAN、FoxBASE和PASCAL,分别存储到位序2、位序3和位序4。 2024/7/30386#include stdio.h#include conio.hvoid sort(char *name , int count) char *temp_p; int i, j, min; /*选择法排

186、序*/ for( i = 0; i count-1; i+) /*外循环:控制选择次数*/ min = i; /*预置本次最小串的位置*/ for( j = i +1; j 0 ) min=j; if( min != i ) /*存在更小的串,交换位置*/ temp_p=namei, namei=namemin, namemin=temp_p; 2024/7/30387void main( ) char *name5= “BASIC” , ”FORTRAN”, ”PASCAL”,”C”,”FoxBASE” ; int i=0; sort( name, 5); for(; i5; i+) pri

187、ntf( “%sn”, namei ); getch(); 字符指针数组名作实参2024/7/303889.5.2 主函数主函数main()的形参的形参案例案例9.12 用同一程序实现文件的加密和解密。约定:程序的可执行文件名为lock.exe, 其用法为:lock +|- lock +|- 文件名文件名,其中“+”为加密,“-”为解密。2024/7/30389#include stdio.h#include conio.hvoid main( int argc, char *argv ) char c; if (argc != 3) printf(参数个数不对!n); else c = *a

188、rgv1;/*截取第1个实参的第0个字符*/ switch(c) case +: /*执行加密*/ printf(执行加密程序段n); break; case -: /*执行解密*/ printf(执行解密程序段n); break; default: printf(第1个参数错误!n); getch(); 2024/7/303901、主函数main()的有参形式 main( int argc,char *argv ) (1) argc 命令行中参数个数参数个数(含可执行文件名)。例如: lock +|- 文件名,则形参argc=3。(2) argv指向实参字符串的指针数组。lock +|- 文

189、件名:argv0指向 “lock”, argv1 指向 “+|-”, argv2指向 “文件名”。注注:形参argcargc和argvargv,可以为其他名字。2024/7/303912、实参的来源运行带参主函数,必须在操作系统操作系统下: 可执行文件名可执行文件名 实参实参 实参实参2 2 例如:lock +|- 文件名说说明明:在TC+3.0TC+3.0的集成开发环境下,也可直接利用Run|ArgumentsRun|Arguments项,输入主函数所需要的实参:只须输入各参数(相邻参数用空格分开),可执行文件名可省略。在本案例中,输入“+|- 文件名”即可。 返回返回2024/7/3039

190、29.6 返回指针值的函数返回指针值的函数 返回指针值的函数(指针函数)定义: 函数类型函数类型 * *函数名函数名(形参表形参表) 案例案例9.13 已知某数理化三项竞赛训练组3人的各项成绩,找出其中有成绩不及格者的各项成绩。解题要求:编写函数int *seek( int (*pnt_row)3 ),如果有不及格成绩,则函数返回指向本行首列的一个(列)指针;否则,返回值为指向下一行首列的一个(列)指针。 2024/7/30393#include stdio.h#include conio.hint *seek( int (*pnt_row)3 );void main() int grade3

191、3=55, 65, 75, 65, 75, 85, 75, 80, 90 ; int i, j, *pointer;2024/7/30394 for( i = 0; i 3; i+) /*控制每个学生*/ pointer = seek( grade + i); if( pointer = = *( grade + i) ) /*该学生至少有一项不及格*/ /*输出该学生的序号和各项成绩*/ printf(No.%d grade list: , i+1); for( j = 0; j 3; j+) printf(%d , *( pointer + j) ); printf(n); getch()

192、; 返回返回2024/7/30395int *seek( int (*pnt_row)3 ) int i = 0, *pnt_col; /* (列)指针变量pnt_col */ pnt_col = * (pnt_row + 1); /*使pnt_col指向下一行之首*/ for(; i 3; i+) if( *( *pnt_row + i) 60) /*某项成绩不及格*/ pnt_col = *pnt_row; /*使pnt_col指向本行之首*/ break; return(pnt_col); 2024/7/30396本 章 要 点1 1、指针变量、指针变量(1)定义:数据类型 *指针变量,

193、*指针变量2;特别说明:悬空指针变量。(2)取地址运算 : 变量名(3)指针运算: *指针变量名2024/7/303972 2、 指针指针( (变量变量) )作函数参数作函数参数实参实参对形参形参是地址传递地址传递,形参指针变量不可改变实参指针(变量)的值,但可以改变改变它所指向的变量的值变量的值,通过不变的实参实参指针变量将变化的值保留保留下来。2024/7/303983 3、1 1维数组指针变量维数组指针变量(1)定义:int array10, *pointer = array;(2) pointer + i和array + i都是数组元素arrayi的地址。 (3)*(pointer+i

194、)和*(array+i)就是数组元素arrayi。(4) pointer + 1使指针指向数组的下下一个元素一个元素,而不是内存下一个存储单元。2024/7/30399(5)指向数组的指针变量(px和py):px n:指向从当前位置向前(+)或回退(-)n个元素(不是n个字节)的元素。 px - py:两指针之间的元素个数元素个数,不是地址之差。2024/7/304004、指针数组指针数组: 数据类型 *数组名元素个数5、有参主函数有参主函数main( int argc,char *argv ) 实参来源在操作系统下运行: 可执行文件名可执行文件名 实参实参 实参实参2 2 6 6、指针函数、

195、指针函数 函数类型 *函数名(形参表) 返回返回2024/7/30401本章作业与上机实践作业作业:1, 3 ,7 上机实践上机实践:验证本章作业。返回返回2024/7/30402第第1010章章 结构体结构体为整合不同数据类型不同数据类型、但相互关联相互关联的一组数据,C语言提供一种称为“结构体结构体”的数据结构。教学目的教学目的:掌握掌握结构体类型结构体类型的定义,结构体变量结构体变量的定义与引用,指向结构体数据的指针变量指针变量的应用;了解了解结构体数组 ,链表,枚举型,共用型,已有类型的别名定义等。2024/7/30403教学内容教学内容:10.1* 结构体类型与结构体变量的定义结构体

196、类型与结构体变量的定义10.2* 结构体变量的引用与初始化结构体变量的引用与初始化10.3 结构体数组结构体数组10.4* 指向结构体数据的指针指向结构体数据的指针本章要点本章要点本章作业与上机实践本章作业与上机实践2024/7/3040410.110.1* * 结构体类型与结构体变量的定义结构体类型与结构体变量的定义案例案例10.110.1 定义一组反映学生基本情况的结构类型,用以存储学生的相关信息。struct date /*日期结构类型*/ int year ; int month ; int day ; ;struct date /*日期结构类型*/ int year, month,

197、day ; ;2024/7/30405struct std_info/*学生信息结构类型*/ char no7; char name9; char sex3; struct date birthday; ; struct score/*成绩结构类型*/ char no7; int score1, score2, score3; ; 字符数组的长度 = 实际长度 +1 (存储结束标志)允许是已定义的另一个结构体类型结构体类型2024/7/304061、 结构体类型的定义结构体类型的定义 struct struct 结构体类型名结构体类型名 数据类型 数据项1; 数据类型 数据项2; 数据类型 数

198、据项; ;分号不能少!结构体类型关键字2024/7/30407(1)“结构体类型名”和“数据项”的命名规则,与变量名相同。(2)相同数据类型的数据项,既可逐逐个个、逐逐行行分别定义,也可合并成一行合并成一行定义。例如,案例10.1中的结构体类型date。 (3)结构体类型中的数据项,允许是已定义的另一个结构体类型结构体类型。 例如, 案例10.1中、结构体类型std_info的数据项“birthday” 。2024/7/304082、结构体变量的定义、结构体变量的定义(1)间接定义间接定义先定义类型、再定义变量例如,利用案案例例10.110.1中、结构体类型std_info,定义结构体变量st

199、udent: struct std_info student ;则结构体变量student拥有结构体类型std_info的全部数据项。结构体类型名不可缺!下列写法是错误的:struct student ;2024/7/30409(2)直接定义直接定义定义类型的同时,定义变量 struct 结构类型名结构类型名 结构变量表结构变量表;说说明明:结构类型中的数数据据项项名名(又称成成员员名名),可以与程序中的变量变量同名。返回返回2024/7/3041010.210.2* * 结构体变量的引用与初始化结构体变量的引用与初始化案例案例10.210.2 利用案例案例10.110.1中的结构体类型std

200、_info,定义结构体变量student,用于存储和显示1个学生的信息。2024/7/30411#include struct.h struct std_info student =000102,张三张三,男男,1980,9,20 ;#include stdio.h#include conio.hvoid main( ) printf(No: %sn, student . no); printf(Name: %sn, student . name); printf(Sex: %sn, student . sex); printf(Birthday: %d-%d-%dn, student.bir

201、thday. year, student.birthday. month, student.birthday. day ) ; getch(); 案例10.1中定义的结构体类型成员运算符2024/7/30412程序运行结果: No: 000102 Name: 张三 Sex: 男 Birthday: 1980-9-202024/7/304131、结构体变量成员的引用规则、结构体变量成员的引用规则(1) 基本类型基本类型: 结构变量结构变量. .成员成员例如,student.no,student.name等。(2) 结构体类型结构体类型:结构变量结构变量. .成员成员 . .成员成员 例如:stu

202、dent.birthday.year student.birthday.month student.birthday.day 本身是结构类型,只能访问它的成员2024/7/30414(3) 最低1级成员,等价同类型的普通变量。(4) 既可引用结构体变量成成员员的地址,也可引用结构变量变量的地址。例如,&student.name ,&student 。2024/7/304152、结构体变量的初始化、结构体变量的初始化 结构体变量结构体变量=初值表初值表 与1维数组相似,但结构体类型成员的初初值值,是一个初值表表。例如,struct std_info student = 000102, 张张三三,

203、 男男 , 1980,9,20 。注注:初值的数据类型,应与结构变量中相应成员所要求的一致,否则会出错。返回返回2024/7/3041610.3 10.3 结构体数组结构体数组 结构体数组的每一个元素元素,都是结构体类型结构体类型数据,均包含结构体类型的所有成员所有成员。 案例案例10.310.3 利用struct struct std_info,定义一个结构体 数组student3,用于存储和显示3个学生的基本情况。#include stdio.h#include conio.h #include struct.hstruct std_info student3 = “000102”,“张三

204、”,“男”,1980,9,20, “000105”,“李四”,“男”,1980,8,15, “000112”,“王五”,“女”,1980,3,10 ;2024/7/30417void main( ) int i; /*打印表头: 表示1个空格字符*/ printf(No.NameSexBirthdayn); for(i=0; i-no); printf(Name: %sn, p_std-name); printf(Sex: %sn, p_std-sex); printf(Birthday: %d-%d-%dn, p_std-birthday.year, p_std-birthday.month

205、, p_std-birthday.day ); getch(); -:指向结构变量成员运算符2024/7/30422如果指针变量pointer已指向结构体变量var,则以下三种形式等价三种形式等价:(1) var.成员(2) pointer -成员(3) (*pointer).成员思思考考:如果要求从键盘上输入student的各成员数据,如何修改程序?var只能是结构体变量结构体变量名pointer只能是指针变量指针变量括号不能缺!2024/7/30423void main( ) struct std_info *p_std = &student; printf(“No=”); scanf(“

206、%s”, p_std-no ); printf(year=“); scanf(“%d”, & p_std-birthday.year); 注注:无论输入或输出,最最低低级级成成员员的的性性质质(变量/指针),决定输入项或输出项表达式的性质表达式的性质。取birthday.year的地址此处不能加&。为什么?2024/7/3042410.4.2 指向指向结构体数组结构体数组的指针的指针例例10.5 使用指向结构数组的指针来访问结构数组。#include stdio.h#include conio.h#include struct.hstruct std_info student3=000102,

207、张三,男,1980,5,20, 000105,李四,男,1980,8,15, “000112”,“王五”,“女”,1980,3,10 ;void main() struct std_info *p_std = student; int i=0;指向结构数组student的指针2024/7/30425 /*打印表头*/ printf(No.NameSexBirthdayn); /*输出*/ for( ; ino, p_std-name, p_std-sex, p_std-birthday.year, p_std-birthday.month, p_std-birthday.day); getch

208、();指向结构数组的下一个元素元素,而不是当前元素的下一个成员成员2024/7/30426 10.4.3 指向结构数据的指向结构数据的指针指针作函数参数作函数参数 例例10.6 编写显示函数display(),通过主函数调用来实现例例10.5的显示。#include stdio.h#include conio.h#include struct.hstruct std_info student3=000102,张三,男,1980,5,20, 000105,李四,男,1980,8,15, “000112”,“王五”,“女”,1980,3,10 ;2024/7/30427void display(

209、struct std_info *p_std ) printf(%-7s%-9s%-4s, p_std-no, p_std-name, p_std-sex); printf(%4d-%2d-%2dn, p_std-birthday.year, p_std-birthday.month, p_std-birthday.day); 2024/7/30428void main() int i = 0; printf(No.NameSexBirthdayn); for( ; i 成员返回返回2024/7/30432 本章作业与上机实践本章作业与上机实践作业作业:2,3,4 上机实践上机实践:验证本章作

210、业。返回返回2024/7/30433第第1111章章 位运算位运算 为节省内存节省内存空间,在系统软件中常将多个标志多个标志状态位状态位,简单地组合在一起,存储到1个字个字 (节节)中。为此,语言提供了按二进制位二进制位进行运算的功能,将标志状态位从标志字节中分离分离出来。教学目的教学目的:掌握各种位运算位运算主要用途用途和实现方法方法;了解数的原码、反码和补码(数在计算机中的表示)。2024/7/30434教学内容教学内容:11.1 数值在计算机中的表示数值在计算机中的表示11.2* 位运算位运算 本章要点本章要点本章作业与上机实践本章作业与上机实践2024/7/3043511.1 11.1

211、 数值在计算机中的表示数值在计算机中的表示1、二进制位与字节、二进制位与字节1个字节个字节由8个二进制位个二进制位(bit)构成,每位的取值为0/1。自右左,从0开始,依次编号,如下图所示:01234567最低位最高位2024/7/304362、数值的原码表示、数值的原码表示将最高位最高位用作符号位符号位(0-正数,1-负数),其余各位其余各位代表数值本身的绝对值绝对值(以二进制形式表示)的表示形式。为简化描述起见,本节约定用1个字节表示1个整数。例如,+9的原码是0 0001001 -9的原码是1 0001001。 表示正数表示负数2024/7/304373、数值的反码表示、数值的反码表示(

212、1)正数正数的反码:与原码相同。例如,+9的反码是0 0001001。(2)负负数数的反码:符号位为1;其余各位,为该数绝对值的原码原码,按位取反按位取反(1变0、0变1)。例如,-9的反码:符号位 :1其余7位:|-9|的原码 = 0001001 按位取反 = 1110110-9的反码= 1 11101102024/7/304384、数值的补码表示、数值的补码表示(1)正数正数的补码:与原码相同。(2)负负数数的补码:符号位为1;其余位为该数绝对值的原码,按位取反,再加1。例如,求-9的补码:符号位:1其余7位:|-9|的原码 = 0001001 按位取反 = 1110110 再加1 = 1

213、110111 -9的补码= 1 11101112024/7/304395、数值在计算机中的表示、数值在计算机中的表示补码补码在计算机系统中,数值一律用补码表示(存储) :(1)使用补码,可以将符号位符号位和其它位其它位统一处理;(2)减法减法也可按加法加法来处理。返回返回2024/7/3044011.211.2* * 位位 运运 算算11.2.1 按位与按位与( & )11.2.2 按位或按位或( | ) 11.2.3 按位异或按位异或( ) 11.2.4 按位取反按位取反( ) 11.2.5 位左移位左移( ) 11.2.7 说明说明11.2.8 应用举例应用举例返回返回2024/7/304

214、4111.2 .1 按位与按位与(&)1. 格式:x & y2. 规则:对应位均为1时,才为1;否则为0。例如,3 & 9 = 1: 0011 & 1001 = 0001 3. 主要用途:保持1个数的某某( (些些) )位不变位不变,其余各位置置0 0。2024/7/304424. 实现方法(1) 构造1个整数:保持不变的位为1,其余为0。(2) 进行按位与操作。例如,保持9的最低位不变,其余各位置0 : 构造1个整数00000001=1 9 & 1 = 00000001。思考思考:如何保留整数x的最低2位,其余各位置0 ?返回返回2024/7/3044311.2 .2 按位或按位或( | )

215、1. 格式:x | y2. 规则:对应位均为0时才为0,否则为1。例如,3 | 9 = 11: 0011 | 1001 = 1011 (11)3. 主要用途:将1个数的某(些)位置置1,其余各位不变。2024/7/304444. 实现方法(1) 构造1个整数:置1的位上为1,其余位均为0。(2) 进行按位或操作。例如,将8的最低位置1 ,其余各位不变: 构造整数00000001=1 8 | 1 = 00001001思考思考:如何将整数x的最低2位置1 ,其余各位不变?返回返回2024/7/3044511.2 .3 按位异或按位异或()1. 格式:x y2. 规则:对应位相同时为0,不同时为1。

216、例如,39=10:0011 1001 = 1010 (10)3. 主要用途:使1个数的某(些)位翻翻转转,其余各位不变。10,012024/7/304464. 实现方法(1)构造1个整数:要翻转的位上为1,其余均为0。(2)进行按位异或操作。例如,使9的最低2位翻转,其余各位不变: 构造整数00000011=3 9 3 = 00001010。思考思考:如何使整数x的最低2位翻转,其余各位不变?返回返回2024/7/3044711.2 .4 按位取反按位取反( )1. 格式: x2. 规则:各位翻转。例如,在IBM-PC机中,00xffff,9=0xfff6。3. 主要用途:间接地构造一个全全1

217、 1的数的数( ( 0 ) 。 无论16/32位计算机,0的表达都是0。2024/7/30448例如,直接构造一个全1的数: 在IBM-PC等16位机中为0x f f f f (2字节); 在VAX-11/780等32位机中,却是0x ffff ffff (4字节)。如果用 0 来构造,系统可以自动适应。返回返回2024/7/3044911.2 .5 位左移位左移( )1. 格式:x 位数2. 规则:使操作数的各位左移,移出的高位(包括符符号位号位)舍弃,低位补0 。例如,5 2 :00 000101 000101 00 = 20 36 10 :0000,0000,0010,0100 1001

218、,00 00,0000,0000 = - 286722024/7/30450-100 )1. 格式:x 位数2. 规则:使操作数的各位右移,移出的低位舍弃;高位:对无符号数无符号数和正数正数,补0;有符号数中的负数负数,取决于所使用的系统: 补补0:称为“逻辑右移逻辑右移” 补补1:称为“算术右移算术右移”2024/7/30452例如,20 2=5, 21 2=5 。思思考考:在不溢出情况下,算算术术右移1位,意味着什么?返回返回2024/7/3045311.2 .7 说明说明1. 操作数(x、y和“位数”) :只能是整型(或字符型)数据。2. 操作数x和y参与运算时,都必须首先转换成二二进制

219、进制,然后再执行相应的按位运算位运算。3. 复合赋值位运算符除按位取反运算外,其余5个均可构成复合赋值运算符: &= |+ = =。2024/7/304544. 不同长度数据间的位运算低字节对齐低字节对齐短短数数的高字节,按最最高高位位补补位位:即负数补1;其余补0。返回返回2024/7/3045511.2.8 11.2.8 应用举例应用举例案案例例11.111.1 从键盘上输入1个正整数,给int变量num,输出由811位构成的数。算法设计算法设计:(1) 使变量num右移8位,将811位移到低4位上。(2) 构造1个低4位为1、其余各位为0的整数。(3) 与num进行按位与运算。2024/

220、7/30456#include stdio.h#include conio.hvoid main() int num, mask; printf(Input a integer number: ); scanf(%d, &num); num = 8; /*将811位移到低4位*/ mask = ( 0 4); /*低4位1、其余位0*/ printf(result=0x%xn, num & mask); getch(); 思考思考:为什么不直接使用“mask = 0x000f”? 0 :全1左移4位:低4位0,其余位1再取反 :低4位1,其余位02024/7/30457 案案例例11.211.

221、2 在PC机中,从键盘上输入1个正整数给int变量num,从高到低输出该数的各二进制位。#include stdio.h#include conio.hvoid main() int num, mask, len, i; len = 8 * sizeof( int );/*求int 型数据的二进制位数*/ mask = 1 (len - 1); /*构造最高位为1、其余位为0的屏蔽码*/ printf(Input a integer number: ); scanf(%d, &num); printf(%d = , num);2024/7/30458 for( i = 1; i = len;

222、i+) putchar( num & mask ? 1 : 0);/*输出最高位*/ num = 1; /*将次高位移到最高位上*/ if( i % 4 = 0 ) putchar(,); /*四位一组,用逗号分开*/ printf(bBn); getch(); 返回返回回退1格,用“B”(二进制后缀)覆盖掉最后一个逗号2024/7/30459本本 章章 要要 点点按位与与(&)按位或或( | )按位异或异或()按位取反取反( )按位左左移( )返回返回运算规规则则、主要用途用途与实现方法方法2024/7/30460 本章作业与上机实践本章作业与上机实践作业作业:3,5 上机实践上机实践:验证

223、本章作业。返回返回2024/7/30461第第1212章章 文文 件件在程序运行时,程序程序本身和数据数据一般都存放在内内存存中;运行结束后,数据被释放。如果需要长期保存长期保存程序运行所需的原始数据,或程序运行产生的结果,就必须以文件文件形式存储到外部存储介质上。教学目的教学目的:掌握掌握文件的打开打开、常用读写读写函数与定位定位函数;了解了解文件关闭、出错检测等函数。2024/7/30462教学内容教学内容:12.1 文件概述文件概述12.2* 文件的打开与关闭文件的打开与关闭12.3* 文件的读写操作文件的读写操作12.4* 位置指针与文件定位位置指针与文件定位12.5 出错检测出错检测

224、本章要点本章要点本章作业与上机实践本章作业与上机实践2024/7/3046312.1 12.1 文件概述文件概述1文件与文件名文件与文件名文件文件是指存放在外部存储介质存储介质上的数据集合数据集合。为标识一个文件,每个文件都必须有一个文件名文件名,其一般结构为: 主文件名主文件名.扩展名扩展名 文件命名规则,遵循操作系统操作系统的约定。文件的内容文件的类别2024/7/304642文件分类文件分类(1)根据文件的内容内容:程序程序文件 + 数据数据文件。 (2)根据文件的组织形式组织形式:顺序顺序存取文件 + 随机随机存取文件。源源文件、目标目标文件 + 可执行可执行文件2024/7/3046

225、5(3)在C语言中,根据存储形式分为:ASCIIASCII码码文件:逐个字符字符存储其ASCIIASCII码码。1个字节存储1个字符,因而便于对字符进行逐个处理,所以适合存储文本内容。如果用于存储数值,则一般占用存储空间较多,而且要花费转换时间(ASCII码与二进制之间的转换)。 2024/7/30466二进制二进制文件:内存内存中的数据,原样输出。用二进制形式存储数值,可以节省存储空间和转换时间;但1个字节并不对应1个字符,不能直接输出字符形式。 2024/7/304670110010000000000内存中的存储形式001100000011000000110001 ASCII码存储形式 (

226、1) (0) (0) 01100100二进制存储形式 例如,整数100:ASCII码形式:每位数字占用1B,共3B。 二进制形式:1个字节就够用,如下图所示:2024/7/304683读文件与写文件读文件与写文件(1)所谓读读文件是指,将磁盘文件中的数据传送到计算机内存的操作:文件文件( (磁盘) ) 内存内存(2)所谓写写文件是指,从计算机内存向磁盘文件中传送数据的操作:内存内存 文件文件( (磁盘) ) 2024/7/304694构成文件的基本单元与流式文件构成文件的基本单元与流式文件语言将文件看作是,一个字字符符(ASCII码文件)或字节字节(二进制文件)流,如下图所示:字符n-1字符i

227、字符1字符0读写指针这种文件称为流流式文件。2024/7/304705文件类型文件类型FILE系统给每个打开的文文件件都在内存中开辟一个区域,用于存放文件的有关信信息息(如文件名、文件位置等)。这些信息保存在一个FILE结构类型的变量(由系统定义)中。返回返回必须大写2024/7/3047112.212.2* * 文件的打开与关闭文件的打开与关闭对文件进行操作之前,必须先打开该文件;使用结束后,应立即关闭,以免数据丢失。12.2.1* 文件的打开文件的打开fopen()函数函数1用法: FILE * fopen (文件名文件名,操作方式操作方式);2功能:返回一个指向文件的指针。3函数原型:s

228、tdio.h 。对文件操作的库函数,函数原型均在该头文件中。2024/7/30472(1)“文件名”是指要打开(或创建)的文件名。如果使用字符数组数组( (或指针或指针),则无需双引号。如果文件不在搜索路径搜索路径下,则必须使用全称全称。(2)“操作方式”如下表所示:带绝对路径2024/7/30473打开目的ASCII码文件二进制二进制文件备 注只读(输入)rrb文件已经存在只写(输出)wwb有则删无则建向文件尾追加数据aab文件已经存在读/写文件r+a+rb+ab+文件已经存在创建新文件w+wb+有则删无则建2024/7/30474(3)如果打开操作失失败败,则fopen()函数返回一个空空

229、指针指针NULL (其值在头文件stdio.h中被定义为)。为增强程序可靠性,常用如下方法打开一个文件:if( ( fp = fopen(文件名文件名,操作方式操作方式) )=NULL) printf(can not open this filen); exit(0); 关闭所有打开的文件,结束程序运行。2024/7/3047512.2.2 文件的关闭文件的关闭fcolse()函数函数1用法: int fclose(FILE *文件指针文件指针);2功能:关闭“文件指针”所指向的文件。3函数返回值:正常关闭,返回值为;否则,返回值为非。例如,fclose( fp );/*关闭fp所指向的文件*

230、/返回返回2024/7/3047612.312.3* * 文件的读文件的读/ /写操作写操作文件打开之后,就可以对它进行读/写操作了。12.3.1 读写一个字符读写一个字符12.3.2 读写一个字符串读写一个字符串12.3.3 读写一个数据块读写一个数据块12.3.4 格式化读写格式化读写12.3.5 读写函数的选用原则读写函数的选用原则返回返回2024/7/3047712.3.1 12.3.1 读写一个字符读写一个字符1写写1个字符到文件中个字符到文件中fputc()函数函数案例案例12.112.1 从键盘上输入一个字符串(以“”作为结束字符),以ASCII码形式存储到一个磁盘文件diskf

231、ile.txt中。 2024/7/30478#include stdio.h#include conio.hvoid main( ) FILE *fp; char ch; if ( ( fp = fopen(diskfile.txt, w) ) = = NULL) printf(can not open this file, press any key to exit.); getch(); exit(0); /*输入字符,并存储到指定文件中*/ for( ; ( ch = getchar() ) != ; ) fputc( ch, fp ); fclose(fp); Next必须大写2024

232、/7/30479 库函数库函数fputc()(1)用法:int fputcfputc(字符数据字符数据,文件指针文件指针);(2)功能:将字符数据写到指定文件中,并将读读/写位置指针写位置指针向前移动1个字节(即指向下一个写入位置)。(3)返回值: 输出成功,返回输出的字符数据; 输出失败,返回一个符号常量EOF(其值在头文件stdio.h中,被定义为-1)。返回程序常量常量 / 变量变量注:所有读写函数均自动自动调整该 指针,到下一个读写位置。2024/7/304802从文件中读从文件中读1个字符个字符fgetc() 和和feof()函数函数案案例例12.2 顺序显示案案例例12.1创建的磁

233、盘文件diskfile.txt。 2024/7/30481#include stdio.h#include conio.hvoid main( ) FILE *fp; char ch; if ( ( fp = fopen(diskfile.txt, r) ) = = NULL) printf(can not open source file, press any key to exit.); getch(); exit(0); for(; ( ch = fgetc(fp) ) != EOF; ) putchar( ch ); fclose(fp); getch(); Next2024/7/30

234、482 库函数库函数fgetc() (1)用法:int fgetcfgetc( 文件指针文件指针 ); (2)功能:从指定文件中读1个字符,并将读写位置指针向前移动1个字节。该函数无出错返回值。例如:ch = fgetc ( fp );返回程序2024/7/30483 符号常量符号常量EOF 在对ASCIIASCII码码文文件件执行读读入操作时,如果遇到文文件件尾尾,则返回一个文件结束标志EOFEOF(其值在头文件stdio.h中被定义为-1)。End Of File,只适用于ASCII码文件2024/7/30484 库函数库函数feof()(1)用法:int feoffeof( 文件指针文件

235、指针 ) ;(2)功能:在执行读读文件操作时,如果遇到文件文件尾尾,则函数返回逻辑真真(1);否则,则返回逻辑假假(0)。feof()函数同时适用于ASCII码文件和二进制文件二进制文件(只能使用该函数,不能使用EOFEOF)。返回程序2024/7/30485 案案例例12.3 设计一个程序:实现制作任意1个ASCII码文件的副本(文件名由用户任意指定)。 算法设计要点:(1) 制作副本可以有两种方法:一种是使用带参主函数;另一种是在程序运行时,提示用户输入文件名。本案例采用第一种方法。(2) 首先校验参数个数,然后依次打开、并校验源文件和目标文件,如果校验均通过,则进行复制操作。 2024/

236、7/30486/*使用格式:可执行文件名可执行文件名 源文件名源文件名 目标文件名目标文件名*/#include stdio.h#include conio.hvoid main(int argc, char *argv) FILE *input, *output; char ch; if( argc != 3) printf(参数个数不对n); printf(n Usage: 可执行文件名 source-file dest-file); exit(0); 源文件指针目标文件指针2024/7/30487 if ( input=fopen(argv1,r) )=NULL) /*打开源文件失败*/

237、 printf(can not open source filen); exit(0); if (output=fopen(argv2,w)=NULL) /*创建目标文件失败*/ printf(can not create destination filen); exit(0); /*复制源文件到目标文件中*/ for( ; ( ! feof(input) ) ; ) fputc( fgetc(input), output ); fclose(input); fclose(output);/*关闭文件*/返回返回2024/7/3048812.3.2 12.3.2 读写一个字符串读写一个字符串f

238、gets()fgets()和和fputs()fputs()案例案例12.4 密码管理程序。要求:(1)密码设置(密码长度612个字符);(2)加密存储到1个ASCII码文件中;(3)登录密码校验。算法设计要点:算法设计要点:(1)密码设置(密码长度612个字符):请参阅案例6.6。2024/7/30489(2)加密存储到1个ASCII码文件:字符串加密,请参阅案例6.4。本案例直接利用fputs()函数,将加密后的密文写入密码文件password.txt。 (3)登录密码校验:首先提示用户输入输入密码,然后使用同一加密算法对用户输入的密码字符串进行加密加密,再与密码文件中存储的密文密文比较。为

239、突出本案例重点对文件的读写操作,密码设置和密码串加密,留给读者自己设计和实现,本案例对密码字符串进行不加密存储和校验。 2024/7/30490#include stdio.h#include conio.hvoid main( ) FILE *fp; char password13, password213; if ( ( fp = fopen(password.txt, w) ) = NULL) printf(n can not open this file, press any key to exit.); getch(); exit(0); 2024/7/30491 /*设置、并存储密

240、码*/ printf(n Setup a password(6-12 characters): ); gets(password); fputs( password, fp ); fclose(fp); /*重新打开密码文件,读出密码字符串用于登录校验*/ if ( ( fp = fopen(password.txt, r) ) = NULL) printf(n can not open this file, press any key to exit.); getch(); exit(0); fgets( password, 13, fp ); fclose(fp);2024/7/30492

241、 printf(n Input the password(6-12 characters): ); gets( password2 ); if( strcmp(password2, password) = = 0 )/*密码正确*/ printf(n The password is correct, press any key to continue.); else printf(n The password is incorrect, press any key to exit.); getch( ); 返回返回2024/7/30493 库函数库函数fputs()向指定文件输出一个字符串向指

242、定文件输出一个字符串用法:int fputs(fputs(字符串,文件指针字符串,文件指针) );功能:向指定文件输出一个字符串,并将读写位置指针向前移动length(串长)个字节。如果输出成功,则函数返回值为0;否则,为非0值。返回程序返回程序2024/7/30494 库函数库函数fgets()从文件中读一个字符串从文件中读一个字符串 用法:char *fgetsfgets( 指针,串长指针,串长+1+1,文件指针,文件指针 ); 功能:从指定文件中读入一个字符串,存入“字符数组/指针”中,并在尾端自动加一个结束标志0;同时,将读写位置指针向前移动length(串长)个字节。 注注:如果在读

243、入规定长度之前,遇到文件尾EOF或换行符,读入即结束。返回程序返回程序为结束标志预留2024/7/3049512.3.3 12.3.3 读读/ /写一个数据块写一个数据块fread()fread()和和fwrite()fwrite()实际应用中,常常要求1次读写1个数据块。 1读1个数据块fread( )int fread(void *buffer,int size,int count,FILE *fp);从fp所指向文件的当前位置开始,一次读入size个字节,重复count次,并将读入的数据存放到从buffer(起始地址)开始的内存中;同时,将读写位置指针向前移动size* count个字节

244、。2024/7/304962 写1个数据块fwrite ()int fwrite( void *buffer,int size,int count,FILE *fp);从buffer开始,一次输出size个字节,重复count次,并将输出的数据存放到fp所指向的文件中;同时,将读写位置指针向前移动size* count个字节。如果调用fread()或fwrite()成功,则函数返回值等于count。fread()和fwrite()函数,一般用于二进制文件二进制文件。返回返回2024/7/3049712.3.4 12.3.4 格式化读格式化读/ /写写fscanf()fscanf()和和fpri

245、ntf()fprintf()函数函数与scanf()和printf() 功能相似,区别在于:操作对象不同:scanf()和printf():标准输入(stdin)输出(stdout)文件。 fscanf()和fprintf():指定文件。int fscanf(文件指针,格式符,输入变量首地址表);int fprintf(文件指针,格式符,输出表达式表);2024/7/30498例如:int i=3; float f=9.80; . fprintf( fp, %2d, %6.2f, i, f ) ; . fprintf()函数的作用是,将变量i按%2d格式、变量f按%6.2f格式,以逗号作分隔符

246、,输出到fp所指向的文件中:3,9.80(表示1个空格)。返回返回2024/7/3049912.3.5 12.3.5 读写函数的选用原则读写函数的选用原则从功能角度来说,fread()和fwrite()函数可以完成对文件的任何操作。为方便起见,依下列原则选用:1读/写1个字符个字符(或字节) :选用fgetc()和fputc() 。2读/写1个个字符串串:选用fgets()和fputs()。3读/写1个(或多个)不不含含格格式式的数据:选用fread()和fwrite()。 4读/写1个(或多个)含含格格式式的数据:选用fscanf()和fprintf()。返回返回2024/7/3050012

247、.4 12.4 位置指针与文件定位位置指针与文件定位每个文件都有一个读读/写位置指针写位置指针,指向当前读写位置。每次读读/写写后,系统自动自动将位置指针移动到下一个下一个读/写位置上。如果想改变系统这种读写规律,可使用文件定位函数。2024/7/3050112.4.1 12.4.1 位置指针复位函数位置指针复位函数rewind()rewind()1用法:int rewind( 文件指针文件指针 ) ;2功能:使文件的位置指针返回到文件头文件头。2024/7/3050212.4.212.4.2* * 随机读写与随机读写与fseek()fseek()函数函数对于流式文件,既可以顺序读写,也可随机

248、读写,关键在于控制文件的位置指针。顺序读写顺序读写:读写完当前数据后,系统自动将文件的位置指针,移动到下一个读写位置上。随随机机读读写写:读写完当前数据后,通过fseek()函数,将位置指针移动到文件中的任何一个地方。2024/7/305031用法:int fseek(文件指针,位移量,参照点文件指针,位移量,参照点 );2功能:将指定文件的位位置置指指针针,从参参照照点点开始,移动指定的位移量位移量。(1)参参照照点点:用0(文件头)、1(当前位置)和2(文件尾)表示。在ANSI C标准中,还规定如下符号常量: SEEK_SET文件头, SEEK_CUR当前位置, SEEK_END文件尾20

249、24/7/30504(2)位位移移量量:以参参照照点点为起点,向前(位移量)或后(位移量)移动的字节数。在ANSI C标准中,要求位移量为long int数据。假设文件的当前位置指针指向50(从0 0开始编号),则:fseek(fp, 10, 0):将位置指针移动到10;fseek(fp, 10, 1):将位置指针移动到60。实际应用建议实际应用建议:最好使用文件头文件头作为参照点。2024/7/3050512.4.3 12.4.3 返回文件当前位置的函数返回文件当前位置的函数ftell()ftell()文件的位置指针可任意移动,也经常移动,往往容易迷失当前位置,ftell()就可以解决这个问

250、题。1用法:long ftell( 文件指针文件指针 ) ;2功能:返回文件位置指针的当前位置(用相对于文件头文件头的位移量表示)。如果返回值为-1L,则表明调用出错。例如: offset = ftell( fp ); if( offset = = -1L ) printf(“ftell() errorn”);返回返回2024/7/3050612.5 12.5 出错检测出错检测12.5.1 ferror()12.5.1 ferror()函数函数在调用I/O库函数时,如果出错,除函数返回值函数返回值有所反映外,也可利用ferror()函数来检测。1用法: int ferror(文件指针文件指针)

251、; 2功能:返回0未出错;返回非0出错。(1) 每次调用I/O函数,均产生一个新的ferror()值,所以应立即检测,否则出错信息会丢失。(2)在执行fopen()函数时,系统将ferror()的值自动置为0。2024/7/3050712.5.2 clearerr()12.5.2 clearerr()函数函数1用法: void clearerr(文件指针文件指针);2功能:将ferror()和feof()函数值置为0。对同一文件,只要出错就一直保留,直至遇到clearerr()函数或rewind()函数,或其它任何一个输入输出库函数。返回返回2024/7/30508本本 章章 小小 结结1 重点掌握以下11个库函数:fopen()fgetc()、fputc()fgets()、fputs()fread()、fwrite()fscanf()、fprintf()feof(),fseek()2024/7/305092 程序可靠性可靠性和人机交互性人机交互性衡量程序质量的2个重要指标自动校验自动校验输入数据是否正确,判断判断文件操作是否成功,并进行相应提示提示和处理,可有效地提高程序的可靠性和人机交互性。返回返回2024/7/30510 本章作业与上机实践本章作业与上机实践作业作业:4,8,9 上机实践上机实践:验证本章作业。返回返回

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号