C语言知识点串讲.ppt

上传人:M****1 文档编号:570548225 上传时间:2024-08-05 格式:PPT 页数:185 大小:704.50KB
返回 下载 相关 举报
C语言知识点串讲.ppt_第1页
第1页 / 共185页
C语言知识点串讲.ppt_第2页
第2页 / 共185页
C语言知识点串讲.ppt_第3页
第3页 / 共185页
C语言知识点串讲.ppt_第4页
第4页 / 共185页
C语言知识点串讲.ppt_第5页
第5页 / 共185页
点击查看更多>>
资源描述

《C语言知识点串讲.ppt》由会员分享,可在线阅读,更多相关《C语言知识点串讲.ppt(185页珍藏版)》请在金锄头文库上搜索。

1、计算机二级计算机二级C语言程序设计语言程序设计知识点串讲知识点串讲一、一、C语言程序的结构语言程序的结构1.程序的构成,程序的构成,main函数和其他函数。函数和其他函数。2.头文件,数据说明,函数的开始和结束头文件,数据说明,函数的开始和结束标志以及程序中的注释。标志以及程序中的注释。3.源程序的书写格式。源程序的书写格式。4.C语言的风格。语言的风格。8/5/20242目标目标l熟记熟记C语言的基本概念语言的基本概念l熟悉熟悉VC+6.0的上机操作环境的上机操作环境l会读、会编、会调试程序会读、会编、会调试程序8/5/20243 C语言结构特点语言结构特点: (1)C程序是由函数构成的。程

2、序是由函数构成的。(2)一个函数由两部分组成:一个函数由两部分组成:函数的首部和函数体函数的首部和函数体。(3)main函函数数通通常常位位于于程程序序之之首首,实实际际上上它它位位于于程程序序的的开开头头、最最后后及及函函数数与与函函数数之之间间均均是是合合法法的的,但但不不管管在在什什么么位置,一个位置,一个C程序总是从程序总是从main函数开始执行的。函数开始执行的。(4)C程程序序书书写写格格式式自自由由,一一行行内内可可以以写写几几个个语语句句,一一个语句可以分写在多行上。个语句可以分写在多行上。(5)每条语句以分号结束,分号是语句的必要组成部分。每条语句以分号结束,分号是语句的必要

3、组成部分。(6)C语言本身没有输入输出语句。语言本身没有输入输出语句。(7)可可以以用用/*/对对C程程序序中中的的任任何何部部分分作作注注释释,它它可可增加程序的可读性。增加程序的可读性。8/5/20244C语言的基本词法语言的基本词法1.标识符标识符标识符是以字母、数字和下划线组成的,但第一标识符是以字母、数字和下划线组成的,但第一个字符必须是字母或下划线。而且字母区分大小写。个字符必须是字母或下划线。而且字母区分大小写。2.关键字关键字关键字又称保留字,关键字又称保留字,C语言编译系统对关键字语言编译系统对关键字赋有专门的含义。赋有专门的含义。TurboC共有共有43个关键字。个关键字。

4、3.字符集字符集C语言的字符集包括:大小写英文字母、数字、语言的字符集包括:大小写英文字母、数字、下划线及下划线及*/,;?;?“.&|()等,等,还有不可打印字符空格、换行符、制表符。还有不可打印字符空格、换行符、制表符。8/5/20245函数的一般结构函数的一般结构 任任何何函函数数(包包括括主主函函数数main())都都是是由由函函数数说说明明和和函函数数体体两两部部分组成。其一般结构如下:分组成。其一般结构如下:函数返回值的类型函数返回值的类型函数名函数名(函数参数表函数参数表)说明语句部分;说明语句部分;执行语句部分;执行语句部分;函数首部函数体函数返回值的类型函数返回值的类型函数名

5、函数名函数参数表函数参数表intmax(intx,inty)8/5/20246C语言的语句和关键字(一) C语言的语句 与与其其它它高高级级语语言言一一样样,语语言言也也是是利利用用函函数数体体中中的的可可执执行行语语句句,向向计计算算机机系系统统发发出出操操作作命命令令。按按照照语语句句功功能能或或构构成成的的不不同,可将语言的语句分为五类。同,可将语言的语句分为五类。1.控制语句控制语句控控制制语语句句完完成成一一定定的的控控制制功功能能。语语言言只只有有条条控控制制语语句句,又可细分为三种:又可细分为三种:(1)选择结构控制语句)选择结构控制语句if()else,switch()(2)循

6、环结构控制语句循环结构控制语句dowhile(),for(),while(),break,continue8/5/20247(3)其它控制语句)其它控制语句goto,return2. 函数调用语句函数调用语句由一次函数调用加一个分号(语句结束标志)函数调用语句由一次函数调用加一个分号(语句结束标志)构成。构成。3. 表达式语句表达式语句由表达式后加一个分号构成。最典型的表达式语表达式语句由表达式后加一个分号构成。最典型的表达式语句是,在赋值表达式后加一个分号构成的赋值语句。句是,在赋值表达式后加一个分号构成的赋值语句。4. 空语句空语句仅由一个分号构成。显然,空语句什么操作也不执行。空语句仅由

7、一个分号构成。显然,空语句什么操作也不执行。5. 复合语句复复合合语语句句是是由由大大括括号号括括起起来来的的一一组组(也也可可以以是是1条条)语语句句构构成。成。8/5/20248运行C的步骤与方法1.编辑:选择适当的编辑程序编辑:选择适当的编辑程序,将将C语言源程序通过键语言源程序通过键盘输入到计算机中盘输入到计算机中,并以文件的形式存入到并以文件的形式存入到磁盘中(磁盘中(.C)2.编译:即将源程序翻译成机器语言程序的过程。编编译:即将源程序翻译成机器语言程序的过程。编译出来的程序称为目标程序(译出来的程序称为目标程序(.OBJ)3.连接:编译后生成的目标文件经过连接后生成最终连接:编译

8、后生成的目标文件经过连接后生成最终的可执行程序(的可执行程序(.EXE)8/5/20249二、数据类型及其运算二、数据类型及其运算 1.C的数据类型(基本类型,构造类型,指针类型,的数据类型(基本类型,构造类型,指针类型,无值类型)及其定义方法。无值类型)及其定义方法。2.C运算符的种类、运算优先级和结合性。运算符的种类、运算优先级和结合性。3.不同类型数据间的转换与运算。不同类型数据间的转换与运算。4.C表达式类型(赋值表达式,算术表达式,关系表达式类型(赋值表达式,算术表达式,关系表达式,逻辑表达式,条件表达式,逗号表达式)和求表达式,逻辑表达式,条件表达式,逗号表达式)和求值规则。值规则

9、。8/5/202410l一般用大写字母一般用大写字母l是宏定义预处理命令,不是是宏定义预处理命令,不是C语句语句直接常量直接常量: :l整型常量整型常量 l实型常量实型常量 l字符常量字符常量 l字符串常量字符串常量常量常量l定义:程序运行时其值不能改变的量(即常数)定义:程序运行时其值不能改变的量(即常数)l分类分类: :符号常量符号常量: :用标识符代表常量用标识符代表常量l定义格式:定义格式: #define #define 符号常量符号常量 常量常量8/5/202411变量变量l概念:其值可以改变的量l变量名与变量值l变量说明的一般格式:l 数据类型 变量1,变量2,变量n;l变量的显

10、式初始化:说明时赋初值l变量的使用:先说明,后使用l变量定义位置:一般放在函数开头8/5/202412l数据类型数据类型数据类型总表C C数数据据类类型型基本类型基本类型构造类型构造类型指针类型指针类型空类型空类型void定义类型定义类型typedef字符类型char枚举类型enum整 型实型单精度型float双精度型double数组结构体struct共用体union短整型short长整型long整型int数据类型决定:1. 数据占内存字节数2. 数据取值范围3. 其上可进行的操作8/5/202413l不同类型数据间的转换不同类型数据间的转换隐式转换隐式转换l什么情况下发生什么情况下发生运算转

11、换运算转换-不同类型数据混合运算时不同类型数据混合运算时赋值转换赋值转换-把一个值赋给与其类型不同的变量时把一个值赋给与其类型不同的变量时输出转换输出转换-输出时转换成指定的输出格式输出时转换成指定的输出格式函数调用转换函数调用转换-实参与形参类型不一致时转换实参与形参类型不一致时转换l运算转换规则运算转换规则: :不同类型数据运算时先不同类型数据运算时先自动自动转换转换成同一类型成同一类型8/5/202414doublefloatlongunsignedintchar,short低高显式转换(强制转换)显式转换(强制转换)一般形式:一般形式:(类型名类型名)(表达式)表达式)例例(int)(

12、x+y)(int)x+y(double)(3/2)(int)3.68/5/202415l运算符和表达式运算符和表达式C运算符算术运算符:(算术运算符:(+ - * / % + -+ - * / % + -)关系运算符:(关系运算符:( = != = !=)逻辑运算符:(!逻辑运算符:(! & |& |)位运算符位运算符 :(:( | & | &)赋值运算符:(赋值运算符:(= = 及其扩展)及其扩展)条件运算符:(条件运算符:(?:?:)逗号运算符:(逗号运算符:(, ,)指针运算符:(指针运算符:(* * & &)求字节数求字节数 :(:(sizeofsizeof)强制类型转换:(类型)强制

13、类型转换:(类型)分量运算符:(分量运算符:(. -. -)下标运算符:(下标运算符:()其它其它 :(:(( ) ( ) )8/5/202416学习运算符应注意:学习运算符应注意:l运算符功能运算符功能l与运算量关系与运算量关系要求运算量个数要求运算量个数要求运算量类型要求运算量类型l运算符优先级别运算符优先级别l结合方向结合方向 l结果的类型结果的类型8/5/202417算术运算符和表达式算术运算符和表达式l基本算术运算符:基本算术运算符: + + - - * / %* / %结合方向:从左向右结合方向:从左向右优先级:优先级: ( (正负正负) ) + -+ - - -* / %* /

14、% - - + - + - ( (加减加减) ) (2) (3) (4) (2) (3) (4)说明:说明:“+ +”、“-”“-”可为可为单目单目运算符时运算符时, ,右结合性右结合性两整数相除,结果为整数两整数相除,结果为整数% %要求两侧均为整型数据要求两侧均为整型数据l自增、自减运算符+ -+ -作用:使变量值加1或减1种类:l前缀式 +i, -i (先执行i+1或i-1,再使用i值)l后缀式 i+,i- (先使用i值,再执行i+1或i-1)8/5/202418赋值运算符和表达式赋值运算符和表达式l简单赋值运算符简单赋值运算符符号:符号: = =格式:格式: 变量标识符变量标识符= =

15、表达式表达式作用:将一个数据(常量或表达式)赋给一个变量作用:将一个数据(常量或表达式)赋给一个变量l复合赋值运算符复合赋值运算符种类种类:+= -= *= /= %=+= -= *= /= %= = &= = |= &= = |=含义:含义: exp1 op= exp2exp1 op= exp2 exp1 = exp1 op exp2exp1 = exp1 op exp2a+=3a=a+3x*=y+8x=x*(y+8)x%=3x=x%38/5/202419顺序求值运算符(逗号运算符)和表达式顺序求值运算符(逗号运算符)和表达式l形式:形式:表达式表达式1,表达式表达式2,表达式表达式nl结合

16、性结合性:从左向右从左向右l优先级优先级:15l逗号表达式逗号表达式的值:等于表达式的值:等于表达式n的值的值l用途:用途:常用于循环常用于循环for语句中语句中8/5/202420关系运算符和表达式关系运算符和表达式关系运算符关系运算符种类种类:=!=结合方向:自左向右结合方向:自左向右优先级别:优先级别:=!=优先级优先级6(高)(高)优先级优先级7(低)(低)关系表达式的值:是逻辑值关系表达式的值:是逻辑值“真真”或或“假假”,用,用1和和0表表示示8/5/202421逻辑运算符和表达式逻辑运算符和表达式l逻辑运算符逻辑运算符种类:种类:!&|逻辑运算真值表逻辑运算真值表C C语言中语言

17、中, ,运算量运算量: : 0 0表示表示“假假”, 非非0 0表示表示“真真”,”, 运算结果运算结果: : 0 0表示表示“假假”, 1 1表示表示“真真”,”,8/5/202422条件运算符与表达式条件运算符与表达式l一般形式:一般形式:expr1?expr2:expr3l执行过程执行过程l功能:相当于条件语句,但不能取代一般功能:相当于条件语句,但不能取代一般if语句语句l条件运算符可嵌套条件运算符可嵌套如如x0?1:(x0?-1:0)l优先级优先级:13l结合方向:结合方向:自右向左自右向左8/5/202423三、基本语句三、基本语句1.表达式语句,空语句,复合语句。表达式语句,空语

18、句,复合语句。2.输入输出函数的调用,正确输入数据并输入输出函数的调用,正确输入数据并正确设计输出格式。正确设计输出格式。8/5/202424说明说明1、所谓输入输出是以计算机为主体而言的。、所谓输入输出是以计算机为主体而言的。2、输入输出操作是由函数实现的。、输入输出操作是由函数实现的。标准输入标准输入输出函数输出函数putchar( ) getchar( )puts( ) gets( )printf( ) scanf( )预编译命令预编译命令在使用在使用C语言库函数时,要用预编译命令语言库函数时,要用预编译命令#include将有关的将有关的头文件头文件包括到用户源文件包括到用户源文件中。

19、中。举例举例#include main() printf(Hello! );#include stdio.h注:在注:在TC环境中,若使用环境中,若使用printf()或或scanf()函数,则前面的预编译命令可以省略!函数,则前面的预编译命令可以省略!在在VC+环境中不能省略环境中不能省略!(一)、C的输入与输出8/5/202425格式格式printf(格式控制格式控制字符串字符串 ,输出列表,输出列表);说明说明1、格式控制字符串格式控制字符串是用双撇号引起来的字符串,是用双撇号引起来的字符串,包括三种信息:包括三种信息:(1)格式说明:由)格式说明:由%和和格式字符格式字符组成。组成。(

20、如如%d、%f)(2)普通字符:需要按原样输出的字符。普通字符:需要按原样输出的字符。(3)转义字符:)转义字符:(如如t、n、b、r等等)2、输出列表输出列表是需要输出的一些数据,可以是表达是需要输出的一些数据,可以是表达式。式。将输出的数据转换为将输出的数据转换为指定的格式输出。指定的格式输出。(二)、格式输出printf函数作用作用向终端向终端(或系统默认的输出设备)(或系统默认的输出设备)输出输出若干个若干个任意任意类型类型的数据的数据。8/5/202426格式说明必须以格式说明必须以开始,以格式字符结束。开始,以格式字符结束。一般形式如下:一般形式如下:%标志标志宽度宽度.精度精度l

21、格式字符格式字符- -nmd/f/c/u/s等等长整型整数长整型整数输出数据输出数据向左靠拢向左靠拢输出数据输出数据最小最小宽度宽度对实数:输出对实数:输出小数点位数;小数点位数;对字符串:截对字符串:截取字符的个数取字符的个数格式说明的一般形式8/5/202427格式格式字符字符格式字符格式字符格式说明格式说明d, i 以带符号的十进制数输出整数以带符号的十进制数输出整数(正数不输出符号正数不输出符号)c 以字符形式输出以字符形式输出,只输出一个字符只输出一个字符f 以小数形式输出单、双精度数,隐含以小数形式输出单、双精度数,隐含6位小数位小数e,E 以指数形式输出实数以指数形式输出实数o

22、以以八进制无符号形式输出整数(不输出前导符八进制无符号形式输出整数(不输出前导符0)x,X 以以十六进制无符号形式输出整数(不输出前导符十六进制无符号形式输出整数(不输出前导符0x) 附加附加格式格式说明说明字符字符字符字符说明说明l 用于长整型数据输出,可加在用于长整型数据输出,可加在d o x u 前面前面m 数据最小宽度数据最小宽度n 对实数,表示输出对实数,表示输出n位小数;对字符串,表示位小数;对字符串,表示 截取的字符个数截取的字符个数- 输出数据向左靠拢输出数据向左靠拢格式字符8/5/202428格式格式scanf(格式控制格式控制字符串字符串 ,地址地址列表列表);说明说明1、

23、格式控制字符串格式控制字符串与与printf函数类似。可以包含以下三种函数类似。可以包含以下三种类型类型 的信息:的信息:格式说明:与格式说明:与printf类似,以开始,以一个格式字符类似,以开始,以一个格式字符结束;结束;空白字符(空格、空白字符(空格、t、n):):输入多个数据时的缺省分输入多个数据时的缺省分隔符,可以省略,在输入数据时可以以任一种空白字符分隔符,可以省略,在输入数据时可以以任一种空白字符分隔;隔;普通字符(普通字符(照原样输入照原样输入)。)。2、地址地址表列表列是由是由若干个地址组成的列表,各地址之间用逗若干个地址组成的列表,各地址之间用逗号分隔。如变量的地址表示为:

24、号分隔。如变量的地址表示为:&变量名。变量名。(三)、格式输入scanf函数作用作用从终端从终端(或系统默认的输入设备)(或系统默认的输入设备)输入输入若干个任意类型若干个任意类型的数据的数据。8/5/202429例例1从键盘输入一个大写字母,转换成相应的小写字母输出。从键盘输入一个大写字母,转换成相应的小写字母输出。#include void main() char c1,c2; /增强人机交互性。增强人机交互性。 printf(请输入一个大写字母:请输入一个大写字母:); c1=getchar(); printf(%c,%dn,c1,c1); c2=c1+32; printf(%c,%dn

25、,c2,c2);请输入一个大写字母:请输入一个大写字母:A A,65a,97四、顺序结构程序设计 (写程序结果)在顺序结构程序中,各语句(或命令)是按照位置的先在顺序结构程序中,各语句(或命令)是按照位置的先后次序,顺序执行的,且每条语句都会被执行到。后次序,顺序执行的,且每条语句都会被执行到。运行情况:运行情况:8/5/202430四、选择结构程序设计四、选择结构程序设计1.用用if语句实现选择结构。语句实现选择结构。2.用用switch语句实现多分支选择结构。语句实现多分支选择结构。3.选择结构的嵌套。选择结构的嵌套。8/5/202431if语句语句1.If语句的三种基本形式(1)if (

26、表达式) 语句例: if(xy) printf(“%d”,x);表达式语句真(非0)假(0)8/5/202432if语句语句(2)if(表达式) 语句1 else 语句2例: if (xy) printf(“%d”,x); else printf(“%d”,y); 条件条件语句句1语句句2YN8/5/202433if语句语句(3)if(表达式1)语句1 else if(表达式2)语句2 else if(表达式3)语句3 else if(表达式m)语句m else 语句n8/5/202434if语句语句2.If语句的嵌套在if语句中又包含一个或多个if语句称为if语句的嵌套。形式:If()if(

27、) if() 语句语句1 1else else 语句语句2 2Elseif() 语句3else 语句4内嵌内嵌ififElse总是与它上面的,最近的,统一复合语句中的,未配对总是与它上面的,最近的,统一复合语句中的,未配对的的if语句配对。语句配对。8/5/202435switch语句语句switch语句的格式:switch (表达式) case常量表达式:语句 case常量表达式:语句 case常量表达式:语句 default :语句 8/5/202436l五、循环结构程序设计五、循环结构程序设计1.for循环结构。循环结构。2.while和和do-while循环结构。循环结构。3.cont

28、inue语句和语句和break语句。语句。4.循环的嵌套。循环的嵌套。8/5/202437用用while语句实现循环语句实现循环注意:注意:(1)(1)循环体如果包含一个以上的语循环体如果包含一个以上的语句,应该用花括弧括起来,以句,应该用花括弧括起来,以复合语句形式出现。复合语句形式出现。 (2)(2)在循环体中应有使循环趋向于在循环体中应有使循环趋向于结束的语句。如果无此语句,结束的语句。如果无此语句,则则i i的值始终不改变,循环永不的值始终不改变,循环永不结束。结束。8/5/202438用用do-while语句实现循环语句实现循环 do-whiledo-while语句的特点语句的特点:

29、 :先先执行循环体,然后判断循执行循环体,然后判断循环条件是否成立。环条件是否成立。 一般形式一般形式: do : do 循环体语句循环体语句 while (while (表达式表达式) );8/5/202439用用for语句实现循环语句实现循环lC C语言中的语言中的forfor语句使用最为灵活,不仅可以用于循环次语句使用最为灵活,不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定而只数已经确定的情况,而且可以用于循环次数不确定而只给出循环结束条件的情况,它完全可以代替给出循环结束条件的情况,它完全可以代替whilewhile语句。语句。l一般形式一般形式: : for( for

30、(表达式表达式1 1;表达式;表达式2 2;表达式;表达式3) 3) 语句语句8/5/2024408/5/202441循环的嵌套循环的嵌套l一个循环体内又包含另一个完整的循环结构一个循环体内又包含另一个完整的循环结构 称为循环的嵌套。内嵌的循环中还可以嵌套称为循环的嵌套。内嵌的循环中还可以嵌套 循环,这就是多层循环。循环,这就是多层循环。l三种循环三种循环(while(while循环、循环、do-whiledo-while循环和循环和forfor循循 环环) )可以互相嵌套。可以互相嵌套。8/5/202442循环的嵌套循环的嵌套l下面几种都是合法的形式:(1) while( ) (2) do

31、(3) for(;)(1) while( ) (2) do (3) for(;) while( ) do for(;) while( ) do for(;) while( ); while( ); while( ); while( ); 8/5/202443循环的嵌套循环的嵌套(4) while( ) (5) for(;) (6) do(4) while( ) (5) for(;) (6) do do while( ) for(;) do while( ) for(;) while( ) while( ) while( ) while( ) 8/5/202444几种循环的比较几种循环的比较(1

32、)(1)四种循环都可以用来处理同一问题,一般情况下它四种循环都可以用来处理同一问题,一般情况下它们可以互相代替。但一般不提倡用们可以互相代替。但一般不提倡用gotogoto型循环。型循环。(2)(2)在在whilewhile循环和循环和do-whiledo-while循环中,只在循环中,只在whilewhile后面的后面的括号内指定循环条件,因此为了使循环能正常结束,括号内指定循环条件,因此为了使循环能正常结束,应在循环体中包含使循环趋于结束的语句应在循环体中包含使循环趋于结束的语句( (如如i+i+,或或i=i+1i=i+1等等) )。8/5/202445几种循环的比较几种循环的比较 for

33、for循环可以在表达式循环可以在表达式3 3中包含使循环趋于结束的操中包含使循环趋于结束的操作,甚至可以将循环体中的操作全部放到表达式作,甚至可以将循环体中的操作全部放到表达式3 3中。中。因此因此forfor语句的功能更强,凡用语句的功能更强,凡用whilewhile循环能完成的,循环能完成的,用用forfor循环都能实现。循环都能实现。 (3)(3)用用whilewhile和和do-whiledo-while循环时,循环变量初始化的操循环时,循环变量初始化的操作应在作应在whilewhile和和do-whiledo-while语句之前完成。而语句之前完成。而forfor语句语句可以在表达式

34、可以在表达式1 1中实现循环变量的初始化。中实现循环变量的初始化。8/5/202446几种循环的比较几种循环的比较(4)while(4)while循环、循环、do-whiledo-while循环和循环和forfor循环,可以循环,可以用用breakbreak语句跳出循环,用语句跳出循环,用continuecontinue语句结束本语句结束本次循环次循环(break(break语句和语句和continuecontinue语句见下节语句见下节) )。而。而对用对用gotogoto语句和语句和ifif语句构成的循环,不能用语句构成的循环,不能用breakbreak语句和语句和continuecont

35、inue语句进行控制。语句进行控制。 8/5/202447break语句和语句和continue语句语句breakbreak语句语句 breakbreak语句可以用来从循环体内跳出循环体,即提前语句可以用来从循环体内跳出循环体,即提前结束循环,接着执行循环下面的语句结束循环,接着执行循环下面的语句 一般形式:一般形式: break;break;注意注意:break:break语句不能用于循环语句和语句不能用于循环语句和switchswitch语句之外语句之外的任何其他语句中。的任何其他语句中。 8/5/202448break语句和语句和continue语句语句例例: float pi=3.14

36、159;: float pi=3.14159;for(r=1;r=10;r+)for(r=1;r100) break; if(area100) break; printf(rprintf(r=%f,area=%fn=%f,area=%fn,r,area);r,area); 程序的作用是计算程序的作用是计算r=1r=1到到r=10r=10时的圆面积,直到面时的圆面积,直到面积积areaarea大于大于100100为止。从上面的为止。从上面的forfor循环可以看到:循环可以看到:当当area100area100时,执行时,执行breakbreak语句,提前结束循环,语句,提前结束循环,即不再继续

37、执行其余的几次循环。即不再继续执行其余的几次循环。8/5/202449break语句和语句和continue语句语句continuecontinue语句语句 作用为结束本次循环,即跳过循环体中下面尚未执作用为结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定行的语句,接着进行下一次是否执行循环的判定. .一般形式:一般形式: continue;continue;8/5/202450break语句和语句和continue语句语句continuecontinue语句和语句和breakbreak语句的区别:语句的区别: continuecontinue语句只结束本次循环

38、,语句只结束本次循环,而不是终止整个循环的执行。而不是终止整个循环的执行。 while(while(表达式表达式1) for1) for if( if(表达式表达式2) continue;2) continue; 0 08/5/202451break语句和语句和continue语句语句 continuecontinue和和breakbreak的区别的区别 breakbreak语句则是结束整个循环过程,不再判断执语句则是结束整个循环过程,不再判断执行循环的条件是否成立。行循环的条件是否成立。 while(while(表达式表达式1) for 1) for if( if(表达式表达式2) brea

39、k;2) break; 8/5/202452六、数组的定义和引用六、数组的定义和引用l1.一维数组和二维数组的定义、初始化和一维数组和二维数组的定义、初始化和数组元素的引用。数组元素的引用。l2.字符串与字符数组。字符串与字符数组。8/5/202453一维数组一维数组例如:例如:inta10;floatscore5;“数据类型数据类型”:是数组元素的数据类型。是数组元素的数据类型。“数组名数组名”:遵循遵循C语言语言标识符规则。标识符规则。“常量表达式常量表达式”:表示数组中有多少个元素,即数组的长度。:表示数组中有多少个元素,即数组的长度。它可以是整型常量、整型常量表达式或符号常量。它可以是

40、整型常量、整型常量表达式或符号常量。一维数组的定义一维数组的定义数据类型数据类型数组名数组名常量表达式常量表达式;8/5/202454以下数组定义是正确的:以下数组定义是正确的:#defineN10floatscore1N,score2N;intnum10+N;charc26;以下数组定义是不正确的:以下数组定义是不正确的:intarray(10);intn;floatscoren;doubleba.d;charstr;一维数组的定义一维数组的定义8/5/202455数组元素的引用数组元素的引用 格式:格式:例如:输入学生成绩 for(i=0;i5;i+) scanf(%f,&scorei);

41、例如:fibn=fibn-1+fibn-2;下标表达式的值必须是整型表达式。数组名数组名下标表达式下标表达式8/5/202456一维数组的初始化一维数组的初始化初始化:在定义数组时给数组元素赋初值。初始化:在定义数组时给数组元素赋初值。1在定义数组时,对全部数组元素赋初值在定义数组时,对全部数组元素赋初值例如:例如:inta5=0,1,2,3,4;此时可以省略数组长度,例如:此时可以省略数组长度,例如:inta=0,1,2,3,4;2在定义数组时,对部分数组元素赋初值在定义数组时,对部分数组元素赋初值例如:例如:inta5=1,2,3;系统为其余元素赋系统为其余元素赋0。3当初值的个数多于数组

42、元素的个数时,编译出错当初值的个数多于数组元素的个数时,编译出错 例如: inta5=0,1,2,3,4,5; 8/5/202457二维数组二维数组数据类型数据类型数组名常量表达式数组名常量表达式1常量表达式常量表达式2; 例如:例如:floatx23;二维数组二维数组的定义的定义X00X01X02X10X11X12inta3,4,b(3,4),c,d(3)(4);8/5/202458x0是数组名,是元素是数组名,是元素x00的地址的地址x1是数组名,是数组名,是元素是元素x10的地址的地址二维数组可看作是一种特殊的一维数组二维数组可看作是一种特殊的一维数组x0-x00,x01,x02x0-x

43、00,x01,x02x1-x10,x11,x12x1-x10,x11,x12例如,可以把例如,可以把例如,可以把例如,可以把x x x x数组看作是包含二个元素的一维数组,数组看作是包含二个元素的一维数组,数组看作是包含二个元素的一维数组,数组看作是包含二个元素的一维数组,每个元素又是一个含有三个元素一维数组。每个元素又是一个含有三个元素一维数组。每个元素又是一个含有三个元素一维数组。每个元素又是一个含有三个元素一维数组。8/5/202459a34=3;/*下标越界下标越界*/a1,2=1;/*应写成应写成a12=1;*/二维数组元素的引用二维数组元素的引用例:例:inta34;a00=3;a

44、01=a00+10;数组名数组名数组名数组名行下标表达式列下标表达式行下标表达式列下标表达式行下标表达式列下标表达式行下标表达式列下标表达式 数组元素的表示形式数组元素的表示形式:8/5/202460二维数组的初始化二维数组的初始化例:例:inta23=1,2,3,4,5,6; 1 1 1 1按行赋初值按行赋初值按行赋初值按行赋初值例:例:inta23=1,2,3,4,5,6;初始化后结果:初始化后结果:初始化后结果:初始化后结果:1231234564562 2 2 2按数组元素在内存中排列的顺序对各元素赋初值按数组元素在内存中排列的顺序对各元素赋初值按数组元素在内存中排列的顺序对各元素赋初值

45、按数组元素在内存中排列的顺序对各元素赋初值3 3 3 3给部分元素赋初值给部分元素赋初值给部分元素赋初值给部分元素赋初值例:例:inta23=1,4;初始化后结果:初始化后结果:1004008/5/202461二维数组的初始化二维数组的初始化4 4数组初始化时,行长度可省,列长度不能省数组初始化时,行长度可省,列长度不能省 例如:例如:intint a a3 3=1,2,3,4,5,6=1,2,3,4,5,6,7,7; intint b4=1,4,5; b4=1,4,5;初始化结果:初始化结果: a a 结果结果结果结果: :a0:123a0:123a1:456a1:456a2:700a2:7

46、00b b b b 结果:结果:结果:结果:b0: 1 0 0 0b0: 1 0 0 0b0: 1 0 0 0b0: 1 0 0 0b1: 4 5 0 0b1: 4 5 0 0b1: 4 5 0 0b1: 4 5 0 08/5/202462下面对二维数组的定义都是错误的:下面对二维数组的定义都是错误的:二维数组的初始化二维数组的初始化floatx3=1.0,2.0,3.0,4.0,5.0,6.0;inta,b2,c3;intm24=1,2,3,4,5,6,7,8,9;/*编译出错,初值个数多于数组元素的个数编译出错,初值个数多于数组元素的个数*/ 8/5/202463二维数组应用举例二维数组应

47、用举例【例例7.2】给一个给一个4行行3列的二维数组输入列的二维数组输入/出数据。出数据。main()inta43,i,j,k;for(i=0;i4;i+)for(j=0;j3;j+)scanf(%d,&aij);for(i=0;i4;i+)printf(n);for(j=0;j3;j+)printf(%dt,aij);printf(n);程序运行情况如下:程序运行情况如下:123 456 789 101112 1234567891011128/5/202464字符数组字符数组字符数组字符数组: :可以存放若干个可以存放若干个字符字符, ,也可以存放也可以存放字符串字符串。基本概念基本概念Ch

48、ina0字符串:字符串:字符串:字符串:字符串的末尾必须有字符串的末尾必须有字符串的末尾必须有字符串的末尾必须有 00字符,它的字符,它的字符,它的字符,它的ASCIIASCII码值为码值为码值为码值为0 0。China不是字符串不是字符串是字符是字符是字符是字符串串串串8/5/202465再例如:再例如:chara35;a数组是一个二维的字符数组,可以存放数组是一个二维的字符数组,可以存放15个字符或个字符或3个个长度不大于长度不大于4的字符串。的字符串。字符数组的定义字符数组的定义例如:例如:chars10;s数组是一维字符数组,它可以存放数组是一维字符数组,它可以存放10个字符或一个长度

49、个字符或一个长度不大于不大于9的字符串。的字符串。注意:字符串只能存放在字符数组中。注意:字符串只能存放在字符数组中。8/5/202466字符数组的初始化字符数组的初始化China1 1用字符常量赋初值用字符常量赋初值用字符常量赋初值用字符常量赋初值例如:例如:例如:例如:charc5=C,h,i,n,a;charc5=C,h,i,n,a;再例如:再例如:再例如:再例如:charc6=C,h,i,n,a,0;charc6=C,h,i,n,a,0;China0是字符串是字符串是字符串是字符串不是字符串不是字符串8/5/202467字符数组的初始化字符数组的初始化再例如:再例如:chara310=

50、basic,pascal,c;astring002 2用字符串常量赋初值用字符串常量赋初值用字符串常量赋初值用字符串常量赋初值例如:例如:例如:例如:charstr10=astring;charstr10=astring;或或或或charstr10=astring;charstr10=astring;b asic00000p ascal0000c000000000是字符串吗?是字符串吗?是字符串吗?是字符串吗?8/5/202468字符数组的初始化字符数组的初始化例如:例如:chars37=s,t,r,i,n,g;Go o dmo r n i n g ! 03 3初始化时长度的省略初始化时长度的

51、省略初始化时长度的省略初始化时长度的省略例如:例如:例如:例如:chars1=Goodmorning!;chars1=Goodmorning!;b0b13例如:例如:例如:例如:chars2=s,t,r,i,n,g;chars2=s,t,r,i,n,g;stringstring0思考:哪个数组存放的是字符串思考:哪个数组存放的是字符串?8/5/202469程序如下:程序如下:main()charc110,c226;inti;for(i=0;i10;i+)c1i=i+48;for(i=0;i26;i+)c2i=i+A;for(i=0;i10;i+)printf(%c,c1i);printf(n)

52、;for(i=0;iy?x:y;return(z);类型省略时类型省略时默认为默认为int类型类型没有形式参数没有形式参数为为无参函数无参函数 8/5/202477intmax(x,y)intx,y;intz;z=xy?x:y;return(z);intmax(x,y)intx,y;或或intmax(intx,y)或或intmax(x,y)intx,y,z;z=xy?x:y;return(z);花括号中也可以为空,这种函数叫花括号中也可以为空,这种函数叫花括号中也可以为空,这种函数叫花括号中也可以为空,这种函数叫空函数空函数空函数空函数 。不能在函数体内定义其他函数,即函数不能在函数体内定义其

53、他函数,即函数不能在函数体内定义其他函数,即函数不能在函数体内定义其他函数,即函数不能嵌套定义不能嵌套定义不能嵌套定义不能嵌套定义。形参也可以这样定义形参也可以这样定义如下定义都是错误的如下定义都是错误的如下定义都是错误的如下定义都是错误的 8/5/202478函数名(实参表列)函数名(实参表列)在在C语言中,把函数调用也作为一个表达式。语言中,把函数调用也作为一个表达式。因此凡是表达式可以出现的地方都可以出现函数因此凡是表达式可以出现的地方都可以出现函数调用。例如:调用。例如:welcome();if(iabs(a)max)max=iabs(a);m=max(c,max(a,b);函数的调用

54、函数的调用函数调用的一般形式:函数调用的一般形式:8/5/202479voidswap(intx,inty)intz;z=x;x=y;y=z;printf(nx=%d,y=%d,x,y);main()inta=10,b=20;swap(a,b);printf(na=%d,b=%dn,a,b); 函数参数与函数的返回值函数参数与函数的返回值1 1函数的形式参数与实际参数函数的形式参数与实际参数程序输出结果:程序输出结果:x=20,y=10a=10,b=20形式参数(形参)形式参数(形参)实际参数(实参)实际参数(实参)实际参数(实参)实际参数(实参)【例例7.4】编一程序,将主函数中的两个变量的

55、值传编一程序,将主函数中的两个变量的值传递给递给swap函数中的两个形参,交换两个形参的值。函数中的两个形参,交换两个形参的值。单向值传递单向值传递8/5/202480有关形参和实参的说明:有关形参和实参的说明: 当函数被调用时才给形参分配内存单元。调用结当函数被调用时才给形参分配内存单元。调用结束,所占内存被释放。束,所占内存被释放。实参可以是常量、变量或表达式,但要求它们有实参可以是常量、变量或表达式,但要求它们有确定的值。确定的值。实参与形参类型要一致,字符型与整型可以兼容。实参与形参类型要一致,字符型与整型可以兼容。实参与形参的个数必须相等。在函数调用时,实实参与形参的个数必须相等。在

56、函数调用时,实参的值赋给与之相对应的形参。参的值赋给与之相对应的形参。“单向值传递单向值传递”。注意:在注意:在注意:在注意:在TCTCTCTC中,实参的求值顺序是从右到左。中,实参的求值顺序是从右到左。中,实参的求值顺序是从右到左。中,实参的求值顺序是从右到左。 8/5/202481函数的返回值是通过函数的返回值是通过return语句带回到主调函数的语句带回到主调函数的功能:功能:终止函数的运行,返回主调函数,若有返回值,将终止函数的运行,返回主调函数,若有返回值,将返回值带回主调函数。返回值带回主调函数。说明:说明:说明:说明: 若函数没有返回值,若函数没有返回值,若函数没有返回值,若函数

57、没有返回值,returnreturn语句可以省略。语句可以省略。语句可以省略。语句可以省略。 returnreturn语句中的表达式类型一般应和函数的类语句中的表达式类型一般应和函数的类语句中的表达式类型一般应和函数的类语句中的表达式类型一般应和函数的类型一致,型一致,型一致,型一致,如果不一致,系统自动将表达式类型转如果不一致,系统自动将表达式类型转换为函数类型换为函数类型。函数的返回值函数的返回值returnreturn语句格式:语句格式:语句格式:语句格式:returnreturn( (表达式表达式表达式表达式); ); 或或或或 returnreturn表达式表达式表达式表达式 ; ;

58、或或或或return;return;8/5/202482 对被调函数的声明和函数原型对被调函数的声明和函数原型变量要变量要变量要变量要先定义后使用先定义后使用先定义后使用先定义后使用,函数也如此函数也如此函数也如此函数也如此。即。即。即。即被调函数的被调函数的被调函数的被调函数的定义要出现在主调函数的定定义要出现在主调函数的定定义要出现在主调函数的定定义要出现在主调函数的定义之前义之前义之前义之前。如。如。如。如swapswapswapswap函数函数函数函数: : : :允许整型函数(且参数允许整型函数(且参数允许整型函数(且参数允许整型函数(且参数也是整型)的定义出现在主也是整型)的定义出

59、现在主也是整型)的定义出现在主也是整型)的定义出现在主调函数之后。如调函数之后。如调函数之后。如调函数之后。如maxmaxmaxmax函数函数函数函数: : : :如果非整型函数在主调如果非整型函数在主调如果非整型函数在主调如果非整型函数在主调函数之后定义,则应在主调函数之后定义,则应在主调函数之后定义,则应在主调函数之后定义,则应在主调函数中或主调函数之前对函数中或主调函数之前对函数中或主调函数之前对函数中或主调函数之前对被被被被调函数进行声明。调函数进行声明。调函数进行声明。调函数进行声明。voidswap(intx,inty)main()swap(a,b);main()main()c=m

60、ax(a,b);c=max(a,b); max(intmax(int x,intx,inty)y)8/5/202483对被调函数进行声明的一般形式对被调函数进行声明的一般形式函数类型函数类型 函数名(参数类型函数名(参数类型1 1 参数名参数名1 1,); ;或或 函数类型函数类型 函数名(参数类型函数名(参数类型1 1,参数类型,参数类型2 2,); ;思考思考思考思考: :以下哪种情况需要在主调函数中对被调函数声明以下哪种情况需要在主调函数中对被调函数声明以下哪种情况需要在主调函数中对被调函数声明以下哪种情况需要在主调函数中对被调函数声明被调函数定义在前,主调函数定义在后。被调函数定义在前

61、,主调函数定义在后。被调函数定义在前,主调函数定义在后。被调函数定义在前,主调函数定义在后。主调函数定义在前,被调函数定义在后,且被调主调函数定义在前,被调函数定义在后,且被调主调函数定义在前,被调函数定义在后,且被调主调函数定义在前,被调函数定义在后,且被调函数的类型不是整型的。函数的类型不是整型的。函数的类型不是整型的。函数的类型不是整型的。被调函数定义在后,但被调函数的类型是整型。被调函数定义在后,但被调函数的类型是整型。被调函数定义在后,但被调函数的类型是整型。被调函数定义在后,但被调函数的类型是整型。第二种形式省略了参数名,此种形式也称为函数的原型。第二种形式省略了参数名,此种形式也

62、称为函数的原型。8/5/202484函数的嵌套调用函数的嵌套调用函数嵌套调用:函数嵌套调用:函数调用中又存在调用。如函数函数调用中又存在调用。如函数1调用函数调用函数2,函数又调用函数,函数又调用函数3。函数之间没有从属关系,。函数之间没有从属关系,一个函数可以被其它函数调用,同时该函数也一个函数可以被其它函数调用,同时该函数也可以调用其它函数。可以调用其它函数。8/5/202485函数的递归调用函数的递归调用函数的递归调用:函数的递归调用:是指函数直接调用或间接调用自己,或调是指函数直接调用或间接调用自己,或调用一个函数的过程中出现直接或间接调用该函用一个函数的过程中出现直接或间接调用该函数

63、自身。前者称为直接递归调用,后者称为间数自身。前者称为直接递归调用,后者称为间接递归调用。接递归调用。8/5/202486局部变量和全局变量及其作用域局部变量和全局变量及其作用域1.变量的作用域变量的作用域2.局部变量及其作用域局部变量及其作用域变量的作用域变量的作用域:变量在程序中可以被使用的范围。:变量在程序中可以被使用的范围。根据变量的作用域可以将变量分为根据变量的作用域可以将变量分为局部变量和全局局部变量和全局变量。变量。局部变量(局部变量(内部变量内部变量内部变量内部变量):在:在函数内函数内或或复合语句内复合语句内定定义的变量以及义的变量以及形参形参形参形参。作用域作用域:函数内或

64、复合语句内。:函数内或复合语句内。问题:问题:问题:问题:一个变量在程序的哪个函数中都能使用吗?一个变量在程序的哪个函数中都能使用吗?一个变量在程序的哪个函数中都能使用吗?一个变量在程序的哪个函数中都能使用吗?8/5/202487全局变量及其作用域全局变量及其作用域全局变量全局变量(外部变量外部变量):在):在函数外部函数外部定义的定义的变量。变量。作用域作用域:从定义变量的位置开始到本源文件从定义变量的位置开始到本源文件结束结束。如在其作用域内的函数或分程序中定。如在其作用域内的函数或分程序中定义了同名局部变量,则在局部变量的作用域义了同名局部变量,则在局部变量的作用域内,同名全局变量暂时不

65、起作用。内,同名全局变量暂时不起作用。8/5/202488变量的存储类别及变量的生存期变量的存储类别及变量的生存期1.变量的生存期与变量的存储分类变量的生存期与变量的存储分类变量的生存期变量的生存期:变量在内存中占据存储空间的时间。:变量在内存中占据存储空间的时间。思考思考思考思考:1.1.何时为变量分配内存单元?何时为变量分配内存单元?何时为变量分配内存单元?何时为变量分配内存单元?2.2.将变量分配在内存的什么区域?将变量分配在内存的什么区域?将变量分配在内存的什么区域?将变量分配在内存的什么区域?3.3.变量占据内存的时间(生存期)?变量占据内存的时间(生存期)?变量占据内存的时间(生存

66、期)?变量占据内存的时间(生存期)?程序代码区静态存储区动态存储区存储分配存储分配动态存储变动态存储变量量静态存储变量静态存储变量8/5/202489变量的存储类别变量的存储类别变量的属性数据类型:数据类型:数据类型:数据类型:决定为变量分配内存单元的长度,决定为变量分配内存单元的长度,决定为变量分配内存单元的长度,决定为变量分配内存单元的长度,数据的存放形式,数据的存放形式,数据的存放形式,数据的存放形式,数的范围。数的范围。数的范围。数的范围。存储类别:存储类别:存储类别:存储类别:决定了变量的生存期,决定了变量的生存期,决定了变量的生存期,决定了变量的生存期,给它分配在哪个存储区。给它分

67、配在哪个存储区。给它分配在哪个存储区。给它分配在哪个存储区。8/5/202490变量定义语句的一般形式变量定义语句的一般形式存储类别存储类别存储类别存储类别 数据类型数据类型数据类型数据类型 变量名变量名变量名变量名1,1,变量名变量名变量名变量名n;n;autoauto(自动的)(自动的)(自动的)(自动的)registerregister(寄存器的)(寄存器的)(寄存器的)(寄存器的)staticstatic(静态的)(静态的)(静态的)(静态的) externextern(外部的)(外部的)(外部的)(外部的)1自动变量(自动变量(auto类别)类别)局部变量可以定义为自动变量。局部变量

68、可以定义为自动变量。main()intx,y;main()autointx,y;自动变量自动变量自动变量自动变量等价等价可省8/5/202491内存分配内存分配调用函数或执行分程序时在调用函数或执行分程序时在动态存储区动态存储区为其分配存储单元,为其分配存储单元,函数或分程序执行结束,所占内存空间即刻释放。函数或分程序执行结束,所占内存空间即刻释放。变量的初值变量的初值定义变量时若没赋初值,变量的定义变量时若没赋初值,变量的初值不确定初值不确定;如果赋初值则;如果赋初值则每次函数被调用时执行一次赋值操作。每次函数被调用时执行一次赋值操作。生存期生存期在函数或分程序执行期间。在函数或分程序执行期

69、间。作用域作用域自动变量所在的函数内或分程序内。自动变量所在的函数内或分程序内。自动变量自动变量8/5/2024922 2静态变量(静态变量(staticstatic类别)类别)除形参外,局部变量和全局变量都可以定义为静态变量。除形参外,局部变量和全局变量都可以定义为静态变量。局部静态变量(或称内部静态变量)局部静态变量(或称内部静态变量)局部静态变量(或称内部静态变量)局部静态变量(或称内部静态变量)全局静态变量(或称外部静态变量)全局静态变量(或称外部静态变量)静态变量静态变量静态变量静态变量静态变量静态变量静态变量静态变量staticinta;main()floatx,y;f()stat

70、icintb=1;全局静态变量全局静态变量局部静态变量局部静态变量局部静态变量局部静态变量自动变量自动变量自动变量自动变量不能省8/5/202493intc;staticinta;main()floatx,yx,y;chars;f()staticintb=1;3.3.外部变量(外部变量(externextern类别)类别)在函数外定义的变量若没有用在函数外定义的变量若没有用static说明,则是外部变量。说明,则是外部变量。外部变量只能隐式定义为外部变量只能隐式定义为extern类别,不能显式定义。类别,不能显式定义。全局静态变量全局静态变量自动变量自动变量自动变量自动变量局部静态变量局部静态

71、变量局部静态变量局部静态变量外部变量外部变量8/5/202494 内存分配内存分配编译时,将其分配在静态存储区,程序运行结编译时,将其分配在静态存储区,程序运行结束释放该单元。束释放该单元。 变量的初值变量的初值若定义变量时未赋初值,在编译时,系统自动若定义变量时未赋初值,在编译时,系统自动赋初值为赋初值为0 0。 生存期生存期整个程序的执行期间。整个程序的执行期间。 作用域作用域从定义处开始到本源文件结束。从定义处开始到本源文件结束。此外,还可以用此外,还可以用externextern进行声明,以使其作用进行声明,以使其作用域扩大到该程序的其它文件中。域扩大到该程序的其它文件中。外部变量外部

72、变量问题:问题:全局静全局静态变量态变量的作用的作用域可以域可以扩展到扩展到本程序本程序的其它的其它文件吗文件吗?8/5/202495外部变量声明的一般格式外部变量声明的一般格式externextern数据类型数据类型数据类型数据类型 变量名变量名变量名变量名1 1,变量名,变量名,变量名,变量名n n;或或或或externextern变量名变量名变量名变量名1 1,变量名,变量名,变量名,变量名n n;注意:注意:外部变量声明用关键字外部变量声明用关键字externextern,而外部变量的,而外部变量的定义不能用定义不能用externextern,只能隐式定义。,只能隐式定义。定义外部变量

73、时,系统要给变量分配存储空间,定义外部变量时,系统要给变量分配存储空间,而对外部变量声明时,系统不分配存储空间,而对外部变量声明时,系统不分配存储空间,只是让编译系统知道该变量是一个已经定义过只是让编译系统知道该变量是一个已经定义过的外部变量,与函数声明的作用类似。的外部变量,与函数声明的作用类似。8/5/2024964.4.寄存器变量(寄存器变量(registerregister类别)类别)只有只有函数内定义的变量或形参函数内定义的变量或形参可以定义为寄存器变量。可以定义为寄存器变量。寄存器变量的值保存在寄存器变量的值保存在CPUCPU的寄存器中。的寄存器中。受寄存器长度的限制,受寄存器长度

74、的限制,寄存器变量只能是寄存器变量只能是charchar、intint和指和指针类型的变量。针类型的变量。【例例7.26】寄存器变量的使用。寄存器变量的使用。main()longintsum=0;registerinti;for(i=1;i=1000;i+)sum+=i;printf(sum=%ldn,sum);程序输出结果:程序输出结果:sum=5005008/5/202497归纳变量的分类归纳变量的分类1 1按照变量的作用域对变量分类按照变量的作用域对变量分类 局部变量局部变量 全局变量全局变量2 2按照变量的生存期对变量分类按照变量的生存期对变量分类 静态存储变量静态存储变量包括:局部静

75、态变量和全局静态变量包括:局部静态变量和全局静态变量 动态存储变量动态存储变量包括:自动变量包括:自动变量8/5/202498八、编译预处理八、编译预处理l1.宏定义和调用宏定义和调用(不带参数的宏,带参数的不带参数的宏,带参数的宏宏)。l2.“文件包含文件包含”处理。处理。8/5/202499预处理命令预处理命令语语言言提提供供了了多多种种预预处处理理功功能能,如如宏宏定定义义、文文件件包包含含、条条件件编编译译等等。合合理理地地使使用用预预处处理理功功能能编编写写的的程程序序便便于于阅阅读读、修修改改、移移植植和和调调试试,也有利于模块化程序设计。也有利于模块化程序设计。8/5/20241

76、00宏定义宏定义用标识符来代表一个字符串(给字符串取个名字)。用标识符来代表一个字符串(给字符串取个名字)。C语言语言用用“#define”进行宏定义。进行宏定义。C编译系统在编译前将这些标识符替编译系统在编译前将这些标识符替换成所定义的字符串。换成所定义的字符串。宏定义分为不带参数的宏定义和带参数宏定义。宏定义分为不带参数的宏定义和带参数宏定义。1不带参数的宏不带参数的宏(1)一般形式一般形式定义格式:定义格式:#define标识符标识符字符串字符串宏名遵循标识符规定,习惯用大写字母表示,以便区别普宏名遵循标识符规定,习惯用大写字母表示,以便区别普通的变量。通的变量。#define之间不留空

77、格,宏名两侧空格(至少一个)分隔。之间不留空格,宏名两侧空格(至少一个)分隔。宏定义字符串不要以分号结束,否则分号也作为字符串的宏定义字符串不要以分号结束,否则分号也作为字符串的一部分参加展开。从这点上看宏展开实际上是简单的替换。一部分参加展开。从这点上看宏展开实际上是简单的替换。8/5/2024101宏定义宏定义(2)几点说明几点说明宏定义用宏名代替一个字符串,并不管它的数据类型是什宏定义用宏名代替一个字符串,并不管它的数据类型是什么,也不管宏展开后的词法和语法的正确性,只是简单么,也不管宏展开后的词法和语法的正确性,只是简单的替换。是否正确,编译时由编译器判断。的替换。是否正确,编译时由编

78、译器判断。#define宏定义宏名的作用范围从定义命令开始直到本源宏定义宏名的作用范围从定义命令开始直到本源程序文件结束。可以通过程序文件结束。可以通过#undef终止宏名的作用域。终止宏名的作用域。宏定义中,可以出现已经定义的宏名,还可以层层置换。宏定义中,可以出现已经定义的宏名,还可以层层置换。宏名出现在双引号宏名出现在双引号“”括起来的字符串中时,将不会产生括起来的字符串中时,将不会产生宏替换。(因为出现在字符串中的任何字符都作为字符宏替换。(因为出现在字符串中的任何字符都作为字符串的组成部分)串的组成部分)宏定义是预处理指令,与定义变量不同,它只是进行简单宏定义是预处理指令,与定义变量

79、不同,它只是进行简单的字符串替换,不分配内存。的字符串替换,不分配内存。8/5/2024102宏定义宏定义例例1不带参数的宏不带参数的宏#definePI3.14main()floatr=3,s,c;s=PI*r*r;c=2*PI*r;printf(r,s,c);8/5/2024103宏定义宏定义2带参数的宏带参数的宏(1)一般形式一般形式定义格式:定义格式:#define宏名宏名(参数表参数表)字符串字符串(2)几点说明几点说明正因为带参宏定义本质还是简单字符替换(除了参数替换),所以正因为带参宏定义本质还是简单字符替换(除了参数替换),所以容易发生错误。为了避免出错,建议将宏定义容易发生错

80、误。为了避免出错,建议将宏定义“字符串字符串”中的所有形参用中的所有形参用括号()括起来。以后,替换时括号作为一般字符原样照抄,这样用实参括号()括起来。以后,替换时括号作为一般字符原样照抄,这样用实参替换时,实参就被括号括起来作为整体。不至于发生类似错误。替换时,实参就被括号括起来作为整体。不至于发生类似错误。定义带参数宏时还应该注意宏名与参数表之间不能有空格。有空格就定义带参数宏时还应该注意宏名与参数表之间不能有空格。有空格就变成了不带参数的宏定义。变成了不带参数的宏定义。8/5/2024104宏定义宏定义带参数的宏定义在程序中使用时,它的形式及带参数的宏定义在程序中使用时,它的形式及特性

81、与函数相似,但本质完全不同。特性与函数相似,但本质完全不同。许多问题可以用函数也可以用带参数的宏定义。许多问题可以用函数也可以用带参数的宏定义。宏占用的是编译时间,函数调用占用的是运行宏占用的是编译时间,函数调用占用的是运行时间。在多次调用时,宏使得程序变长,而函时间。在多次调用时,宏使得程序变长,而函数调用不明显。数调用不明显。8/5/2024105“文件包含文件包含”处理处理(1)一般形式一般形式#include“文件名文件名”或或#include(2)几点说明几点说明被包含的文件常常被称为被包含的文件常常被称为“头文件头文件”(#include一般一般写在模块的开头)。头文件常常以写在模

82、块的开头)。头文件常常以“.h”为扩展名(也可以为扩展名(也可以用其它的扩展名,用其它的扩展名,.h只是习惯或风格)。只是习惯或风格)。一条一条#include只能包含一个头文件,如果要包含多个只能包含一个头文件,如果要包含多个头文件,使用多条头文件,使用多条#include命令。命令。被包含的头文件可以用被包含的头文件可以用“”括起来,也可以用括起来,也可以用括起括起来。区别在于:来。区别在于:先在先在C系统目录中查找头文件,系统目录中查找头文件,“”先在先在用户当前目录查找头文件。用户当前目录查找头文件。习惯上,用户头文件一般在用户目录下,所以常常用习惯上,用户头文件一般在用户目录下,所以

83、常常用“”;系统库函数的头文件一般在系统指定目录下,所以常;系统库函数的头文件一般在系统指定目录下,所以常常用常用。8/5/2024106九、指针九、指针l1.地址与指针变量的概念,地址运算符与间址地址与指针变量的概念,地址运算符与间址运算符。运算符。l2.一维、二维数组和字符串的地址以及指向变一维、二维数组和字符串的地址以及指向变量、数组、字符串、函数、结构体的指针变量的定量、数组、字符串、函数、结构体的指针变量的定义。通过指针引用以上各类型数据。义。通过指针引用以上各类型数据。l3.用指针作函数参数。用指针作函数参数。l4.返回地址值的函数。返回地址值的函数。l5.指针数组,指向指针的指针

84、。指针数组,指向指针的指针。8/5/2024107一、指针概述一、指针概述1、指针和指针变量、指针和指针变量指针指针即地址即地址一一个个变变量量的的地地址址称称为为该该变变量量的的指指针针。通通过过变变量量的的指针能够找到该变量。指针能够找到该变量。(2)指针变量)指针变量专门用于存储其它变量地址的变量专门用于存储其它变量地址的变量指针变量指针变量num_pointer的值就是变量的值就是变量num的地址。的地址。指针与指针变量的区别,就是变量值与变量的区别。指针与指针变量的区别,就是变量值与变量的区别。8/5/20241082、直接访问和间接访问、直接访问和间接访问(1)直接访问直接利用变量

85、的直接利用变量的地址进行存取地址进行存取如如scanf(“%d”,&num)的执行:的执行:用用变变量量名名num作作为为索索引引值值,检检索索符符号号表表,找找到到变变量量num的的起起始始地地址址3000;然然后后将将键键盘盘输输入入的的值值(假假设设为为)送送到到内内存存单元单元3000和和3001中。中。(2)间间接接访访问问通通过过另另一一变变量量访问该变量的值访问该变量的值8/5/2024109二、指针变量的定义和使用二、指针变量的定义和使用l定义指针变量的一般形式为基类型基类型*指针变量名;指针变量名;8/5/2024110在定义指针变量时要注意两点:在定义指针变量时要注意两点:

86、(1)指针变量前面的“*”,表示该变量的类型为指针型变量。(2)例: float *pointer_1;(3)指针变量名是pointer_1 ,而不是*pointer_1 。 (4)(2) 在定义指针变量时必须指定基类型。(5) 需要特别注意的是,只有整型变量的地址才能放到指向整型变量的指针变量中。下面的赋值是错误的(6) float a; (7) int * pointer_1; (8) pointer_1=&a; 8/5/2024111指针变量的引用指针变量的引用注意注意:指针变量中只能存放地址(指针),指针变量中只能存放地址(指针),不要将一个整数(或任何其他非地址类型的数据)不要将一个

87、整数(或任何其他非地址类型的数据)赋给一个指针变量。赋给一个指针变量。 例例10.通过指针变量访问整型变量通过指针变量访问整型变量#includevoidmain()int,;,;int*pointer_,*pointer_;pointer_;/*把变量的地址赋给把变量的地址赋给pointer_1*/8/5/2024112对对“”和和“* *”运算符说明:运算符说明:如果已执行了语句 pointer_;(1)*pointer_的含义是什么?的含义是什么? “”和和“*”两个运算符的优先级别相同,但按自右而两个运算符的优先级别相同,但按自右而左方向结合。因此,左方向结合。因此,*pointer_

88、与相同,即变量与相同,即变量a的地的地址。址。如果有如果有pointer_2*pointer_;它的作用是将;它的作用是将(的地址)赋给(的地址)赋给pointer_2,如果,如果pointer_2原来指向,经原来指向,经过重新赋值后它已不再指向了,而指向了。过重新赋值后它已不再指向了,而指向了。8/5/2024113(2) *的含义是什么?的含义是什么?先进行运算,得的地址,再进行*运算。*和*pointer_的作用是一样的,它们都等价于变量。即*与等价。(3)(*pointer_)相当于。相当于。8/5/2024114三、数组与指针三、数组与指针1、一维数组与指针、一维数组与指针l数组的指

89、针数组的指针数组在内存中的起始地址,数组元素的数组在内存中的起始地址,数组元素的指针指针数组元素在内存中的起始地址。数组元素在内存中的起始地址。l指向数组的指针变量的定义指向数组的指针变量的定义指向数组的指针变量的定义,与指向普通变量的指针变指向数组的指针变量的定义,与指向普通变量的指针变量的定义方法一样。量的定义方法一样。例如,例如,intarray10,*pointer=array(或或&array0);或者:或者:intarray10,*pointer;pointerarray;注意注意:数组名代表数组在内存中的起始地址(与第:数组名代表数组在内存中的起始地址(与第1个元个元素的地址相同

90、),所以可以用数组名给指针变量赋值。素的地址相同),所以可以用数组名给指针变量赋值。8/5/2024115l数组元素的引用数组元素的引用数数组组元元素素的的引引用用,既既可可用用下下标标法法,也也可可用用指指针针法法。使使用用下下标标法法,直直观观;而而使使用用指指针针法法,能能使使目目标标程程序序占占用用内存少、运行速度快。内存少、运行速度快。8/5/2024116数组元素的引用数组元素的引用如果有如果有“intarray10,*pointer=array;”,则:,则:(1)pointer+i和和array+i都是数组元素都是数组元素arrayi的地址的地址(2)*(pointer+i)和

91、和*(array+i)就是数组元素就是数组元素arrayi(3)指向数组的指针变量,也可将其看作是数组名,因而)指向数组的指针变量,也可将其看作是数组名,因而可按下标法来使用。可按下标法来使用。例如,例如,pointeri等价于等价于*(pointer+i)。注意注意:pointer+1指向数组的下一个元素,而不是简单地使指向数组的下一个元素,而不是简单地使指针变量指针变量pointer的值的值+1。其实际变化为。其实际变化为pointer+1*size(size为一个元素占用的字节数)。为一个元素占用的字节数)。8/5/20241172、二维数组和指针、二维数组和指针假设有如下数组定义语句:

92、假设有如下数组定义语句:intarray34;(1)从)从2维数组角度看,数组名维数组角度看,数组名array代表数组的起始地址,代表数组的起始地址,是一个以行为单位进行控制的行指针:是一个以行为单位进行控制的行指针:array+i:行指针值,指向:行指针值,指向2维数组的第维数组的第i行。行。*(array+i):(列)指针值,指向第:(列)指针值,指向第i行第列(控制由行第列(控制由行转为列,但仍为指针)。行转为列,但仍为指针)。*(*(array+i):数组元素:数组元素arrayi0的值。的值。用用array作指针访问数组元素作指针访问数组元素arrayij的格式:的格式:*(*(ar

93、ray+i)j)8/5/2024118行指针变量行指针变量指向由指向由n个元素组成的一维数组的指针变量个元素组成的一维数组的指针变量(1)定义格式定义格式数据类型数据类型(*指针变量指针变量)n;(2)赋值赋值行指针变量行指针变量2维数组名维数组名|行指针变量行指针变量;8/5/2024119字符串和指针字符串和指针字符串在内存中的起始地址称为字符串的指针,字符串在内存中的起始地址称为字符串的指针,可以定义一个字符指针变量指向一个字符串。可以定义一个字符指针变量指向一个字符串。l字符串指针的定义字符串指针的定义char*指针变量名;指针变量名;main()char*string=”IloveB

94、eijing.”;for(;*string!=0;string+)printf(“%c”,*string);printf(“n”);8/5/2024120程序运行结果:程序运行结果:IloveBeijing.程序说明:char*string=IloveBeijing.;语句语句定定义义并并初初始始化化字字符符指指针针变变量量string:用用串串常常量量“I loveBeijing.”的的地地址址(由由系系统统自自动动开开辟辟、存存储储串串常常量量的的内内存存块块的的首地址)给首地址)给string赋初值。赋初值。该语句也可分成如下所示的两条语句:该语句也可分成如下所示的两条语句:char*s

95、tring;string=IloveBeijing.;注意:字字符符指指针针变变量量string中中,仅仅存存储储串串常常量量的的地地址址,而而串串常常量量的的内内容容(即即字字符符串串本本身身),是是存存储储在在由由系系统统自自动动开开辟辟的的内内存块中,并在串尾添加一个结束标志存块中,并在串尾添加一个结束标志0。8/5/2024121指针数组指针数组l一个数组,若其元素均为指针类型数据,称为指针数一个数组,若其元素均为指针类型数据,称为指针数组,也就是说,指针数组中的每一个元素都相当于一组,也就是说,指针数组中的每一个元素都相当于一个指针变量。个指针变量。l一维指针数组的定义形式为一维指针

96、数组的定义形式为:类型名类型名数组名数组长度;数组名数组长度;例如:例如:*;8/5/20241228/5/2024123五、指针函数和函数指针五、指针函数和函数指针l指针函数指针函数带回指针值的函数,一般定义形式为带回指针值的函数,一般定义形式为类型名类型名*函数名(参数表列)函数名(参数表列);例如:例如:int*(int,int);float*search(float(*b)4,intn)float*pt;pt*(bn););return(pt););8/5/2024124l函数指针函数指针一个函数在编译时,被分配了一个入口地址,这个地址就一个函数在编译时,被分配了一个入口地址,这个地址

97、就称为该函数的指针。称为该函数的指针。(1)定义格式)定义格式函数类型函数类型(*指针变量指针变量)();注意:注意:“*指针变量指针变量”外的括号不能缺,否则成了返外的括号不能缺,否则成了返回指针值的函数。回指针值的函数。例如,例如,int(*fp)();(2)赋值)赋值函数名代表该函数的入口地址。因此,可用函数名给函数名代表该函数的入口地址。因此,可用函数名给指向函数的指针变量赋值。指向函数的指针变量赋值。指向函数的指针变量指向函数的指针变量&函数名函数名;注意:函数名后不能带括号和参数;函数名前的注意:函数名后不能带括号和参数;函数名前的“&”符号是可选的。符号是可选的。8/5/2024

98、125六、指针的指针六、指针的指针定义一个指向指针数据的指针变量定义一个指向指针数据的指针变量:char*; *运算符的结合性是从右到左,因此*相当于*(*),显然*是指针变量的定义形式。如果没有最前面的*,那就是定义了一个指向字符数据的指针变量。 表示指针变量是指向一个字符指针变量的。*就是所指向的另一个指针变量。8/5/2024126举例举例intint i=2; /* i=2; /* 定义整型变量定义整型变量i */i */intint *p1,*p2; *p1,*p2; /* /* 定定义义p1p1为为整整型型指指针针,定定义义p2p2为整型指针的指针为整型指针的指针 * */ /p1

99、=&i; p1=&i; /* /* i i的的地地址址=p1=p1,即即,指指针针p1p1指指向向变变量量i */i */p2=&p1; p2=&p1; /* /* 指指针针p1p1的的地地址址=p2=p2,即即,指指针针p2p2指指向指针向指针p1 */p1 */对变量对变量i的访问可以是的访问可以是i,*p1,又因为又因为*p2=p1,即,即,*p2=*p1,所以对变量所以对变量i的访问可以是的访问可以是i,*p1,*p2。8/5/2024127指针的指针指针的指针指针的指针:指针的指针:指指向向指指针针变变量量的的指指针针变变量量。指指针针的的指指针针存存放放的的是指针变量地址。是指针变

100、量地址。8/5/2024128十、结构体十、结构体(即即“结构结构”)与共同体与共同体(即即“联合联合”)l1.用用typedef说明一个新类型。说明一个新类型。l2.结构体和共用体类型数据的定义和成员结构体和共用体类型数据的定义和成员的引用。的引用。l3.通过结构体构成链表,单向链表的建立,通过结构体构成链表,单向链表的建立,结点数据的输出、删除与插入。结点数据的输出、删除与插入。8/5/2024129结构体结构体在实际问题中,一组数据往往具有不同的数据类型。在实际问题中,一组数据往往具有不同的数据类型。例如,在学生登记表中,姓名应为字符型;学号可为整型或例如,在学生登记表中,姓名应为字符型

101、;学号可为整型或字符型;年龄应为整型;性别应为字符型;成绩可为整型或实型。字符型;年龄应为整型;性别应为字符型;成绩可为整型或实型。显然不能用一个数组来存放这一组数据。因为数组中各元素的类显然不能用一个数组来存放这一组数据。因为数组中各元素的类型和长度都必须一致,以便于编译系统处理。为了解决这个问题,型和长度都必须一致,以便于编译系统处理。为了解决这个问题,语言中给出了另一种构造数据类型语言中给出了另一种构造数据类型“结构结构(structure)”或叫或叫“结构体结构体”。8/5/20241301、结构体定义、结构体定义一般形式为:一般形式为: structstruct 结构体名结构体名 成

102、员表列;成员表列;如:如:structstruct student student intint num;char name20;char sex; num;char name20;char sex; intint age;float score;char addr30; age;float score;char addr30; 8/5/20241312、结构体变量定义、结构体变量定义(1)先定义结构,再说明结构变量。)先定义结构,再说明结构变量。如:如:structstuintnum;charname20;charsex;floatscore;structstuboy1,boy2;8/5/2

103、024132(2)在声明类型的同时定义变量在声明类型的同时定义变量这种形式的定义的一般形式为这种形式的定义的一般形式为:struct结构体名结构体名成员表列成员表列变量名表列;变量名表列;8/5/2024133(3)直接定义结构体类型变量直接定义结构体类型变量其一般形式为其一般形式为:struct成员表列成员表列变量名表列;变量名表列;即不出现结构体名。即不出现结构体名。8/5/20241343、结构体成员引用、结构体成员引用在在定定义义了了结结构构体体变变量量以以后后,当当然然可可以以引引用用这这个个变变量。但应遵守以下规则量。但应遵守以下规则:(1)不不能能将将一一个个结结构构体体变变量量

104、作作为为一一个个整整体体进进行行输输入和输出。入和输出。例例如如:已已定定义义student1和和student2为为结结构构体体变变量并且它们已有值。量并且它们已有值。8/5/2024135引用结构体变量中成员的方式为:引用结构体变量中成员的方式为:结构体变量名结构体变量名.成员名成员名例如,例如,student1.num表示表示student1变量中的变量中的num成员成员,即即student1的的num(学号学号)项。项。8/5/2024136(2)如果成员本身又属一个结构体类型如果成员本身又属一个结构体类型,则要用若则要用若干个成员运算符干个成员运算符,一级一级地找到最低的一级一级一级

105、地找到最低的一级的成员。的成员。8/5/2024137(3)可以引用结构体变量成员的地址,也可以引可以引用结构体变量成员的地址,也可以引用结构体变量的地址。用结构体变量的地址。例如:例如:scanf(%d,&student1.num);(输入(输入student1.num的值)的值)printf(%o,student1););(输出(输出student1的首地址)的首地址)8/5/20241384、结构体数组、结构体数组一个结构体变量中可以存放一组数据(如一个学生的学号、一个结构体变量中可以存放一组数据(如一个学生的学号、姓名、成绩等数据)。如果有个学生的数据需要姓名、成绩等数据)。如果有个学

106、生的数据需要参加运算,显然应该用数组,这就是结构体数组。参加运算,显然应该用数组,这就是结构体数组。8/5/2024139(1)定义结构体数组)定义结构体数组structstudentintnum;charname20;charsex;intage;floatscore;charaddr30;structstudent3;l以上定义了一个数组以上定义了一个数组stu,数组有个元素,数组有个元素,均为均为structstudent类类型数据。型数据。8/5/2024140(2)结构体数组初始化)结构体数组初始化structstudentintnum;charname20;charsex;inta

107、ge;floatscore;charaddr30;;stu210101,LiLin,M,18,87.5,103BeijingRoad,10102,ZhangFun,M,19,99,130ShanghaiRoad;l图图11-511-58/5/2024141当然,数组的初始化也可以用以下形式:当然,数组的初始化也可以用以下形式:structstudentintnum;structstudentstr,;即先声明结构体类型,然后定义数组为该结构体类即先声明结构体类型,然后定义数组为该结构体类型,在定义数组时初始化。型,在定义数组时初始化。l结构体数组初始化的一般形式结构体数组初始化的一般形式是在定

108、义数组的后面加上是在定义数组的后面加上“初值表列;初值表列;”。8/5/20241425、结构体指针、结构体指针一个结构体变量的指针就是该变量所占据的内存一个结构体变量的指针就是该变量所占据的内存段的起始地址。段的起始地址。一般形式为:一般形式为:struct结构名结构名*结构指针变量名结构指针变量名如:如:structstu*pstu;如果如果boy是被说明为是被说明为stu类型的结构变量,则:类型的结构变量,则:pstu=&boy8/5/2024143访问的一般形式为:访问的一般形式为:(*结构指针变量结构指针变量).成员名成员名或为:或为:结构指针变量结构指针变量-成员名成员名例如:例如

109、:(*pstu).num或者:或者:pstu-num应该注意应该注意(*pstu)两侧的括号不可少,因为成两侧的括号不可少,因为成员符员符“.”的优先级高于的优先级高于“*”。如去掉括号写。如去掉括号写作作*pstu.num则等效于则等效于*(pstu.num)8/5/2024144共 用 体 1、共用体的概念 使几个不同的变量共占同一段内存的结构称为 “共用体”类型的结构。定义共用体类型变量的一般形式为:union共用体名 成员表列 变量表列;图11-24例如:union data union data int i; int i; char ch; 或 char ch; float f; f

110、loat f;a,b,c; ;union data a,b,c;共用体和结构体的比较: 结构体变量所占内存长度是各成员占的内存长度之和。每个成员分别占有其自己的内存单元。 共用体变量所占的内存长度等于最长的成员的长度。 例如:上面定义的“共用体”变量、各占个字节(因为一个实型变量占个字节),而不是各占个字节。 2 、共用体变量的引用 只有先定义了共用体变量才能引用它,而且不能引用共用体变量,而只能引用共用体变量中的成员。例如:前面定义了a、b、c为共用体变量 a.i (引用共用体变量中的整型变量) a.ch(引用共用体变量中的字符变量) a.f (引用共用体变量中的实型变量) 3、共用体类型数

111、据的特点(1)同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一种,而不是同时存放几种。(2) 共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原有的成员就失去作用。 (3) 共用体变量的地址和它的各成员的地址都是同一地址。 (4) 不能对共用体变量名赋值,也不能企图引用变量名来得到一个值,又不能在定义共用体变量时对它初始化。(5) 不能把共用体变量作为函数参数,也不能使函数带回共用体变量,但可以使用指向共用体变量的指针 (6) 共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员

112、。十一、位运算十一、位运算l1.位运算符的含义和使用。位运算符的含义和使用。l2.简单的位运算。简单的位运算。8/5/2024151 C 既具有高级语言的特点,又具有低级语言的功既具有高级语言的特点,又具有低级语言的功能,位运算能力就是其特色之一。能,位运算能力就是其特色之一。 位运算就是指进行二进制位的运算。位运算就是指进行二进制位的运算。C提供的位提供的位运算有:运算有: 名称名称 运算符运算符 名称名称 运算符运算符 按位与按位与 & & 按位异或按位异或 按位或按位或 左移左移 8/5/2024152位逻辑运算位逻辑运算1. 1. 位运算说明位运算说明 (1 1)位位运运算算的的操操作

113、作数数,只只能能是是整整型型或或字字符符型型数数据据,不能为实型数据。不能为实型数据。 (2 2)位位运运算算符符中中除除按按位位取取反反“ ”为为单单目目运运算算符符外外,其余均为二目运算符,即要求两侧各有一个运算量。其余均为二目运算符,即要求两侧各有一个运算量。 (3 3)参参与与运运算算时时,操操作作数数都都必必须须首首先先转转换换成成二二进进制制形式,然后再执行相应的按位运算。形式,然后再执行相应的按位运算。 8/5/2024153 2. 2. 按位与运算符按位与运算符 (1) (1) 按位与运算符:按位与运算符:& & (2) (2) 按按位与运算格式:位与运算格式: 操作数操作数

114、& & 操作数操作数 (3) (3) 按位与运算规则按位与运算规则 将将2 2个个操操作作数数先先转转换换成成二二进进制制数数(补补码码),当当参参加加运运算算的的2 2个个二二进进制制数数之之对对应应位位都都为为1 1,则则该该位位的的结结果果为为1 1,否否则则为为0 ,0 ,即:即:0&0=0 0&1=0 1&0=0 1&1=1 8/5/2024154例:例:3&5=13的补码:的补码:000000115的补码:的补码:000001013&500000001取一个数中的某些指定位清零如:取一个数中的某些指定位清零如:a: 0 0 1 0 1 1 0 0 1 0 1 0 1 1 0 0 b

115、: 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 (377)8 a &b 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 结果得到结果得到a的低的低8位位(4) (4) 按位与运算作用按位与运算作用8/5/20241553 3. .按位或运算按位或运算 (1 1)按位或运算符:)按位或运算符: (2 2)按按位或运算格式:位或运算格式: 操作数操作数 操作数操作数 (3 3)运算规则:参加运算的两个运算量之对应位)运算规则:参加运算的两个运算量之对应位, ,只要有只要有一个为一个为1 1,则该位的结果为,则该位的结果为1 1。即:。即:0 0 = 0 0 1

116、= 1 1 0 = 1 1 1 = 1例如:例如:00110000 (060)8 00001111 (017)8 00111111 (077)8一个数与一个数与017进行按位或运算,可将该数的低进行按位或运算,可将该数的低4位全置为位全置为1 1;与;与0377进行按位或运算,可将该数的低进行按位或运算,可将该数的低8位全置为位全置为1。8/5/20241564.异或运算异或运算(1 1)运算符)运算符 (2 2)按按位位异或异或运算格式:运算格式: 操作数操作数 操作数操作数 (3 3)按位按位异异或运算规则或运算规则:参加运算的两个运算量参加运算的两个运算量的对应位相同,则该位的结果为的对

117、应位相同,则该位的结果为0 0。否则为。否则为1 1。即:。即:0 0 = 0 0 1 = 1 1 0 = 1 1 1 = 0 (4 4)运算的用途:使指定的位翻转)运算的用途:使指定的位翻转如:如:01111010 00001111对应原数的低对应原数的低4位均置为位均置为1 01110101 原数的低原数的低4位被翻转位被翻转8/5/20241575.5.取反运算取反运算(1 1)运算符)运算符 (2 2) 按位取反按位取反运算格式:运算格式: 操作数操作数 (3 3)按位取反按位取反运算运算规则规则 :是对一个二进制数按位取反,是对一个二进制数按位取反,即将即将0 0变为变为1 1,1

118、1变为变为0 0。例如:例如:a的补码:的补码:0 0 0 0 1 1 0 0 1 0 0 1 0 0 1 1 a 1 1 1 1 0 0 1 1 0 1 1 0 1 1 0 0 (4 4)按位取反按位取反运算运算主要用途主要用途 按位取反按位取反运算运算主要用途是间接地构造一个数,以增强程主要用途是间接地构造一个数,以增强程序的可移植性。例如,通过求序的可移植性。例如,通过求 0 0,可以间接地构造一个,可以间接地构造一个各位全各位全1 1的的二进制二进制数。数。 8/5/2024158 位移位运算位移位运算 1.1.按位按位左移运算左移运算 (1)(1)按位按位左移运算符左移运算符: (2

119、) (2)按位按位左移运算格式:左移运算格式: 操作数操作数移移位数位数 (3)(3)按位按位左移运算左移运算规则规则: :将一个将一个操作数先转换成操作数先转换成二二进制进制数数,然后将二进制,然后将二进制数各位左移数各位左移若干位若干位,并在并在低低位补位补若干个若干个0 0,高位左移后溢出,舍弃不起作用。高位左移后溢出,舍弃不起作用。 (4)(4)按位按位左移运算用途左移运算用途: :将乘以将乘以 2 2n n 的幂运算处理的幂运算处理为左移为左移 n n 位。位。例如:例如:7 (2)(2)按位右按位右移运算格式:移运算格式: 操作数操作数移移位数值位数值 (3)(3)按位按位右移运算

120、右移运算规则规则: :将一个将一个操作数先转换成操作数先转换成二进制二进制数数,然后将二进制然后将二进制数各位数各位右右移移若干位若干位,移出的低位舍弃;,移出的低位舍弃;并在并在高高位补位补位,位,补补位分位分2 2种情况种情况: : 若为无符号数,右移时左边高位移入若为无符号数,右移时左边高位移入0 0。 若为有符号数,如果原来符号位为若为有符号数,如果原来符号位为0(0(正数正数) ),则左边,则左边补补若干若干0 0 ;如果原来符号位为;如果原来符号位为1 1 ,左边,左边补补若干若干0 0的称为的称为“逻逻辑右移辑右移” ,左边,左边补补若干若干1 1的称为的称为“算术右移算术右移”

121、。如:如:a: 1001011111101101 (113755)8逻辑右移逻辑右移a1:0100101111110110得得045766算术右移算术右移a1:1100101111110110得得1457668/5/2024160(4) (4) 按位按位右右移运算移运算主要用途主要用途按按位位右右移移运运算算主主要要用用途途是是对对操操作作数数做做除除法法运运算算,即即将将一一个个操操作作数数除除以以 2 2n n 的的幂幂运运算算处处理理为为右右移移 n n 位位的的按按位位右右移移运运算算。右右移移一一位位相相当当于于除以除以2 2 ,右移,右移 n n 位相当于除以位相当于除以2 2n

122、n。 8/5/2024161十二、文件操作十二、文件操作l只要求缓冲文件系统只要求缓冲文件系统(即高级磁盘即高级磁盘I/O系统系统),对非标准缓冲文件系统,对非标准缓冲文件系统(即低级磁盘即低级磁盘I/O系统系统)不要求。不要求。l1.文件类型指针文件类型指针(FILE类型指针类型指针)。l2.文件的打开与关闭文件的打开与关闭(fopen,fclose)。l3.文件的读写文件的读写(fputc,fgetc,fputs,fgets,fread,fwrite,fprintf,fscanf函数的函数的应用应用),文件的定位,文件的定位(rewind,fseek函数的应函数的应用用)。8/5/2024

123、162一、一、C文件概述文件概述文件:文件指存储在外部介质文件:文件指存储在外部介质( (如磁盘磁带如磁盘磁带) )上上数据的集合。数据的集合。 操作系统是以文件为单位对数据进行管理的。操作系统是以文件为单位对数据进行管理的。文件文件程序程序数据区数据区输输出出文件缓冲区文件缓冲区输输入入文件缓冲区文件缓冲区8/5/2024163文件分类文件分类文件的分类文件的分类从用户观点从用户观点: :特殊文件特殊文件( (标准输入输出文件或标准设备文件标准输入输出文件或标准设备文件) )。普通文件普通文件( (磁盘文件磁盘文件) )。从操作系统的角度看,每一个与主机相连的输入从操作系统的角度看,每一个与

124、主机相连的输入输出设备看作是一个文件。输出设备看作是一个文件。例:输入文件:终端键盘例:输入文件:终端键盘 输出文件:显示屏和打印机输出文件:显示屏和打印机8/5/2024164lASCIIASCII文件和二进制文件的比较:文件和二进制文件的比较: ASCIIASCII文文件件便便于于对对字字符符进进行行逐逐个个处处理理,也也便便于于输输出出字字符符。但但一一般般占占存存储储空空间间较较多多,而而且且要要花花费费转转换时间。换时间。 二二进进制制文文件件可可以以节节省省外外存存空空间间和和转转换换时时间间,但但一一个个字字节节并并不不对对应应一一个个字字符符,不不能能直直接接输输出出字字符符形

125、形式。式。 一一般般中中间间结结果果数数据据需需要要暂暂时时保保存存在在外外存存上上,以以后后又需要输入内存的,常用二进制文件保存。又需要输入内存的,常用二进制文件保存。8/5/2024165文件的一般操作步骤文件的一般操作步骤打开文件打开文件 文件操作文件操作 关闭文件关闭文件8/5/2024166文件指针文件指针Turbo Turbo 在在stdio.hstdio.h文件中有以下的文件类型声明:文件中有以下的文件类型声明:typedeftypedef structstruct shortlevelshortlevel; ; * *缓冲区缓冲区“满满”或或“空空”的程度的程度* * unsi

126、gnedflagsunsignedflags; ; * *文件状态标志文件状态标志* * charfdcharfd; ; * *文件描述符文件描述符* * unsignedcharholdunsignedcharhold; ; * *如无缓冲区不读取字符如无缓冲区不读取字符* * shortbsizeshortbsize; ; * *缓冲区的大小缓冲区的大小* * unsignedcharunsignedchar*buffer;/*buffer;/*数据缓冲区的位置数据缓冲区的位置* */ / unsignedarunsignedar* *curpcurp;/*;/*指针,当前的指向指针,当前

127、的指向* */ / unsignedistempunsignedistemp;/*;/*临时文件,指示器临时文件,指示器* */ / shorttokenshorttoken;/*;/*用于有效性检查用于有效性检查* */ /FILEFILE; 在缓冲文件系统中在缓冲文件系统中, ,每个被使用的文件都要在内存中每个被使用的文件都要在内存中开辟一开辟一FILEFILE类型的区类型的区, ,存放文件的有关信息。存放文件的有关信息。8/5/2024167 FILEFILEf f5 5; ;定义了一个结构体数组定义了一个结构体数组f f,它有它有5 5个元素,个元素,可以用来存放可以用来存放5 5个文

128、件的信息。个文件的信息。文件型指针变量文件型指针变量: : FILE * FILE *fpfp;fpfp是一个指向是一个指向FILEFILE类型结构体的指针变量。可以类型结构体的指针变量。可以使使fpfp指向某一个文件的结构体变量,从而通过该结构体变量中指向某一个文件的结构体变量,从而通过该结构体变量中的文件信息能够访问该文件。如果有个文件,一般应设的文件信息能够访问该文件。如果有个文件,一般应设个指针变量,使它们分别指向个文件,以实现对文件的访问。个指针变量,使它们分别指向个文件,以实现对文件的访问。FILE类型的数组:类型的数组:8/5/2024168二、文件的基本操作二、文件的基本操作l

129、打开文件打开文件FILE *fp;fpfopen(文件名,使用文件方式);需要打开的文件名,也就是准备访问的文件的名字;使用文件的方式(“读”还是“写”等);让哪一个指针变量指向被打开的文件。8/5/2024169文件使用方式含文件使用方式含义义“r” (r” (只读只读) )为为输入输入打开一个打开一个文本文本文件文件“w” (w” (只写只写) )为为输出输出打开一个打开一个文本文本文件文件“a” (a” (追加追加) )向向文本文本文件尾增加数据文件尾增加数据“rbrb” (” (只读只读) )为为输入输入打开一个打开一个二进制二进制文件文件“wbwb” (” (只写只写) )为为输出输

130、出打开一个打开一个二进制二进制文件文件ab“ (ab“ (追加追加) )向向二进制二进制文件尾增加数据文件尾增加数据r+“ (r+“ (读写读写) )为为读读/ /写写打开一个打开一个文本文本文件文件w+” (w+” (读写读写) )为为读读/ /写建立写建立一个新的一个新的文本文本文件文件a+” (a+” (读写读写) )为读为读/ /写打开一个文本文件写打开一个文本文件 rbrb+“ (+“ (读写读写) )为读为读/ /写打开一个写打开一个二进制二进制文件文件“wbwb+“ (+“ (读写读写) )为读为读/ /写写建立建立一个新的一个新的二进制二进制文件文件“abab+” (+” (读

131、写读写) )为读为读/ /写打开一个写打开一个二进制二进制文件文件8/5/2024170文件打开举例文件打开举例例如:例如:FILE*fp;fpfp=fopen(“d:a1.txt”=fopen(“d:a1.txt”,“r”); r”); 8/5/2024171说明说明1、打开打开d:d:盘根目录下文件名为盘根目录下文件名为a1.txta1.txt的文件,的文件,打开方式打开方式“r”r”表示只读。表示只读。2、fopenfopen函数返回指向函数返回指向d:a1.txtd:a1.txt的文件指针,的文件指针,然后赋值给然后赋值给fpfp,fpfp-此文件,即此文件,即fpfp与此文件关与此文

132、件关联。联。3、关于文件名要注意:文件名包含文件名关于文件名要注意:文件名包含文件名. .扩展扩展名;路径要用名;路径要用“”表示。表示。8/5/2024172文件打开方式(使用方式)的说明文件打开方式(使用方式)的说明1、文件打开一定要检查、文件打开一定要检查fopen函数的返回值。因为有可函数的返回值。因为有可能文件不能正常打开。不能正常打开时能文件不能正常打开。不能正常打开时fopen函数返回函数返回NULL。可以用下面的形式检查:可以用下面的形式检查:if(fpif(fp= =fopenfopen(.)=NULL)(.)=NULL) printf(“errorprintf(“error

133、 open filen”); exit(1); open filen”); exit(1); 8/5/2024173l关闭文件关闭文件fclose(文件指针文件指针);函数功能函数功能: 使文件指针变量不指向该文件,也就是文件指针变使文件指针变量不指向该文件,也就是文件指针变量与文件量与文件“脱钩脱钩”,此后不能再通过该指针对原来与,此后不能再通过该指针对原来与其相联系的文件进行读写操作。其相联系的文件进行读写操作。返回值返回值:关闭成功返回值为;否则返回关闭成功返回值为;否则返回EOF(-1)。8/5/2024174文件读写函数文件读写函数lfputsfputs函数函数函数调用函数调用: :

134、fputs ( ch,fp ) ; 函数功能函数功能: :将字符(将字符(chch的值)的值)输出输出到到fpfp所指向的文件中所指向的文件中去。去。 返回值返回值: :如果输出成功,则返回值就是输出的字符;如如果输出成功,则返回值就是输出的字符;如果输出失败,则返回一个果输出失败,则返回一个EOFEOF。8/5/2024175写一个字符到磁盘文件写一个字符到磁盘文件格式:格式:fputc(ch,fp)功功能能:将将字字符符ch(可可以以是是字字符符表表达达式式,字字符符常常量量、变量等)写入变量等)写入fp所指向的文件。所指向的文件。返返回回:输输出出成成功功返返回回值值-输输出出的的字字符

135、符ch;输输出出失失败败-返回返回EOF(-1)。)。其它说明:每次写入一个字符,文件位置指针自其它说明:每次写入一个字符,文件位置指针自动指向下一个字节。动指向下一个字节。8/5/2024176从磁盘文件读一个字符从磁盘文件读一个字符格式:格式:ch=fgetc(fp)功功能能:从从fp所所指指向向的的文文件件读读一一个个字字符符,字字符符由由函函数数返返回回。返返回回的的字字符符可可以以赋赋值值给给ch,也也可可以以直直接参与表达式运算。接参与表达式运算。返回:输入成功返回值返回:输入成功返回值- -输入的字符;遇到文件输入的字符;遇到文件结束结束- -返回返回EOFEOF(-1-1)8/

136、5/2024177从磁盘文件读一个字符串从磁盘文件读一个字符串格式:格式:char*fgets(char*str,intn,FILE*fp)l l功功能能:从从fp所所指指向向的的文文件件读读n-1个个字字符符,并并将将这这些些字字符符放放到到以以str为为起起始始地地址址的的单单元元中中。如如果果在在读读入入n-1个个字字符符结结束束前前遇遇到到换换行行符符或或EOF,读读入入结结束束。字字符符串串读读入后最后加一个入后最后加一个0字符。字符。返回:输入成功返回值返回:输入成功返回值- -输入串的首地址;遇到文件结输入串的首地址;遇到文件结束或出错束或出错- -返回返回NULLNULL。8/

137、5/2024178写一个字符串到磁盘文件写一个字符串到磁盘文件格式:格式:fputs(char*str,FILE*fp)LL功功能能:向向fp所所指指向向的的文文件件写写入入以以str为为首首地地址址的的字符串。字符串。返回:输入成功返回值返回:输入成功返回值-0-0;出错;出错- -返回非返回非0 0值。值。8/5/2024179l从一个文本文件顺序读入字符并在屏幕上显示出来:从一个文本文件顺序读入字符并在屏幕上显示出来:ch=fgetc(fp););while(ch!=EOF)putchar(ch););ch=fgetc(fp););注意:注意:EOF不是可输出字符,因此不能在屏幕上显示。

138、由不是可输出字符,因此不能在屏幕上显示。由于字符的于字符的ASCII码不可能出现,因此码不可能出现,因此EOF可定义为可定义为。当读入的字符值等于时,表示读入的已不是正。当读入的字符值等于时,表示读入的已不是正常的字符而是文件结束符。常的字符而是文件结束符。8/5/2024180l从一个从一个二进制文件二进制文件顺序读入字符:顺序读入字符:while(!(!feof(fp)ch=fgetc(fp););注意:注意:ANSIC提供一个提供一个feof()函数来判断文件()函数来判断文件是否真的结束。如果是文件结束,函数是否真的结束。如果是文件结束,函数feof(fp)的值为(真);否则为(假)。

139、)的值为(真);否则为(假)。以上也适用于文本文件的读取以上也适用于文本文件的读取8/5/2024181三、文件的数据块读写三、文件的数据块读写fread(buffer,size,count,fp);fwrite(buffer,size,count,fp);参数说明:参数说明:buffer:是一个指针。是一个指针。对对fread来说,它是读入数据的存放地址。来说,它是读入数据的存放地址。对对fwrite来说,是要输出数据的地址(均指起始地址)。来说,是要输出数据的地址(均指起始地址)。size:要读写的字节数。要读写的字节数。count:要进行读写多少个要进行读写多少个size字节的数据项。字

140、节的数据项。fp:文件型指针。文件型指针。8/5/2024182使用举例:使用举例: 若文件以二进制形式打开:若文件以二进制形式打开: fread(f,4,2,fpfread(f,4,2,fp); 此函数从此函数从fpfp所指向的文件中读入所指向的文件中读入2 2个个4 4个字节的个字节的数据,存储到数组数据,存储到数组f f中。中。8/5/2024183文件的定位文件的定位对文件的读写可以顺序读写,也可以随机读写。对文件的读写可以顺序读写,也可以随机读写。1、文文件件顺顺序序读读写写:从从文文件件的的开开头头开开始始,依依次次读读写写数数据据。(从文件开头读写直到文件尾部)(从文件开头读写直

141、到文件尾部)2、文文件件随随机机读读写写(文文件件定定位位读读写写):从从文文件件的的指指定定位位置置读写数据。读写数据。3、文文件件位位置置指指针针:在在文文件件的的读读写写过过程程中中,文文件件位位置置指指针针指指出出了了文文件件的的当当前前读读写写位位置置(实实际际上上是是:下下一一步步读读写写位位置置),每每次次读读写写后后,文文件件位位置置指指针针自自动动更更新新指指向向新新的读写位置(实际上是:下一步读写位置)。的读写位置(实际上是:下一步读写位置)。 注意区分:文件位置指针,文件指针。注意区分:文件位置指针,文件指针。 8/5/2024184文件位置指针函数文件位置指针函数rewindrewind重返文件头函数重返文件头函数fseekfseek位置指针移动函数位置指针移动函数ftellftell获取当前位置指针函数获取当前位置指针函数8/5/2024185

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

最新文档


当前位置:首页 > 高等教育 > 研究生课件

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