好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

C语言程序设计教程电子教案推荐课件.ppt

317页
  • 卖家[上传人]:壹****1
  • 文档编号:588232260
  • 上传时间:2024-09-07
  • 文档格式:PPT
  • 文档大小:1.25MB
  • / 317 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • C 语言程序设计语言程序设计教程教程刘新铭刘新铭 吉顺如吉顺如 辜碧容辜碧容 郑君华郑君华编著编著2021/8/221 2 2目目目目 录录录录 第第第第1 1章章章章 C C语言概述语言概述语言概述语言概述第第第第2 2章章章章 数据类型、运算符和表达式数据类型、运算符和表达式数据类型、运算符和表达式数据类型、运算符和表达式第第第第3 3章章章章 C C程序中的输入、输出程序中的输入、输出程序中的输入、输出程序中的输入、输出第第第第4 4章章章章 C C程序的控制结构程序的控制结构程序的控制结构程序的控制结构第第第第5 5章章章章 数数数数 组组组组第第第第6 6章章章章 函数函数函数函数第第第第7 7章章章章 编译预处理命令编译预处理命令编译预处理命令编译预处理命令第第第第8 8章章章章 指指指指 针针针针第第第第9 9章章章章 结结结结 构构构构 体体体体第第第第1010章章章章 文文文文 件件件件 第第 1 章章 C语言概述语言概述2021/8/223 4 4学习目标学习目标 对C语言有一个概括的了解,能够编写包含键盘输入、计算和显示输出等操作的简单C程序。

      5 5主要内容主要内容•C C语言的产生与特点语言的产生与特点 •简单简单C C程序的组成程序的组成•C C语言语言应用程序开发的基本步骤应用程序开发的基本步骤 6 61.1 C1.1 C语言的产生及特点语言的产生及特点 C C语言是为了编写系统程序而在语言是为了编写系统程序而在19681968年开始年开始研发的计算机高级语言研发的计算机高级语言C C语言表达能力强,使用灵活,程序结构清语言表达能力强,使用灵活,程序结构清晰,紧凑,可移植性好晰,紧凑,可移植性好C C语言是进一步学习面向对象的程序设计语语言是进一步学习面向对象的程序设计语言言 C++ C++和和VC VC 的基础的基础 7 7 【例【例【例【例1-11-11-11-1】从键盘输入三个整数,输出它们的和】从键盘输入三个整数,输出它们的和】从键盘输入三个整数,输出它们的和】从键盘输入三个整数,输出它们的和 main() /* main() /* main() /* main() /* 计算三个整数的和计算三个整数的和计算三个整数的和计算三个整数的和 */ */ */ */ { { { { int x,y,z,sum; int x,y,z,sum; int x,y,z,sum; int x,y,z,sum; scanf(" scanf(" scanf(" scanf("%%%%d,d,d,d,%%%%d,d,d,d,%%%%d",&x,&y,&z);d",&x,&y,&z);d",&x,&y,&z);d",&x,&y,&z); sum sum sum sum====x+y+z; x+y+z; x+y+z; x+y+z; printf("sum printf("sum printf("sum printf("sum=%=%=%=%d d d d\\\\n "n "n "n ",,,,sum);sum);sum);sum); } } } } 语语语语句句句句 函函函函数数数数体体体体 主函数名主函数名最简单的最简单的最简单的最简单的C C C C程序的组成程序的组成程序的组成程序的组成对程序的对程序的注释注释1.2 C1.2 C语言程序的结构及书写格式语言程序的结构及书写格式 一一一一.C.C.C.C程序的结构程序的结构程序的结构程序的结构 8 8 main() main() { { int x,y,z,sum; int x,y,z,sum; scanf("%d,%d,%d",&x,&y,&z); scanf("%d,%d,%d",&x,&y,&z); sum=x+y+z; sum=x+y+z; printf("sum=%d printf("sum=%d\\n",sum)n",sum) } }定义变量定义变量x x,y,z,y,z和和sumsum从键盘输入三个整从键盘输入三个整数赋给变量数赋给变量x x,y,y和和z z显示变量显示变量sumsum的值的值计算计算x+y+z,x+y+z,并将结并将结果赋给变量果赋给变量sumsum程序说明程序说明 9 9一般一般C C程序的组成程序的组成【例【例【例【例1-21-21-21-2】采用模块结构,改写例】采用模块结构,改写例】采用模块结构,改写例】采用模块结构,改写例1-11-11-11-1的程序。

      的程序add(int x,int y,int z )add(int x,int y,int z )add(int x,int y,int z )add(int x,int y,int z ) { { { { return(x+y+z); return(x+y+z); return(x+y+z); return(x+y+z); } } } } main() main() main() main() { { { { int x,y,z; int x,y,z; int x,y,z; int x,y,z; printf("Please Input Three Integers:\n "); printf("Please Input Three Integers:\n "); printf("Please Input Three Integers:\n "); printf("Please Input Three Integers:\n "); scanf("%d,%d,%d ",&x,&y,&z); scanf("%d,%d,%d ",&x,&y,&z); scanf("%d,%d,%d ",&x,&y,&z); scanf("%d,%d,%d ",&x,&y,&z); printf("sum printf("sum printf("sum printf("sum====%d\n ",add(x,y,z));%d\n ",add(x,y,z));%d\n ",add(x,y,z));%d\n ",add(x,y,z)); } } } }函数函数add()add()主函数主函数main()main()调用函数调用函数add()add() 1010 …… …… 函数函数函数函数1 1主函数主函数主函数主函数main()main()函数函数函数函数2 2函数函数函数函数k k注意:注意: 每个每个C C程序必定有一个、而且只能有一个程序必定有一个、而且只能有一个主函数主函数main() main() 。

      主函数可以调用其它子函数,而子函数不主函数可以调用其它子函数,而子函数不可以调用主函数,子函数彼此之间也可以相可以调用主函数,子函数彼此之间也可以相互调用C C程序的组成程序的组成 1111二二.C.C程序的书写格式程序的书写格式1.C1.C程序允许一行写一个或多个语句程序允许一行写一个或多个语句 ,当,当一个语句分几行书写时,在换行前应加一个语句分几行书写时,在换行前应加上上“\”“\”符,然后从下一行的开头继续符,然后从下一行的开头继续2.2.习惯上,书写习惯上,书写C C程序时均使用小写英文字程序时均使用小写英文字母3.3.C C程序一般都采用缩进格式的书写方法,程序一般都采用缩进格式的书写方法,不同结构层次的语句,从不同的起始位不同结构层次的语句,从不同的起始位置开始,同一结构层次中的语句,缩进置开始,同一结构层次中的语句,缩进同样个数的字符位置同样个数的字符位置4.4.应当在程序中适当地添加一些注释行应当在程序中适当地添加一些注释行 12121.3 C1.3 C程序的编辑、调试和运行程序的编辑、调试和运行编辑源程序编辑源程序编辑源程序编辑源程序 生成目标程序生成目标程序生成目标程序生成目标程序 经编译经编译经编译经编译 经连经连经连经连 接库接库接库接库 修改源程序修改源程序修改源程序修改源程序 函数函数函数函数 生成生成生成生成exeexeexeexe文件文件文件文件 运行运行运行运行 运行时出错运行时出错运行时出错运行时出错编译编译编译编译出错出错出错出错 1313第第1 1章章 结束结束    第第 2 2 章章 数据类型、运算符和表达式数据类型、运算符和表达式 2021/8/2214 1515学习目标学习目标1. 1. 掌握基本数据类型的概念和常量表示掌握基本数据类型的概念和常量表示方法,掌握变量的定义方法,能够根方法,掌握变量的定义方法,能够根据实际情况选用适当的数据类型据实际情况选用适当的数据类型2. 2. 熟练掌握数值表达式的构造方法,能熟练掌握数值表达式的构造方法,能够利用表达式完成数值计算够利用表达式完成数值计算 1616主要内容主要内容•C C数据类型概述数据类型概述•常量和变量常量和变量•算术运算表达式算术运算表达式•赋值表达式赋值表达式•自增、自减表达式自增、自减表达式 17172.1 2.1 概概 述述C C语言支持的数据类型语言支持的数据类型基本基本数据数据类型类型整型整型单精度型单精度型主要主要数据数据类型类型构造构造数据数据类型类型指针指针类型类型实型实型字符型字符型数组类型数组类型结构体类型结构体类型双精度型双精度型 1818基本数据类型说明符基本数据类型说明符整型:整型:intint long long字符型:字符型:charchar实型:实型:floatfloat double double long double long double 19192.2 2.2 常常 量量常量∶在程序运行过程中,其值不能被改在程序运行过程中,其值不能被改 变的量。

      变的量              一一. . 不同数制整型常量的表示不同数制整型常量的表示例如例如: 12 : 12 :十进制数:十进制数 12 12 012 012 :八进制数:八进制数 12 12(等于十进(等于十进制数制数10,10,用前导符用前导符0 0表示八进制数表示八进制数常量)) 0x12 0x12:十六进制数:十六进制数 12 12(等于十(等于十进制数进制数 18 18,用前导符,用前导符0X0X或或0x0x表示十六进表示十六进制数制数常量)) 2020二二. .字符常量的表示字符常量的表示1.1.用用用用‘’‘’‘’‘’括起来的可显示字符括起来的可显示字符括起来的可显示字符括起来的可显示字符, , , ,如如如如∶ ‘∶ ‘∶ ‘∶ ‘A’A’A’A’、、、、‘‘‘‘$’$’$’$’、、、、‘‘‘‘3’ 3’ 3’ 3’ 等等等等( ( ( (转义字符除外转义字符除外转义字符除外转义字符除外) ) ) )2. 2. 2. 2. 用八进制数表示其用八进制数表示其用八进制数表示其用八进制数表示其ASCASCASCASC代码的字符代码的字符代码的字符代码的字符, , , ,如如如如‘‘‘‘\101’\101’\101’\101’表表表表示西文字符示西文字符示西文字符示西文字符 A A A A、、、、‘‘‘‘\63’\63’\63’\63’表示数字字符表示数字字符表示数字字符表示数字字符 3 3 3 3。

      3. 3. 3. 3. 用十六进制数表示其用十六进制数表示其用十六进制数表示其用十六进制数表示其ASCASCASCASC代码的字符代码的字符代码的字符代码的字符, , , ,如如如如:‘\x41’:‘\x41’:‘\x41’:‘\x41’表示西文字符表示西文字符表示西文字符表示西文字符A A A A、、、、 ‘ ‘ ‘ ‘\x2A’\x2A’\x2A’\x2A’表示字符表示字符表示字符表示字符 * * * *4. 4. 4. 4. 用用用用‘‘‘‘\’ ’\’ ’\’ ’\’ ’表示字符表示字符表示字符表示字符’ ’ ’ ’ ,,,,‘‘‘‘\”’\”’\”’\”’表示字符表示字符表示字符表示字符””””,,,, ‘‘‘‘\\ ’\\ ’\\ ’\\ ’表示字符表示字符表示字符表示字符\ \ \ \ 5. 5. 5. 5. 用双引号括起来的字符序列表示字符串常量,其用双引号括起来的字符序列表示字符串常量,其用双引号括起来的字符序列表示字符串常量,其用双引号括起来的字符序列表示字符串常量,其中最后一个字符是字符串结束符中最后一个字符是字符串结束符中最后一个字符是字符串结束符中最后一个字符是字符串结束符‘‘‘‘\0’\0’\0’\0’,不显式,不显式,不显式,不显式地表示出来。

      如地表示出来如地表示出来如地表示出来如:“English” :“English” :“English” :“English” 2121【例【例2-12-1】常量的例子】常量的例子             main()              {                 float r;                 printf("Please Input Radius:\n");                 scanf("%f",&r);                 printf("The Circumference of Cirle: %f\n",                                                            2*3.1415926*r);    }定义浮点型定义浮点型变量变量r r人机对话,通知用户人机对话,通知用户输入半径的值输入半径的值从键盘输入半径的值,从键盘输入半径的值,并将值赋给变量并将值赋给变量r r显示结果显示结果常量常量2 2常量常量3.14159263.1415926 2222三三. . 符号常量符号常量 可以用可以用可以用可以用#define#define#define#define命令定义符号常量,在程序的执命令定义符号常量,在程序的执命令定义符号常量,在程序的执命令定义符号常量,在程序的执行过程中不允许改变符号常量的值。

      行过程中不允许改变符号常量的值行过程中不允许改变符号常量的值行过程中不允许改变符号常量的值例【例2-22-2】说明符号常量的例子】说明符号常量的例子#define PRICE 30 main( )  {     int num,total;     num=10;     total=num*PRICE;     printf("total=%d",total);  }通过通过#include#include定义符号常定义符号常量量PRICEPRICE为为3030定义二个整型变量定义二个整型变量numnum和和totaltotal使变量使变量numnum的值为的值为1010执行运算执行运算10×3010×30并把运算的结果赋并把运算的结果赋予变量予变量totaltotal显示结果显示结果 23232.3 2.3 变量的定义和初始化变量的定义和初始化变量变量: :在程序运行时,其值可变的量被称为变量在程序运行时,其值可变的量被称为变量, , 分为整型变量、实型变量和字符型变量分为整型变量、实型变量和字符型变量一一. C. C语言中的标识符语言中的标识符 C C语言把用户给常量、变量、函数、标号和其它语言把用户给常量、变量、函数、标号和其它对象所起的名字统称为标识符。

      对象所起的名字统称为标识符用户定义的标识符须遵循如下规则:用户定义的标识符须遵循如下规则: 标识符只能由字母、数字和下划线三种字符组成,标识符只能由字母、数字和下划线三种字符组成,且第一个字符必须为字母或下划线,标识符的长度不且第一个字符必须为字母或下划线,标识符的长度不超过超过3232个字符同时,个字符同时,C C语言的关键字和库函数名不语言的关键字和库函数名不能作为标识符能作为标识符 2424例如,下面的字符序列均为合法的例如,下面的字符序列均为合法的C C语言标识符:语言标识符:a a,,b b,,wordword,,_file_file,,file2file2,,F_name, f_nameF_name, f_name注意:注意:C C编译程序字母区分大小写,所以上述编译程序字母区分大小写,所以上述F_nameF_name和和 f_name f_name是二个不同的标识符是二个不同的标识符下面的字符序列为不合法的下面的字符序列为不合法的C C语言标识符:语言标识符:2L ── 2L ── 违反了违反了标识符第一个字符必须为字母标识符第一个字符必须为字母 或下划线或下划线的规定。

      的规定a** ── a** ── 违反了违反了标识符只能由字母、数字和下标识符只能由字母、数字和下 划线三种字符组成划线三种字符组成的规定int ── int ── 违反了违反了C C语言的关键字和库函数名不语言的关键字和库函数名不 能作为标识符能作为标识符的规定 2525二二. . 变量分类变量分类 1. 1.整型变量分类整型变量分类有符号整型说明符有符号整型说明符有符号整型说明符有符号整型说明符无符号整型说明符无符号整型说明符无符号整型说明符无符号整型说明符整整整整型型型型intintintintsignedsignedsignedsigned   signed int signed int signed int signed int unsignedunsignedunsignedunsignedunsignedunsignedunsignedunsigned   int int int int 长长长长整整整整型型型型longlonglonglonglonglonglonglong   intintintintsignedsignedsignedsigned   longlonglonglongsignedsignedsignedsigned   long int long int long int long int unsignedunsignedunsignedunsigned   longlonglonglongunsignedunsignedunsignedunsigned   long int long int long int long int   2626有符号整型有符号整型有符号整型有符号整型无符号整型无符号整型无符号整型无符号整型占字节数占字节数占字节数占字节数整整整整型型型型 int int int int-32768 ~32767 -32768 ~32767 -32768 ~32767 -32768 ~32767 unsigned unsigned unsigned unsigned 0 ~65535 0 ~65535 0 ~65535 0 ~65535 2 2 2 2字字字字节节节节长长长长整整整整型型型型 long long long long -2 -2 -2 -231313131~(2~(2~(2~(231313131-1)-1)-1)-1) unsigned unsigned unsigned unsigned   longlonglonglong 0~4,294,967,295 0~4,294,967,295 0~4,294,967,295 0~4,294,967,2954 4 4 4字字字字节节节节整型变量的值域整型变量的值域 27272.2.浮点型变量的分类及其值域浮点型变量的分类及其值域Long doubleLong doubleLong doubleLong double取值取值取值取值(绝对值(绝对值(绝对值(绝对值) ) ) ) 范围范围范围范围 占字节数占字节数占字节数占字节数10101010-4931-4931-4931-4931~10~10~10~104932493249324932 单精度单精度单精度单精度型型型型双精度双精度双精度双精度型型型型10101010-37-37-37-37~10~10~10~1038383838 4 4 4 4 float float float float    double double double double 10101010-307-307-307-307~10~10~10~10308308308308 浮点浮点浮点浮点型型型型说明符说明符说明符说明符816 28283.3.字符型变量及其值域字符型变量及其值域说明符说明符说明符说明符取值范围取值范围取值范围取值范围(字符的(字符的(字符的(字符的ASCASC码值)码值)码值)码值)占字节数占字节数占字节数占字节数 char char0 ~ 2550 ~ 255 1 1在设计程序时,应当根据数据本身的特点和变化范围正确选择变量类型。

      2929三三. .变量的定义和初始化变量的定义和初始化 变量的定义格式:变量的定义格式: 类型说明符类型说明符 变量名表变量名表 ; intint、、unsignedunsigned、、longlong、、floatfloat、、doubledouble、、charchar等等变量名只能由字母变量名只能由字母变量名只能由字母变量名只能由字母、数字和下划线三种、数字和下划线三种、数字和下划线三种、数字和下划线三种字符组成,且第一字符组成,且第一字符组成,且第一字符组成,且第一个字符必须为字母个字符必须为字母个字符必须为字母个字符必须为字母或下划线或下划线或下划线或下划线例如,语句:例如,语句: int a1,a2,age;; float x,y,z;; char ch;;分别定义了整型变量分别定义了整型变量a1,a2,age,浮点型变量,浮点型变量x,y,z和字符型变量和字符型变量ch 3030变量的初始化:变量的初始化: 在定义变量的同时对变量预在定义变量的同时对变量预 先设置初值。

      先设置初值 例如,执行语句例如,执行语句: : int num=20; float pi=3.14; char c1,c2= ' M' ; 变量变量num、、pi、、c2的初值分别为的初值分别为20、、 3.14和和 字符字符M 3131四四. .各类数值型数据间的混合运算各类数值型数据间的混合运算 高高 double float double float long long unsigned unsigned  低低 int char int char当各种当各种不同类型的数据混合运算时不同类型的数据混合运算时,,其运算结果的其运算结果的类型由上图所示的类型转换原则确定类型由上图所示的类型转换原则确定。

      3232【例【例2-32-3】设程序中定义变量:】设程序中定义变量:int  i; float  f; double  d; 执行运算:执行运算:i+(f*d)-(f+i) (i+(f*d)-(f+i) (这里的这里的 * * 表示乘法表示乘法) )下图给出了在运算过程中所发生的数据类型的转换下图给出了在运算过程中所发生的数据类型的转换 i+ ( f * d ) - ( f + i ) i+ ( f * d ) - ( f + i )   double double double double double double  double double double double   double double double double double double  double double 33332.4 2.4 算术运算符和算术运算表达式算术运算符和算术运算表达式一一. . 算术算术运算符运算符算术算术运算符运算符包括:包括: + + (加)(加) - - (减)(减) * * (乘)(乘) / / (除)(除) % % (求余)(求余)操作符操作符操作符操作符 % % 只作用于整数只作用于整数只作用于整数只作用于整数x%y x%y 的值就是的值就是的值就是的值就是 x x除以除以除以除以 y y 的余数。

      的余数 3434 操作符操作符 / / 的两种含义:的两种含义:整数除法(整除)整数除法(整除) 当被除数和除数都是整型数据时,当被除数和除数都是整型数据时,“\”“\”运算的结果为整型运算的结果为整型例如:例如:5/25/2的值为的值为2 2(而不是(而不是2.52.5))实数除法实数除法 当被除数和除数中至少有一个是当被除数和除数中至少有一个是实数型数据时,实数型数据时,“\”“\”运算的结果为运算的结果为实数型 例如:例如:5.0/25.0/2的值为的值为2.52.5 3535二二. .算术运算表达式算术运算表达式 用算术运算符和括号将运算对象连接起来、用算术运算符和括号将运算对象连接起来、并符合并符合C C语言语法规则的式子,称为算术运算表语言语法规则的式子,称为算术运算表达式或算术表达式达式或算术表达式 例如例如: :设设r r、、x x、、y y是已经定义的数值型变量是已经定义的数值型变量, ,则则: 3.14*r*r: 3.14*r*r、、x+2*y-3/zx+2*y-3/z、、(x-y)*(x-y/2)(x-y)*(x-y/2)均是合法的算术运算表达式,单独的均是合法的算术运算表达式,单独的r r、、x x、、y y也也是合法的算术运算表达式。

      实际上,单独的常是合法的算术运算表达式实际上,单独的常量或变量是最简单的算术运算表达式量或变量是最简单的算术运算表达式注意:注意:算术算术运算运算表达式表达式中的分数线须用中的分数线须用中的分数线须用中的分数线须用 / / / / 表示表示表示表示 例如:例如:例如:例如: 2+3×i 2+3×i 2+3×i 2+3×i k×j k×j k×j k×j 表示为表示为表示为表示为C C C C语言表达式就是:语言表达式就是:语言表达式就是:语言表达式就是:(2+3*i)/(k*j) (2+3*i)/(k*j) (2+3*i)/(k*j) (2+3*i)/(k*j) 或或或或 (2+3*i)/k/j (2+3*i)/k/j (2+3*i)/k/j (2+3*i)/k/j 3636C C程序中,称表达式的运算结果为程序中,称表达式的运算结果为表达式的值表达式的值。

      C C语言规定,在表达式求值时,须按运算符优先级的语言规定,在表达式求值时,须按运算符优先级的高低次序执行高低次序执行对算术运算而言,必须遵循先括号对算术运算而言,必须遵循先括号内后括号外,先乘、除及求余运算,后加减的运算内后括号外,先乘、除及求余运算,后加减的运算优先级规则优先级规则C C语言规定了运算符二种不同的结合方向:语言规定了运算符二种不同的结合方向:l左结合:左结合:当参于运算的数据两侧的运算符优先级当参于运算的数据两侧的运算符优先级 相同时,运算顺序为自左至右相同时,运算顺序为自左至右C C语言规定语言规定算术运算符遵循左结合的规则算术运算符遵循左结合的规则 例如,计算算术运算表达式例如,计算算术运算表达式 a+b-c a+b-c 时,时, 运算符运算符““+”+”和和““–”–”具有相同的优先级,所以先执行具有相同的优先级,所以先执行 a+ba+b,, 其结果再和其结果再和c c相减 3737l右结合:右结合:当参于运算的数据两侧的运算符优先级当参于运算的数据两侧的运算符优先级 相同时,运算顺序为自右向左。

      相同时,运算顺序为自右向左 C C语言提供的运算符中有少量运算符遵循右结合的语言提供的运算符中有少量运算符遵循右结合的规则 教材的附录部分列出了教材的附录部分列出了C C语言中所有运算符以及它语言中所有运算符以及它 们的优先级和结合性们的优先级和结合性 38382 .5 2 .5 赋值运算符与赋值运算表达式赋值运算符与赋值运算表达式一一. .赋值运算符赋值运算符 赋值符号赋值符号“=”“=”就是赋值运算符,它的作用是将一就是赋值运算符,它的作用是将一个数据赋给一个变量个数据赋给一个变量例如:执行程序段例如:执行程序段 int a; int a; a=3; a=3; a=a-5; a=a-5; 当执行语句当执行语句“a=3;” “a=3;” 就完成一次赋值运算,把赋就完成一次赋值运算,把赋 值运算符右边的值值运算符右边的值3 3赋给赋值运算符左边的变量赋给赋值运算符左边的变量a a,, 赋值后,赋值后,a a的值为的值为3 3 。

      再执行语句再执行语句“a=a-5;”“a=a-5;”,赋值,赋值 运算符右边的表达式运算符右边的表达式a-5a-5的运算结果为的运算结果为-2, -2, 将将-2-2赋赋 给给a a 最后,变量最后,变量a a的值变为的值变为-2-2 3939复合的赋值运算符复合的赋值运算符复合的赋值运算符的格式:复合的赋值运算符的格式: 算术运算符算术运算符 = 所以,所以,+=、、-=、、*=、、/=、、%= 都是复合的赋值运算符都是复合的赋值运算符二二. .赋值运算表达式赋值运算表达式 将一个变量通过赋值运算符或复合的赋值运算符与将一个变量通过赋值运算符或复合的赋值运算符与一个表达式连接而成的式子称为赋值运算表达式一个表达式连接而成的式子称为赋值运算表达式赋值运算表达式的格式为:赋值运算表达式的格式为: 变量名变量名 = = 表达式表达式 或或 变量名变量名 复合的赋值运算符复合的赋值运算符 表达式表达式 例如:例如:x=1.414 , m1=x=1.414 , m1=''E E'',s=3.14159*r*r,s=3.14159*r*r 或或 a+=5 a+=5,,x/=a+1 x/=a+1 上述各例都是合法的赋值运算表达式。

      上述各例都是合法的赋值运算表达式 4040 赋值运算表达式的作用是把赋值运算符右边表达式赋值运算表达式的作用是把赋值运算符右边表达式的值赋给赋值运算符左边的变量的值赋给赋值运算符左边的变量当算术运算符和赋当算术运算符和赋值运算符同时出现在一个表达式中时,算术运算符的值运算符同时出现在一个表达式中时,算术运算符的优先级高于赋值运算符优先级高于赋值运算符 C C语言允许赋值运算表达式中的表达式部分还是一语言允许赋值运算表达式中的表达式部分还是一个赋值表达式,这样就构成了多重赋值多重赋值个赋值表达式,这样就构成了多重赋值多重赋值表达式中,赋值运算符遵循右结合的法则,即:表达式中,赋值运算符遵循右结合的法则,即:自右向左的运算顺序自右向左的运算顺序 例如:多重赋值语句例如:多重赋值语句 a=b=c=x+8; a=b=c=x+8; 在执行时等价于依次执行三个语句:在执行时等价于依次执行三个语句: c=x+8; c=x+8; b=c; b=c; a=b; a=b; 4141 将一个变量通过复合的赋值运算符与一个表达式连将一个变量通过复合的赋值运算符与一个表达式连接而成的式子同样称为赋值运算表达式。

      接而成的式子同样称为赋值运算表达式 例如:例如: a+=5 a+=5,,x/=a+1x/=a+1 下面的例子说明了复合的赋值运算符的运算规则下面的例子说明了复合的赋值运算符的运算规则 表达式表达式 a+=5 a+=5 等价于等价于 a=a+5 a=a+5表达式表达式 a*=4-b a*=4-b 等价于等价于 a=a*(4-b) a=a*(4-b)表达式表达式 a%=b-1 a%=b-1 等价于等价于 a=a%(b-1) a=a%(b-1)注意:注意: 复合的赋值运算符右边的表达式是作为一个整体复合的赋值运算符右边的表达式是作为一个整体参与其左边算术运算符所规定的运算的参与其左边算术运算符所规定的运算的 4242【例【例【例【例2-42-42-42-4】赋值运算表达式举例】赋值运算表达式举例】赋值运算表达式举例】赋值运算表达式举例1 1 1 1))))y=3*(x-1)y=3*(x-1)y=3*(x-1)y=3*(x-1);;;; /* /* /* /* 将将将将3*(x-1) 3*(x-1) 3*(x-1) 3*(x-1) 的结果的结果的结果的结果 赋值给变量赋值给变量赋值给变量赋值给变量y y y y。

      /*/*/*/2 2 2 2))))a=(b=4)+(c=6)a=(b=4)+(c=6)a=(b=4)+(c=6)a=(b=4)+(c=6);;;; /* /* /* /* 这里的赋值运算表这里的赋值运算表这里的赋值运算表这里的赋值运算表 达式达式达式达式(b=4)(b=4)(b=4)(b=4)、、、、(c=6)(c=6)(c=6)(c=6)参于算术运算,参于算术运算,参于算术运算,参于算术运算,C C C C 言规定言规定言规定言规定, , , , 将赋值运算符右边表达式的值将赋值运算符右边表达式的值将赋值运算符右边表达式的值将赋值运算符右边表达式的值 作为赋值运算表达式的值作为赋值运算表达式的值作为赋值运算表达式的值作为赋值运算表达式的值所以,赋所以,赋所以,赋所以,赋 值运算表达式值运算表达式值运算表达式值运算表达式(b=4)(b=4)(b=4)(b=4)的值为的值为的值为的值为4, (c=6)4, (c=6)4, (c=6)4, (c=6) 的值为的值为的值为的值为6,6,6,6,最后将它们的和赋值给变量最后将它们的和赋值给变量最后将它们的和赋值给变量最后将它们的和赋值给变量a a a a,,,, 由于算术运算符的优先级高于赋值运由于算术运算符的优先级高于赋值运由于算术运算符的优先级高于赋值运由于算术运算符的优先级高于赋值运 算符,所以表达式中的括号是必须的。

      算符,所以表达式中的括号是必须的算符,所以表达式中的括号是必须的算符,所以表达式中的括号是必须的 */ */ */ */ 43433 3 3 3))))a+=a*=a+2a+=a*=a+2a+=a*=a+2a+=a*=a+2;;;; /* /* /* /* 这里的语句等价于:这里的语句等价于:这里的语句等价于:这里的语句等价于: a=a*(a+2); a=a*(a+2); a=a*(a+2); a=a*(a+2); a=a+a; */ a=a+a; */ a=a+a; */ a=a+a; */ 三三三三. . . .字符型与整型的关系字符型与整型的关系字符型与整型的关系字符型与整型的关系1.1.字符型数据的值在内存表现为它们的字符型数据的值在内存表现为它们的字符型数据的值在内存表现为它们的字符型数据的值在内存表现为它们的ASCASCASCASC代码代码代码代码值(值(值(值(0 -- 2550 -- 2550 -- 2550 -- 255之间的一个整数之间的一个整数之间的一个整数之间的一个整数) ) ) ) 2. 2. 2. 2. 字符常量以其字符常量以其字符常量以其字符常量以其ASCASCASCASC代码值参与整数运算。

      代码值参与整数运算代码值参与整数运算代码值参与整数运算如:如:如:如: ‘ ‘ ‘ ‘A’+2 A’+2 A’+2 A’+2 的值为的值为的值为的值为 67676767字符字符A A的的ASCASC码值码值为为6565 4444【例【例【例【例2-52-52-52-5】字符型变量参与算术运算】字符型变量参与算术运算】字符型变量参与算术运算】字符型变量参与算术运算 main() main() main() main() { { { { int a; int a; int a; int a; char i; char i; char i; char i; a='B'-1; a='B'-1; a='B'-1; a='B'-1; i=a+10; i=a+10; i=a+10; i=a+10; printf("a printf("a printf("a printf("a::::%d, a%d, a%d, a%d, a::::%c\n",a,a);%c\n",a,a);%c\n",a,a);%c\n",a,a); printf("i printf("i printf("i printf("i::::%d, i%d, i%d, i%d, i::::%c\n",i,i);%c\n",i,i);%c\n",i,i);%c\n",i,i); } } } } 以字符格式输以字符格式输出变量出变量a a的值的值结果为字符结果为字符A A以整型格式输以整型格式输出变量出变量a a的值的值结果为结果为6767 4545【【例2-6】】大小写字母的转换 main()main() { { char c1='a',c2='B'; char c1='a',c2='B'; c1=c1-32; c1=c1-32; c2=c2+32; c2=c2+32; printf("c1: %c, c2 %c",c1,c2); printf("c1: %c, c2 %c",c1,c2); } }大小写英文字母大小写英文字母的的ASCASC码值相差码值相差3232 46462.6 2.6 自增、自减运算符自增、自减运算符++++、、----功能功能: (: (设设i i为整型变量为整型变量) )++i:++i:在使用在使用i i之前之前, ,先执行先执行i+=1,i+=1,使使i i的值加的值加1 1。

      i:--i:在使用在使用i i之前之前, ,先执行先执行i-=1,i-=1,使使i i的值减的值减1 1i++:i++:在使用在使用i i之后,执行之后,执行i+=1, i+=1, 使使i i的值加的值加1 1i--:i--:在使用在使用i i之后,执行之后,执行i-=1, i-=1, 使使i i的值减的值减1 1上上述述““使使用用””指指的的是是i i加加1 1或或减减1 1前前后后的的其其他他操操作作, ,如赋值、运算、显示等如赋值、运算、显示等若若不不存存在在其其它它操操作作,,则则i++i++与与++i++i一一样样,,执执行行i+=1, i+=1, 使使i i的的值值加加1 1;;i--i--与与--i--i一一样样, , 执执行行i-i-=1, =1, 使使i i的值减的值减1 1 4747【例【例2-72-7】自加、自减运算符的应用自加、自减运算符的应用 main() main() { { int i=10,j; int i=10,j; float pi=3.14,pa; float pi=3.14,pa; j =i++; j =i++; pa=++pi; pa=++pi; printf("j=%d, pa=%f\n",j,pa); printf("j=%d, pa=%f\n",j,pa); printf("i=%d, pi=%f\n", i++,--pi); printf("i=%d, pi=%f\n", i++,--pi); } }先将先将i i的值赋给变量的值赋给变量j j再执行再执行i+=1i+=1;;先执行先执行pi+=1pi+=1;;再将再将pipi的值赋给变量的值赋给变量papa先将先将i i的值输出的值输出再执行再执行i+=1i+=1;;先执行先执行pi-=1pi-=1;;再将再将pipi的值输出的值输出 48482.7 2.7 位运算符位运算符  位运算以字节位运算以字节(byte)(byte)中的每一个二进位中的每一个二进位(bit)(bit)为运为运算对象,最终的运算结果是整型数据。

      算对象,最终的运算结果是整型数据 位运算分为按位逻辑运算和移位运算位运算分为按位逻辑运算和移位运算一一. .按位逻辑运算符按位逻辑运算符 按位逻辑运算符包括:按位逻辑运算符包括: 按位逻辑与运算符:按位逻辑与运算符:“&”“&” 按位逻辑或运算符:按位逻辑或运算符:“|”“|” 按位逻辑非运算符:按位逻辑非运算符:“~”“~” 按位逻辑异或运算符:按位逻辑异或运算符:“^”“^”运算法则运算法则设用设用x x、、y y表示字节中的二进位,取值为表示字节中的二进位,取值为0 0或或1 1按位逻辑运算符的运算法则为逻辑运算符的运算法则为:: 4949按位逻辑与运算:按位逻辑与运算:x&yx&y的结果为的结果为1 1,当且仅当,当且仅当x x、、y y均为均为1 1,否则,否则x&yx&y的的结果为结果为0 0按位逻辑或运算:按位逻辑或运算:x|yx|y的结果为的结果为0 0,当且仅当,当且仅当x x、、y y均为均为0 0,否则,否则x|yx|y的的结果为结果为1 1。

      按位逻辑异或运算:按位逻辑异或运算:x^yx^y的结果为的结果为1 1,当且仅当,当且仅当x x、、y y的值不相同,否则的值不相同,否则x^yx^y的结果为的结果为0 0按位逻辑非运算:按位逻辑非运算: 当当x=1x=1时,时,~x=0, ~x=0, 而当而当x=0x=0时时, ~x=1, ~x=1 位运算表达式的格式:位运算表达式的格式:整型变量名整型变量名 运算符运算符(&(&、、| |、、^) ^) 整型变量名整型变量名或或 ~ ~整型变量名整型变量名 5050【例【例2-82-8】位运算符的应用】位运算符的应用设有:设有: int a=55,b=36; int a=55,b=36; 计算计算: a&b: a&b、、a|ba|b、、a^ba^b及及~a~a的结果 假定每个整型变量占二个字节假定每个整型变量占二个字节(16bit)(16bit),则在内存中的二进,则在内存中的二进 制数制数a a、、b b为:为: a: 00000000 00110111 b: 00000000 00100100 a: 00000000 00110111 b: 00000000 00100100 按上述按位运算的法则,列出下述算式:按上述按位运算的法则,列出下述算式: a&b: a|b:a&b: a|b: 00000000 00110111 00000000 00110111 00000000 00110111 00000000 00110111 & 00000000 00100100 | 00000000 00100100 & 00000000 00100100 | 00000000 00100100 00000000 00100100 00000000 00110111 00000000 00100100 00000000 00110111  a^b:a^b: 00000000 00110111 00000000 00100100 a: 00000000 00110111 00000000 00110111 00000000 00100100 a: 00000000 00110111 ^ 00000000 00100100 ~a: 11111111 11001000 ^ 00000000 00100100 ~a: 11111111 11001000 00000000 00010011 00000000 00010011结果:结果:a&b=24, a|b=37a&b=24, a|b=37 a^b=13, ~a=ffc8 a^b=13, ~a=ffc8(用十六进制表示)(用十六进制表示) 5151二二. .移位运算符移位运算符 C C语言提供的移位运算实现将整数数据按二语言提供的移位运算实现将整数数据按二进位右移或左移的功能。

      进位右移或左移的功能向右移位运算符向右移位运算符: : “>>”, “>>”, 向左移位运算符向左移位运算符: : “<<” “<<”移位运算表达式的格式:移位运算表达式的格式:整型变量名整型变量名 移位运算符移位运算符 整型常量整型常量其中,整型常量指出右移或左移的位数其中,整型常量指出右移或左移的位数例【例2-92-9】移位运算符的应用】移位运算符的应用设定义设定义 int a=55,b=36; int a=55,b=36; 计算计算 (a+b)>>2 (a+b)>>2、、(a-b)<<3(a-b)<<3的结果 a+b a+b和和a-ba-b的结果的结果9191和和1919在内存中的二进制数分别为:在内存中的二进制数分别为: a+b: 00000000 01011011 a+b: 00000000 01011011 和和 a-b: 00000000 00010011 a-b: 00000000 00010011 5252 a+b: 00000000 01011011 a+b: 00000000 01011011(a+b)>>2: 00000000 010110(a+b)>>2: 00000000 010110左边补左边补0 0 结果结果: 00000000 00010110: 00000000 00010110 a-b: 00000000 00010011 a-b: 00000000 00010011(a-b)<<3: 00000 00010011(a-b)<<3: 00000 00010011右边补右边补0 0结果结果: 00000000 10011000: 00000000 10011000 53532.8 2.8 其他运算符和表达式其他运算符和表达式 一一. .强制类型转换运算符强制类型转换运算符 C C语言提供的强制类型转换运算符可以将一语言提供的强制类型转换运算符可以将一个表达式转换成指定的数据类型。

      个表达式转换成指定的数据类型 格式:格式: (类型说明符)(表达式)(类型说明符)(表达式)例如:例如:(double)(x+y) /* (double)(x+y) /* 将表达式将表达式x+yx+y的结果转换的结果转换 成双精度型成双精度型 */ */ (int)a /* (int)a /* 将变量将变量a a的值转换成的值转换成intint类型类型 */ */ 5454【例【例2-102-10】强制类型转换运算符的使用】强制类型转换运算符的使用 main( ) main( ) { { float x=3.6,y=6.6; float x=3.6,y=6.6; printf("x+y=%f\n",x+y); printf("x+y=%f\n",x+y); printf("x+y=%f\n",(int)x+(int)y); printf("x+y=%f\n",(int)x+(int)y); } }将将x x的值强制转换的值强制转换成整型值成整型值3 3将将y y的值强制转换的值强制转换成整型值成整型值6 6 5555二二. .逗号运算符和逗号表达式逗号运算符和逗号表达式 C C语言通过逗号运算符语言通过逗号运算符““,,” ” 将两个以上的表将两个以上的表达式连接起来,组成逗号表达式。

      达式连接起来,组成逗号表达式逗号表达式的一般格式:逗号表达式的一般格式:表达式表达式1 1,表达式,表达式2 2,,…………,表达式,表达式k k 逗号表达式的运算:逗号表达式的运算: 依次求表达式依次求表达式1 1、表达式、表达式2 2、、…………、表达式、表达式k k 的值,并的值,并以最后一个表达式以最后一个表达式k k的值作为整个的值作为整个 逗号表达式的值逗号表达式的值 例如,语句:例如,语句:x=(a=3,6*3)x=(a=3,6*3);;等价于:等价于: a = 3 a = 3;; x=6*3 x=6*3;; x = 6*3 x = 6*3;;将表达式将表达式6*36*3的结果的结果作为整个逗号表达式作为整个逗号表达式的值的值 5656第第2章章 结束结束       第第 3 3 章章C C程序中的输入、输出程序中的输入、输出2021/8/2257 5858学习目标学习目标 对对C C语言的输入、输出有一个初步的了语言的输入、输出有一个初步的了解,学会使用解,学会使用scanf()scanf()、、 printf() printf()函数函数实现整型、浮点型和字符型数据的输入、实现整型、浮点型和字符型数据的输入、输出。

      输出 5959主要内容主要内容 · C · C · C · C语言的输入、输出语言的输入、输出语言的输入、输出语言的输入、输出 · printf() · printf() · printf() · printf()函数函数函数函数 · scanf() · scanf() · scanf() · scanf()函数函数函数函数 · getchar() · getchar() · getchar() · getchar()函数和函数和函数和函数和putchar()putchar()putchar()putchar()函数函数函数函数 60603.1 3.1 概述概述 C C C C语言中没有输入、输出语句,通过调用库函数语言中没有输入、输出语句,通过调用库函数语言中没有输入、输出语句,通过调用库函数语言中没有输入、输出语句,通过调用库函数中的输入、输出函数中的输入、输出函数中的输入、输出函数中的输入、输出函数 printf() printf() printf() printf()、、、、scanf()scanf()scanf()scanf()、、、、getchargetchargetchargetchar()()()()和和和和putchar() putchar() putchar() putchar() 实现输入、输出。

      实现输入、输出实现输入、输出实现输入、输出 在使用输入、输出函数时,应当在源程序的开在使用输入、输出函数时,应当在源程序的开在使用输入、输出函数时,应当在源程序的开在使用输入、输出函数时,应当在源程序的开始处使用始处使用始处使用始处使用 #include #include #include #include 命令将输入、输命令将输入、输命令将输入、输命令将输入、输出函数的头文件包含进来,以便在编译时实现连出函数的头文件包含进来,以便在编译时实现连出函数的头文件包含进来,以便在编译时实现连出函数的头文件包含进来,以便在编译时实现连接 6161一一. . 格式输出函数格式输出函数 printf() printf()函数函数功能功能功能功能∶∶∶∶从指定的输出设备输出数据,从指定的输出设备输出数据,从指定的输出设备输出数据,从指定的输出设备输出数据, 默认的输出设备为显示器默认的输出设备为显示器默认的输出设备为显示器默认的输出设备为显示器使用格式使用格式∶∶ printfprintf(格式控制,输出表列)(格式控制,输出表列)由由格式控制格式控制格式控制格式控制符符符符%%和格式和格式和格式和格式字符字符字符字符实现实现实现实现表达式表达式表达式表达式3.2 3.2 格式输入、输出函数格式输入、输出函数scanf( )scanf( )和和printf( )printf( ) 6262格式控制的内容格式控制的内容这部分是用双引号括起来的字符串,其中包含这部分是用双引号括起来的字符串,其中包含这部分是用双引号括起来的字符串,其中包含这部分是用双引号括起来的字符串,其中包含两种信息:两种信息:两种信息:两种信息: l格式说明:格式说明:格式说明:格式说明:由由由由% % % %和格式字符组成。

      如和格式字符组成如和格式字符组成如和格式字符组成如%d%d%d%d、、、、%f%f%f%f、、、、 %f%f%f%f等,它们的作用是将待输出的等,它们的作用是将待输出的等,它们的作用是将待输出的等,它们的作用是将待输出的 数据按指定的格式输出数据按指定的格式输出数据按指定的格式输出数据按指定的格式输出l普通字符:普通字符:普通字符:普通字符:即需要按原样输出的字符即需要按原样输出的字符即需要按原样输出的字符即需要按原样输出的字符例如,语句:例如,语句:例如,语句:例如,语句: printf("Totalprintf("Total Number is %d, Number is %d, Price is %f\n",total,price) Price is %f\n",total,price);;;; 中的中的中的中的 Total Number isTotal Number is 、、、、 Price isPrice is 6363●●输出表列部分输出表列部分:: 这部分是需要输出的数据值,通常是这部分是需要输出的数据值,通常是 表达式表达式, , 如上例中的如上例中的totaltotal、、priceprice。

      常用的常用的printf()printf()格式字符格式字符   格式字符格式字符格式字符格式字符 说说说说 明明明明 c (*) c (*) 以字符形式输出,只输出一个字符以字符形式输出,只输出一个字符以字符形式输出,只输出一个字符以字符形式输出,只输出一个字符d (*) d (*) 以带符号的十进制形式输出整数(正数不输出符号)以带符号的十进制形式输出整数(正数不输出符号)以带符号的十进制形式输出整数(正数不输出符号)以带符号的十进制形式输出整数(正数不输出符号) e e或或或或,E ,E 以以以以指数形式指数形式指数形式指数形式输出实数,数字部分小数位数为输出实数,数字部分小数位数为输出实数,数字部分小数位数为输出实数,数字部分小数位数为6 6位位位位 f (*) f (*) 以小数形式输出单、双精度数,隐含输出以小数形式输出单、双精度数,隐含输出以小数形式输出单、双精度数,隐含输出以小数形式输出单、双精度数,隐含输出6 6位小数位小数位小数位小数 l l 用于用于用于用于长整型数据长整型数据长整型数据长整型数据,可加在格式符,可加在格式符,可加在格式符,可加在格式符d d,,,,o o,,,,x x,,,,u u前面前面前面前面 如如如如∶ ∶ ∶ ∶2.5E-32.5E-3相相相相当于当于当于当于∶ ∶ ∶ ∶2.5×102.5×10-3-3如如如如∶ ∶ ∶ ∶%ld,%lo, %lx%ld,%lo, %lx等等等等 6464接上页接上页接上页接上页格式字符格式字符格式字符格式字符 说说说说 明明明明 o o 以以以以八进制无符号形式八进制无符号形式八进制无符号形式八进制无符号形式输出整数(不输出前导符输出整数(不输出前导符输出整数(不输出前导符输出整数(不输出前导符0 0)))) s (*) s (*) 输出字符串输出字符串输出字符串输出字符串 u u 以无符号十进制形式输出整数以无符号十进制形式输出整数以无符号十进制形式输出整数以无符号十进制形式输出整数 x x或或或或X X 以以以以十六进制无符号形式十六进制无符号形式十六进制无符号形式十六进制无符号形式输出整数(不输出前导符输出整数(不输出前导符输出整数(不输出前导符输出整数(不输出前导符0x0x),),),), 用用用用x x则输出十六进制数的则输出十六进制数的则输出十六进制数的则输出十六进制数的a~fa~f以小数形式,用以小数形式,用以小数形式,用以小数形式,用X X时,则用时,则用时,则用时,则用 大写字母输出大写字母输出大写字母输出大写字母输出 6565【例【例【例【例3-13-13-13-1】输出格式控制符的应用】输出格式控制符的应用】输出格式控制符的应用】输出格式控制符的应用 main( ) main( ) main( ) main( ) { { { { int x=35; int x=35; int x=35; int x=35; float y=123.456; float y=123.456; float y=123.456; float y=123.456; char ch=' A'; char ch=' A'; char ch=' A'; char ch=' A'; printf("x=%d\n",x); printf("x=%d\n",x); printf("x=%d\n",x); printf("x=%d\n",x); printf("y=%f\n",y); printf("y=%f\n",y); printf("y=%f\n",y); printf("y=%f\n",y); printf("y=%10.2f\n",y); printf("y=%10.2f\n",y); printf("y=%10.2f\n",y); printf("y=%10.2f\n",y); printf("y=%-10.2f\n",y); printf("y=%-10.2f\n",y); printf("y=%-10.2f\n",y); printf("y=%-10.2f\n",y); printf("ch=\' %c\' \n",ch); printf("ch=\' %c\' \n",ch); printf("ch=\' %c\' \n",ch); printf("ch=\' %c\' \n",ch); printf("String : \"%s\"\n"," Shanghai"); printf("String : \"%s\"\n"," Shanghai"); printf("String : \"%s\"\n"," Shanghai"); printf("String : \"%s\"\n"," Shanghai"); } } } } 以整数格式以整数格式以整数格式以整数格式输出表达式输出表达式输出表达式输出表达式x x的值的值的值的值\n\n为转义字为转义字为转义字为转义字符,输出时符,输出时符,输出时符,输出时将光标移到将光标移到将光标移到将光标移到下一行的开下一行的开下一行的开下一行的开始处始处始处始处按原样输出按原样输出按原样输出按原样输出字符串字符串字符串字符串StringString%-m.nf%-m.nf与与与与%m.n%m.n相似,只是在相似,只是在相似,只是在相似,只是在其右边以空格补足不足部分。

      其右边以空格补足不足部分其右边以空格补足不足部分其右边以空格补足不足部分   %m.nf %m.nf 表示以小数形式输出表示以小数形式输出表示以小数形式输出表示以小数形式输出, , 输输输输出结果共占出结果共占出结果共占出结果共占mm位,其中小数部分位,其中小数部分位,其中小数部分位,其中小数部分占占占占n n位如果输出结果不足位如果输出结果不足位如果输出结果不足位如果输出结果不足mm个个个个 字符,则在其左边以空格补足字符,则在其左边以空格补足字符,则在其左边以空格补足字符,则在其左边以空格补足    6666格式转义字符格式转义字符 字符形式字符形式字符形式字符形式 功功功功 能能能能\n (*) \n (*) 换行换行换行换行\t (*) \t (*) 横向跳格(即跳到下一个输出区)横向跳格(即跳到下一个输出区)横向跳格(即跳到下一个输出区)横向跳格(即跳到下一个输出区)\v \v 竖向跳格竖向跳格竖向跳格竖向跳格\b \b 退格退格退格退格 \r \r 回车回车回车回车 \” (*) \” (*) 双引号字符双引号字符双引号字符双引号字符 \\ (*) \\ (*) 反斜杠字符反斜杠字符反斜杠字符反斜杠字符““““\ \””””\’ (*) \’ (*) 单引号字符单引号字符单引号字符单引号字符\ddd 1\ddd 1到到到到3 3位位位位8 8进制数所代表的字符进制数所代表的字符进制数所代表的字符进制数所代表的字符\xhh 1\xhh 1到到到到2 2位位位位1616进制数所代表的字符进制数所代表的字符进制数所代表的字符进制数所代表的字符           6767【例【例【例【例3-23-23-23-2】转义字符的应用】转义字符的应用】转义字符的应用】转义字符的应用main( )main( )main( )main( ) { { { { printf("Chinese\tEnglish\n"); printf("Chinese\tEnglish\n"); printf("Chinese\tEnglish\n"); printf("Chinese\tEnglish\n"); printf("\"Welcome ,friends!\"\n"); printf("\"Welcome ,friends!\"\n"); printf("\"Welcome ,friends!\"\n"); printf("\"Welcome ,friends!\"\n"); printf("\101, \x41\n"); printf("\101, \x41\n"); printf("\101, \x41\n"); printf("\101, \x41\n"); } } } }转义字符转义字符转义字符转义字符'\t''\t'使字符串使字符串使字符串使字符串"English“"English“输出到第输出到第输出到第输出到第2 2个输出区个输出区个输出区个输出区 转义字符转义字符转义字符转义字符\”\”用以输出用以输出用以输出用以输出双引号字符。

      双引号字符双引号字符双引号字符   \101\101以八进制形式以八进制形式以八进制形式以八进制形式给出大写字母给出大写字母给出大写字母给出大写字母A A的的的的ASCASC码值码值码值码值6565   \x41\x41以十六进制形式以十六进制形式以十六进制形式以十六进制形式给出大写字母给出大写字母给出大写字母给出大写字母A A的的的的ASCASC码值码值码值码值6565 6868 二二. .格式输入函数格式输入函数scanfscanf()() 功能功能∶ ∶从键盘输入数据,并存入相应变量从键盘输入数据,并存入相应变量 的存储单元的存储单元使用格式使用格式∶ ∶ scanfscanf(格式控制,地址表)(格式控制,地址表)与与与与printf()printf()函数的格式函数的格式函数的格式函数的格式控制类似,以控制类似,以控制类似,以控制类似,以%d%d%f,%c,%s%f,%c,%s为最常用为最常用为最常用为最常用由取地址运算符由取地址运算符由取地址运算符由取地址运算符“&”“&”取出变量的存储取出变量的存储取出变量的存储取出变量的存储单元的起始地址单元的起始地址单元的起始地址单元的起始地址 6969 格式字符格式字符格式字符格式字符 说说说说 明明明明 c c c c 用以输入单个字符用以输入单个字符用以输入单个字符用以输入单个字符 d d d d 用以输入有符号的十进制整数用以输入有符号的十进制整数用以输入有符号的十进制整数用以输入有符号的十进制整数 f f f f 用以输入实数,可以用小数形式或指数形式输入用以输入实数,可以用小数形式或指数形式输入用以输入实数,可以用小数形式或指数形式输入用以输入实数,可以用小数形式或指数形式输入 L L L L 用以输入长整型数据以及用以输入长整型数据以及用以输入长整型数据以及用以输入长整型数据以及doubledoubledoubledouble型数据型数据型数据型数据 o o o o 用以输入无符号的八进制整数用以输入无符号的八进制整数用以输入无符号的八进制整数用以输入无符号的八进制整数 s s s s 用以输入字符串,将字符串送到一个字符数组中,用以输入字符串,将字符串送到一个字符数组中,用以输入字符串,将字符串送到一个字符数组中,用以输入字符串,将字符串送到一个字符数组中, 在输入时以非空白字符开始,以第一个空白字符在输入时以非空白字符开始,以第一个空白字符在输入时以非空白字符开始,以第一个空白字符在输入时以非空白字符开始,以第一个空白字符 结束。

      字符串以串结束标志结束字符串以串结束标志结束字符串以串结束标志结束字符串以串结束标志’\0’’\0’’\0’’\0’作为其最后一个字作为其最后一个字作为其最后一个字作为其最后一个字符符符符 u u u u 用以输入无符号的十进制整数用以输入无符号的十进制整数用以输入无符号的十进制整数用以输入无符号的十进制整数 x x x x或或或或X X X X 用来输入无符号的十六进制整数(大小写作用相同)用来输入无符号的十六进制整数(大小写作用相同)用来输入无符号的十六进制整数(大小写作用相同)用来输入无符号的十六进制整数(大小写作用相同) * * * * 表示本输入项在读入后不赋给相应的变量表示本输入项在读入后不赋给相应的变量表示本输入项在读入后不赋给相应的变量表示本输入项在读入后不赋给相应的变量 域宽域宽域宽域宽 指定输入数据所占宽度(列数),域宽应为正整数指定输入数据所占宽度(列数),域宽应为正整数指定输入数据所占宽度(列数),域宽应为正整数指定输入数据所占宽度(列数),域宽应为正整数常用的常用的常用的常用的scanf()scanf()scanf()scanf()格式字符表格式字符表格式字符表格式字符表 7070     【例【例【例【例3-33-33-33-3】输入格式控制符的应用】输入格式控制符的应用】输入格式控制符的应用】输入格式控制符的应用 main( ) main( ) main( ) main( ) { { { { int a,b; float c,d; char e; int a,b; float c,d; char e; int a,b; float c,d; char e; int a,b; float c,d; char e; scanf("%d %d",&a,&b); scanf("%d %d",&a,&b); scanf("%d %d",&a,&b); scanf("%d %d",&a,&b); scanf("%f, %f",&c,&d); scanf("%f, %f",&c,&d); scanf("%f, %f",&c,&d); scanf("%f, %f",&c,&d); scanf("%c",&e); scanf("%c",&e); scanf("%c",&e); scanf("%c",&e); printf("%d+%d=%d\n",a,b,a+b); printf("%d+%d=%d\n",a,b,a+b); printf("%d+%d=%d\n",a,b,a+b); printf("%d+%d=%d\n",a,b,a+b); printf("%f-%f=%f\n",c,d,c-d); printf("%f-%f=%f\n",c,d,c-d); printf("%f-%f=%f\n",c,d,c-d); printf("%f-%f=%f\n",c,d,c-d); printf("%c\n",e); printf("%c\n",e); printf("%c\n",e); printf("%c\n",e); } } } }当二个当二个当二个当二个%d%d之间没有分隔符时,之间没有分隔符时,之间没有分隔符时,之间没有分隔符时,相应的二个输入数据之间也相应的二个输入数据之间也相应的二个输入数据之间也相应的二个输入数据之间也必须用空格分隔必须用空格分隔必须用空格分隔必须用空格分隔当二个当二个当二个当二个%f%f之间用逗号分隔时,相应之间用逗号分隔时,相应之间用逗号分隔时,相应之间用逗号分隔时,相应的二个输入数据之间也必须用逗号的二个输入数据之间也必须用逗号的二个输入数据之间也必须用逗号的二个输入数据之间也必须用逗号分隔分隔分隔分隔 71713.3 3.3 3.3 3.3 字符输入、输出函数字符输入、输出函数字符输入、输出函数字符输入、输出函数getchar()getchar()getchar()getchar()和和和和putchar() putchar() putchar() putchar() 一一一一. . . .字符输出函数字符输出函数字符输出函数字符输出函数putchar()putchar()putchar()putchar()putchar()putchar()putchar()putchar()函数用以输出字符变量的值。

      函数用以输出字符变量的值函数用以输出字符变量的值函数用以输出字符变量的值调用调用调用调用putchar()putchar()putchar()putchar()函数的一般格式:函数的一般格式:函数的一般格式:函数的一般格式: putchar(putchar(putchar(putchar(整型表达式整型表达式整型表达式整型表达式) ) ) );;;; 其中,其中,其中,其中,““““整型表达式整型表达式整型表达式整型表达式””””的值应当在字符的值应当在字符的值应当在字符的值应当在字符ASCASCASCASC码值的范码值的范码值的范码值的范围内通常,围内通常,围内通常,围内通常,putchar()putchar()putchar()putchar()的参数是字符型变量、字符的参数是字符型变量、字符的参数是字符型变量、字符的参数是字符型变量、字符常量,也可以是整型变量、整型常量常量,也可以是整型变量、整型常量常量,也可以是整型变量、整型常量常量,也可以是整型变量、整型常量 7272【例【例【例【例3-43-43-43-4】字符输出函数】字符输出函数】字符输出函数】字符输出函数 putchar() putchar() putchar() putchar() 的应用的应用的应用的应用 #include #include #include #include main( ) main( ) main( ) main( ) { { { { char a='C'; char a='C'; char a='C'; char a='C'; int i=97; int i=97; int i=97; int i=97; putchar(a); putchar(a); putchar(a); putchar(a); putchar(b); putchar(b); putchar(b); putchar(b); putchar('t'); putchar('t'); putchar('t'); putchar('t'); } } } }将变量或表达式将变量或表达式将变量或表达式将变量或表达式的值以字符格的值以字符格的值以字符格的值以字符格式输出式输出式输出式输出使用使用使用使用putchar()putchar()函数,必须用命令函数,必须用命令函数,必须用命令函数,必须用命令“#include”“#include”将标准输入输出函数将标准输入输出函数将标准输入输出函数将标准输入输出函数的头文件的头文件的头文件的头文件“stdio.h”“stdio.h”包含到用户包含到用户包含到用户包含到用户的源文件中的源文件中的源文件中的源文件中 7373   二二二二.getchar().getchar().getchar().getchar()函数函数函数函数 功能:功能:功能:功能:getchar()getchar()getchar()getchar()函数用以从键盘上输函数用以从键盘上输函数用以从键盘上输函数用以从键盘上输 入一个字符。

      入一个字符入一个字符入一个字符 调用调用调用调用getchar( )getchar( )getchar( )getchar( )函数的一般格式:函数的一般格式:函数的一般格式:函数的一般格式: getchar() getchar() getchar() getchar()【例【例【例【例3-53-53-53-5】字符输入函数】字符输入函数】字符输入函数】字符输入函数 getchar() getchar() getchar() getchar() 的使用的使用的使用的使用 #include #include #include #include main( ) main( ) main( ) main( ) { { { { char ch; char ch; char ch; char ch; ch=getchar( ); ch=getchar( ); ch=getchar( ); ch=getchar( ); putchar(ch); putchar(ch); putchar(ch); putchar(ch); putchar(getchar()); putchar(getchar()); putchar(getchar()); putchar(getchar()); } } } }由由由由getchar()getchar()getchar()getchar()函数从键盘输入函数从键盘输入函数从键盘输入函数从键盘输入一个字符,并立即由一个字符,并立即由一个字符,并立即由一个字符,并立即由putchar()putchar()putchar()putchar()函数将其输出函数将其输出函数将其输出函数将其输出使用使用使用使用getchar()getchar()getchar()getchar()函数,必须用命令函数,必须用命令函数,必须用命令函数,必须用命令“#include”“#include”“#include”“#include”将标准输入输出函数将标准输入输出函数将标准输入输出函数将标准输入输出函数的头文件的头文件的头文件的头文件“stdio.h”“stdio.h”“stdio.h”“stdio.h”包含到用户包含到用户包含到用户包含到用户的源文件中的源文件中的源文件中的源文件中 7474第第3章章 结束结束       第第4 4章章 C C程序的控制结构程序的控制结构 2021/8/2275 7676学习目标学习目标1.1.熟练掌握熟练掌握熟练掌握熟练掌握 if if if if 语句,掌握语句,掌握语句,掌握语句,掌握 switch switch switch switch 语句,语句,语句,语句,会利用这两种语句进行条件分支结构的程会利用这两种语句进行条件分支结构的程会利用这两种语句进行条件分支结构的程会利用这两种语句进行条件分支结构的程序设计。

      序设计2.2.熟练掌握熟练掌握熟练掌握熟练掌握 for for for for 语句、语句、语句、语句、while while while while 语句和语句和语句和语句和 do…while do…while do…while do…while 语句,会利用这三种语句进行语句,会利用这三种语句进行语句,会利用这三种语句进行语句,会利用这三种语句进行循环结构的程序设计循环结构的程序设计循环结构的程序设计循环结构的程序设计3.3.掌握掌握掌握掌握 break break break break 语句和语句和语句和语句和 continue continue continue continue 语句与上述语句与上述语句与上述语句与上述语句配合使用的方法语句配合使用的方法语句配合使用的方法语句配合使用的方法 7777主要内容主要内容–程序算法的概念程序算法的概念–顺序结构顺序结构–分支结构分支结构–循环结构循环结构 7878 4.1 4.1 程序算法简介程序算法简介计算机科学家沃思提出公式:计算机科学家沃思提出公式: 数据结构 + 算法 = 程序 数据结构数据结构──对数据的描述。

      如前面所介绍的各对数据的描述如前面所介绍的各 种数据类型就是最简单的数据结构种数据类型就是最简单的数据结构 算法算法──对操作的描述对操作的描述, ,是为解决一个问题而采取是为解决一个问题而采取 的方法和步骤通常用流程图表示算法的方法和步骤通常用流程图表示算法一一. .算法的概念算法的概念 计算计算1+2+3+4+…+1001+2+3+4+…+100可以二种不同的算法:可以二种不同的算法:算法一:算法一:先作先作1+21+2,再加,再加3 3,再加,再加4 4,一直加到,一直加到100100,最后得到,最后得到 结果:结果:50505050算法二:算法二:利用等差数列求和公式:利用等差数列求和公式: n(n+1) n(n+1) 2 21+2+3+……+n=1+2+3+……+n= 7979  比较算法一和算法二:比较算法一和算法二:      算法二不具有普遍性,许多级数求和问题是不能简单地用公算法二不具有普遍性,许多级数求和问题是不能简单地用公 式表示的,如:式表示的,如: cos1+cos2+cos3+……+cosn cos1+cos2+cos3+……+cosn 算法一所反复实施的是二个数的加法运算:算法一所反复实施的是二个数的加法运算:1 1、、1 1++2 2、、(1+2)+3(1+2)+3、、(1+2+3)+4(1+2+3)+4、、…………、、(1+2+3+……+99)+100(1+2+3+……+99)+100这种看似枯燥、单一,反复实施的运算利用这种看似枯燥、单一,反复实施的运算利用C C语言提供的选语言提供的选择结构和循环结构却是很容易实现的,而且这一算法适用于择结构和循环结构却是很容易实现的,而且这一算法适用于不同的级数求和问题。

      由于计算机具有极高的运算速度,这不同的级数求和问题由于计算机具有极高的运算速度,这样的程序结构恰好发挥了计算机的特长样的程序结构恰好发挥了计算机的特长结论:结论: 对计算机而言,算法一优于算法二对计算机而言,算法一优于算法二选择一个好的算法是设计出高质量程序的前提选择一个好的算法是设计出高质量程序的前提 8080【例【例4-14-1】为计算】为计算1+2+3+……+n1+2+3+……+n设计一个算法,其中设计一个算法,其中 n n的值由键盘输入的值由键盘输入步骤步骤1 1::从键盘输入从键盘输入n n的值的值步骤步骤2 2::0 0 sum sum (使变量(使变量sumsum具有初值具有初值0 0))步骤步骤3 3::1 1 i i(使变量(使变量i i具有初值具有初值1 1))步骤步骤4 4::sum+isum+i sum sum (用(用sum+isum+i的值取代的值取代sumsum原原 来的值)来的值)步骤步骤5 5::i+1i+1 i i (使变量(使变量i i的值增的值增1 1))步骤步骤6 6::若若i≤n, i≤n, 再返回到步骤再返回到步骤4 4,否则结束。

      否则结束说明:说明:算法中,步骤算法中,步骤4 4到步骤到步骤6 6组成一个循环,最后的计算组成一个循环,最后的计算结果存放在变量结果存放在变量sumsum中上述算法中的每一个步骤都可以用上述算法中的每一个步骤都可以用C C语言来描述,并语言来描述,并最终成为一个完整的最终成为一个完整的C C程序 8181二二. . 算法的表示算法的表示 算法用流程图来表示所谓流程图就是用一些算法用流程图来表示所谓流程图就是用一些图框表示各种操作,形象直观,易于理解图框表示各种操作,形象直观,易于理解 常用的流程图符号常用的流程图符号 ::或开始、结束框开始、结束框开始、结束框开始、结束框输入、输出框输入、输出框输入、输出框输入、输出框处理框处理框处理框处理框判断框判断框判断框判断框流程线流程线流程线流程线 8282 按算法一计算按算法一计算1 1++2 2++3 3++……..……..++n n 的流程图,的流程图, 其中其中n n的值由键盘输入的值由键盘输入              开始开始输入输入n0 sum1 isum++i faci+1 i i≤n ?y输出输出sumn结束结束返回 8383三三. . 算法的特性算法的特性1.1.有穷性:有穷性:一个算法所包含的操作步骤必须是有限的。

      一个算法所包含的操作步骤必须是有限的2.2.确定性:确定性:指算法中的每一个步骤的含义必须是明确指算法中的每一个步骤的含义必须是明确 的,不能有二义性的,不能有二义性3.3.由零个或多个输入:由零个或多个输入:如果算法中的如果算法中的n n是已知的数据,是已知的数据, 而不是来自外部,可以没有输入而不是来自外部,可以没有输入4.4.有一个或多个输出:有一个或多个输出:通过输出了解算法的结果通过输出了解算法的结果5.5.有效性:有效性:算法中的每一个步骤都应当是可以被执行算法中的每一个步骤都应当是可以被执行 的,并能得到确定的结果的,并能得到确定的结果 84844.2 4.2 顺序结构顺序结构 语句语句1 1语句语句2 2 顺序结构:顺序结构:顺序结构:顺序结构: 顺序结构是最简单的顺序结构是最简单的顺序结构是最简单的顺序结构是最简单的程序结构,在执行时,程序结构,在执行时,程序结构,在执行时,程序结构,在执行时,按语句的先后次序依按语句的先后次序依按语句的先后次序依按语句的先后次序依次执行,次执行,次执行,次执行,直至结束。

      直至结束直至结束直至结束 8585【例【例4-24-2】编写程序,要求从键盘输入圆的半径】编写程序,要求从键盘输入圆的半径r r,, 计算圆的面积计算圆的面积s s和周长和周长l l  #define PI 3.1415926#define PI 3.1415926 main() main() { { float s,l,r; float s,l,r; printf("Please Input r"); printf("Please Input r"); scanf("%f",&r); scanf("%f",&r); s=PI*r*r; s=PI*r*r; l l==2*PI*r;2*PI*r; printf("r=%f,s printf("r=%f,s==%f,l%f,l==%f\n",r,s,l);%f\n",r,s,l); } }将将r r2 2表示为表示为r*rr*r或或用函数表示为用函数表示为∶∶pow(r,2)pow(r,2)定义符号常量定义符号常量 8686【例【例4-34-3】从键盘上输入一个三位正整数,然后逆序】从键盘上输入一个三位正整数,然后逆序 输出输出 main() main() { { int a,b; int a,b; scanf("%d",&a); scanf("%d",&a); b=a%10; b=a%10; a/=10; a/=10; printf("%d",b); printf("%d",b); b=a%10; b=a%10; printf("%d",b); printf("%d",b); a/=10; a/=10; printf("%d\n",a); printf("%d\n",a); } } 取出个位数取出个位数得到由百位数数字得到由百位数数字和个位数数字组成和个位数数字组成的二位数的二位数 87874.3 4.3 关系运算符和关系运算表达式关系运算符和关系运算表达式 一一. .关系运算符关系运算符关系运算符用于表达式之间的比较:关系运算符用于表达式之间的比较:大于比较运算符:大于比较运算符: > > 小于比较运算符:小于比较运算符: < < 大于等于比较运算符:大于等于比较运算符: >= >= 小于等于比较运算符:小于等于比较运算符:<= <= 等于比较运算符:等于比较运算符: == == 不等于比较运算符:不等于比较运算符:!= != 关系运算符按运算优先级可分为二组:关系运算符按运算优先级可分为二组:> >、、< <、、>=>=、、<= <= 具有相同的运算优先级,具有相同的运算优先级,== == 和和!=!=具具有相同的运算优先级。

      后一组的运算优先级又低于有相同的运算优先级后一组的运算优先级又低于前一组同优先级的关系运算符遵循同优先级的关系运算符遵循左结合左结合 ── ── 自左至右的自左至右的结合方向结合方向 8888二二二二. . . . 关系运算表达式关系运算表达式关系运算表达式关系运算表达式 二个表达式通过关系运算符连接而成为关系运二个表达式通过关系运算符连接而成为关系运二个表达式通过关系运算符连接而成为关系运二个表达式通过关系运算符连接而成为关系运算表达式算表达式算表达式算表达式 关系运算表达式的一般形式为:关系运算表达式的一般形式为:关系运算表达式的一般形式为:关系运算表达式的一般形式为: < < < <表达式表达式表达式表达式1><1><1><1><关系运算符关系运算符关系运算符关系运算符><><><><表达式表达式表达式表达式2> 2> 2> 2> 例如:例如:例如:例如: c>a+b c>a+b c>a+b c>a+b、、、、a! =2a! =2a! =2a! =2、、、、-5<=b-c -5<=b-c -5<=b-c -5<=b-c 都是合法的关系都是合法的关系都是合法的关系都是合法的关系 运算表达式。

      运算表达式运算表达式运算表达式关系运算表达式的结果为逻辑值关系运算表达式的结果为逻辑值关系运算表达式的结果为逻辑值关系运算表达式的结果为逻辑值 1 1(表示(表示““真真””))── ── 当关系运算表达式当关系运算表达式 成立时成立时(True)(True) 逻辑值逻辑值 = = 0 0(表示(表示““假假””))── ── 当关系运算表达式当关系运算表达式 不成立时不成立时(False)(False) 8989 关系运算符的优先级关系运算符的优先级高高 算术运算符:算术运算符:+ - * / %+ - * / % 关系运算符:关系运算符:> < >= <=> < >= <= 关系运算符:关系运算符:== !=== !=低低 赋值运算符:赋值运算符:= += -= *= /= %== += -= *= /= %= 9090【例【例【例【例4-44-44-44-4】设:】设:】设:】设:a=3, b=4, c=5a=3, b=4, c=5a=3, b=4, c=5a=3, b=4, c=5,判断下列各关系运算表达式的,判断下列各关系运算表达式的,判断下列各关系运算表达式的,判断下列各关系运算表达式的结果。

      结果1)(1)(1)(1) x = b > ax = b > ax = b > ax = b > a(2)(2)(2)(2) 由于由于由于由于关系运算符优先于赋值运算符关系运算符优先于赋值运算符关系运算符优先于赋值运算符关系运算符优先于赋值运算符,所以,所以,所以,所以 原式等价于原式等价于原式等价于原式等价于 x = ( b > a ),x = ( b > a ),x = ( b > a ),x = ( b > a ),由题设可知由题设可知由题设可知由题设可知 b>a b>a b>a b>a 成立,结果为成立,结果为成立,结果为成立,结果为1, 1, 1, 1, 故最后执行赋值运算故最后执行赋值运算故最后执行赋值运算故最后执行赋值运算 x=1x=1x=1x=1 (2) a != b >= c(2) a != b >= c(2) a != b >= c(2) a != b >= c 由于由于由于由于关系运算符关系运算符关系运算符关系运算符 != != != != 的运算优先级低于关系运算符的运算优先级低于关系运算符的运算优先级低于关系运算符的运算优先级低于关系运算符 >=>=>=>=, , , ,所以所以所以所以原式等价于原式等价于原式等价于原式等价于 a != ( b >= c ),a != ( b >= c ),a != ( b >= c ),a != ( b >= c ),由题设可知由题设可知由题设可知由题设可知 b>=c b>=c b>=c b>=c 不成立,不成立,不成立,不成立,结果为结果为结果为结果为0, 0, 0, 0, 原式可化为原式可化为原式可化为原式可化为 a!=0,a!=0,a!=0,a!=0,由题设可知由题设可知由题设可知由题设可知a!=0a!=0a!=0a!=0成立,结果成立,结果成立,结果成立,结果为为为为1 1 1 1。

      9191(3) ( a > b ) > ( b < c)(3) ( a > b ) > ( b < c)(3) ( a > b ) > ( b < c)(3) ( a > b ) > ( b < c)由题设可知,由题设可知,由题设可知,由题设可知,a>b a>b a>b a>b 不成立,结果为不成立,结果为不成立,结果为不成立,结果为0, b 1, 0 > 1, 0 > 1, 0 > 1, 其结果为其结果为其结果为其结果为0 0 0 04) f = a < b < c(4) f = a < b < c(4) f = a < b < c(4) f = a < b < c由于同优先级的关系运算符遵循自左至右的结合方向,由于同优先级的关系运算符遵循自左至右的结合方向,由于同优先级的关系运算符遵循自左至右的结合方向,由于同优先级的关系运算符遵循自左至右的结合方向,故原式等价于:故原式等价于:故原式等价于:故原式等价于: f = (( a < b ) < c ), f = (( a < b ) < c ), f = (( a < b ) < c ), f = (( a < b ) < c ),由题设可知,由题设可知,由题设可知,由题设可知,a < ba < ba < ba < b的结果为的结果为的结果为的结果为1 1 1 1,,,,( a < b ) < c( a < b ) < c( a < b ) < c( a < b ) < c的结果的结果的结果的结果为为为为1 1 1 1,最后执行赋值运算:,最后执行赋值运算:,最后执行赋值运算:,最后执行赋值运算: f=1 f=1 f=1 f=1。

      92924.4 4.4 逻辑运算符和逻辑运算表达式逻辑运算符和逻辑运算表达式 逻辑运算符包括逻辑运算符包括逻辑运算符包括逻辑运算符包括∶∶∶∶ ! ! (逻辑非运算)(逻辑非运算)(逻辑非运算)(逻辑非运算)&&&& (逻辑与运算)(逻辑与运算)(逻辑与运算)(逻辑与运算)|||| (逻辑或运算)(逻辑或运算)(逻辑或运算)(逻辑或运算) 逻辑表达式逻辑表达式逻辑表达式逻辑表达式∶∶∶∶ 用逻辑运算符连接而成的表达式用逻辑运算符连接而成的表达式用逻辑运算符连接而成的表达式用逻辑运算符连接而成的表达式逻辑逻辑逻辑逻辑 运算的结果为逻辑值,以运算的结果为逻辑值,以运算的结果为逻辑值,以运算的结果为逻辑值,以1 1 1 1表示表示表示表示““““真真真真”(true),”(true),”(true),”(true), 以以以以0 0 0 0表示表示表示表示““““假假假假”(false)”(false)”(false)”(false) 9393高高 逻辑运算符:逻辑运算符:! ! 算术运算符:算术运算符:+ +、、 - -、、 * * 、、/ / 、、% % 关系运算符:关系运算符:> > 、、< <、、 >= >=、、 <= <= 关系运算符:关系运算符:== == 、、!= != 逻辑运算符:逻辑运算符:&& && 、、||||低低 赋值运算符:赋值运算符:= =、、 += +=、、 -= -=、、 *= *=、、 /= /=、、n %=n %=运算符的优先级:运算符的优先级:注意:注意: C C++允许算术运算表达式参与逻辑运算,在参++允许算术运算表达式参与逻辑运算,在参与逻辑运算时,与逻辑运算时,一切非零值均作为逻辑值一切非零值均作为逻辑值一切非零值均作为逻辑值一切非零值均作为逻辑值1 1 1 1,而将,而将,而将,而将零值作为逻辑值零值作为逻辑值零值作为逻辑值零值作为逻辑值0 0 0 0。

      9494逻辑运算法则:逻辑运算法则: (设(设A A,,B B是参与逻辑运算的二个量)是参与逻辑运算的二个量)逻辑逻辑““与与””运算法则:运算法则:( ( 运算符:运算符:&& )&& ) A && B A && B 的结果为的结果为1, 1, 当且仅当当且仅当A, BA, B的值均为的值均为 非非0 0,否则,,否则,A && B A && B 的结果为的结果为0 0 例如:例如: 1 && 0 1 && 0 的结果为的结果为0 0 -5 && 3.14 -5 && 3.14 的结果为的结果为1 1 0 && 0 0 && 0的结果为的结果为0 0 9595逻辑逻辑““或或””运算法则:运算法则:( ( 运算符:运算符:|| )|| ) A || B A || B 的结果为的结果为0, 0, 当且仅当当且仅当A A、、B B的值均为的值均为0 0,, 否则,否则,A || B A || B 的结果为的结果为1 1 例如:例如: 1 || 0 1 || 0 的结果为的结果为1 1 -5 || 3.14 -5 || 3.14 的结果为的结果为1 1 0 || 0 0 || 0的结果为的结果为0 0 逻辑逻辑““非非””运算法则:运算法则:( ( 运算符:运算符: !!) ) !A !A 的结果为的结果为0, 0, 当且仅当当且仅当A A的值为非的值为非0 0,, 否则,否则,!A!A的结果为的结果为1 1。

      例如:例如: !0 !0 的结果为的结果为1 1 !3.14 !3.14 的结果为的结果为0 0 9696【例【例4-54-5】设】设 int a= 3, b = 4, c = 5 int a= 3, b = 4, c = 5;判断下列;判断下列表达式的值:表达式的值: 说明:说明: 由于逻辑与、或运算的优先级低于关系运算符,由于逻辑与、或运算的优先级低于关系运算符, 故将下列各式中的括号去除后对结果没有影响故将下列各式中的括号去除后对结果没有影响1) (a>b)||(c>a)(1) (a>b)||(c>a) 由题设可知,原式等于由题设可知,原式等于 0 || 1, 0 || 1, 结果为结果为1 12) (!ca)||(ba)||(b3)||(4<3) (!5<3)&&(4>3)||(4<3) 由于逻辑非运算的优先级高于关系运算符,而由于逻辑非运算的优先级高于关系运算符,而!5!5 的值为的值为 0, 0,故原式又等于故原式又等于 (0<3)&&(4>3)||(4<3) (0<3)&&(4>3)||(4<3) 也即是:也即是:1 && 1||01 && 1||0,按自左向右的结合方向,,按自左向右的结合方向, 最后结果为最后结果为1 1。

      9797【【【【例例例例4-64-64-64-6】】】】设设设设 int int int int a= a= a= a= 3, 3, 3, 3, b b b b = = = = 4, 4, 4, 4, c c c c = = = = 5 5 5 5;;;;判判判判断断断断表表表表达达达达式式式式a= a= a= a= (b=!a) && (c=b)(b=!a) && (c=b)(b=!a) && (c=b)(b=!a) && (c=b)的值 原表达式等价于原表达式等价于原表达式等价于原表达式等价于a=((b=!a) && (c=b)) a=((b=!a) && (c=b)) a=((b=!a) && (c=b)) a=((b=!a) && (c=b)) C C C C语言规定:语言规定:语言规定:语言规定: 在在在在执执执执行行行行“&&”“&&”“&&”“&&”运运运运算算算算时时时时,,,,如如如如果果果果“&&”“&&”“&&”“&&”运运运运算算算算符符符符左左左左边边边边表表表表达达达达式式式式的的的的值值值值为为为为0 0 0 0,,,,则则则则已已已已经经经经可可可可以以以以确确确确定定定定“&&”“&&”“&&”“&&”运运运运算算算算的的的的结结结结果果果果一一一一定定定定为为为为0 0 0 0,,,,故故故故不不不不再再再再执执执执行行行行“&&”“&&”“&&”“&&”运运运运算算算算符符符符右右右右边边边边表表表表达达达达式式式式规规规规定定定定的的的的运运运运算算算算。

      类类类类似似似似地地地地,,,,在在在在执执执执行行行行“||”“||”“||”“||”运运运运算算算算时时时时,,,,如如如如果果果果“||”“||”“||”“||”运运运运算算算算符符符符左左左左边边边边表表表表达达达达式式式式的的的的值值值值为为为为1 1 1 1,,,,则则则则已已已已经经经经可可可可以以以以确确确确定定定定“||”“||”“||”“||”运运运运算算算算的的的的结结结结果果果果一一一一定定定定为为为为1 1 1 1,,,,故故故故不不不不再再再再执执执执行行行行“||”“||”“||”“||”运运运运算算算算符符符符右右右右边边边边表表表表达达达达式式式式规规规规定定定定的的的的运算 由题设可知,由题设可知,由题设可知,由题设可知,!a!a!a!a的值为的值为的值为的值为0 0 0 0,故赋值运算表达式,故赋值运算表达式,故赋值运算表达式,故赋值运算表达式b=!ab=!ab=!ab=!a的值的值的值的值为为为为0 0 0 0,按,按,按,按C C C C语言规定,赋值运算表达式语言规定,赋值运算表达式语言规定,赋值运算表达式语言规定,赋值运算表达式(c=b)(c=b)(c=b)(c=b)将不被执行,将不被执行,将不被执行,将不被执行,c c c c的值还是的值还是的值还是的值还是5 5 5 5,,,,b b b b的值为的值为的值为的值为0 0 0 0,由于逻辑运算表达式,由于逻辑运算表达式,由于逻辑运算表达式,由于逻辑运算表达式(b=!a) (b=!a) (b=!a) (b=!a) && (c=b)&& (c=b)&& (c=b)&& (c=b)的值为的值为的值为的值为0 0 0 0,故,故,故,故a a a a的值为的值为的值为的值为0 0 0 0,整个赋值运算表达式,整个赋值运算表达式,整个赋值运算表达式,整个赋值运算表达式为为为为0 0 0 0。

      9898逻辑表达式的应用举例逻辑表达式的应用举例1.1.1.1.数学中的数学中的数学中的数学中的 1≤x 1≤x 1≤x 1≤x<<<<5,5,5,5,并且并且并且并且 x≠3 x≠3 x≠3 x≠3可用逻辑表达式可用逻辑表达式可用逻辑表达式可用逻辑表达式表示为:表示为:表示为:表示为: x>=1 && x<5 && x!=3 x>=1 && x<5 && x!=3 x>=1 && x<5 && x!=3 x>=1 && x<5 && x!=3;;;;2.x2.x2.x2.x是是是是3 3 3 3的倍数或的倍数或的倍数或的倍数或5 5 5 5的倍数,可用逻辑表达式表示的倍数,可用逻辑表达式表示的倍数,可用逻辑表达式表示的倍数,可用逻辑表达式表示为:为:为:为: x%3==0 || x%5==0 x%3==0 || x%5==0 x%3==0 || x%5==0 x%3==0 || x%5==0;;;; 99994.5 4.5 选择结构选择结构 在在在在许许许许多多多多场场场场合合合合,,,,需需需需要要要要根根根根据据据据不不不不同同同同的的的的情情情情况况况况执执执执行行行行不不不不同同同同的的的的语语语语句句句句。

      称称称称这这这这种种种种程程程程序序序序结结结结构构构构为为为为选选选选择择择择结结结结构构构构C C C C语语语语言言言言提提提提供供供供的的的的条条条条件件件件语语语语句句句句和和和和开开开开关关关关语语语语句句句句可可可可用用用用于于于于实实实实现现现现选选选选择择择择结结结结构构构构程序设计程序设计程序设计程序设计 100100一一. if. if语句和语句和if…else…if…else…语句语句 ifif语句语句ifif语句的格式语句的格式:: if(if(表达式表达式) ) 语句语句 值为值为0 0值为非值为非0 0表达式表达式语句语句执行时,首先计算表达式的值,若其值不为执行时,首先计算表达式的值,若其值不为0 0 ( (表示真表示真) ),则执行语句部分,否则,则执行语句部分,否则, , 跳过语句跳过语句部分,执行其后面的语句部分,执行其后面的语句 101101【例【例4-74-7】从键盘输入实数】从键盘输入实数a a,输出,输出a a的绝对值的绝对值 main() main() { { float a; float a; printf("Enter a float\n"); printf("Enter a float\n"); scanf("%f",&a); scanf("%f",&a); if(a<0) if(a<0) a=-a; a=-a; printf("a=%f\n",a); printf("a=%f\n",a); } }若若a<0a<0成立,执行成立,执行a=-aa=-a否则直接执行否则直接执行printfprintf语句语句 102102【例【例4-84-8】从键盘输入一个正整数】从键盘输入一个正整数n n,如果,如果n n是一个三位数,是一个三位数,将其逆序输出,否则,直接结束。

      将其逆序输出,否则,直接结束 main()main() { { int a,b; int a,b; scanf("%d",&a); scanf("%d",&a); if((a>=100)&&(a<1000)) if((a>=100)&&(a<1000)) printf("The End\n"); printf("The End\n"); } }{ { b=a%10; b=a%10; a/=10; a/=10; printf("%d",b); printf("%d",b); b=a%10; b=a%10; printf("%d",b), printf("%d",b), a/=10; a/=10; printf("%d\n",a); printf("%d\n",a); } }复合语句复合语句取出个位数字取出个位数字取出由百位数字取出由百位数字和十位数字构成和十位数字构成的二位数的二位数 103103 if……else……if……else……语句语句 if……else……if……else……语句的格式:语句的格式:if(if(表达式表达式) ) 语句语句1 1 else else 语句语句2 2值为非值为非0 0值为值为0 0表达式表达式语句语句1 1语句语句2 2执行时,首先计算表达式的值,若其值不为执行时,首先计算表达式的值,若其值不为0 0,则执行语,则执行语句句1, 1, 否则,执行语句否则,执行语句2 2。

      语句语句1 1和语句和语句2 2必定有一个、而且必定有一个、而且只能有一个被执行之后,执行其后续语句只能有一个被执行之后,执行其后续语句 104104【例【例4-94-9】从键盘上输入两个整数】从键盘上输入两个整数a a和和b b,按先大后,按先大后 小的顺序输出小的顺序输出 main() main() { { int a,b; int a,b; printf("Please enter two integers\n"); printf("Please enter two integers\n"); scanf("%d,%d",&a,&b); scanf("%d,%d",&a,&b); if(a>b) if(a>b) printf("MAX=%d, MIN=%d,\n",a,b); printf("MAX=%d, MIN=%d,\n",a,b); else else printf("MAX=%d, MIN=%d,\n", b,a); printf("MAX=%d, MIN=%d,\n", b,a); } }a>ba>b成立,执行成立,执行这一语句这一语句a>ba>b不成立,执不成立,执行这一语句行这一语句 105105例例4.10 4.10 输入输入a,b,ca,b,c,利用求根公式求一元二次方程,利用求根公式求一元二次方程 ax ax2 2+bx+c=0 +bx+c=0 的根。

      的根 流程图流程图 ::开始输入a,b,c计算b*b-4*a*c并赋值给变量deltadelta>=0 ?计算:sqrt(delta)并将结果赋给变量delta输出实根结  束计算:sqrt(-delta)并将结果赋给变量delta输出复根开始开始输入输入a,b,ca,b,c计算计算b*b-4*a*cb*b-4*a*c并赋值给变量并赋值给变量deltadelta delt>=0?Yes No计算计算:sqrt(delta):sqrt(delta)并将结果赋给变量并将结果赋给变量 delta delta输出实根输出实根计算计算:sqrt(-delta):sqrt(-delta) 并将结果赋给变量并将结果赋给变量 delta delta输出复根输出复根结束结束 106106#include#includemain()main() { { float a,b,c; float a,b,c; float x1,x2,delta; float x1,x2,delta; printf(" Please Input printf(" Please Input a,b,c : "); a,b,c : "); scanf(" %f,%f,%f ", scanf(" %f,%f,%f ", &a,&b,&c); &a,&b,&c); delta=b*b-4*a*c; delta=b*b-4*a*c; if(delta>=0) if(delta>=0) { { delta=sqrt(delta); delta=sqrt(delta);printf(" x1=%f , ",(-b+printf(" x1=%f , ",(-b+ delta)/(2*a)); delta)/(2*a));printf(" x2=%f\n ",(-b-printf(" x2=%f\n ",(-b- delta)/(2*a)); delta)/(2*a));} }elseelse{ { delta=sqrt(-delta); delta=sqrt(-delta); printf(" x1=%f + %fi\n printf(" x1=%f + %fi\n ",-b/(2*a),delta/(2*a)); ",-b/(2*a),delta/(2*a)); printf(" x1=%f - %fi\n printf(" x1=%f - %fi\n ", -b/(2*a),delta/(2*a)); ", -b/(2*a),delta/(2*a)); } }} }程序:程序: 107107ifif与与elseelse配对,配对,用以找出用以找出a a、、b b中中的大者的大者【例【例4-114-11】编程求整数】编程求整数a a、、b b、、c c中的最大者,中的最大者,a a、、b b、、c c由键盘由键盘 输入。

      输入 main()main() { { int a,b,c,max; int a,b,c,max; print{("Please enter three integers:\n"); print{("Please enter three integers:\n"); scanf("%d,%d,%d",&a,&b,&c); scanf("%d,%d,%d",&a,&b,&c); if (a>b) if (a>b) max=a; max=a; else else max=b; max=b; if (max

      在某些情况下,条件语句在某些情况下,条件语句if……else……if……else……可以用条件运算表可以用条件运算表达式来代替达式来代替 条件运算表达式的格式:条件运算表达式的格式: 表达式表达式1? 1? 表达式表达式2 2:表达式:表达式3 3 执行时,先判断表达式执行时,先判断表达式1 1的值,如果其不为的值,如果其不为0 0,则以表达式,则以表达式2 2 的值作为条件运算表达式的值,否则,以表达式的值作为条件运算表达式的值,否则,以表达式3 3的值作为的值作为 条件运算表达式的值条件运算表达式的值 例如,赋值语句:例如,赋值语句: y=x>0? 10 y=x>0? 10::-10-10;; 等价于等价于:条件语句:条件语句: if (x>0) if (x>0) y y==10; 10; else else y y==-10; -10; 只有在只有在ifif语句内嵌的语句为语句内嵌的语句为赋值语句、且两个分支都给赋值语句、且两个分支都给同一个变量赋值时,才能用同一个变量赋值时,才能用条件表达式代替条件表达式代替ifif语句语句 109109【例【例4-124-12】从键盘输入二个整数,输出其中的较大者。

      从键盘输入二个整数,输出其中的较大者main()main() { { int a,b; int a,b; printf("Please input two integers:\n "); printf("Please input two integers:\n "); scanf("%d,%d ",&a,&b); scanf("%d,%d ",&a,&b); printf("MAX=%d\n ", (a>b)? a:b); printf("MAX=%d\n ", (a>b)? a:b); } }使用条件运算符使用条件运算符使程序变得简洁使程序变得简洁 110110二二. .条件语句的嵌套条件语句的嵌套 C C语言允许在条件语句中又包含另一个条件语语言允许在条件语句中又包含另一个条件语 句,称之为条件语句的嵌套句,称之为条件语句的嵌套 在在ifif语句中又嵌套语句中又嵌套了另一个了另一个ifif语句语句【例【例4-134-13】从键盘上输入一个字符,判断它是英文字母、】从键盘上输入一个字符,判断它是英文字母、 数字或其它字符。

      数字或其它字符 输入的是数字?输入的是数字?输入的是字母输入的是字母 ?? 显示:是数字显示:是数字 显示:是字母显示:是字母 显示:是其它字符显示:是其它字符 结结 束束yesnoyesno流程简图:流程简图: 111111程序:程序:程序:程序:#includeh>h>h>main() main() main() main() { { { { char ch; char ch; char ch; char ch; printf("Enter a character printf("Enter a character printf("Enter a character printf("Enter a character::::");");");"); ch ch ch ch====getchar();getchar();getchar();getchar(); if(ch>='0'&&ch<='9') if(ch>='0'&&ch<='9') if(ch>='0'&&ch<='9') if(ch>='0'&&ch<='9') printf("The character is a digit\n"); printf("The character is a digit\n"); printf("The character is a digit\n"); printf("The character is a digit\n"); else else else else if((ch>='A'&&ch<='Z')||((ch>='a'&&c<='z')) if((ch>='A'&&ch<='Z')||((ch>='a'&&c<='z')) if((ch>='A'&&ch<='Z')||((ch>='a'&&c<='z')) if((ch>='A'&&ch<='Z')||((ch>='a'&&c<='z')) printf("The character is a captal printf("The character is a captal printf("The character is a captal printf("The character is a captal letter\n"); letter\n"); letter\n"); letter\n"); else else else else printf("The character is other printf("The character is other printf("The character is other printf("The character is other character\n"); character\n"); character\n"); character\n"); } } } } 112112【例【例4-144-14】修改例】修改例4-104-10的程序,要求在求解方程之前,先判的程序,要求在求解方程之前,先判 断输入的二次项系数断输入的二次项系数a a是否为是否为0 0,若为,若为0 0,则输出出错信息。

      则输出出错信息 输入输入a,b,ca,b,c 开始开始 a≠0 ? a≠0 ?其余部分请参阅图其余部分请参阅图4 - 64 - 6中的相应部分中的相应部分 显示:显示: Error! Error! 结束结束计算计算b*b-4*a*cb*b-4*a*c并赋值给变量并赋值给变量deltadelta delta delta >=0=0? ?其余部分请参阅图其余部分请参阅图4 - 64 - 6中的相应部分中的相应部分 yesnoyesno流程图:流程图: 113113“if” “if” 和和“else”“else”的正确配对的正确配对 复合语句和条件语句的嵌套结构为解决一些较为复杂的复合语句和条件语句的嵌套结构为解决一些较为复杂的编程问题提供了必要的条件但同时也使程序的结构变得编程问题提供了必要的条件但同时也使程序的结构变得复杂,不易读懂特别是在程序中有多个复杂,不易读懂特别是在程序中有多个{ }{ }和和if…else…if…else…的情况 在在阅阅读读程程序序之之前前,,必必须须能能正正确确地地将将“{”“{”和和“}”“}”配配对对、、将将“if”“if”和和“else”“else”配对,使程序的结构变得清晰和有条理。

      配对,使程序的结构变得清晰和有条理if” “if” 和和“else”“else”配对应遵循下述规律:配对应遵循下述规律:自上而下,自上而下,“else”“else”总是和上面离它最近的总是和上面离它最近的“if”“if”配对而且,配对而且,每每一一个个“else”“else”只只能能和和一一个个“if”“if”配配对对由由于于单单独独的的“if”“if”也也是是条件语句,所以,允许无条件语句,所以,允许无“else”“else”配对的配对的“if”“if”单独存在单独存在同理,同理,“{”“{”和和“}”“}”配对应遵循下述规律:配对应遵循下述规律:自上而下,自上而下,“}”“}”总是和上面离它最近的总是和上面离它最近的“{”“{”配对 114114【例【例4-154-15】如果变量】如果变量x x的值是的值是-15, -15, 变量变量y y的值是的值是-10, -10, 则执则执 行下面的程序段后,屏幕上显示的内容是什么?行下面的程序段后,屏幕上显示的内容是什么?if(x>0)if(x>0)if(x>10)if(x>10)printf("A");printf("A");elseelseprintf("B");printf("B");elseelseif(y<-8)if(y<-8)if(y>-20)if(y>-20)printf("C");printf("C");elseelseprintf("D");printf("D");printf("E"); printf("E"); 为了看清程序结构,必须先将为了看清程序结构,必须先将ifif和和elseelse正确配对。

      正确配对 115115if(x>0)if(x>0)if(x>10)if(x>10)printf("A");printf("A");elseelseprintf("B");printf("B");elseelseif(y<-8)if(y<-8)if(y>-20)if(y>-20)printf("C");printf("C");elseelseprintf("D");printf("D"); printf("E"); printf("E");if(x>0)if(x>0) if(x>10) if(x>10) printf("A"); printf("A"); else else printf("B"); printf("B"); else else if(y<-8) if(y<-8) if(y>-20) if(y>-20) printf("C"); printf("C"); else else printf("D"); printf("D"); printf("E"); printf("E");将将ifif和和elseelse正确配对:正确配对:该程序段采用了缩进格式,该程序段采用了缩进格式,这种格式更容易反映出程这种格式更容易反映出程序结构。

      序结构 116116 显示:显示:E Ex>0x>0 ? ?x>10 ?x>10 ? 显示:显示:A A 显示:显示:B B y<-8 y<-8 ? ?   y>-20 y>-20 ? 显示:显示:C C 显示:显示:D Dyesyesnonoyesnonoyes流程图:流程图: 117117switch switch switch switch 语句的格式:语句的格式:语句的格式:语句的格式: switch(switch(switch(switch(整型表达式整型表达式整型表达式整型表达式) ) ) ) { { { { case case case case 整型常量表达式整型常量表达式整型常量表达式整型常量表达式1:1:1:1:语句序列语句序列语句序列语句序列1 1 1 1 〖〖〖〖 break; break; break; break; 〗〗〗〗 case case case case 整型常量表达式整型常量表达式整型常量表达式整型常量表达式2:2:2:2:语句序列语句序列语句序列语句序列2 2 2 2 〖〖〖〖 break; break; break; break; 〗〗〗〗 …… …… …… …… case case case case 整型常量表达式整型常量表达式整型常量表达式整型常量表达式k:k:k:k:语句序列语句序列语句序列语句序列k k k k 〖〖〖〖 break; break; break; break; 〗〗〗〗 〖〖〖〖 default: default: default: default:语句序列语句序列语句序列语句序列k+1 k+1 k+1 k+1 〗〗〗〗 } } } }三三. .开关语句开关语句 开关语句用于在程序中实现多路选择。

      开关语句用于在程序中实现多路选择 118118Yes语句序列语句序列1 1语句序列语句序列2 2有有 break break ? ?有有 break break ? ?语句序列语句序列k-1k-1有有 break break ? ?语句序列语句序列k k语句序列语句序列k+1k+1开开关关语语句句之之后后的语句的语句有有 break break ? ?开关:开关:整型表达式整型表达式………YesYesYesnonononoSwitch语句的执行流程: 119119说明:说明:说明:说明:    格式中的格式中的格式中的格式中的breakbreakbreakbreak语句不是必须的,应根据需要而语句不是必须的,应根据需要而语句不是必须的,应根据需要而语句不是必须的,应根据需要而 定    格式中的格式中的格式中的格式中的defaultdefaultdefaultdefault语句不是必须的,在缺省的情语句不是必须的,在缺省的情语句不是必须的,在缺省的情语句不是必须的,在缺省的情 况下,相当于语句序列况下,相当于语句序列况下,相当于语句序列况下,相当于语句序列k+1k+1k+1k+1是空语句。

      是空语句是空语句是空语句    格式中的格式中的格式中的格式中的{ }{ }{ }{ }是必须的是必须的是必须的是必须的1)switch(1)switch语句与语句与ifif语句的不同之处在于:语句的不同之处在于: switch switch语句只能对整型语句只能对整型( (含字符型含字符型) )表达式的值是否等于表达式的值是否等于 给定的值进行判断,而给定的值进行判断,而ifif语句可以用于判断各种表达式语句可以用于判断各种表达式2)switch(2)switch语句中,语句中,casecase后面只能是常量后面只能是常量3)(3)同一个同一个switchswitch语句中,任意两个语句中,任意两个casecase后面的常量值不能后面的常量值不能 相同 注意:注意: 120120【例【例4-164-16】编写一个四则运算计算器程序】编写一个四则运算计算器程序, , 可以实现输入二可以实现输入二 个数和一个四则运算符,输出运算结果的功能个数和一个四则运算符,输出运算结果的功能main()main() { { float operandl,operand2,result; float operandl,operand2,result; char operator; char operator; scanf("%f,%c,%f",&operandl,&operator,&operand2); scanf("%f,%c,%f",&operandl,&operator,&operand2); switch(operator) switch(operator) { { case '+': case '+': result result==operandl+operand2;operandl+operand2; break; break; case '-': case '-': result=operandl result=operandl一一operand2;operand2; break; break; case '*': case '*': result=operandl*operand2; result=operandl*operand2; break; break; case '/': case '/': result result==operandloperandl//operand2;operand2; break; break; default: default: printf("Illegal operator , error!\n"); printf("Illegal operator , error!\n"); } } printf("result=%f\n",result); printf("result=%f\n",result); } }由由operatoroperator的值的值决定执行哪一个决定执行哪一个casecase语句语句执行执行breakbreak语句后语句后就结束就结束switchswitch语句语句 121121【例【例4-174-17】用】用 switch switch 语句实现从键盘输入成绩,转换成相应的语句实现从键盘输入成绩,转换成相应的 等级后输出等级后输出(90 - 100(90 - 100为为A,80 - 89A,80 - 89为为B,70 - 79B,70 - 79为为C,C, 60 - 69 60 - 69为为D,59D,59及以下为及以下为E) E) 。

      main()main() { { int score; int score; printf("Please Input A Score: "); printf("Please Input A Score: "); scanf("%d",&score); scanf("%d",&score); printf("\n"); printf("\n"); switch(score/10) switch(score/10) { { case 10: case 10: case 9: printf("%c\n",'A');break; case 9: printf("%c\n",'A');break; case 8: printf("%c\n",'B');break; case 8: printf("%c\n",'B');break; case 7: printf("%c\n",'C');break; case 7: printf("%c\n",'C');break; case 6: printf("%c\n",'D');break; case 6: printf("%c\n",'D');break; default: printf("%c\n",'E'); default: printf("%c\n",'E'); } } } } 用以将输入的成绩用以将输入的成绩按等级与按等级与1010以内的以内的某一个非负整数某一个非负整数相对应相对应 case10case10、、case9case9执行相同的语句执行相同的语句 122122 4.6 4.6 循环结构循环结构 在程序中,若干个在一定条件下反复执行的语句在程序中,若干个在一定条件下反复执行的语句就构成了循环体,循环体连同对循环的控制就组成就构成了循环体,循环体连同对循环的控制就组成了循环结构。

      循环结构也是最常见的程序结构几了循环结构循环结构也是最常见的程序结构几乎所有实用的程序都包含循环结构乎所有实用的程序都包含循环结构在在C C程序中常用的循环语句包括:程序中常用的循环语句包括:● ● whilewhile语句语句● ● do — whiledo — while语句语句● ● forfor语句语句 123123 一一.while.while语句语句 while while语句的格式:语句的格式: while while(表达式)(表达式) 语句语句 语语 句句表达式表达式 值为非值为非0 0值为值为0 0执行流程:执行流程:循环体循环体循环控制循环控制, ,称控制称控制循环的变量为循环的变量为循环变量循环变量 124124【例【例4-184-18】编程求】编程求1+2+3+4+…+n (n1+2+3+4+…+n (n由键盘输入由键盘输入) ),, 并输出结果并输出结果 根据例根据例4-14-1给出的算法和流程图,设计如下的程序:给出的算法和流程图,设计如下的程序:main( )main( ) { { int n, i=1,sum=0; int n, i=1,sum=0; printf("Please input n:\n "); printf("Please input n:\n "); scanf("%d",&n); scanf("%d",&n); printf("1+2+……+%d = %d",n,sum); printf("1+2+……+%d = %d",n,sum); } }流程图while(i<=n)    sum+=i++;循环体,在循环循环体,在循环体中须有修改体中须有修改循环变量的语句循环变量的语句 125125【例【例4-194-19】编程计算级数】编程计算级数 1+1+ 的和的和, , 当最后一项小于当最后一项小于0.000010.00001时结束。

      时结束 分析:分析:这也是一个连加问题,可以采用类似于例这也是一个连加问题,可以采用类似于例4-184-18的的 算法来实现用变量算法来实现用变量sumsum存放部分和级数第存放部分和级数第i i项项 的分母为的分母为(i-1)×i (i=2,3,….)(i-1)×i (i=2,3,….) main() main() { { int i=2; int i=2; float sum=1.0; float sum=1.0; while(1.0/((i-1)*i)>=0.00001) while(1.0/((i-1)*i)>=0.00001) printf(“SUM=%f”,sum); printf(“SUM=%f”,sum); } }循环的次数循环的次数预先不知预先不知{ {  sum+=1.0/((i-1)*i);sum+=1.0/((i-1)*i); i++; i++;} }循环体是复循环体是复合语句合语句 126126二二.do-while.do-while语句语句do-whiledo-while语句的格式:语句的格式: do do 语句语句 while( while(表达式表达式) );;语句语句表达式表达式值为非值为非0值为值为0执行流程:执行流程:循环体循环体循环控制循环控制 127127【例【例4-204-20】用】用do do -- while while 语句实现【例语句实现【例4-184-18】。

      main() main() { { int n, i=1,sum=0; int n, i=1,sum=0; printf("Please input n:\ "); printf("Please input n:\ "); scanf("%d ",&n); scanf("%d ",&n); do do sum+=i++; sum+=i++; while(i<=n); while(i<=n); printf("1+2+……+%d = %d \n ",n,sum); printf("1+2+……+%d = %d \n ",n,sum); } }循环体至少被循环体至少被执行一次执行一次 128128【例【例4-214-21】编程计算】编程计算n! n! ,,n n由键盘输入由键盘输入 开开 始始 1 1  fac fac 2 2  i ifac×ifac×ifacfac i+1 i+1  i i从键盘输入从键盘输入n n i ≤ n ? i ≤ n ?输出输出 fac fac 结结 束束流程图流程图: 129129 main() main() { { int n, i=2; int n, i=2; long int fac=1; long int fac=1; printf("Please input n:\ "); printf("Please input n:\ "); scanf("%d",&n); scanf("%d",&n); do do fac*=i++; fac*=i++; while(i<=n); while(i<=n); printf("%d!=%ld\n",n,fac); printf("%d!=%ld\n",n,fac); } }程序:程序: 130130说明:表达式说明:表达式1 1用于给循环变量赋初值用于给循环变量赋初值, , 表达式表达式2 2给出执行给出执行循环体的条件循环体的条件, , 表达式表达式3 3用于修改循环变量。

      用于修改循环变量三三.for.for语句语句forfor语句的格式:语句的格式:forfor(表达式(表达式1 1;表达式;表达式2 2;表达式;表达式3 3)) 语句语句( (循环体循环体) ) 表达式表达式1 1 表达式表达式2 2 语句语句 表达式表达式3值为非值为非0 0值为值为0 0执行流程:执行流程: 131131【例【例4-224-22】编程计算】编程计算1-3+5-7+……-991-3+5-7+……-99 分析:分析:原题就是计算原题就是计算1+(-3)+5+(-7)+……+(-99)1+(-3)+5+(-7)+……+(-99),这还是一个连,这还是一个连加问题主要应解决加数符号的交叉变化主要应解决加数符号的交叉变化在程序中用变在程序中用变量量j j表示符号,以表示符号,以1 1表示正号、-表示正号、-1 1表示负号表示负号 main() main() { { int i,j,sum=0; int i,j,sum=0; j=1; j=1; for(i=1;i<=99;i+=2) for(i=1;i<=99;i+=2) { { sum+=i*j; sum+=i*j; j*=-1; j*=-1; } } printf("1-3+5-7+……-99=%d\n",sum); printf("1-3+5-7+……-99=%d\n",sum); } } 132132【例【例4-234-23】编程求】编程求1 1到到100100以内所有能被以内所有能被3 3整除但不能被整除但不能被7 7整除整除 的整数的和。

      的整数的和 分析:分析:本例还是一个连加问题,只是要求加数能被本例还是一个连加问题,只是要求加数能被3 3整除且整除且 不能被不能被7 7整除 main() main() { { int i,sum=0; int i,sum=0; for(i=1;i<=100;i++) for(i=1;i<=100;i++) if((i%3==0)&&(i%7!=0)) if((i%3==0)&&(i%7!=0)) sum+=i; sum+=i; printf("SUM=%d\n",sum); printf("SUM=%d\n",sum); } } 133133C C语言允许语言允许forfor语句一般格式中的表达式语句一般格式中的表达式1 1,表达式,表达式2 2和表达式和表达式3 3空缺,但它们所具有的功能应当在适当的空缺,但它们所具有的功能应当在适当的地方由另外的语句来实现。

      地方由另外的语句来实现例例4-23-14-23-1与例与例4-234-23程序的功能是一样的程序的功能是一样的例【例4-23-14-23-1】】 main() main() { { int i=1,sum=0; int i=1,sum=0; for(;i<=100;i++) for(;i<=100;i++) if((i%3==0)&&(i%7!=0)) if((i%3==0)&&(i%7!=0)) sum+=i; sum+=i; printf("SUM=%d\n",sum); printf("SUM=%d\n",sum); } } 对循环变量对循环变量i i赋初值赋初值省却了对循环省却了对循环变量变量i i赋初值的赋初值的表达式表达式1 1 134134例例4-23-24-23-2与例与例4-234-23程序的功能也是一样的程序的功能也是一样的例【例4-23-24-23-2】】 main() main() { { int i=1,sum=0; int i=1,sum=0; for(;i<=100;) for(;i<=100;) { { if((i%3==0)&&(i%7!=0)) if((i%3==0)&&(i%7!=0)) sum+=i; sum+=i; i++; i++; } } printf("SUM=%d\n",sum); printf("SUM=%d\n",sum); } }省却了修改循环省却了修改循环变量变量在这里修改在这里修改循环变量循环变量 135135 四四. .循环的嵌套循环的嵌套 循环的嵌套是指一个循环体内又包含另一个完整循环的嵌套是指一个循环体内又包含另一个完整 的循环结构。

      的循环结构 例如:例如:(1) while( ) (2) while( )(1) while( ) (2) while( ) { { { {  …… …… …… …… while( ) do while( ) do { { { { … … … … } } } } } while( ); } while( ); …… …… } }外循环外循环内循环内循环 136136再如:再如:(3) do (4) for()(3) do (4) for() { { { { …… for() …… for() while( ) { while( ) { { … { … … } … } } } } } } } while( ); while( ); 外循环外循环内循环内循环注意:注意:在循环嵌套时,外循环必须完全包含内循环。

      在循环嵌套时,外循环必须完全包含内循环 137137【例【例4-244-24】编程输出如下由】编程输出如下由“*”“*”组成的三角形组成的三角形 * * *** *** ***** ***** ******* ******* ********* *********外循环控制外循环控制输出输出5 5行行* *字符字符 内循环控制一行内循环控制一行输出输出2*i-12*i-1个个* *字符字符输出一行输出一行* *字符字符后换行后换行 main() main() { { int i,j; int i,j; for(i=1;i<=5;i++) for(i=1;i<=5;i++) { { for(j=1;j<=2*i-1;j++) for(j=1;j<=2*i-1;j++) printf("*"); printf("*"); printf(" \n"); printf(" \n"); } } } } 138138 4.7 continue4.7 continue语句和语句和breakbreak语句语句continuecontinue语语句句和和breakbreak语语句句属属于于转转向向语语句句,,它它们们常常用用在循环体中在循环体中, , 用于改变循环的执行顺序。

      用于改变循环的执行顺序一一.continue.continue语句语句在循环体中执行在循环体中执行continuecontinue语句后,程序将立即跳过语句后,程序将立即跳过continuecontinue语句之后尚未执行的语句,提前结束本轮语句之后尚未执行的语句,提前结束本轮循环,返回到循环的开始处循环,返回到循环的开始处, , 准备执行下一轮循环准备执行下一轮循环 注意:注意: ((1 1)) continuecontinue、、breakbreak语句必须和语句必须和ifif语句配合使用,语句配合使用, 否则,循环体中否则,循环体中continue continue 、、breakbreak语句后面的语句后面的 部分将是多余的部分将是多余的 ((2 2))continue continue 、、breakbreak语句只对其直接所属的循环语句只对其直接所属的循环 语句起作用语句起作用 139139【例【例4-254-25】从键盘输入整数,如果是奇数,则继续输入,如】从键盘输入整数,如果是奇数,则继续输入,如 果是非果是非0 0偶数,则显示该偶数后继续输入,如果是偶数,则显示该偶数后继续输入,如果是0 0则输则输 出出“The end.”“The end.”后结束。

      后结束 分析:分析: 题目要求不断地从键盘输入整数,直到输入题目要求不断地从键盘输入整数,直到输入0 0时结束这可时结束这可 以用循环结构来实现以用循环结构来实现 main() main() { { int n=1; int n=1; while(n!=0) while(n!=0) { { printf(" Please input an integer:\n "); printf(" Please input an integer:\n "); scanf("%d",&n); scanf("%d",&n); if(n%2==1) if(n%2==1) continue; continue; else else if(n!=0) if(n!=0) printf(" %d\n ",n); printf(" %d\n ",n); } } printf(" The end.\n "); printf(" The end.\n "); } }保证循环体至少保证循环体至少被执行一次被执行一次 若输入的是奇数若输入的是奇数则结束本轮循环则结束本轮循环并返回循环开始处并返回循环开始处 140140用用forfor语句来实现【例语句来实现【例4-254-25】】 。

      例【例4-25-14-25-1】】 main() main() { { int n=1; int n=1; for(;n!=0;) for(;n!=0;) { { printf(" Please input an integer:\n "); printf(" Please input an integer:\n "); scanf("%d",&n); scanf("%d",&n); if(n%2==1) if(n%2==1) continue; continue; else else if(n!=0) if(n!=0) printf(" %d\n ",n); printf(" %d\n ",n); } } printf(" The end.\n "); printf(" The end.\n "); } } 141141二二.break.break语句语句在循环体中执行在循环体中执行breakbreak语句后,将立即结束循环。

      语句后,将立即结束循环例【例4-264-26】每次从键盘输入一个整数进行累加,一】每次从键盘输入一个整数进行累加,一 旦累加和大于旦累加和大于100100时,停止输入并输出累加和时,停止输入并输出累加和 main() main() { { int n,sum=0; int n,sum=0; while(1) while(1) { { printf("Please input an integer:\n"); printf("Please input an integer:\n"); scanf("%d",&n); scanf("%d",&n); sum+=n; sum+=n; if(sum>100) if(sum>100) break; break; } } printf("SUM=%d\n",sum); printf("SUM=%d\n",sum); } }若条件满足,若条件满足,则结束本次循环则结束本次循环永真条件永真条件 142142用用forfor语句来实现【例语句来实现【例4-264-26】】 。

      例【例4-26-14-26-1】】main()main() { { int n,sum=0; int n,sum=0; for(;;) for(;;) { { printf("Please input an integer:\n"); printf("Please input an integer:\n"); scanf("%d",&n); scanf("%d",&n); sum+=n; sum+=n; if(sum>100) if(sum>100) break; break; } } printf("SUM=%d\n",sum); printf("SUM=%d\n",sum); } }省却了对循环省却了对循环条件的判断条件的判断用用breakbreak语句语句控制结束循环控制结束循环 143143第第4章章 结束结束       第第5 5章章数数 组组 2021/8/22144 145145学习目标学习目标1.1.熟练掌握一维数组、二维数组、字符熟练掌握一维数组、二维数组、字符数组的定义、初始化。

      数组的定义、初始化2.2.熟练掌握数组元素的引用方法熟练掌握数组元素的引用方法3.3.3. 3. 熟练掌握熟练掌握C C程序处理字符串的常用程序处理字符串的常用方法 146146主要内容主要内容–一维数组一维数组–二维数组二维数组–字符数组和字符串字符数组和字符串 1471475.l 5.l 一维数组的定义及应用一维数组的定义及应用 一一. . 一维数组的定义一维数组的定义n n 次多项式通常被表示为:次多项式通常被表示为: f(x) = a f(x) = an n x xn n+ a+ an-1n-1 x xn-1n-1+ a+ a n-2 n-2 x xn-2n-2 + …… + a + …… + a 2 2 x x 2 2 + + a a 1 1 x + a x + a0 0各项系数为:各项系数为: a an n,, a an-1n-1,, a an-2n-2 ,,…………,, a a2 2 ,, a a1 1 ,, a a0 0它们有下列特点:它们有下列特点: 同名同名 ── a ── a 同类型同类型 ── ──实数类型实数类型 以下标以下标 0,1,2,……, n-1, n 0,1,2,……, n-1, n 区别各元素区别各元素 ──── a an n、、a an-1n-1、、a an-2n-2、、、、…………、、a a2 2、、a a1 1、、a a0 0在在C C语言中,把具有一定顺序关系的同名、同类型变量的集语言中,把具有一定顺序关系的同名、同类型变量的集合称为数组,称元素的共名合称为数组,称元素的共名a a为数组名,将各元素记为:为数组名,将各元素记为:a[0]a[0],a[1],a[2],……, a[n-1],a[n] ,a[1],a[2],……, a[n-1],a[n] 。

      根据元素下标的个数将数根据元素下标的个数将数组分为组分为 一维数组、一维数组、 二维数组、二维数组、……故又称数组元素为下标故又称数组元素为下标变量 148148一维数组的定义:一维数组的定义:  数据类型数据类型 数组名数组名[ [元素个数元素个数];];例如:例如: int data[4] int data[4];; 定定义义了了一一个个有有4 4个个元元素素的的一一维维数数组组datadata,,元元素素类类型为型为intint型;型; 又如:又如: char c[10] char c[10];; 定定义义了了一一个个有有4 4个个元元素素的的一一维维数数组组c c,,元元素素类类型型为为charchar型型        149149注意注意: : 1.1.在数组定义中,方括号中的元素个数只能是整数常在数组定义中,方括号中的元素个数只能是整数常量(包括符号常量)量(包括符号常量) ;; 2. 2. 数组元素的下标从数组元素的下标从0 0开始;开始; 3. 3. 数组名的命名规则与变量名相同;数组名的命名规则与变量名相同; 4. 4. 数组在内存中按其下标递增的顺序连续存储各元数组在内存中按其下标递增的顺序连续存储各元素的值素的值 ,数组名表示第一个变量的存储地址,数组名表示第一个变量的存储地址 ;;5. 5. 参加数据处理的只能是数组中的元素变量参加数据处理的只能是数组中的元素变量 ,数组,数组整体不能参加数据处理整体不能参加数据处理 150150 二二二二. .一维数组的初始化一维数组的初始化一维数组的初始化一维数组的初始化一维数组的初始化就是在定义数组时对所有的数一维数组的初始化就是在定义数组时对所有的数一维数组的初始化就是在定义数组时对所有的数一维数组的初始化就是在定义数组时对所有的数组元素赋初值。

      组元素赋初值组元素赋初值组元素赋初值 例如:定义例如:定义例如:定义例如:定义 int data[4]={3 int data[4]={3 int data[4]={3 int data[4]={3,,,,0 0 0 0,,,,5 5 5 5,,,,0};0};0};0};则等号右边花括号中的数值则等号右边花括号中的数值则等号右边花括号中的数值则等号右边花括号中的数值3 3 3 3,,,,0 0 0 0,,,,5 5 5 5,,,,0 0 0 0依次被赋予依次被赋予依次被赋予依次被赋予data[0],data[0],data[0],data[0],data[1]data[1]data[1]data[1],,,,data[2]data[2]data[2]data[2]及及及及date[3]date[3]date[3]date[3]作为初值作为初值作为初值作为初值设数组设数组设数组设数组datadatadatadata从地址为从地址为从地址为从地址为2000H2000H2000H2000H的内存单元开始存放的内存单元开始存放的内存单元开始存放的内存单元开始存放, , , ,其在内存中其在内存中其在内存中其在内存中的存储情况如下图所示:的存储情况如下图所示:的存储情况如下图所示:的存储情况如下图所示: data[0] data[0]:: 2000H 2000H 0 30 3 data[1] data[1]:: 2002H 0 0 2002H 0 0 data[2] data[2]:: 2004H 0 5 2004H 0 5 data[3] data[3]:: 2006H 0 0 2006H 0 0 151151 此此此此外外外外,,,,在在在在初初初初始始始始化化化化的的的的格格格格式式式式中中中中,,,,{}{}{}{}中中中中的的的的某某某某个个个个初初初初始始始始化化化化数数数数据据据据可可可可以以以以缺缺缺缺省省省省,,,,但但但但是是是是用用用用以以以以分隔数据的逗号不能省略。

      默认缺省的数据为零值例如分隔数据的逗号不能省略默认缺省的数据为零值例如分隔数据的逗号不能省略默认缺省的数据为零值例如分隔数据的逗号不能省略默认缺省的数据为零值例如, , , ,执行语句:执行语句:执行语句:执行语句: int data[4]={3,,5,}; int data[4]={3,,5,}; int data[4]={3,,5,}; int data[4]={3,,5,}; 和和和和 int data[4]={3,0,5,0}; int data[4]={3,0,5,0}; int data[4]={3,0,5,0}; int data[4]={3,0,5,0};的结果也是一样的的结果也是一样的的结果也是一样的的结果也是一样的 C C C C语言还允许在数组初始化时不指明数组元素的个数语言还允许在数组初始化时不指明数组元素的个数语言还允许在数组初始化时不指明数组元素的个数语言还允许在数组初始化时不指明数组元素的个数例例例例如如如如::::用用用用int int int int b[]={1b[]={1b[]={1b[]={1,,,,2 2 2 2,,,,3 3 3 3,,,,4} 4} 4} 4} ; ; ; ;定定定定义义义义并并并并初初初初始始始始化化化化一一一一维维维维数数数数组组组组b[]b[]b[]b[]是是是是合合合合法法法法的的的的。

      此此此此时时时时,,,,{}{}{}{}中中中中初初初初始始始始化化化化数数数数据据据据的的的的个个个个数数数数即即即即为为为为数数数数组组组组元元元元素素素素个个个个数数数数所所所所以以以以,,,,数数数数组组组组b[]b[]b[]b[]有有有有4 4 4 4个个个个元元元元素 说明:说明: 在初始化的格式中,在初始化的格式中,{ }{ }中的初始化数据用逗号分隔当初中的初始化数据用逗号分隔当初始化数据个数少于数组元素个数时,剩下的数组元素被赋予始化数据个数少于数组元素个数时,剩下的数组元素被赋予零值所以,零值所以, int data[4] ={3,0,5}; int data[4] ={3,0,5}; 和和 int data[4]={3,0,5,0}; int data[4]={3,0,5,0};的结果是一样的的结果是一样的 152152三三三三. . 一维数组元素的引用一维数组元素的引用一维数组元素的引用一维数组元素的引用 数组元素在程序中可参与同类型的变量所能进行的各种数组元素在程序中可参与同类型的变量所能进行的各种数组元素在程序中可参与同类型的变量所能进行的各种数组元素在程序中可参与同类型的变量所能进行的各种运算运算运算运算, , , ,并遵循与同类型变量相同的运算规则。

      并遵循与同类型变量相同的运算规则并遵循与同类型变量相同的运算规则并遵循与同类型变量相同的运算规则 在程序中,通过数组名和下标引用相应的数组元素在程序中,通过数组名和下标引用相应的数组元素在程序中,通过数组名和下标引用相应的数组元素在程序中,通过数组名和下标引用相应的数组元素 【例【例【例【例5-15-15-15-1】】】】 用用用用1 1 1 1,,,,3 3 3 3,,,,5 5 5 5,,,,7 7 7 7,,,,9 9 9 9,,,,11111111,,,,13131313,,,,15151515,,,,17171717,,,,19191919为数组为数组为数组为数组 a[] a[] a[] a[]的各元素赋值,然后按的各元素赋值,然后按的各元素赋值,然后按的各元素赋值,然后按a[9]a[9]a[9]a[9]、、、、a[8]a[8]a[8]a[8]、、、、a[7]a[7]a[7]a[7]、、、、……………………、、、、 a[0] a[0] a[0] a[0]的顺序输出。

      的顺序输出的顺序输出的顺序输出 main( ) main( ) main( ) main( ) { { { { int i ,a[10]; int i ,a[10]; int i ,a[10]; int i ,a[10]; for( i=0;i<=9; i++) for( i=0;i<=9; i++) for( i=0;i<=9; i++) for( i=0;i<=9; i++) a[i]=2*i+1; a[i]=2*i+1; a[i]=2*i+1; a[i]=2*i+1; for(i=9;i>=0;i--) for(i=9;i>=0;i--) for(i=9;i>=0;i--) for(i=9;i>=0;i--) printf("%d, ", a[ i ]); printf("%d, ", a[ i ]); printf("%d, ", a[ i ]); printf("%d, ", a[ i ]); } } } } 153153【例【例【例【例5-25-25-25-2】】】】 输入输入输入输入4 4 4 4个整数个整数个整数个整数a a a a0 0 0 0,a,a,a,a1 1 1 1, a, a, a, a2 2 2 2, a, a, a, a3 3 3 3将它们从小到大按升将它们从小到大按升将它们从小到大按升将它们从小到大按升 序排序后输出。

      序排序后输出序排序后输出序排序后输出●●●● 排序方法之一:起泡法排序 排序方法之一:起泡法排序 排序方法之一:起泡法排序 排序方法之一:起泡法排序起泡法升序排序的思路是:起泡法升序排序的思路是: 将相邻两个数将相邻两个数a ai i, a, ai+1i+1((i=0i=0,,1 1,,2 2)进行比较,若)进行比较,若a ai i

      排序 一般地,对一般地,对n n个数进行排序,共需进行个数进行排序,共需进行n-1n-1轮比较,在第轮比较,在第i i 轮中要对轮中要对n-i+1n-i+1个数进行个数进行n-in-i次相邻元素的两两比较、交换次相邻元素的两两比较、交换 154154设设 int a[]={ 8, 6, 4, 2 }; int a[]={ 8, 6, 4, 2 }; 数组数组a a在内存中的排列如下图所示:在内存中的排列如下图所示:a[0]∶ 0 8 a[0]∶ 0 8 要求变成要求变成 0 2 0 2 a[1]∶ 0 6 0 4 a[1]∶ 0 6 0 4 a[2]∶ 0 4 0 6 a[2]∶ 0 4 0 6 a[3]∶ 0 2 0 8 a[3]∶ 0 2 0 8根据算法:执行第一轮比较:根据算法:执行第一轮比较: for(j=0;j<=2;j++) for(j=0;j<=2;j++) if(a[j] > a[j+1]) if(a[j] > a[j+1]) 将将a[j]a[j]的值与的值与a[j+1]a[j+1]的值互换;的值互换; j=0 j=1 j=2 j=0 j=1 j=2a[0]∶8 6 6 6 a[0]∶8 6 6 6 a[1]∶6 8 4 4 a[1]∶6 8 4 4 a[2]∶4 4 8 2a[2]∶4 4 8 2a[3]∶2 2 2 8a[3]∶2 2 2 8示意图:示意图:结果:经过三次循环,结果:经过三次循环,a[0]~ a[3] a[0]~ a[3] 中的内容变为:中的内容变为: 6,4,2,8 6,4,2,8。

      最大值最大值8 8已经已经““沉沉””到最下面到最下面 155155根据算法:再执行第二轮比较:根据算法:再执行第二轮比较: for(j=0;j<=1;j++) for(j=0;j<=1;j++) if(a[j] > a[j+1]) if(a[j] > a[j+1]) 将将a[j]a[j]的值与的值与a[j+1]a[j+1]的值互换;的值互换; j=0 j=1 j=0 j=1a[0]∶6 4 4 a[0]∶6 4 4 a[1]∶4 6 2 a[1]∶4 6 2 a[2]∶2 2 6 a[2]∶2 2 6 a[3]∶8 8 8 a[3]∶8 8 8 示意图:示意图:结果:经过二次循环,结果:经过二次循环,a[0]~ a[3] a[0]~ a[3] 中的内容变为:中的内容变为: 4,2,6,8 4,2,6,8。

      156156根据算法:执行第三轮比较:根据算法:执行第三轮比较: for(j=0;j<=0;j++) for(j=0;j<=0;j++) if(a[j] > a[j+1]) if(a[j] > a[j+1]) 将将a[j]a[j]的值与的值与a[j+1]a[j+1]的值互换;的值互换; j=0 j=0 a[0]∶4 2 a[0]∶4 2 a[1]∶2 4 a[1]∶2 4 a[2]∶6 6 a[2]∶6 6 a[3]∶8 8 a[3]∶8 8 示意图:示意图:结果:经过一次循环,结果:经过一次循环,a[0]~ a[3] a[0]~ a[3] 中的内容变为:中的内容变为:2,4,6,82,4,6,8。

      实现了所要求的排序实现了所要求的排序 157157一般地,设:一般地,设:一般地,设:一般地,设: n n n n个数为个数为个数为个数为 a[0], a[1], a[2],……, a[0], a[1], a[2],……, a[0], a[1], a[2],……, a[0], a[1], a[2],……, a[n-2], a[n-1] a[n-2], a[n-1] a[n-2], a[n-1] a[n-2], a[n-1],,,, 则则则则 n n n n 个数的起泡排序算法可用个数的起泡排序算法可用个数的起泡排序算法可用个数的起泡排序算法可用forforforfor循环表示为:循环表示为:循环表示为:循环表示为: for(i=0;i<=n-2;i++) for(i=0;i<=n-2;i++) for(i=0;i<=n-2;i++) for(i=0;i<=n-2;i++) for(j=0;j<=n-2-i;j++) for(j=0;j<=n-2-i;j++) for(j=0;j<=n-2-i;j++) for(j=0;j<=n-2-i;j++) if(a[j] > a[j+1]) if(a[j] > a[j+1]) if(a[j] > a[j+1]) if(a[j] > a[j+1]) 将将将将a[j]a[j]a[j]a[j]的值与的值与的值与的值与a[j+1]a[j+1]a[j+1]a[j+1]的值互换;的值互换;的值互换;的值互换; 158158【例【例【例【例5-2-15-2-15-2-15-2-1】】】】 起泡法排序的程序:起泡法排序的程序:起泡法排序的程序:起泡法排序的程序: 用符号常量用符号常量N N表表示元素个数示元素个数 #define N 4#define N 4#define N 4#define N 4main() main() main() main() { { { { int a[N]; int a[N]; int a[N]; int a[N]; int i,j,t; int i,j,t; int i,j,t; int i,j,t; printf("Please input printf("Please input printf("Please input printf("Please input %d numbers:\n",N); %d numbers:\n",N); %d numbers:\n",N); %d numbers:\n",N); for(i=0;ia[j+1]) if(a[j]>a[j+1]) if(a[j]>a[j+1]) if(a[j]>a[j+1]) { { { { t=a[j]; t=a[j]; t=a[j]; t=a[j]; a[j]=a[j+1]; a[j]=a[j+1]; a[j]=a[j+1]; a[j]=a[j+1]; a[j+1]=t; a[j+1]=t; a[j+1]=t; a[j+1]=t; } } } } printf("\n The sorted printf("\n The sorted printf("\n The sorted printf("\n The sorted numbers:\n"); numbers:\n"); numbers:\n"); numbers:\n"); for(i=0;i<=N-1;i++) for(i=0;i<=N-1;i++) for(i=0;i<=N-1;i++) for(i=0;i<=N-1;i++) printf("%d, ",a[i]); printf("%d, ",a[i]); printf("%d, ",a[i]); printf("%d, ",a[i]); printf("\n "); printf("\n "); printf("\n "); printf("\n "); } } } }起泡法起泡法排序排序 159159排序方法之二:选择法排序排序方法之二:选择法排序排序方法之二:选择法排序排序方法之二:选择法排序选择法排序的思路是:选择法排序的思路是:选择法排序的思路是:选择法排序的思路是: 先经过先经过先经过先经过3 3 3 3次比较找出次比较找出次比较找出次比较找出a[0]a[0]a[0]a[0]、、、、a[1]a[1]a[1]a[1]、、、、a[2]a[2]a[2]a[2]和和和和a[3]a[3]a[3]a[3]中的最小数并中的最小数并中的最小数并中的最小数并与与与与a[0]a[0]a[0]a[0]对换,再经过对换,再经过对换,再经过对换,再经过2 2 2 2次比较找出次比较找出次比较找出次比较找出a[1]a[1]a[1]a[1]、、、、a[2]a[2]a[2]a[2]和和和和a[3]a[3]a[3]a[3]中的最小中的最小中的最小中的最小数并与数并与数并与数并与a[1]a[1]a[1]a[1]进行对换,最后,进行一次比较,选出进行对换,最后,进行一次比较,选出进行对换,最后,进行一次比较,选出进行对换,最后,进行一次比较,选出a[2] a[2] a[2] a[2] 和和和和a[3]a[3]a[3]a[3]中的最小数与中的最小数与中的最小数与中的最小数与a[2]a[2]a[2]a[2]进行对换。

      进行对换进行对换进行对换 一般地,对一般地,对一般地,对一般地,对n n n n个数进行排序,共需进行个数进行排序,共需进行个数进行排序,共需进行个数进行排序,共需进行n-1n-1n-1n-1轮比较,在第轮比较,在第轮比较,在第轮比较,在第i i i i轮要轮要轮要轮要经过经过经过经过n-in-in-in-i次两两比较次两两比较次两两比较次两两比较, , , ,从而在数组未经排序的从而在数组未经排序的从而在数组未经排序的从而在数组未经排序的n-i+1n-i+1n-i+1n-i+1个数中找出个数中找出个数中找出个数中找出最小数并与最小数并与最小数并与最小数并与a[i-1]a[i-1]a[i-1]a[i-1]对换与起泡法相比,选择法只是在每轮比对换与起泡法相比,选择法只是在每轮比对换与起泡法相比,选择法只是在每轮比对换与起泡法相比,选择法只是在每轮比较结束后,根据需要,作一次对换操作在数据个数较多的情较结束后,根据需要,作一次对换操作在数据个数较多的情较结束后,根据需要,作一次对换操作在数据个数较多的情较结束后,根据需要,作一次对换操作在数据个数较多的情况下,相比起泡法有更高的效率。

      况下,相比起泡法有更高的效率况下,相比起泡法有更高的效率况下,相比起泡法有更高的效率 160160 【例【例【例【例5-2-25-2-25-2-25-2-2】】】】 选择法排序的程序选择法排序的程序选择法排序的程序选择法排序的程序for(i=0;i<=N-2;i++)for(i=0;i<=N-2;i++)for(i=0;i<=N-2;i++)for(i=0;i<=N-2;i++) { { { { k=i; k=i; k=i; k=i; for(j=i+1;j<=N-1;j++) for(j=i+1;j<=N-1;j++) for(j=i+1;j<=N-1;j++) for(j=i+1;j<=N-1;j++) if(a[j]

      值秦九韶算法:a an n x xn n+ a+ an-1n-1 x xn-1n-1+ a+ a n-2 n-2 x xn-2n-2 + …… + a + …… + a 2 2 x x 2 2 + a + a 1 1 x+ a x+ a0 0 =(x…(x(x(a=(x…(x(x(an nx+ax+an-1n-1)+a)+an-2n-2)+a)+an-3n-3)+…a)+…a1 1)+a)+a0 0由此可知,由此可知,n n次多项式的计算步骤为:次多项式的计算步骤为: 第一步:计算第一步:计算 a[n]*x+a[n-1] ── a[n]*x+a[n-1] ── 记为记为A A 第二步:计算第二步:计算 A*x+a[n-2] ── A*x+a[n-2] ──记为记为A A  …… …… 第第n-1n-1步:计算步:计算A*x+a[1] ── A*x+a[1] ── 记为记为A A 第第n n步:计算步:计算 A*x+a[0] ── A*x+a[0] ── 得到最后结果得到最后结果 162162【例【例5-35-3】的程序:】的程序: #define N 3 #define N 3 main() main() { { float a[N+1],A,x; float a[N+1],A,x; int i; int i; printf("Please Input a[%d],a[%d],…,a[0]: printf("Please Input a[%d],a[%d],…,a[0]: \n",N,N-1); \n",N,N-1); for(i=N;i>=0; i for(i=N;i>=0; i--) ) scanf("%f",&a[i]); scanf("%f",&a[i]); printf("Please Input x: \n"); printf("Please Input x: \n"); scanf("%f",&x); scanf("%f",&x); f=a[N]; f=a[N]; for(i=N;i>0;i for(i=N;i>0;i--) ) A=A*x+a[i-1]; A=A*x+a[i-1]; printf("Result=%f\n",A); printf("Result=%f\n",A); } } 输入输入x x以便计算以便计算多项式的值多项式的值 163163 5.2 5.2 字符型数组与字符串字符型数组与字符串一一一一. . . . 字符型数组字符型数组字符型数组字符型数组 字符型数组也是一维数组。

      在定义字符型数组的同时可对字符型数组也是一维数组在定义字符型数组的同时可对字符型数组也是一维数组在定义字符型数组的同时可对字符型数组也是一维数组在定义字符型数组的同时可对其初始化,用其初始化,用其初始化,用其初始化,用{}{}{}{}将初始化数据括起将初始化数据括起将初始化数据括起将初始化数据括起 例例例例如如如如::::语语语语句句句句 char char char char str1[]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’}str1[]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’}str1[]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’}str1[]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’};;;; 定义了一个有七个元素的字符数组定义了一个有七个元素的字符数组定义了一个有七个元素的字符数组定义了一个有七个元素的字符数组str1[]str1[]str1[]str1[],并用花括号中,并用花括号中,并用花括号中,并用花括号中的字符常量对数组进行初始化下面的语句实现的是同样的功的字符常量对数组进行初始化。

      下面的语句实现的是同样的功的字符常量对数组进行初始化下面的语句实现的是同样的功的字符常量对数组进行初始化下面的语句实现的是同样的功能:能:能:能: char str1[ ] char str1[ ] char str1[ ] char str1[ ]===={112{112{112{112,,,,114114114114,,,,111111111111,,,,103103103103,,,,114114114114,,,,97979797,,,,109}109}109}109};;;;所不同的是,花括号中的数据不是字符常量本身,而是字符常所不同的是,花括号中的数据不是字符常量本身,而是字符常所不同的是,花括号中的数据不是字符常量本身,而是字符常所不同的是,花括号中的数据不是字符常量本身,而是字符常量相应的量相应的量相应的量相应的ASCASCASCASC代码值 设数组设数组设数组设数组str1[]str1[]str1[]str1[]从地址为从地址为从地址为从地址为2000H2000H2000H2000H的内存单元开始存放,由于一的内存单元开始存放,由于一的内存单元开始存放,由于一的内存单元开始存放,由于一个字符型数据占一个字节,所以各数组元素的存储单元地址从个字符型数据占一个字节,所以各数组元素的存储单元地址从个字符型数据占一个字节,所以各数组元素的存储单元地址从个字符型数据占一个字节,所以各数组元素的存储单元地址从2000H2000H2000H2000H到到到到2006H2006H2006H2006H。

      164164 2000H 'p' 2001H 'r' 2002H 'o' 2003H 'g' 2004H 'r' 2005H 'a' 2006H 'm'字符型数组字符型数组字符型数组字符型数组str1[ ]str1[ ]str1[ ]str1[ ]在内存中的存储情况:在内存中的存储情况:在内存中的存储情况:在内存中的存储情况: 165165 【例【例【例【例5-45-45-45-4】】】】 从键盘输入十个字符,统计字符从键盘输入十个字符,统计字符从键盘输入十个字符,统计字符从键盘输入十个字符,统计字符'g''g''g''g'出现的次数出现的次数出现的次数出现的次数 main() main() main() main() { { { { int counter=0,i; int counter=0,i; int counter=0,i; int counter=0,i; char c[10]; char c[10]; char c[10]; char c[10]; printf("Please input ten characters\n"); printf("Please input ten characters\n"); printf("Please input ten characters\n"); printf("Please input ten characters\n"); for(i=0;i<=9;i++) for(i=0;i<=9;i++) for(i=0;i<=9;i++) for(i=0;i<=9;i++) scanf("%c",&c[i]); scanf("%c",&c[i]); scanf("%c",&c[i]); scanf("%c",&c[i]); for(i=0;i<=9;i++) for(i=0;i<=9;i++) for(i=0;i<=9;i++) for(i=0;i<=9;i++) if(c[i]!= 'g') if(c[i]!= 'g') if(c[i]!= 'g') if(c[i]!= 'g') continue; continue; continue; continue; else else else else counter++; counter++; counter++; counter++; printf("Charater g appears %d printf("Charater g appears %d printf("Charater g appears %d printf("Charater g appears %d times.\n",counter); times.\n",counter); times.\n",counter); times.\n",counter); } } } } 166166二二二二. . . .字符串字符串字符串字符串 C C C C语言不支持字符串变量,而是通过字符数组对字符串进行语言不支持字符串变量,而是通过字符数组对字符串进行语言不支持字符串变量,而是通过字符数组对字符串进行语言不支持字符串变量,而是通过字符数组对字符串进行存储和处理。

      字符数组的一个元素对应于字符串中的一个字符,存储和处理字符数组的一个元素对应于字符串中的一个字符,存储和处理字符数组的一个元素对应于字符串中的一个字符,存储和处理字符数组的一个元素对应于字符串中的一个字符,最后用转义字符最后用转义字符最后用转义字符最后用转义字符“\0” (ASC“\0” (ASC“\0” (ASC“\0” (ASC码表中的码表中的码表中的码表中的NULLNULLNULLNULL字符字符字符字符) ) ) ) 作为字符串作为字符串作为字符串作为字符串的结束符因此,的结束符因此,的结束符因此,的结束符因此, n n n n个字符的字符串,须占用个字符的字符串,须占用个字符的字符串,须占用个字符的字符串,须占用n+1n+1n+1n+1个字节的内个字节的内个字节的内个字节的内存空间可以用字符串对字符数组初始化,其格式为:可以用字符串对字符数组初始化,其格式为:char char 字符数组名字符数组名[ [元素个数元素个数]= "]= "字符串字符串";";或:或: char char 字符数组名字符数组名[]= "[]= "字符串字符串";"; 例如,语句:例如,语句:char str2[]=“program ”; char str2[]=“program ”; 定义了字定义了字符数组符数组str2[], str2[], 并用字符串并用字符串"program ""program "对其初始化。

      对其初始化 167167 假定数组假定数组假定数组假定数组str2[]str2[]str2[]str2[]从地址为从地址为从地址为从地址为2000H2000H2000H2000H的内存单元开始存的内存单元开始存的内存单元开始存的内存单元开始存放,放,放,放,str2[]str2[]str2[]str2[]在内存中的存储情况如下图所示:在内存中的存储情况如下图所示:在内存中的存储情况如下图所示:在内存中的存储情况如下图所示: 2000H 'p' 2000H 'p' 2000H 'p' 2000H 'p' 2001H 'r' 2001H 'r' 2001H 'r' 2001H 'r' 2002H 'o' 2002H 'o' 2002H 'o' 2002H 'o' 2003H 'g' 2003H 'g' 2003H 'g' 2003H 'g' 2004H 'r' 2004H 'r' 2004H 'r' 2004H 'r' 2005H 'a' 2005H 'a' 2005H 'a' 2005H 'a' 2006H 'm' 2006H 'm' 2006H 'm' 2006H 'm' 2007H '\0' 2007H '\0' 2007H '\0' 2007H '\0' 168168 【例【例【例【例5-55-55-55-5】】】】 使用使用使用使用scanf()scanf()scanf()scanf()函数和函数和函数和函数和printf()printf()printf()printf()函数输入并函数输入并函数输入并函数输入并 输出字符串。

      输出字符串输出字符串输出字符串 main( ) main( ) main( ) main( ) { { { { char str[ ]= "what is your name ? "; char str[ ]= "what is your name ? "; char str[ ]= "what is your name ? "; char str[ ]= "what is your name ? "; char name[20]; char name[20]; char name[20]; char name[20]; printf(" printf(" printf(" printf("%%%%s\n",str) ;s\n",str) ;s\n",str) ;s\n",str) ; scanf(" scanf(" scanf(" scanf("%%%%s",name) ;s",name) ;s",name) ;s",name) ; printf("\n My name is %s.\n", printf("\n My name is %s.\n", printf("\n My name is %s.\n", printf("\n My name is %s.\n", name) ; name) ; name) ; name) ; } } } } 输出对象以字符输出对象以字符输出对象以字符输出对象以字符数组名数组名数组名数组名strstr表示表示表示表示不可将不可将不可将不可将namename写写写写成成成成&name&name 169169 【例【例5-65-6】】 编程实现字符串复制编程实现字符串复制, , 同时将小写字母变换成同时将小写字母变换成 大写字母。

      大写字母分析:分析:由于在程序中不能将一个字符串赋值给另一个字符数由于在程序中不能将一个字符串赋值给另一个字符数 组,所以采用逐个字符赋值的办法实现字符串复制组,所以采用逐个字符赋值的办法实现字符串复制注意:字符串结束符注意:字符串结束符“\0” “\0” 也是字符串的组成部分也是字符串的组成部分 main( ) main( ) { { char a[20],b[20]; char a[20],b[20]; int i=0; int i=0; printf("Please enter a string: \n"); printf("Please enter a string: \n"); scanf("%s",a); scanf("%s",a); do do b[i] b[i]==(a[i]>(a[i]>=='a'&& a[i]<'a'&& a[i]<=='z')?'z')? a[i]-32:a[i]; a[i]-32:a[i]; while(a[i++]!='\0'); while(a[i++]!='\0'); printf("Copyed string:%s\n",b); printf("Copyed string:%s\n",b); } } 170170三三. .常用的字符串处理函数常用的字符串处理函数 为了方便对字符串的处理,为了方便对字符串的处理,C C语言提供了若干字语言提供了若干字符串处理函数。

      符串处理函数在使用这些函数时,应在程序的开在使用这些函数时,应在程序的开始使用预处理命令:始使用预处理命令: “#include” “#include” 或或 “#include”“#include”1 1.字符串输入函数.字符串输入函数gets()gets() gets() gets()函数的作用是:从键盘上输入一个字符串,并把它函数的作用是:从键盘上输入一个字符串,并把它 存放在参数所指示的字符数组中,输入的字符串以存放在参数所指示的字符数组中,输入的字符串以< <回车回车> >作作 为结束 函数函数gets() gets() 的调用格式:的调用格式: gets( gets(字符数组名字符数组名) ) 如果函数调用成功,将返回字符数组的首地址,否则,返如果函数调用成功,将返回字符数组的首地址,否则,返 回空值回空值NULLNULL 171171 2 2.字符串输出函数.字符串输出函数puts()puts() 函数函数puts()puts()的作用是:将参数中提供的字符串输出到显示的作用是:将参数中提供的字符串输出到显示 屏。

      屏 函数函数puts() puts() 的调用格式:的调用格式: puts( puts(字符数组名或字符串常量字符数组名或字符串常量) ) 如如果果函函数数调调用用成成功功,,将将返返回回字字符符串串结结束束符符“\0”“\0”,,否否则则,,返返 回一个非回一个非0 0值   说明:说明: 在使用在使用gets()gets()、、puts()puts()函数之前,应当使用预处理命令函数之前,应当使用预处理命令 #include #include 3 3.求字符串长度函数.求字符串长度函数strlen()strlen() 函数函数strlen()strlen()的作用是:统计由参数提供的字符串所包的作用是:统计由参数提供的字符串所包 含的字符个数含的字符个数 ( (字符串末尾的字符串末尾的“\0” “\0” 不计在内不计在内) ) 函数函数strlen() strlen() 的调用格式:的调用格式: strlen( strlen(字符数组名字符数组名) ) 如果函数调用成功,将返回字符个数。

      如果函数调用成功,将返回字符个数 172172 4 4 4 4.字符串连接函数.字符串连接函数.字符串连接函数.字符串连接函数strcat()strcat()strcat()strcat() 函函函函数数数数strcat()strcat()strcat()strcat()的的的的作作作作用用用用是是是是::::用用用用于于于于连连连连接接接接二二二二个个个个由由由由参参参参数数数数提提提提供供供供的的的的字字字字符符符符串串串串, , , , 将将将将第第第第二二二二个个个个参参参参数数数数提提提提供供供供的的的的字字字字符符符符串串串串连连连连接接接接在在在在第第第第一一一一个个个个参参参参数数数数提提提提供供供供的的的的字字字字符符符符串串串串之之之之后后后后,,,,成成成成为为为为一一一一个个个个新新新新的的的的字字字字符符符符串 函数函数函数函数strcat() strcat() strcat() strcat() 的调用格式:的调用格式:的调用格式:的调用格式: strcat( strcat( strcat( strcat(字符数组字符数组字符数组字符数组1 1 1 1,字符数组,字符数组,字符数组,字符数组2)2)2)2) 如果函数调用成功,将返回字符数组如果函数调用成功,将返回字符数组如果函数调用成功,将返回字符数组如果函数调用成功,将返回字符数组1 1 1 1。

      说明:说明:说明:说明: (1) (1) (1) (1)字符数组字符数组字符数组字符数组1 1 1 1要定义得足够大以便能容纳连接后的新字要定义得足够大以便能容纳连接后的新字要定义得足够大以便能容纳连接后的新字要定义得足够大以便能容纳连接后的新字 符串 (2) (2) (2) (2)字符数组字符数组字符数组字符数组2 2 2 2既可以是字符数组名,也可以是字符串常既可以是字符数组名,也可以是字符串常既可以是字符数组名,也可以是字符串常既可以是字符数组名,也可以是字符串常 量 例如:例如:例如:例如: char c[30]= "China"; char c[30]= "China"; char c[30]= "China"; char c[30]= "China"; puts(strcat(c, " is a great country.")); puts(strcat(c, " is a great country.")); puts(strcat(c, " is a great country.")); puts(strcat(c, " is a great country.")); 1731735 5 5 5.字符串拷贝函数.字符串拷贝函数.字符串拷贝函数.字符串拷贝函数strcpy( )strcpy( )strcpy( )strcpy( ) 函函函函数数数数strcpy()strcpy()strcpy()strcpy()的的的的作作作作用用用用是是是是::::用用用用于于于于拷拷拷拷贝贝贝贝由由由由参参参参数数数数提提提提供供供供的的的的字字字字符符符符串串串串, , , , 将将将将第第第第二二二二个个个个参参参参数数数数提提提提供供供供的的的的字字字字符符符符串串串串拷拷拷拷贝贝贝贝到到到到由由由由第第第第一一一一个个个个参参参参数数数数提提提提供供供供的的的的字字字字符符符符数数数数组组组组中中中中。

      该该该该数数数数组组组组中中中中原原原原有有有有的的的的字字字字符符符符串串串串将被覆盖将被覆盖将被覆盖将被覆盖 函数函数函数函数strcpy( ) strcpy( ) strcpy( ) strcpy( ) 的调用格式:的调用格式:的调用格式:的调用格式: strcpy( strcpy( strcpy( strcpy(字符数组字符数组字符数组字符数组1 1 1 1,字符数组,字符数组,字符数组,字符数组2)2)2)2) 如果函数调用成功,将返回字符数组如果函数调用成功,将返回字符数组如果函数调用成功,将返回字符数组如果函数调用成功,将返回字符数组1 1 1 1说明:说明:说明:说明: 字符数组字符数组字符数组字符数组2 2 2 2既可以是字符数组名,也可以是字符串常量既可以是字符数组名,也可以是字符串常量既可以是字符数组名,也可以是字符串常量既可以是字符数组名,也可以是字符串常量。

      6. 6. 字符串比较函数字符串比较函数strcmp()strcmp() 函数函数strcmp()strcmp()的作用是:用于比较二个由参数提供的字符串的作用是:用于比较二个由参数提供的字符串 的大小 比较二个字符串的大小,就是依次比较二个字符串中字符的比较二个字符串的大小,就是依次比较二个字符串中字符的 ASC ASC代码值,若二个字符串中各对应位置上的字符都相同,则代码值,若二个字符串中各对应位置上的字符都相同,则 认为这二个字符串相等若第一个字符串中某个位置上字符认为这二个字符串相等若第一个字符串中某个位置上字符 的的ASCASC代码值大于第二个字符串中对应位置上字符的代码值大于第二个字符串中对应位置上字符的ASCASC代码代码 值,而在此之前二个字符串中对应位置上的字符都相同,则值,而在此之前二个字符串中对应位置上的字符都相同,则 认为第一个字符串大于第二个字符串反之,则认为第二个认为第一个字符串大于第二个字符串反之,则认为第二个 字符串大于第一个字符串字符串大于第一个字符串 174174 函数函数strcmp( ) strcmp( ) 的调用格式:的调用格式: strcmp( strcmp(字符数组字符数组1 1,字符数组,字符数组2)2) 如果函数调用成功,返回值如下:如果函数调用成功,返回值如下: 为为 0 0,当字符数组,当字符数组1 1等于字符数组等于字符数组2 2 返回值:返回值: 为为 1 1,当字符数组,当字符数组1 1大于字符数组大于字符数组2 2 为为 –1, –1, 当字符数组当字符数组1 1小于字符数组小于字符数组2 2 例如,比较字符串例如,比较字符串“English”“English”和和“England”“England”,按上述规则,,按上述规则, strcmp(“English”,“England”) strcmp(“English”,“England”) 的返回值为的返回值为1 1,, 而而strcmp("England"strcmp("England",,"English") "English") 的返回值为的返回值为-1-1。

      说明:说明: 字符数组字符数组1 1、字符数组、字符数组2 2既可以是字符数组名,也可以是字符既可以是字符数组名,也可以是字符串常量 175175【例【例5-75-7】】 预先设定以字符串预先设定以字符串“123456”“123456”为密码,再从键盘输为密码,再从键盘输入入 一个字符串,若和密码相符,显示:一个字符串,若和密码相符,显示:Welcome!Welcome!,否,否 则显示:则显示:Sorry!Sorry!#include#include#include#includemain()main() { { char pw[]="123456",c[10]; char pw[]="123456",c[10]; printf("Please input your password:\n"); printf("Please input your password:\n"); gets(c); gets(c); if(strcmp(pw,c) if(strcmp(pw,c)==0)0) printf("Welcome!\n"); printf("Welcome!\n"); else else printf("Sorry!\n"); printf("Sorry!\n"); } }  必须使用必须使用strcmp()函数函数 1761767. 7. 7. 7. 将字符串中大写字母转换成小写字母函数将字符串中大写字母转换成小写字母函数将字符串中大写字母转换成小写字母函数将字符串中大写字母转换成小写字母函数strlwr( )strlwr( )strlwr( )strlwr( ) 函数函数函数函数strlwr()strlwr()strlwr()strlwr()的作用是:将由参数提供的字符串中所的作用是:将由参数提供的字符串中所的作用是:将由参数提供的字符串中所的作用是:将由参数提供的字符串中所 有的大写字母转换成小写字母。

      有的大写字母转换成小写字母有的大写字母转换成小写字母有的大写字母转换成小写字母 函数函数函数函数strlwr( ) strlwr( ) strlwr( ) strlwr( ) 的调用格式:的调用格式:的调用格式:的调用格式: strlwr( strlwr( strlwr( strlwr(字符数组名字符数组名字符数组名字符数组名或字符串常量或字符串常量或字符串常量或字符串常量) ) ) ) 8. 8. 8. 8. 将字符串中小写字母转换成大写字母函数将字符串中小写字母转换成大写字母函数将字符串中小写字母转换成大写字母函数将字符串中小写字母转换成大写字母函数strupr( )strupr( )strupr( )strupr( ) 函函函函数数数数strupr()strupr()strupr()strupr()的的的的作作作作用用用用是是是是::::将将将将由由由由参参参参数数数数提提提提供供供供的的的的字字字字符符符符串串串串中中中中所所所所有有有有的的的的小小小小写写写写字字字字母母母母转换成大写字母。

      转换成大写字母转换成大写字母转换成大写字母 函数函数函数函数strupr( ) strupr( ) strupr( ) strupr( ) 的调用格式:的调用格式:的调用格式:的调用格式: strupr( strupr( strupr( strupr(字符数组名字符数组名字符数组名字符数组名或字符串常量或字符串常量或字符串常量或字符串常量) ) ) ) 1771775.3 5.3 二维数组二维数组一一. .二维数组的定义和初始化二维数组的定义和初始化成绩表:成绩表: 语文语文 数学数学 外语外语 75 88 72 75 88 72 68 91 92 68 91 92 87 96 98 87 96 98 78 82 90 78 82 90 75 88 72 75 88 72 第第0 0行行 68 91 92 68 91 92 第第1 1行行 87 96 98 87 96 98 第第2 2行行 78 82 90 78 82 90 第第3 3行行 第第0 0列列 第第1 1列列 第第2 2列列二维矩阵:二维矩阵:(二维数组二维数组) 178178 定义二维数组的格式:定义二维数组的格式:定义二维数组的格式:定义二维数组的格式: 类型说明符类型说明符类型说明符类型说明符 数组名数组名数组名数组名 [ [ [ [行数行数行数行数][][][][列数列数列数列数] ] ] ] ;;;; 例如,语句:例如,语句:例如,语句:例如,语句: int score[4][3]; int score[4][3]; int score[4][3]; int score[4][3];定义了四行三列的二维数组定义了四行三列的二维数组定义了四行三列的二维数组定义了四行三列的二维数组( ( ( (矩阵矩阵矩阵矩阵)score[][])score[][])score[][])score[][]。

      可以在定义二维数组时同时对其初始化可以在定义二维数组时同时对其初始化可以在定义二维数组时同时对其初始化可以在定义二维数组时同时对其初始化 下面的语句在定义二维数组下面的语句在定义二维数组下面的语句在定义二维数组下面的语句在定义二维数组( ( ( (矩阵矩阵矩阵矩阵)score[][])score[][])score[][])score[][]的同时对其初始化:的同时对其初始化:的同时对其初始化:的同时对其初始化: int score[4][3]= int score[4][3]= int score[4][3]= int score[4][3]= {75,88,72,68,91,92,87,96,98,78,82,90}; {75,88,72,68,91,92,87,96,98,78,82,90}; {75,88,72,68,91,92,87,96,98,78,82,90}; {75,88,72,68,91,92,87,96,98,78,82,90}; 矩阵中的元素由其所在的行与列唯一确定,矩阵中的元素由其所在的行与列唯一确定,矩阵中的元素由其所在的行与列唯一确定,矩阵中的元素由其所在的行与列唯一确定,score[i][j]score[i][j]score[i][j]score[i][j]表示矩阵中第表示矩阵中第表示矩阵中第表示矩阵中第i i i i行,行,行,行,第第第第j j j j列的元素列的元素列的元素列的元素, , , ,于是:于是:于是:于是: score[0][0]=75, score[2][1]=96, score[3][2]=90, score[0][0]=75, score[2][1]=96, score[3][2]=90, score[0][0]=75, score[2][1]=96, score[3][2]=90, score[0][0]=75, score[2][1]=96, score[3][2]=90, score[2][2]=98 score[2][2]=98 score[2][2]=98 score[2][2]=98,,,,……………………。

      179179 设设设设数数数数组组组组score[][]score[][]score[][]score[][]在在在在内内内内存存存存中中中中的的的的起起起起始始始始地地地地址址址址为为为为2000H, 2000H, 2000H, 2000H, 则则则则其其其其在在在在内内内内存存存存中中中中的的的的存存存存储储储储情情情情况况况况如如如如下图所示:下图所示:下图所示:下图所示: 2000H 75 200CH 87 2000H 75 200CH 87 2000H 75 200CH 87 2000H 75 200CH 87 2002H 88 2002H 88 2002H 88 2002H 88 第第第第0 0 0 0行的行的行的行的 200EH 96 200EH 96 200EH 96 200EH 96 第第第第2 2 2 2行的行的行的行的 2004H 72 2004H 72 2004H 72 2004H 72 各元素各元素各元素各元素 2010H 98 2010H 98 2010H 98 2010H 98 各元素各元素各元素各元素 2006H 68 2012H 78 2006H 68 2012H 78 2006H 68 2012H 78 2006H 68 2012H 78 2008H 91 2008H 91 2008H 91 2008H 91 第第第第1 1 1 1行的行的行的行的 2014H 82 2014H 82 2014H 82 2014H 82 第第第第3 3 3 3行的行的行的行的 200AH 92 200AH 92 200AH 92 200AH 92 各元素各元素各元素各元素 2016H 90 2016H 90 2016H 90 2016H 90 各元素各元素各元素各元素结论:结论: 二维数组在内存中按行的次序排列,在各行中,又按列元素二维数组在内存中按行的次序排列,在各行中,又按列元素的次序分配存储单元。

      所以,在进行初始化时,向二维数组的的次序分配存储单元所以,在进行初始化时,向二维数组的各个元素赋初值的数据排列顺序一定要和数组各元素在内存中各个元素赋初值的数据排列顺序一定要和数组各元素在内存中的存储顺序完全一致的存储顺序完全一致 二维数组的行、列下标都从二维数组的行、列下标都从0 0开始 180180二维数组初始化的另一种格式:二维数组初始化的另一种格式:二维数组初始化的另一种格式:二维数组初始化的另一种格式: 将对应于数组每一行的数据用一对花括号将对应于数组每一行的数据用一对花括号将对应于数组每一行的数据用一对花括号将对应于数组每一行的数据用一对花括号{}{}{}{}括起来 例如:例如:例如:例如:int x[2][3]={{1int x[2][3]={{1int x[2][3]={{1int x[2][3]={{1,,,,2 2 2 2,,,,3}3}3}3},,,,{4{4{4{4,,,,5 5 5 5,,,,6}}6}}6}}6}};;;; 其其其其 中中中中 第第第第 一一一一 组组组组 数数数数 据据据据 {1{1{1{1,,,, 2 2 2 2,,,, 3}3}3}3}对对对对 应应应应 于于于于 第第第第 0 0 0 0行行行行 的的的的 三三三三 个个个个 元元元元 素素素素 x[0][0], x[0][0], x[0][0], x[0][0], x[0][1],x[0][2]x[0][1],x[0][2]x[0][1],x[0][2]x[0][1],x[0][2]。

      第第第第二二二二组组组组数数数数据据据据{4{4{4{4,,,,5 5 5 5,,,,6}6}6}6}对对对对应应应应于于于于第第第第1 1 1 1行行行行的的的的三三三三个个个个元元元元素素素素 x[1][0], x[1][1], x[1][2]x[1][0], x[1][1], x[1][2]x[1][0], x[1][1], x[1][2]x[1][0], x[1][1], x[1][2] 使使使使用用用用这这这这种种种种花花花花括括括括号号号号嵌嵌嵌嵌套套套套的的的的方方方方法法法法,,,,可可可可以以以以像像像像一一一一维维维维数数数数组组组组初初初初始始始始化化化化那那那那样样样样,,,,对对对对于于于于赋赋赋赋0 0 0 0值值值值的的的的元素,在其对应的初值数据位置上缺省该数据例如:元素,在其对应的初值数据位置上缺省该数据例如:元素,在其对应的初值数据位置上缺省该数据例如:元素,在其对应的初值数据位置上缺省该数据例如: int x[2][3] int x[2][3] int x[2][3] int x[2][3]===={{3},{,,4}}{{3},{,,4}}{{3},{,,4}}{{3},{,,4}};;;; 等价于:等价于:等价于:等价于: int x[2][3]={{3,0,0},{0,0,4}} int x[2][3]={{3,0,0},{0,0,4}} int x[2][3]={{3,0,0},{0,0,4}} int x[2][3]={{3,0,0},{0,0,4}};;;;第二个花括号中的二个逗号不可省略,第二个花括号中的二个逗号不可省略,因为它们表示还有二个元素。

      因为它们表示还有二个元素 181181 再如:再如:再如:再如: int x[2][3]={{1,2},{}} int x[2][3]={{1,2},{}} int x[2][3]={{1,2},{}} int x[2][3]={{1,2},{}};;;; 等价于:等价于:等价于:等价于: int x[2][3]={{1,2,0},{0,0,0}} int x[2][3]={{1,2,0},{0,0,0}} int x[2][3]={{1,2,0},{0,0,0}} int x[2][3]={{1,2,0},{0,0,0}};;;; 在在在在定定定定义义义义二二二二维维维维数数数数组组组组并并并并进进进进行行行行初初初初始始始始化化化化时时时时,,,,允允允允许许许许省省省省略略略略其其其其行行行行数数数数但但但但要要要要注注注注意意意意,,,,二二二二维维维维数数数数组组组组的的的的列数在定义时不可省略。

      例如:列数在定义时不可省略例如:列数在定义时不可省略例如:列数在定义时不可省略例如:int a[][3]={{75,88,72},{68,91,92},{87,96,98},int a[][3]={{75,88,72},{68,91,92},{87,96,98},int a[][3]={{75,88,72},{68,91,92},{87,96,98},int a[][3]={{75,88,72},{68,91,92},{87,96,98}, {78,82,90}}; {78,82,90}}; {78,82,90}}; {78,82,90}}; 等价于:等价于:等价于:等价于:int a[4][3]={{75,88,72},{68,91,92},{87,96,98},int a[4][3]={{75,88,72},{68,91,92},{87,96,98},int a[4][3]={{75,88,72},{68,91,92},{87,96,98},int a[4][3]={{75,88,72},{68,91,92},{87,96,98}, {78,82,90}}; {78,82,90}}; {78,82,90}}; {78,82,90}}; 再如:再如:再如:再如: float b[][3]={{1.21},{2.0,-5.5},{4.32,-5.8,-9.60}}; float b[][3]={{1.21},{2.0,-5.5},{4.32,-5.8,-9.60}}; float b[][3]={{1.21},{2.0,-5.5},{4.32,-5.8,-9.60}}; float b[][3]={{1.21},{2.0,-5.5},{4.32,-5.8,-9.60}}; 等价于:等价于:等价于:等价于:float b[3][3]={{1.21,0.0,0.0},{2.0,-5.5,0.0},float b[3][3]={{1.21,0.0,0.0},{2.0,-5.5,0.0},float b[3][3]={{1.21,0.0,0.0},{2.0,-5.5,0.0},float b[3][3]={{1.21,0.0,0.0},{2.0,-5.5,0.0}, {4.32,-5.8,-9.60}}; {4.32,-5.8,-9.60}}; {4.32,-5.8,-9.60}}; {4.32,-5.8,-9.60}}; 第二个花括号不可省略,第二个花括号不可省略,因为在这里它们表示该因为在这里它们表示该行元素全部为行元素全部为0 0 182182二二二二. . . .二维数组元素的引用及应用举例二维数组元素的引用及应用举例二维数组元素的引用及应用举例二维数组元素的引用及应用举例在程序中,通过数组名和下标引用数组元素。

      在程序中,通过数组名和下标引用数组元素在程序中,通过数组名和下标引用数组元素在程序中,通过数组名和下标引用数组元素 其格式为:其格式为:其格式为:其格式为: 数组名数组名数组名数组名[ [ [ [行下标行下标行下标行下标][ ][ ][ ][ 列下标列下标列下标列下标] ] ] ] 二维数组元素的行、列下标从二维数组元素的行、列下标从二维数组元素的行、列下标从二维数组元素的行、列下标从0 0 0 0开始例【例【例【例5-85-85-85-8】从键盘输入整型的二行三列的矩阵,将其转置后】从键盘输入整型的二行三列的矩阵,将其转置后】从键盘输入整型的二行三列的矩阵,将其转置后】从键盘输入整型的二行三列的矩阵,将其转置后 输出 main( )main( )main( )main( ) { { { { int a[2][3],b[3][2],i,j; int a[2][3],b[3][2],i,j; int a[2][3],b[3][2],i,j; int a[2][3],b[3][2],i,j; for(i=0;i<2;i++) for(i=0;i<2;i++) for(i=0;i<2;i++) for(i=0;i<2;i++) for(j=0;j<3;j++) for(j=0;j<3;j++) for(j=0;j<3;j++) for(j=0;j<3;j++) scanf(" %d ",&a[i][j]); scanf(" %d ",&a[i][j]); scanf(" %d ",&a[i][j]); scanf(" %d ",&a[i][j]); for(i=0;i<2;i++) for(i=0;i<2;i++) for(i=0;i<2;i++) for(i=0;i<2;i++) { { { { for(j=0;j<3;j++) for(j=0;j<3;j++) for(j=0;j<3;j++) for(j=0;j<3;j++) printf(" %d ",a[i][j]); printf(" %d ",a[i][j]); printf(" %d ",a[i][j]); printf(" %d ",a[i][j]); printf("\n"); printf("\n"); printf("\n"); printf("\n"); } } } } for(j=0;j<3;j++)for(j=0;j<3;j++) for(i=0;i<2;i++) for(i=0;i<2;i++) b[j][i]=a[i][j]; b[j][i]=a[i][j];for(j=0;j<3;j++)for(j=0;j<3;j++) { { for(i=0;i<2;i++) for(i=0;i<2;i++) printf (" %d ", printf (" %d ", b[j][i]); b[j][i]); printf (" \n"); printf (" \n"); } } } } 矩阵转置矩阵转置矩阵转置矩阵转置 183183【例【例5-95-9】】 设有一个四行三列的整型矩阵,从键盘上输入矩阵设有一个四行三列的整型矩阵,从键盘上输入矩阵 元素的值,计算并输出每行元素的平均值。

      元素的值,计算并输出每行元素的平均值 main( ) main( ) { { int a[4][3], i,j; int a[4][3], i,j; float ave,b[4]; float ave,b[4]; for(i=0;i<4;i++) for(i=0;i<4;i++) for(j for(j==0;j<3;j++) 0;j<3;j++) scanf("%d",&a[i][j]); scanf("%d",&a[i][j]); for(i for(i==0;i<4;i++) 0;i<4;i++) { { ave=0.0; ave=0.0; for(j for(j==0;j<3;j++) 0;j<3;j++) ave+ ave+==a[i][j];a[i][j]; b[i] b[i]==ave/3; ave/3; } } for(i for(i==0;i<4;i++) 0;i<4;i++) printf("b[%d] printf("b[%d]==%f\n",i,b[ i ]);%f\n",i,b[ i ]); } } 184184【例【例5-105-10】】 编程找出四行三列的整型矩阵中元素的最小值,编程找出四行三列的整型矩阵中元素的最小值, 并指出其所在的行与列。

      并指出其所在的行与列分分析析: :首首先先,,默默认认位位于于第第0 0行行、、第第0 0列列的的元元素素是是当当前前的的最最小小值值,,然然后后,,依依次次用用矩矩阵阵中中元元素素的的值值与与当当前前的的最最小小值值比比较较,,若若比比当当前前的的最最小小值值更更小小,,令令其其成成为为当当前前的的最最小小值值,,并并记记下下其其所所在在的的行行号号与与列列号号这这样样,,到到最最后后,,当当前前的的最最小小值值也也就就是是整整个个矩矩阵阵中中元元素素的的最小值,同时也记下了其所在的行号与列号最小值,同时也记下了其所在的行号与列号 main( )main( ) { { int row=0,column=0,min, int row=0,column=0,min, i,j; i,j; int a[4][3]={{-8,3,67}, int a[4][3]={{-8,3,67}, {12,-31,5},{0,64,-100}, {12,-31,5},{0,64,-100}, {98,0,16}}; {98,0,16}}; min=a[0][0]; min=a[0][0]; for(i=0;i<4;i++) for(i=0;i<4;i++) for(j for(j==0;j<3;j++)0;j<3;j++) if(a[i][j]

      在功能上,由主函数调用其它函数,其它函块化结构在功能上,由主函数调用其它函数,其它函数也可以互相调用数也可以互相调用main( ) main( ) 函数函数A(A(形式参数表形式参数表) ) 函数函数B(B(形式参数表形式参数表) ){ { {{ { { …… ; …… ; …… ; …… ; …… ; …… ; 调用函数调用函数A; A; 调用函数调用函数B; …… ;B; …… ; …… ; …… ; } …… ; …… ; } } } } } 返回主调函数返回主调函数A( )A( ) 返回主调函数返回主调函数main( ) main( ) 说明:说明: (1) (1) 一个源程序文件由一个或多个函数组成。

      一个源程序文件由一个或多个函数组成C C语言以源文语言以源文 件为单位进行编译,而不是以函数为单位进行编译件为单位进行编译,而不是以函数为单位进行编译 190190 (2) C (2) C程序的执行从程序的执行从main()main()函数开始,如果在函数开始,如果在main()main()函数中调函数中调 用了其它函数用了其它函数, , 在调用结束后在调用结束后, ,流程最后必须回到主调函流程最后必须回到主调函 数,在数,在main()main()函数中结束整个程序的运行函数中结束整个程序的运行 (3) (3) 所有的函数都是平行的,函数之间只有调用关系,所有的函数都是平行的,函数之间只有调用关系,——个个 函数并不从属于另一函数函数并不从属于另一函数      二二. .函数的分类函数的分类1.1.库函数和用户自定义的函数库函数和用户自定义的函数( (从使用的角度分类从使用的角度分类) ) 库函数也叫标准函数,这是由系统提供的,用户库函数也叫标准函数,这是由系统提供的,用户 可直接调用的函数。

      可直接调用的函数 例如:例如:printf( )printf( )、、scanf( )scanf( )、、sqrt( )sqrt( )、、pow( )pow( ) 、、strcmp( )strcmp( )都是都是C C语言的标准函数语言的标准函数 用户自定义的函数就是用户根据需要,自行设计用户自定义的函数就是用户根据需要,自行设计 的函数 1911912.2.无参函数和有参函数无参函数和有参函数( (从函数的形式分类从函数的形式分类) ) 函函数数的的参参数数,,就就是是被被调调用用的的函函数数运运行行时时,,由由主主调调函函数数提提供供的的数数据据如如果果被被调调用用的的函函数数运运行行时时,,不不需需要要由由主主调调函函数数提提供供数数据据,,则则称称之之为为无无参参函函数数,,否否则则就称为有参函数就称为有参函数 【例【例6-16-1】】 无参函数的例子无参函数的例子void output()void output() { { char c[10]; char c[10]; printf("Please Input printf("Please Input A Word: "); A Word: "); scanf("%s",c); scanf("%s",c); printf("%s\n", printf("%s\n", strupr(c)); strupr(c)); } } main()main() { { int i; int i; for(i=0;i<3;i++) for(i=0;i<3;i++) output(); output(); printf("THE END\n"); printf("THE END\n"); } } 192192【例【例【例【例6-26-26-26-2】】】】 有参函数的例子。

      有参函数的例子有参函数的例子有参函数的例子int max(int x,int y)int max(int x,int y)int max(int x,int y)int max(int x,int y) { { { { return(x>y? x:y); return(x>y? x:y); return(x>y? x:y); return(x>y? x:y); } } } }main()main()main()main() { { { { int a,b,c; int a,b,c; int a,b,c; int a,b,c; printf("Please Input two integers:\n"); printf("Please Input two integers:\n"); printf("Please Input two integers:\n"); printf("Please Input two integers:\n"); scanf("%d,%d",&a,&b); scanf("%d,%d",&a,&b); scanf("%d,%d",&a,&b); scanf("%d,%d",&a,&b); printf("Max is %d", max(a,b); printf("Max is %d", max(a,b); printf("Max is %d", max(a,b); printf("Max is %d", max(a,b); } } } }    193193 6.2 6.2 6.2 6.2 函数的定义函数的定义函数的定义函数的定义调用函数必须遵循调用函数必须遵循调用函数必须遵循调用函数必须遵循““““定义在先、使用在后定义在先、使用在后定义在先、使用在后定义在先、使用在后””””的原则。

      的原则函数定义的格式:函数定义的格式:函数定义的格式:函数定义的格式:类型说明符类型说明符类型说明符类型说明符 函数名函数名函数名函数名( ( ( (类型说明符类型说明符类型说明符类型说明符 形参变量形参变量形参变量形参变量1 1 1 1,类型说明符,类型说明符,类型说明符,类型说明符 形参变量形参变量形参变量形参变量2 2 2 2,,,,…)…)…)…) { { { { 语句部分语句部分语句部分语句部分 } } } }函数首部函数首部 函数体函数体 形参表形参表 函数名由用户确定,但必须遵循与定义变量名相同的规则函数名由用户确定,但必须遵循与定义变量名相同的规则。

      函数名前面的类型说明符用以指出函数调用后,返回结果的函数名前面的类型说明符用以指出函数调用后,返回结果的数据类型,称之为函数类型,在缺省的情况下,默认的函数数据类型,称之为函数类型,在缺省的情况下,默认的函数类型为类型为 int int 型 194194 6.3 6.3 函数参数和函数的值函数参数和函数的值一一. .形式参数和实际参数形式参数和实际参数形式参数和实际参数具有的特点和关系:形式参数和实际参数具有的特点和关系:(1)(1)在在定定义义函函数数时时指指定定的的形形参参变变量量,,只只有有在在函函数数被被调调用用时时才才被被分分配配内内存存单单元元在在调调用用结结束束后后,,形形参参所所占占的的内内存存单单元元也也随随即即被释放  该语句是无法执行的,在结束对该语句是无法执行的,在结束对max()max()的调用后,形参变量所占用的调用后,形参变量所占用的存储单元已被释放,在这里,变的存储单元已被释放,在这里,变量名量名 x x 和和 y y 是无意义的是无意义的 例如例如: : int max(int x int max(int x,,int y)int y) { { return(x>y? x:y); return(x>y? x:y); } } main() main() { { int a,b,c; int a,b,c; printf("Please Input two integers:\n"); printf("Please Input two integers:\n"); scanf("%d,%d",&a,&b); scanf("%d,%d",&a,&b); printf("Max is %d", max(a,b); printf("Max is %d", max(a,b); printf("x= %d, y=%d", x,y); printf("x= %d, y=%d", x,y); } } 195195(2) (2) 形参只能是变量,而实参必须是具有确定值的表达式。

      形参只能是变量,而实参必须是具有确定值的表达式 main()main(){ {int a,b,c;int a,b,c;scanf("%d,%d",&a,&b); scanf("%d,%d",&a,&b); c=max(10,a+b); c=max(10,a+b); printf("MAX=%d",max(a-b,a*b)); printf("MAX=%d",max(a-b,a*b)); } } 实参为常量实参为常量1010和和表达式表达式a+ba+b实参为表达式实参为表达式a-ba-b和和a+ba+b执行该语句后,变执行该语句后,变量量a a、、b b均已有了确均已有了确定的值定的值例如例如: : int max(int x int max(int x,,int y)int y) { { return(x>y? x:y); return(x>y? x:y); } } 196196(3) (3) (3) (3) 调用函数时实参与形参的个数、类型和先后顺序应调用函数时实参与形参的个数、类型和先后顺序应调用函数时实参与形参的个数、类型和先后顺序应调用函数时实参与形参的个数、类型和先后顺序应 当保持一致。

      当保持一致当保持一致当保持一致例【例【例【例6-36-36-36-3】实参与形参的个数、类型和先后顺序对函数调用的影】实参与形参的个数、类型和先后顺序对函数调用的影】实参与形参的个数、类型和先后顺序对函数调用的影】实参与形参的个数、类型和先后顺序对函数调用的影 响int add(char x,int y)int add(char x,int y)int add(char x,int y)int add(char x,int y) { { { { int z; int z; int z; int z; return(x+y); return(x+y); return(x+y); return(x+y); } } } } main()main()main()main() { { { { char a; char a; char a; char a; int i; int i; int i; int i; printf("Please Input An Integer Number and a printf("Please Input An Integer Number and a printf("Please Input An Integer Number and a printf("Please Input An Integer Number and a character"); character"); character"); character"); scanf("%d,%c",&I,&a); scanf("%d,%c",&I,&a); scanf("%d,%c",&I,&a); scanf("%d,%c",&I,&a); printf("The first result is %d\n",add(a,i)); printf("The first result is %d\n",add(a,i)); printf("The first result is %d\n",add(a,i)); printf("The first result is %d\n",add(a,i)); printf("The second result is %d\n",add(i,a)); printf("The second result is %d\n",add(i,a)); printf("The second result is %d\n",add(i,a)); printf("The second result is %d\n",add(i,a)); } } } }正确的调用正确的调用  错错误误的的调调用用 197197这个这个returnreturn语句永语句永远也不会被执行远也不会被执行 二二. . 函数的返回值函数的返回值 函数的返回值就是通过函数调用函数的返回值就是通过函数调用, , 主调函数从被调用函数主调函数从被调用函数 中的中的 return return 语句获得的一个确定的值。

      语句获得的一个确定的值 return return语句的格式语句的格式::return(return(表达式表达式) );; 或或 return return 表达式;表达式; returnreturn语句中表达式的值就是被返回的值语句中表达式的值就是被返回的值注意:注意: (1) (1) 一个函数中可以包含一个以上的一个函数中可以包含一个以上的returnreturn语句,但一旦执语句,但一旦执 行了其中任何一个行了其中任何一个returnreturn语句,就结束该函数的调用所以,语句,就结束该函数的调用所以, 每次调用函数以后,只能通过每次调用函数以后,只能通过returnreturn语句返回一个值语句返回一个值 例如:例如: int f(int x,int y) int f(int x,int y) { { return(x+y); return(x+y); return(x*y); return(x*y); } } 198198 (2) (2) (2) (2) 如果不需要从被调用函数带回函数值,可以不要如果不需要从被调用函数带回函数值,可以不要如果不需要从被调用函数带回函数值,可以不要如果不需要从被调用函数带回函数值,可以不要 return return return return 语句。

      对于此类函数应当将其定义为语句对于此类函数应当将其定义为语句对于此类函数应当将其定义为语句对于此类函数应当将其定义为void”void”void”void” ( ( ( (空值类型空值类型空值类型空值类型) ) ) ) (3) (3) (3) (3) 在函数定义中,函数类型应该和在函数定义中,函数类型应该和在函数定义中,函数类型应该和在函数定义中,函数类型应该和returnreturnreturnreturn语句中表达语句中表达语句中表达语句中表达 式的类型一致如果它们的类型不式的类型一致如果它们的类型不式的类型一致如果它们的类型不式的类型一致如果它们的类型不————致,则以函数致,则以函数致,则以函数致,则以函数 类型为准,由函数类型决定返回值的类型类型为准,由函数类型决定返回值的类型类型为准,由函数类型决定返回值的类型类型为准,由函数类型决定返回值的类型 199199 6.4 6.4 6.4 6.4 函数的调用函数的调用函数的调用函数的调用 一 一 一 一. . . .函数调用的一般形式函数调用的一般形式函数调用的一般形式函数调用的一般形式程序中通过函数名调用函数,格式为:程序中通过函数名调用函数,格式为:程序中通过函数名调用函数,格式为:程序中通过函数名调用函数,格式为: 函数名函数名函数名函数名( ( ( (实参表列实参表列实参表列实参表列) ) ) ) 如果是调用无参函数,则实参表列可以没有,但括弧不能省如果是调用无参函数,则实参表列可以没有,但括弧不能省如果是调用无参函数,则实参表列可以没有,但括弧不能省如果是调用无参函数,则实参表列可以没有,但括弧不能省略。

      实参表列各参数间用逗号隔开实参与形参的个数、类型略实参表列各参数间用逗号隔开实参与形参的个数、类型略实参表列各参数间用逗号隔开实参与形参的个数、类型略实参表列各参数间用逗号隔开实参与形参的个数、类型与顺序应保持一致,以保证实参与形参之间能正确地实现参数与顺序应保持一致,以保证实参与形参之间能正确地实现参数与顺序应保持一致,以保证实参与形参之间能正确地实现参数与顺序应保持一致,以保证实参与形参之间能正确地实现参数传递例【例6-46-4】】 输入半径,输出相应的圆面积和相应的球的体积输入半径,输出相应的圆面积和相应的球的体积float f (float r1)float f (float r1) { { return(3.1415926*r1*r1); return(3.1415926*r1*r1); } }main()main() { { float r; float r; printf("Please input printf("Please input radius\n"); radius\n"); scanf("%f",&r); scanf("%f",&r); printf("Area=%f\n", f(r)); printf("Area=%f\n", f(r)); printf("Volume=%f\n", printf("Volume=%f\n", f(r)*4.0/3*r); f(r)*4.0/3*r); } } 200200【例【例【例【例6 6 6 6 -5-5-5-5】】】】 编程输出由编程输出由编程输出由编程输出由“*”“*”“*”“*”组成的三角形。

      组成的三角形组成的三角形组成的三角形 * * *************************************************************************************************本例在程序结构上显得更为清晰,这就是模块化结构的特点本例在程序结构上显得更为清晰,这就是模块化结构的特点本例在程序结构上显得更为清晰,这就是模块化结构的特点本例在程序结构上显得更为清晰,这就是模块化结构的特点void pr(int n)void pr(int n)void pr(int n)void pr(int n) { { { { int j; int j; int j; int j; for(j=0;j

      为为此此,,C C语语言通过函数声明语句解决这个问题言通过函数声明语句解决这个问题函数声明语句的格式:函数声明语句的格式:类型说明符类型说明符 函数名函数名( (类型说明符类型说明符 形参变量形参变量1 1,类型说明,类型说明 符符 形参变量形参变量2 2,,…)…);;从从形形式式上上看看,,函函数数声声明明就就是是在在函函数数定定义义格格式式的的基基础础上上去去掉掉了了函函数数体体通通常常,,将将函函数数声声明明安安排排在在源源文文件件的的开开始始部部分分函函数数声声明明中的形参变量名可以省略中的形参变量名可以省略例如:例如: 函数声明函数声明 int f(int x,iny y,float z); int f(int x,iny y,float z); 与与 int f(int,int,float); int f(int,int,float); 是等价的是等价的 函数声明是语句,函数声明是语句,这里的;不能少这里的;不能少 202202【例【例【例【例6-5-16-5-16-5-16-5-1】】】】编程输出由编程输出由编程输出由编程输出由“*”“*”“*”“*”组成的三角形。

      组成的三角形组成的三角形组成的三角形void pr(); /* void pr(); /* void pr(); /* void pr(); /* 函数声明语句,函数声明语句,函数声明语句,函数声明语句, */ */ */ */main()main()main()main() { { { { int i; int i; int i; int i; for(i=1;i<=5;i++) for(i=1;i<=5;i++) for(i=1;i<=5;i++) for(i=1;i<=5;i++) pr(2*i-1); pr(2*i-1); pr(2*i-1); pr(2*i-1); } } } }void pr(int n)void pr(int n)void pr(int n)void pr(int n) { { { { int j; int j; int j; int j; for(j=0;j

      法通过调用函数来改变实参变量的值法通过调用函数来改变实参变量的值法通过调用函数来改变实参变量的值   形参变量的值形参变量的值被交换了被交换了 【例【例6-66-6】】 试分析下面的程序,从键盘依次输入二个不同的整试分析下面的程序,从键盘依次输入二个不同的整 数,判断其输出数,判断其输出void swap(int,int);void swap(int,int);main()main() { { int a,b; int a,b; printf("Please Input printf("Please Input Two Integers : "); Two Integers : "); scanf("%d,%d",&a,&b); scanf("%d,%d",&a,&b); swap(a,b); swap(a,b); printf("a=%d, printf("a=%d, b=%d\n",a,b); b=%d\n",a,b); } }void swap(int x,int y)void swap(int x,int y) { { int t; int t; t=x; t=x; x=y; x=y; y=t; y=t; printf("x=%d, y=%d printf("x=%d, y=%d \n",x,y); \n",x,y); } }实参变量还是实参变量还是原来的值原来的值  2042042. 2. 2. 2. 地址传递地址传递地址传递地址传递 在在在在数数数数组组组组参参参参与与与与函函函函数数数数调调调调用用用用的的的的情情情情况况况况下下下下,,,,采采采采用用用用的的的的不不不不是是是是单单单单个个个个变变变变量量量量的的的的值值值值传传传传递递递递的的的的方方方方法法法法。

      由由由由于于于于数数数数组组组组名名名名代代代代表表表表了了了了数数数数组组组组存存存存储储储储的的的的起起起起始始始始地地地地址址址址,,,,所所所所以以以以,,,,在在在在函函函函数数数数调调调调用用用用时时时时,,,,实实实实参参参参把把把把数数数数组组组组存存存存储储储储的的的的起起起起始始始始地地地地址址址址传传传传递递递递给给给给形形形形参参参参,,,,使使使使其其其其指指指指向向向向同同同同样样样样的的的的存存存存储储储储区区区区域域域域,,,,这这这这就就就就是是是是地地地地址址址址传传传传递递递递在在在在执执执执行行行行函函函函数数数数的的的的过过过过程程程程中中中中,,,,凡凡凡凡是是是是对对对对形形形形参参参参数数数数组组组组元元元元素素素素的的的的加加加加工工工工处处处处理理理理实实实实际际际际上上上上就就就就是是是是对对对对实实实实参参参参数数数数组组组组元元元元素素素素的的的的加加加加工工工工处处处处理理理理这是地址传递和值传递的本质区别这是地址传递和值传递的本质区别这是地址传递和值传递的本质区别这是地址传递和值传递的本质区别 205205【例【例【例【例6-76-76-76-7】】】】 设计一个函数用以计算一维数组中所有元素值的总和。

      设计一个函数用以计算一维数组中所有元素值的总和设计一个函数用以计算一维数组中所有元素值的总和设计一个函数用以计算一维数组中所有元素值的总和 #define N 5#define N 5#define N 5#define N 5 sum(int arr[],int); sum(int arr[],int); sum(int arr[],int); sum(int arr[],int); main() main() main() main() { { { { int a[N],i; int a[N],i; int a[N],i; int a[N],i; printf("Please input %d integers:\n",N); printf("Please input %d integers:\n",N); printf("Please input %d integers:\n",N); printf("Please input %d integers:\n",N); for(i=0;i

      另一个函数另一个函数另一个函数例【例【例【例6-86-86-86-8】】】】 编程求三个整数中的最大数编程求三个整数中的最大数编程求三个整数中的最大数编程求三个整数中的最大数 max3(int,int,int);max3(int,int,int);max3(int,int,int);max3(int,int,int);max2(int,int);max2(int,int);max2(int,int);max2(int,int);main()main()main()main() { { { { int a,b,c; int a,b,c; int a,b,c; int a,b,c; printf("Please Input printf("Please Input printf("Please Input printf("Please Input Three Integers: "); Three Integers: "); Three Integers: "); Three Integers: "); scanf("%d,%d,%d",&a,&b,&c); scanf("%d,%d,%d",&a,&b,&c); scanf("%d,%d,%d",&a,&b,&c); scanf("%d,%d,%d",&a,&b,&c); printf("MAX=%d\n", printf("MAX=%d\n", printf("MAX=%d\n", printf("MAX=%d\n", max3(a,b,c)); max3(a,b,c)); max3(a,b,c)); max3(a,b,c)); } } } }max3(int x1,int y1,int max3(int x1,int y1,int max3(int x1,int y1,int max3(int x1,int y1,int z1)z1)z1)z1) { { { { int max; int max; int max; int max; max=max2(x1,y1); max=max2(x1,y1); max=max2(x1,y1); max=max2(x1,y1); max=max2(max,z1); max=max2(max,z1); max=max2(max,z1); max=max2(max,z1); return(max); return(max); return(max); return(max); } } } }max2(int x2,int y2)max2(int x2,int y2)max2(int x2,int y2)max2(int x2,int y2) { { { { return (x2>y2? x2:y2); return (x2>y2? x2:y2); return (x2>y2? x2:y2); return (x2>y2? x2:y2); } } } } 207207 6.5 6.5 局部变量和全局变量局部变量和全局变量一一. .局部变量局部变量 根据变量的有效范围将其分为局部变量和全局变量,称根据变量的有效范围将其分为局部变量和全局变量,称变量的有效范围为变量的作用域。

      变量的有效范围为变量的作用域 在一个函数或复合语句内部定义的变量称为局部变量,在一个函数或复合语句内部定义的变量称为局部变量,它只在本函数或复合语句范围内有效,只有在本函数或复它只在本函数或复合语句范围内有效,只有在本函数或复合语句内部才能使用它们合语句内部才能使用它们复复合合语语句句这里定义的这里定义的i i在在主函数内部有效主函数内部有效 【例【例6-96-9】说明局部变量概念的例子之一说明局部变量概念的例子之一main()main() { { int i=5,sum1=0,sum2=0; int i=5,sum1=0,sum2=0; { { int i=0; int i=0; for(;i<=10;i++) for(;i<=10;i++) sum1=sum1+i; sum1=sum1+i; } } for(;i<=10;i++)for(;i<=10;i++) sum2=sum2+i; sum2=sum2+i; printf("SUM1=%d\n ", printf("SUM1=%d\n ", sum1); sum1); printf("SUM2=%d\n ", printf("SUM2=%d\n ", sum2); sum2);} }这里定义的这里定义的i i在复合在复合语句内部有效语句内部有效 主函数中定义的整型变量主函数中定义的整型变量i让位于复合语句内部定义的让位于复合语句内部定义的整型变量整型变量i。

      , 208208【例【例【例【例6-8-16-8-16-8-16-8-1】】】】 编程求三个整数中的最大数编程求三个整数中的最大数编程求三个整数中的最大数编程求三个整数中的最大数 max3(int,int,int);max3(int,int,int);max3(int,int,int);max3(int,int,int);max2(int,int);max2(int,int);max2(int,int);max2(int,int);main()main()main()main() { { { { int a,b,c; int a,b,c; int a,b,c; int a,b,c; printf("Please Input printf("Please Input printf("Please Input printf("Please Input Three Integers: "); Three Integers: "); Three Integers: "); Three Integers: "); scanf("%d,%d,%d",&a,&b,&c); scanf("%d,%d,%d",&a,&b,&c); scanf("%d,%d,%d",&a,&b,&c); scanf("%d,%d,%d",&a,&b,&c); printf("MAX=%d\n", printf("MAX=%d\n", printf("MAX=%d\n", printf("MAX=%d\n", max3(a,b,c)); max3(a,b,c)); max3(a,b,c)); max3(a,b,c)); } } } }max3(int x,int y,int z)max3(int x,int y,int z)max3(int x,int y,int z)max3(int x,int y,int z) { { { { int max; int max; int max; int max; max=max2(x,y); max=max2(x,y); max=max2(x,y); max=max2(x,y); max=max2(max,z1); max=max2(max,z1); max=max2(max,z1); max=max2(max,z1); return(max); return(max); return(max); return(max); } } } }max2(int x,int y)max2(int x,int y)max2(int x,int y)max2(int x,int y) { { { { return (x>y? x:y); return (x>y? x:y); return (x>y? x:y); return (x>y? x:y); } } } } 函数函数max2( )max2( )和函数和函数max3( )max3( )具有相同的形参变量名具有相同的形参变量名x,yx,y。

      但由于它们均为局部变量,只在定义它们的函数内部有效,但由于它们均为局部变量,只在定义它们的函数内部有效,所以实际上,它们代表的是不同的变量所以实际上,它们代表的是不同的变量 209209 二二二二. . . .全局变量全局变量全局变量全局变量 在函数之外定义的变量称为全局变量全局变量可以为源文件中其它在函数之外定义的变量称为全局变量全局变量可以为源文件中其它在函数之外定义的变量称为全局变量全局变量可以为源文件中其它在函数之外定义的变量称为全局变量全局变量可以为源文件中其它函数所共用,它的有效范围从定义变量的位置开始到源文件结束函数所共用,它的有效范围从定义变量的位置开始到源文件结束函数所共用,它的有效范围从定义变量的位置开始到源文件结束函数所共用,它的有效范围从定义变量的位置开始到源文件结束 例例例例 :三个函数:三个函数:三个函数:三个函数int pint pint pint p====1,q=51,q=51,q=51,q=5;;;; float fl(int a)float fl(int a)float fl(int a)float fl(int a) { { { { int b,c int b,c int b,c int b,c;;;; …… ; …… ; …… ; …… ; } } } }char c1char c1,,c2c2;;char f2 (int xchar f2 (int x,,int y) int y) { { int i,j; int i,j; …… ; …… ;} }main() main() { {int m,nint m,n;; …… ; …… ; } } p,qp,qp,qp,q为全局变量,函数为全局变量,函数为全局变量,函数为全局变量,函数f1()f1()f1()f1()、、、、f2f2f2f2()()()()、、、、main()main()main()main()都可以使用都可以使用都可以使用都可以使用局部变量局部变量局部变量局部变量a,b,ca,b,ca,b,ca,b,c只在只在只在只在f1f1f1f1()()()()函数内部有效函数内部有效函数内部有效函数内部有效c1,c2c1,c2是全局变量,是全局变量,函数函数函数函数f2f2f2f2()()()()、、、、main()main()main()main()都可以使用都可以使用都可以使用都可以使用局部变量局部变量局部变量局部变量x,y,i,jx,y,i,j只在只在只在只在f2f2f2f2()()()()函数内部有效函数内部有效函数内部有效函数内部有效局部变量局部变量局部变量局部变量m,nm,nm,nm,n只在只在只在只在main()main()main()main()函函函函数内部有效数内部有效数内部有效数内部有效 210210【例【例【例【例6-116-116-116-11】】】】 使用全局变量以后的例使用全局变量以后的例使用全局变量以后的例使用全局变量以后的例6-66-66-66-6的程序。

      的程序 int a,b;int a,b;int a,b;int a,b;void swap(int,int);void swap(int,int);void swap(int,int);void swap(int,int);main()main()main()main() { { { { printf("Please Input Two printf("Please Input Two printf("Please Input Two printf("Please Input Two Integers : "); Integers : "); Integers : "); Integers : "); scanf("%d,%d",&a,&b); scanf("%d,%d",&a,&b); scanf("%d,%d",&a,&b); scanf("%d,%d",&a,&b); swap(a,b); swap(a,b); swap(a,b); swap(a,b); printf("a=%d, b=%d\n", printf("a=%d, b=%d\n", printf("a=%d, b=%d\n", printf("a=%d, b=%d\n", a,b); a,b); a,b); a,b); } } } }void swap(int x,int y)void swap(int x,int y)void swap(int x,int y)void swap(int x,int y) { { { { int t; int t; int t; int t; t=x; t=x; t=x; t=x; x=y; x=y; x=y; x=y; y=t; y=t; y=t; y=t; printf("x=%d, y=%d\n", printf("x=%d, y=%d\n", printf("x=%d, y=%d\n", printf("x=%d, y=%d\n", x,y); x,y); x,y); x,y); a=x; a=x; a=x; a=x; b=y; b=y; b=y; b=y; } } } }全局变量全局变量全局变量全局变量a,ba,ba,ba,b在在在在sawpsawpsawpsawp()()()()函数和主函数内部函数和主函数内部函数和主函数内部函数和主函数内部都有效都有效都有效都有效 211211【例【例6-126-12】设计函数,用以找出三个整数中的最大、最小】设计函数,用以找出三个整数中的最大、最小 数。

      数 int max,min;int max,min; void f(int x,int y,int z) void f(int x,int y,int z) { { if(x>y) if(x>y) { { max=x; max=x; min=y; min=y; } } else else { { max=y; max=y; min=x; min=x; } } if(z>max) if(z>max) max=z; max=z; else else if(z

      元 (2). (2). (2). (2).多人合作完成的程序通常由多个源文件组成多人合作完成的程序通常由多个源文件组成多人合作完成的程序通常由多个源文件组成多人合作完成的程序通常由多个源文件组成 一旦出现全局变量同名的情况,将引起程序出错一旦出现全局变量同名的情况,将引起程序出错一旦出现全局变量同名的情况,将引起程序出错一旦出现全局变量同名的情况,将引起程序出错 (3). (3). (3). (3).使用全局变量过多,会降低程序的清晰度,使使用全局变量过多,会降低程序的清晰度,使使用全局变量过多,会降低程序的清晰度,使使用全局变量过多,会降低程序的清晰度,使 人难以判断某一时刻各个全局变量的值,因为各个人难以判断某一时刻各个全局变量的值,因为各个人难以判断某一时刻各个全局变量的值,因为各个人难以判断某一时刻各个全局变量的值,因为各个 函数在执行时都可以改变全局变量的值函数在执行时都可以改变全局变量的值函数在执行时都可以改变全局变量的值函数在执行时都可以改变全局变量的值 213213 根据变量所占存储单元的时间来划分,可以将其分为静态根据变量所占存储单元的时间来划分,可以将其分为静态根据变量所占存储单元的时间来划分,可以将其分为静态根据变量所占存储单元的时间来划分,可以将其分为静态存储变量和动态存储变量。

      存储变量和动态存储变量存储变量和动态存储变量存储变量和动态存储变量 静态存储变量在程序运行过程中一直占有固定的存储单元,静态存储变量在程序运行过程中一直占有固定的存储单元,静态存储变量在程序运行过程中一直占有固定的存储单元,静态存储变量在程序运行过程中一直占有固定的存储单元,直到程序运行结束直到程序运行结束直到程序运行结束直到程序运行结束 动态存储变量是在程序运行过程中由系统动态地分配和回动态存储变量是在程序运行过程中由系统动态地分配和回动态存储变量是在程序运行过程中由系统动态地分配和回动态存储变量是在程序运行过程中由系统动态地分配和回收的 因此,全局变量是静态存储的变量,在程序运行过程中,因此,全局变量是静态存储的变量,在程序运行过程中,它们的存储单元地址是不变的而局部变量,它们是动态存储它们的存储单元地址是不变的而局部变量,它们是动态存储的变量只有在调用函数时,系统才为其分配存储单元,一旦的变量只有在调用函数时,系统才为其分配存储单元,一旦调用结束,该存储单元即由系统收回当再次调用函数时,系调用结束,该存储单元即由系统收回。

      当再次调用函数时,系统将重新为它们分配存储单元,二次分配的存储单元可能是不统将重新为它们分配存储单元,二次分配的存储单元可能是不同的6.6 6.6 动态存储变量与静态存储变量动态存储变量与静态存储变量 214214C C语语言言提提供供四四种种存存储储类类型型说说明明符符,,用用于于在在定定义义变变量量时时指指定定不不同同的变量存储方式,与类型说明符配合使用的变量存储方式,与类型说明符配合使用存储类型说明符:存储类型说明符: autoauto、、staticstatic、、register register 、、externextern它们分别对应自动变量、静态变量、寄存器变量和外部变量它们分别对应自动变量、静态变量、寄存器变量和外部变量存储类型说明符使用格式:存储类型说明符使用格式: 存储类型说明符存储类型说明符 类型说明符类型说明符 变量名变量名1, 1, 变量名变量名2,……2,……;;1. auto1. auto变量变量 用存储类型说明符用存储类型说明符autoauto修饰的局部变量称为为自动变量,修饰的局部变量称为为自动变量,自动变量是动态存储的变量。

      自动变量是动态存储的变量C C语言规定,在定义局部变量时,语言规定,在定义局部变量时,如果缺省存储类型说明符,则默认其为如果缺省存储类型说明符,则默认其为autoauto变量 由于全局变量是静态存储的变量,所以由于全局变量是静态存储的变量,所以在定义全局变量时,在定义全局变量时,不能使用存储类型说明符不能使用存储类型说明符autoauto 215215 2. 2. 2. 2. 用用用用staticstaticstaticstatic将局部变量定义为静态存储的变量将局部变量定义为静态存储的变量将局部变量定义为静态存储的变量将局部变量定义为静态存储的变量 虽然局部变量是动态存储的变量,但可以用存储类型说明虽然局部变量是动态存储的变量,但可以用存储类型说明虽然局部变量是动态存储的变量,但可以用存储类型说明虽然局部变量是动态存储的变量,但可以用存储类型说明符符符符staticstaticstaticstatic将其定义为静态存储的变量这样,一旦系统为其分将其定义为静态存储的变量这样,一旦系统为其分将其定义为静态存储的变量这样,一旦系统为其分将其定义为静态存储的变量。

      这样,一旦系统为其分配了存储单元,就一直由该变量占有该存储单元,直到程序运配了存储单元,就一直由该变量占有该存储单元,直到程序运配了存储单元,就一直由该变量占有该存储单元,直到程序运配了存储单元,就一直由该变量占有该存储单元,直到程序运行结束才将其收回行结束才将其收回行结束才将其收回行结束才将其收回 【例【例【例【例6-136-136-136-13】】】】 通过将局部变量定义为静态存储变量的方法计算通过将局部变量定义为静态存储变量的方法计算通过将局部变量定义为静态存储变量的方法计算通过将局部变量定义为静态存储变量的方法计算 1!, 2!,…. n! 1!, 2!,…. n! 1!, 2!,…. n! 1!, 2!,…. n! long fac(int k)long fac(int k)long fac(int k)long fac(int k) { { { { static long f=1; static long f=1; static long f=1; static long f=1; f=f*k; f=f*k; f=f*k; f=f*k; return f; return f; return f; return f; } } } }main()main()main()main() { { { { int i,n; int i,n; int i,n; int i,n; printf("Please input an printf("Please input an printf("Please input an printf("Please input an integer:\n"); integer:\n"); integer:\n"); integer:\n"); scanf("%d",&n); scanf("%d",&n); scanf("%d",&n); scanf("%d",&n); for(i=1;i<=n;i++) for(i=1;i<=n;i++) for(i=1;i<=n;i++) for(i=1;i<=n;i++) printf("%d!=%ld\n",i, printf("%d!=%ld\n",i, printf("%d!=%ld\n",i, printf("%d!=%ld\n",i, fac(i)); fac(i)); fac(i)); fac(i)); } } } }调用结束时,保留静态调用结束时,保留静态存储变量存储变量f f的当前值作为的当前值作为下次调用时的初始值下次调用时的初始值 第第i i次调用函数次调用函数fac()fac(),,得到的是得到的是i!i!的值的值 2162163. register3. register3. register3. register变量变量变量变量 为为为为了了了了减减减减少少少少访访访访问问问问内内内内存存存存变变变变量量量量所所所所需需需需的的的的时时时时间间间间,,,, C C C C语语语语言言言言允允允允许许许许将将将将局局局局部部部部变变变变量量量量的的的的值值值值放放放放在在在在CPUCPUCPUCPU的的的的寄寄寄寄存存存存器器器器中中中中。

      registerregisterregisterregister变变变变量量量量是是是是动动动动态态态态存存存存储储储储的的的的变变变变量 实际上,现在的优化编译系统能自动识别使用频繁的变量,实际上,现在的优化编译系统能自动识别使用频繁的变量,实际上,现在的优化编译系统能自动识别使用频繁的变量,实际上,现在的优化编译系统能自动识别使用频繁的变量,并将其存放在寄存器中,不必再由编程人员定义并将其存放在寄存器中,不必再由编程人员定义并将其存放在寄存器中,不必再由编程人员定义并将其存放在寄存器中,不必再由编程人员定义registerregisterregisterregister变变变变量 217217【例【例【例【例6-146-146-146-14】存储类型说明符】存储类型说明符】存储类型说明符】存储类型说明符externexternexternextern应用举例应用举例应用举例应用举例 int max(int x,int y) int max(int x,int y) int max(int x,int y) int max(int x,int y) { { { { int z; int z; int z; int z; z=(x>y)?x:y; z=(x>y)?x:y; z=(x>y)?x:y; z=(x>y)?x:y; return z; return z; return z; return z; } } } } main() main() main() main() { { { { extern a,b;extern a,b;extern a,b;extern a,b; printf(“%d\n”,max(a,b)); printf(“%d\n”,max(a,b)); printf(“%d\n”,max(a,b)); printf(“%d\n”,max(a,b)); } } } } int a=13,b=14; int a=13,b=14; int a=13,b=14; int a=13,b=14; 4. 4. 4. 4. 用用用用externexternexternextern声明全局变量声明全局变量声明全局变量声明全局变量 在在C C程序中,可以通过存储类型说明符程序中,可以通过存储类型说明符externextern扩大全局变扩大全局变 量的作用域。

      量的作用域 extern声明全局变量声明全局变量a、、b,从而使它,从而使它们的作用域扩大为从本行直至最后的们的作用域扩大为从本行直至最后的所有语句,否则,程序将出错所有语句,否则,程序将出错  218218存储类型说明符存储类型说明符存储类型说明符存储类型说明符externexternexternextern在多个源文件组成的程序中的应用在多个源文件组成的程序中的应用在多个源文件组成的程序中的应用在多个源文件组成的程序中的应用 源文件源文件1 1 源文件源文件2 2 int a,b,c; extern int a; int a,b,c; extern int a; main() int b,c; main() int b,c; { f(int a,int x) { f(int a,int x) …; { …; { } ……; } ……; } } 在源文件在源文件1 1中定义了全局变量中定义了全局变量a a、、b b、、c c,其作用域为整个源文,其作用域为整个源文件件1 1。

      源文件源文件2 2一开始就用一开始就用externextern声明变量声明变量a,a,表明其中的变量表明其中的变量a a与与源文件源文件1 1中的变量中的变量a a是同一个变量而源文件是同一个变量而源文件2 2中的全局变量中的全局变量b,cb,c未用未用externextern声明,它们的作用域为整个源文件声明,它们的作用域为整个源文件2 2,和源文件,和源文件1 1中中的变量的变量b,cb,c是不同的变量是不同的变量 如果不希望在其它的源文件中使用源文件如果不希望在其它的源文件中使用源文件1 1的全局变量的全局变量a, a, 可可以用以用static int a; static int a; 定义全局变量定义全局变量a a,在其前面冠以,在其前面冠以staticstatic,这,这样,只有源文件样,只有源文件1 1可以使用全局变量可以使用全局变量a a 219219 6.7 6.7 内部函数和外部函数内部函数和外部函数一一. .内部函数内部函数如如果果一一个个函函数数只只能能被被本本源源文文件件中中的的其其它它函函数数所所调调用用,,则则称称为为内部函数内部函数定义内部函数的格式:定义内部函数的格式: static static 类型标识符类型标识符 函数名函数名( (形参表形参表) ) 例如:例如: static int f (int a, int b); static int f (int a, int b);使使用用内内部部函函数数,,可可以以使使函函数数只只局局限限于于所所在在源源文文件件,,允允许许在在不不同的源文件中使用同名的内部函数。

      同的源文件中使用同名的内部函数二二. .外部函数外部函数 如果一个函数可以为其它源文件调用,则称为外部函数如果一个函数可以为其它源文件调用,则称为外部函数 定义外部函数的格式:定义外部函数的格式: extern extern 类型标识符类型标识符 函数名函数名( (形参表形参表) ;) ; 如果在定义函数时省略如果在定义函数时省略externextern,则默认为外部函数前面各,则默认为外部函数前面各例所定义的函数都是外部函数例所定义的函数都是外部函数 220220 第第6 6章章 结束结束 第第 7 7 章章编译预处理命令编译预处理命令 2021/8/22221 222222学习目标学习目标1.1.熟练掌握宏定义和宏替换的一般方法熟练掌握宏定义和宏替换的一般方法;;2.2.熟练文件包含的处理方法;熟练文件包含的处理方法;3.3.3. 3. 了解条件编译的作用和实现方法了解条件编译的作用和实现方法 223223主要内容主要内容–宏宏–文件包含处理文件包含处理–条件编译条件编译 2242247.1 #define7.1 #define命令命令 一一. . 编译预处理命令的作用编译预处理命令的作用 编译预处理命令通过指令告诉编译系统,在对源程序进行编译预处理命令通过指令告诉编译系统,在对源程序进行编译之前应该做些什么。

      所以,编译预处理命令通常位于源编译之前应该做些什么所以,编译预处理命令通常位于源程序的开始位置程序的开始位置 编译预处理命令以编译预处理命令以“#”“#”符号打头,每个命令占用一个单符号打头,每个命令占用一个单独的书写行,命令尾不使用分号作为结束符独的书写行,命令尾不使用分号作为结束符 宏定义预处理命令宏定义预处理命令#define#define的作用是把一个标识符的作用是把一个标识符( (宏名宏名) )定义为一个字符串定义为一个字符串define#define预处理命令的格式:预处理命令的格式: #define #define 标识符标识符 字符串字符串 在编译预处理时,编译系统把源程序中出现的该标识符,在编译预处理时,编译系统把源程序中出现的该标识符,均以定义的字符串替换均以定义的字符串替换, , 将将替换过程称为宏替换将将替换过程称为宏替换C C程序中程序中通常以大写字母定义宏名标识符通常以大写字母定义宏名标识符 二二. .宏定义预处理命令宏定义预处理命令#define#define 225225 例如例如例如例如, , , ,有如下的宏定义预处理命令:有如下的宏定义预处理命令:有如下的宏定义预处理命令:有如下的宏定义预处理命令: #define E_MS "Standard error On input #define E_MS "Standard error On input #define E_MS "Standard error On input #define E_MS "Standard error On input\\\\n " n " n " n " 而程序中有语句:而程序中有语句:而程序中有语句:而程序中有语句: printf(E_MS) printf(E_MS) printf(E_MS) printf(E_MS);;;; 则编译预处理时,凡遇到标识符则编译预处理时,凡遇到标识符则编译预处理时,凡遇到标识符则编译预处理时,凡遇到标识符E_MSE_MSE_MSE_MS时,就用字符串时,就用字符串时,就用字符串时,就用字符串 “Standard error on input “Standard error on input “Standard error on input “Standard error on input\\\\n” n” n” n” 替换。

      替换 因此,语句因此,语句因此,语句因此,语句printf((E_MS )printf((E_MS )printf((E_MS )printf((E_MS );经编译预处理后成为:;经编译预处理后成为:;经编译预处理后成为:;经编译预处理后成为: printf("Standard error on input printf("Standard error on input printf("Standard error on input printf("Standard error on input\\\\n")n")n")n");;;; 这是一个显示这是一个显示这是一个显示这是一个显示“Standard error on input”“Standard error on input”“Standard error on input”“Standard error on input”的的的的C C C C程序语句程序语句程序语句程序语句注意:注意: #define#define预处理命令格式中的字符串不需要用预处理命令格式中的字符串不需要用“"”“"”作为作为分分 隔符,例中宏定义预处理命令中的隔符,例中宏定义预处理命令中的“"”“"”是字符串的一部是字符串的一部分。

      分 226226 #define#define#define#define预预预预处处处处理理理理命命命命令令令令允允允允许许许许宏宏宏宏名名名名可可可可以以以以带带带带形形形形式式式式参参参参数数数数,,,,称称称称之之之之为为为为带带带带参参参参数的宏 带参数的宏的格式:带参数的宏的格式:带参数的宏的格式:带参数的宏的格式: #define #define #define #define 标识符标识符标识符标识符( ( ( (形参表形参表形参表形参表) ) ) ) 字符串字符串字符串字符串 编编编编译译译译预预预预处处处处理理理理时时时时,,,,遇遇遇遇到到到到带带带带参参参参数数数数的的的的宏宏宏宏名名名名时时时时,,,,与与与与之之之之相相相相联联联联的的的的形形形形参参参参由由由由程程程程序序序序中中中中的的的的实实实实参参参参替替替替换换换换,,,,但但但但是是是是,,,,C C C C程程程程序序序序中中中中用用用用双双双双引引引引号号号号括括括括起起起起的的的的字字字字符符符符串串串串中中中中的宏名将不被替换。

      的宏名将不被替换的宏名将不被替换的宏名将不被替换 【例【例7-17-1】宏名替换示例宏名替换示例define MIN(a,b) (a

      S(3,4) 3*4S(3,4) 3*4 3 3替换替换a, 4a, 4替换替换b b S(x+y,z) x+y*zS(x+y,z) x+y*z x+y x+y替换替换a,za,z替换替换b b  S((x+y),z) (x+y)*zS((x+y),z) (x+y)*z (x+y) (x+y) 替换替换a,za,z替换替换b b注意:注意: 虽然带参数宏的使用形式与函数相似,但是它们在本质虽然带参数宏的使用形式与函数相似,但是它们在本质上却是完全不同的,使用带参数的宏只是进行简单的字符替上却是完全不同的,使用带参数的宏只是进行简单的字符替换,没有函数调用中复杂的参数传递过程换,没有函数调用中复杂的参数传递过程。

      228228 7.2 #include 7.2 #include命令命令 文件包含预处理命令文件包含预处理命令文件包含预处理命令文件包含预处理命令#include#include#include#include的作用是使一个源文件可以的作用是使一个源文件可以的作用是使一个源文件可以的作用是使一个源文件可以将另外一个源文件的全部内容包含进来将另外一个源文件的全部内容包含进来将另外一个源文件的全部内容包含进来将另外一个源文件的全部内容包含进来源文件源文件1: 1: 源文件源文件2: 2: 最终的源文件:最终的源文件: file1.c file1.cfile1.c file1.c#include file2.c f2()#include file2.c f2()main( ) { {main( ) { {{ ……; { ……; ……;……; …; } } …; } } } main( ) } main( )f1() {f1() {{ { ……;……; ……; } ……; } } f1( ) } f1( ) { { ……;……; } }包含包含预处理预处理执行执行#include#include预处理命令后,把预处理命令后,把file2.cfile2.c插入插入file1.cfile1.c的的#include#include命令的位置处,使命令的位置处,使file2.cfile2.c成为源程序成为源程序file1.cfile1.c的一部分。

      的一部分 229229#include#include#include#include预处理命令的两种格式:预处理命令的两种格式:预处理命令的两种格式:预处理命令的两种格式: 格式格式格式格式1 1 1 1:::: #include <#include <#include <#include <包含文件名包含文件名包含文件名包含文件名> > > > ( ( ( (标准方式标准方式标准方式标准方式) ) ) ) 格式格式格式格式2 2 2 2:::: #include " #include " #include " #include "包含文件名包含文件名包含文件名包含文件名" " " " 其中,包含文件名是指存放在磁盘上的待包含的源文件名其中,包含文件名是指存放在磁盘上的待包含的源文件名其中,包含文件名是指存放在磁盘上的待包含的源文件名其中,包含文件名是指存放在磁盘上的待包含的源文件名 使使使使用用用用格格格格式式式式1 1 1 1时时时时,,,,C C C C编编编编译译译译系系系系统统统统到到到到存存存存放放放放C C C C语语语语言言言言库库库库函函函函数数数数头头头头文文文文件件件件所所所所在在在在的的的的目目目目录中搜索包含文件。

      录中搜索包含文件录中搜索包含文件录中搜索包含文件 使使使使用用用用格格格格式式式式2 2 2 2时时时时,,,,将将将将按按按按指指指指定定定定的的的的路路路路径径径径搜搜搜搜索索索索未未未未指指指指定定定定路路路路径径径径时时时时,,,,则则则则在在在在当当当当前目录中搜索,若找不到,再按标准方式查找前目录中搜索,若找不到,再按标准方式查找前目录中搜索,若找不到,再按标准方式查找前目录中搜索,若找不到,再按标准方式查找 230230 7.3 7.3 条件编译命令条件编译命令条件编译命令的条件编译命令的条件编译命令的条件编译命令的作用是实现对源程序代码有选择地进行编译作用是实现对源程序代码有选择地进行编译 条件编译命令的格式条件编译命令的格式1 1:: #ifdef #ifdef 符号常量符号常量 程序段程序段1 1#else#else 程序段程序段2 2 #endif #endif 编译预处理时,如果编译预处理时,如果#ifdef#ifdef后面的符号常量已经被定义,则后面的符号常量已经被定义,则编译程序段编译程序段1 1,否则编译程序段,否则编译程序段2 2。

      其中其中, , 可以没有程序段可以没有程序段2 2的的部分,相当于程序段部分,相当于程序段2 2为空语句为空语句 231231 【例【例【例【例7-37-37-37-3】】】】 条件编译命令应用示例之一条件编译命令应用示例之一条件编译命令应用示例之一条件编译命令应用示例之一 #define MAX 10 #define MAX 10 #define MAX 10 #define MAX 10 main() main() main() main() { { { { #ifdef MAX #ifdef MAX #ifdef MAX #ifdef MAX printf("Happy New Year!\n"); printf("Happy New Year!\n"); printf("Happy New Year!\n"); printf("Happy New Year!\n"); #else #else #else #else printf("Happy New Spring Festival!\n"); printf("Happy New Spring Festival!\n"); printf("Happy New Spring Festival!\n"); printf("Happy New Spring Festival!\n"); #endif #endif #endif #endif printf("The end\n"); printf("The end\n"); printf("The end\n"); printf("The end\n"); } } } }定义一个宏名为定义一个宏名为MAXMAX的符号常量的符号常量该部分语句将不被编译该部分语句将不被编译 232232 #if #if #if #if 表达式表达式表达式表达式 程序段程序段程序段程序段1 1 1 1 #else #else #else #else 程序段程序段程序段程序段2 2 2 2 #endif #endif #endif #endif 编译预处理时,若表达式的值为非编译预处理时,若表达式的值为非编译预处理时,若表达式的值为非编译预处理时,若表达式的值为非0 0 0 0,则编译程序段,则编译程序段,则编译程序段,则编译程序段1 1 1 1 ,否则编译程序段,否则编译程序段,否则编译程序段,否则编译程序段2 2 2 2。

      与格式与格式1 1 1 1相同,程序段相同,程序段相同,程序段相同,程序段2 2 2 2的部分可以的部分可以的部分可以的部分可以 没有,相当于程序段没有,相当于程序段没有,相当于程序段没有,相当于程序段2 2 2 2为空语句为空语句为空语句为空语句 把把file2.c插入插入file1.c的的#include命令的位置处,命令的位置处,使使file2.c成为源程序成为源程序file1.c的一部分的一部分 条件编译命令的格式条件编译命令的格式2 2:: 233233【例【例7-47-4】条件编译命令应用示例之二条件编译命令应用示例之二 #define LETTER 0 #define LETTER 0 main() main() { { char c; char c; printf("Please input a character\n"); printf("Please input a character\n"); scanf("%c",&c); scanf("%c",&c); #if LETTER #if LETTER if(c>='A’&&c<='Z') if(c>='A’&&c<='Z') c=c+32; c=c+32; #else #else if(c>='a'&&c<='z') if(c>='a'&&c<='z') c=c-32; c=c-32; #endif #endif printf("%c",c); printf("%c",c); } }符号常量符号常量LETTERLETTER值为值为0 0 这部分语句被编译这部分语句被编译 234234 第第 7 7 章章 结束结束 指指 针针第第 8 8 章章2021/8/22235 236236学习目标学习目标•掌握定义指针的方法,掌握指针的掌握定义指针的方法,掌握指针的 基本操作;基本操作;•掌握利用指针作为函数参数传递数掌握利用指针作为函数参数传递数据的方法;据的方法;•掌握一维数组指针和行指针的概念掌握一维数组指针和行指针的概念和应用和应用 237237主要内容主要内容•指针的概念指针的概念•指针变量的定义指针变量的定义•指针的基本操作指针的基本操作 •指针变量的简单应用指针变量的简单应用•指针作为函数参数指针作为函数参数•一维数组的指针一维数组的指针•行指针行指针 238238先显示变量先显示变量x x的存储地址的存储地址, , 然后显示然后显示变量变量x x的值。

      地址以十六进制格式输出的值地址以十六进制格式输出 239239 Address of x is ffdcH Address of x is ffdcH Address of x is ffdcH Address of x is ffdcH,,,, Value of x is 3 Value of x is 3 Value of x is 3 Value of x is 3 说说说说明明明明变变变变量量量量x x x x的的的的指指指指针针针针为为为为ffdc, ffdc, ffdc, ffdc, 即即即即变变变变量量量量x x x x存存存存储储储储在在在在起起起起始始始始地地地地址址址址为为为为ffdcH ffdcH ffdcH ffdcH 的内存单元中如图所示:的内存单元中如图所示:的内存单元中如图所示:的内存单元中如图所示: ffdcH 3 ffdcH 3 ffdcH 3 ffdcH 3 ffddH 0 ffddH 0 ffddH 0 ffddH 0 空指针的概念空指针的概念空指针的概念空指针的概念 一一一一个个个个不不不不指指指指向向向向任任任任何何何何存存存存储储储储单单单单元元元元的的的的指指指指针针针针称称称称之之之之为为为为空空空空指指指指针针针针,,,,空空空空指指指指针针针针的的的的值值值值为为为为ASCASCASCASC码表中的码表中的码表中的码表中的NULLNULLNULLNULL值,也即是值,也即是值,也即是值,也即是0 0 0 0值值值值 。

      2. 2. 2. 2. 指针变量指针变量指针变量指针变量专门用来表示变量的存储地址的一类变量,称之为指针变量专门用来表示变量的存储地址的一类变量,称之为指针变量定义指针变量的格式:定义指针变量的格式:定义指针变量的格式:定义指针变量的格式: 类型说明符类型说明符 * *指针变量名;指针变量名; 240240定义指针变量的例子:定义指针变量的例子: 例例1. float x,y,*pf; 1. float x,y,*pf; /* /* 定义浮点型变量定义浮点型变量x x、、y y及一个指向浮点型数据及一个指向浮点型数据 的指针变量的指针变量pf */pf */ 例例2.char ch1,ch2; /* 2.char ch1,ch2; /* 先定义字符型变量先定义字符型变量ch1,ch2 */ch1,ch2 */ char *p1; char *p1; /* /* 再定义一个指向字符型数据的指针变量再定义一个指向字符型数据的指针变量 p1 */ p1 */ 例例3. char ch,*pc=&ch; 3. char ch,*pc=&ch; /* /* 定义字符型变量定义字符型变量chch及一个指向字符型数据的及一个指向字符型数据的 指针变量指针变量pcpc,同时使,同时使pcpc指向指向chch的存储单元的存储单元 */ */ 例例4. int a=7,*p=&a; 4. int a=7,*p=&a; /* /* 定义整型变量定义整型变量a, a, 并初始化等於并初始化等於7 7,又定义一个,又定义一个 指向整型数据的指针变量指向整型数据的指针变量p, p, 同时使同时使p p指向指向a a的存的存 储单元储单元 */ */ 注意:注意:注意:注意:(1).(1).类型说明符说明的是指针变量所指向的数据类型。

      不同类型说明符说明的是指针变量所指向的数据类型不同 类型的指针变量不能相互替代类型的指针变量不能相互替代 (2). (2).指针变量具有与其他变量相同的命名规则指针变量具有与其他变量相同的命名规则 (3). (3).指针变量的初始化要遵循指针变量的初始化要遵循““先说明、后使用先说明、后使用””的原则 241241二二二二. . . .指针变量的简单应用指针变量的简单应用指针变量的简单应用指针变量的简单应用1. 1. 1. 1. 给指针变量赋值给指针变量赋值给指针变量赋值给指针变量赋值 在程序中通过赋值语句给指针变量赋值在程序中通过赋值语句给指针变量赋值 例如:例如: int a,*p; /* int a,*p; /* 定义整型变量定义整型变量a,a,又定义一个指向整又定义一个指向整 型数据的指针变量型数据的指针变量p */p */ p=&a; /* p=&a; /* 使指针变量使指针变量p p指向指向a a的存储单元的存储单元 */ */ 2. 2. 2. 2. 取得指针变量所指向的变量值取得指针变量所指向的变量值取得指针变量所指向的变量值取得指针变量所指向的变量值 在程序中在程序中 “* “*指针变量名指针变量名” ” 表示取得其所指向的变量的值。

      表示取得其所指向的变量的值 例如:例如: int a=7,b=5,c,*p1=&a,*p2=&b; int a=7,b=5,c,*p1=&a,*p2=&b; c=*p1+*p2; /* c=*p1+*p2; /* 取出取出a, ba, b的值,相加后将结果赋的值,相加后将结果赋 给变量给变量c c,等价于,等价于 c=a+b */ c=a+b */ 242242【例【例8-28-2】】 输入三个整数输入三个整数, , 输出其中的最大值输出其中的最大值 main main()() { { int x,y,z,*p1=&x,*p2=&y,*p3=&z,*pmax; int x,y,z,*p1=&x,*p2=&y,*p3=&z,*pmax; scanf("%d,%d,%d",p1,p2,p3); scanf("%d,%d,%d",p1,p2,p3); pmax=p1; pmax=p1; if(*pmax<*p2) if(*pmax<*p2) pmax=p2; pmax=p2; if(*pmax<*p3) if(*pmax<*p3) pmax=p3; pmax=p3; printf("MAX=%d\n",*pmax); printf("MAX=%d\n",*pmax); } } 交换指针交换指针交换指针交换指针指向指向指向指向 243243【例【例8-38-3】】 输入三个整数输入三个整数, , 按从大到小的顺序输出这三个数。

      按从大到小的顺序输出这三个数main()main() { { int a,b,c,*p1=&a,*p2=&b, int a,b,c,*p1=&a,*p2=&b, *p3=&c,*t; *p3=&c,*t; printf("Please Input printf("Please Input Three Integers:\n"); Three Integers:\n"); scanf("%d,%d,%d",p1,p2, scanf("%d,%d,%d",p1,p2, p3); p3); if(*p1<*p2) if(*p1<*p2) { { t=p2; t=p2; p2=p1; p2=p1; p1=t; p1=t; } } if(*p2<*p3) if(*p2<*p3) { { t=p3; t=p3; p3=p2; p3=p2; p2=t; p2=t; } } if(*p1<*p2) if(*p1<*p2) { { t=p2; t=p2; p2=p1; p2=p1; p1=t; p1=t; } } printf("%d,%d,%d",*p1, printf("%d,%d,%d",*p1, *p2,*p3); *p2,*p3); } }交换指针交换指针交换指针交换指针指向指向指向指向 244244通过改变变量的存储实现排序通过改变变量的存储实现排序 4 4 8 8 11 11 4 4 11 11 8 8abcabc通过改变指针变量的指向实现排序通过改变指针变量的指向实现排序 41184118P1P2p3P1P2p3 2452458.2 8.2 指针作为函数参数指针作为函数参数  指针可以作为函数的形参和实参参与函数调用。

      在函数调用指针可以作为函数的形参和实参参与函数调用在函数调用时,通过地址传递,把实参变量的存储地址传递给形参变量,时,通过地址传递,把实参变量的存储地址传递给形参变量,被调函数通过这些存储地址访问实参变量,使实参变量参与函被调函数通过这些存储地址访问实参变量,使实参变量参与函数调用 指针变量要作为函数参数,必须满足:在函数调用中,形式指针变量要作为函数参数,必须满足:在函数调用中,形式 参数和实在参数在类型,个数和顺序上必须保持一致的要求:参数和实在参数在类型,个数和顺序上必须保持一致的要求: 在函数调用时,如果实在参数是指针,那么函数中在函数调用时,如果实在参数是指针,那么函数中 相应的形式参数必须被说明为同类型的指针变量相应的形式参数必须被说明为同类型的指针变量 246246【例【例8-48-4】】 通过函数调用交换实参变量的值通过函数调用交换实参变量的值 void swap(int *x,int *y) void swap(int *x,int *y) { { int temp; int temp; temp=*x; temp=*x; *x *x==*y;*y; *y *y==temp; temp; } } main() main() { { int a,b; int a,b; printf("Please input two integers:\n"); printf("Please input two integers:\n"); scanf("%d,%d",&a,&b); scanf("%d,%d",&a,&b); printf("a=%d b printf("a=%d b==%d\n",a,b);%d\n",a,b); swap(&a,&b); swap(&a,&b); printf("Exchanged a,b: a=%d, b=%d\n ",a,b); printf("Exchanged a,b: a=%d, b=%d\n ",a,b); } }形式参数为形式参数为形式参数为形式参数为指针变量指针变量指针变量指针变量实在参数为实在参数为实在参数为实在参数为指针指针指针指针 247247【例【例8-58-5】从键盘输入三个整数,通过函数调用,同时返回这】从键盘输入三个整数,通过函数调用,同时返回这 三个整数的和与积。

      三个整数的和与积 void f(int,int,int,int *,int *); void f(int,int,int,int *,int *); main() main() { { int a,b,c,sum,mul; int a,b,c,sum,mul; printf("Please Input Three Integers:\n"); printf("Please Input Three Integers:\n"); scanf("%d,%d,%d",&a,&b,&c); scanf("%d,%d,%d",&a,&b,&c); f(a,b,c,&sum,&mul); f(a,b,c,&sum,&mul); printf("SUM=%d MUL=%d\n",sum,mul); printf("SUM=%d MUL=%d\n",sum,mul); } } void f(int x,int y,int z,int *p1,int *p2) void f(int x,int y,int z,int *p1,int *p2) { { *p1=x+y+z; *p1=x+y+z; *p2=x*y*z; *p2=x*y*z; } } 248248 8.3 8.3 指针和数组指针和数组一一一一. . . .一维数组的指针及其应用一维数组的指针及其应用一维数组的指针及其应用一维数组的指针及其应用1. 1. 1. 1. 一维数组指针的概念一维数组指针的概念一维数组指针的概念一维数组指针的概念 在在在在C C C C语言中,一维数组的数组名表示数组存放的首地址,称语言中,一维数组的数组名表示数组存放的首地址,称语言中,一维数组的数组名表示数组存放的首地址,称语言中,一维数组的数组名表示数组存放的首地址,称其为数组的指针。

      显然,该指针与数组首元素的指针有相同其为数组的指针显然,该指针与数组首元素的指针有相同其为数组的指针显然,该指针与数组首元素的指针有相同其为数组的指针显然,该指针与数组首元素的指针有相同的值 2000H 5 2000H 5 0 0 2002H 4 2002H 4 0 0 2004H 3 2004H 3 0 0 2006H 2 2006H 2 0 0 2008H 1 2008H 1 0 0 定义一维数组定义一维数组 int arr[5]= int arr[5]={5,4,3,2,1}{5,4,3,2,1};并假定数组在内存中;并假定数组在内存中从从2000H2000H开始存放。

      开始存放 则:则:数组名数组名arrarr就是数组就是数组arr[]arr[]的指的指针,针,arrarr的值为数组的存储地址的值为数组的存储地址2000H2000H显然,数组元素显然,数组元素arr[0]arr[0]的指的指针也是针也是2000H2000H,数组元素,数组元素arr[1]arr[1]的指的指针是针是2002H2002H,,…………在C C程序中,执行语句:程序中,执行语句:printfprintf(("%x",arr"%x",arr)); ; 即可输出一维数组即可输出一维数组arr[]arr[]的指针 249249一维数组指针和数组元素指针的关系一维数组指针和数组元素指针的关系一维数组指针和数组元素指针的关系一维数组指针和数组元素指针的关系 数组名+数组名+数组名+数组名+i i i i 指向数组第指向数组第指向数组第指向数组第i i i i个元素个元素个元素个元素例如:例如:例如:例如: arrarr是数组是数组arr[]arr[]的指针,则的指针,则 arr+i arr+i 指向数组指向数组指向数组指向数组arr[]arr[]arr[]arr[]的第的第的第的第i i i i个元素,即:个元素,即:个元素,即:个元素,即: arr+iarr+i ==== &arr[i] &arr[i] &arr[i] &arr[i] 【例【例8-68-6】】 从键盘输入十个整数从键盘输入十个整数, , 然后逆序输出。

      然后逆序输出 main( ) main( ) { { int a[10],i,*p; int a[10],i,*p; printf("Please input ten Integers:\"); printf("Please input ten Integers:\"); for(i=0;i<=9;i++) for(i=0;i<=9;i++) scanf("%d",a+i); scanf("%d",a+i); for(p=a+9;p>=a;p--) for(p=a+9;p>=a;p--) printf("%d, ",*p); printf("%d, ",*p); printf("\n"); printf("\n"); } } 250250 注意:注意:注意:注意:(1).(1).指针变量可以施行自加、自减运算,指针变量可以施行自加、自减运算,p++p++或或++p++p使指针变使指针变量指向数组当前元素的下一个元素,而量指向数组当前元素的下一个元素,而p--p--或或--p--p使指针变量使指针变量指向数组当前元素的前一个元素。

      指向数组当前元素的前一个元素2).(2).数组名数组名a a是数组的首地址,是一个常量,所以不可以施行是数组的首地址,是一个常量,所以不可以施行自加、自减运算自加、自减运算3).(3).如果指针变量如果指针变量p p指向数组的某一个元素指向数组的某一个元素a[i]a[i],则,则*p++*p++表示表示读取读取a[i]a[i]的值后,再使的值后,再使p p指向指向a[i+1]a[i+1]可以类似地理解可以类似地理解*p--*p--4).(4).如果指针变量如果指针变量p p指向数组的某一个元素指向数组的某一个元素a[i]a[i],则,则--*p--*p表示表示先使先使p p指向指向a[i-1]a[i-1],再读取,再读取a[i-1]a[i-1]的值可以类似地理解的值可以类似地理解++*p++*p5). (5). 如果指针变量如果指针变量p p指向数组的某一个元素指向数组的某一个元素a[i]a[i],则,则(*p)++(*p)++表示读取表示读取a[i]a[i]的值后,执行的值后,执行a[i]+=1a[i]+=1,而,而p p的指向不变可以的指向不变可以类似地理解类似地理解(*p)--(*p)--。

      (6). *p++ (6). *p++和和*(p++)*(p++)、、*p--*p--和和*(p--)*(p--)的运算结果是一样的的运算结果是一样的 251251【例【例8-78-7】从键盘输入】从键盘输入5 5个数,输出其中的最大值和最小值个数,输出其中的最大值和最小值int max,min;int max,min;void f(int *arr,int n)void f(int *arr,int n) { { int *p,*arr_end; int *p,*arr_end; arr_end=arr+n; arr_end=arr+n; max=min=*arr; max=min=*arr; for(p=arr+1;pmax) max=*p; if(*p>max) max=*p; else else if(*p

      二维数组的数组名表示数组存储的首地址 例如,定义二维数组:例如,定义二维数组: int a[3][4]={{2,4,6,8},{10, int a[3][4]={{2,4,6,8},{10,12,14,16},{18,28,22,24}}; 12,14,16},{18,28,22,24}}; 设数组设数组a[][]a[][]存储在从存储在从2000H2000H开始的存储单元中开始的存储单元中2000H 2 a[0][0] 2008H 10 a[1][0] 2010H 18 a[2][0]2000H 2 a[0][0] 2008H 10 a[1][0] 2010H 18 a[2][0] 0 0 0 0 0 0 2002H 4 a[0][1] 200AH 12 a[1][1] 2012H 20 a[2][1] 2002H 4 a[0][1] 200AH 12 a[1][1] 2012H 20 a[2][1] 0 0 0 0 0 0 2004H 6 a[0][2] 200CH 14 a[1][2] 2014H 22 a[2][2] 2004H 6 a[0][2] 200CH 14 a[1][2] 2014H 22 a[2][2] 0 0 0 0 0 0 2006H 8 a[0][3] 200EH 16 a[1][3] 2016H 24 a[2][3] 2006H 8 a[0][3] 200EH 16 a[1][3] 2016H 24 a[2][3] 0 0 0 0 0 0 第第0行行 第第1行行 第第2行行 数组名数组名a a指向数组存储的首地址指向数组存储的首地址2000H2000H。

      但但a+1a+1不是指向不是指向a[0][1]a[0][1]的存储单元,而是指向二维数组第的存储单元,而是指向二维数组第1 1行的存储首地址行的存储首地址2008H,a+22008H,a+2指向二维数组第指向二维数组第2 2行的存储首地址行的存储首地址2010H ..…. 2010H ..…. 确切地说确切地说, ,数组数组名名a a指向二维数组第指向二维数组第0 0行的存储首地址行的存储首地址2000H2000H 注意:注意:注意:注意: 253253 称二维数组各行的存储首地址为该行的行指针,是以二维称二维数组各行的存储首地址为该行的行指针,是以二维数组的行为存储单位的地址数组的行为存储单位的地址二维数组的行指针和数组元素指针的关系二维数组的行指针和数组元素指针的关系二维数组的行指针和数组元素指针的关系二维数组的行指针和数组元素指针的关系 *(*(*(*(数组名+数组名+数组名+数组名+i)i)i)i)++++j j j j 指向二维数组第指向二维数组第指向二维数组第指向二维数组第i i i i行、第行、第行、第行、第j j j j列的元素列的元素列的元素列的元素 而而*(*(*(*(数组名+数组名+数组名+数组名+i)+j)i)+j)i)+j)i)+j)即是取出第即是取出第即是取出第即是取出第i i i i行、第行、第行、第行、第j j j j列的元素值。

      列的元素值列的元素值列的元素值 例如:例如:例如:例如: a a是二维数组是二维数组a[]a[]的行指针,则的行指针,则 *(a+i)+j *(a+i)+j 指向数组指向数组指向数组指向数组a[]a[]a[]a[]的第的第的第的第i i i i行、第行、第行、第行、第j j j j列的元素,即:列的元素,即:列的元素,即:列的元素,即: *(a+i)+j *(a+i)+j ==== &a[i][j] &a[i][j] &a[i][j] &a[i][j] 而:而:*(*(a+i)+j)*(*(a+i)+j)即是取出即是取出即是取出即是取出a[i][j]a[i][j]a[i][j]a[i][j]的值为了使用行指针,需要定义行指针变量为了使用行指针,需要定义行指针变量定义行指针变量的格式:定义行指针变量的格式:定义行指针变量的格式:定义行指针变量的格式: 类型说明符类型说明符 ((* *行指针变量名)行指针变量名)[ [数组的列元素个数数组的列元素个数] ] ;; 对二维数组对二维数组a[3][4]a[3][4],定义行指针变量:,定义行指针变量:int (*p)[4];int (*p)[4]; 其中:其中:(*p)(*p)表示表示p p是行指针变量是行指针变量, [4], [4]表示该行指针变量指向的表示该行指针变量指向的 行有行有4 4个列元素个列元素, int, int表示二维数组的元素为整型变量。

      表示二维数组的元素为整型变量 254254【例【例8-88-8】以二种不同的方式输出数组元素】以二种不同的方式输出数组元素a[i][j] a[i][j] 的存储单元的存储单元 地址和值地址和值 main() main() { { int a[2][2]={{2,4},{6,8}},i,j; int a[2][2]={{2,4},{6,8}},i,j; int (*p)[2]=a; int (*p)[2]=a; for(i=0;i<=1;i++) for(i=0;i<=1;i++) for(j=0;j<=1;j++) for(j=0;j<=1;j++) { { printf("Address1 of a[%d][%d] is %x", printf("Address1 of a[%d][%d] is %x", i,j,*(p+i)+j); i,j,*(p+i)+j); printf(" a[%d][%d]=%d\n",i,j, printf(" a[%d][%d]=%d\n",i,j, *(*(p+i)+j)); *(*(p+i)+j)); printf("Address2 of a[%d][%d] is %x", printf("Address2 of a[%d][%d] is %x", i,j,*(a+i)+j); i,j,*(a+i)+j); printf(" a[%d][%d]=%d\n",i,j, printf(" a[%d][%d]=%d\n",i,j, *(*(a+i)+j)); *(*(a+i)+j)); } } } }用二维数组用二维数组用二维数组用二维数组a[][]a[][]的数组名的数组名的数组名的数组名a a对行指针变量对行指针变量对行指针变量对行指针变量p p作初始化作初始化作初始化作初始化行指针的方法输出数组行指针的方法输出数组行指针的方法输出数组行指针的方法输出数组元素元素元素元素a[i][j] a[i][j] 的指针和值的指针和值的指针和值的指针和值 用二维数组名的方法输出用二维数组名的方法输出数组元素数组元素a[i][j] 的指针和值的指针和值 255255【例【例8-98-9】】 用行指针的方法计算并输出二维数组用行指针的方法计算并输出二维数组a[][]a[][]各行各行 元素的和。

      元素的和 main() main() { { int a[3][4]= {{2,4,6,8},{10,12,14,16}, int a[3][4]= {{2,4,6,8},{10,12,14,16}, {18,20,22,24}}; {18,20,22,24}}; int (*p)[4]=a,i=0,j; int (*p)[4]=a,i=0,j; for(p=a;p<=a+2;p++,i++) for(p=a;p<=a+2;p++,i++) { { int sum=0; int sum=0; for(j=0;j<=3;j++) for(j=0;j<=3;j++) sum+=*(*p+j); sum+=*(*p+j); printf("Sum of Row %d is %d\n",i,sum); printf("Sum of Row %d is %d\n",i,sum); } } } } 256256【例【例8-108-10】】 用访问一维数组的方法输出二维数组所有元素的和。

      用访问一维数组的方法输出二维数组所有元素的和 main() main() { { int a[3][4]={{2,4,6,8},{10,12,14,16}, int a[3][4]={{2,4,6,8},{10,12,14,16}, {18,20,22,24}}; {18,20,22,24}}; int i,j,sum=0,*p=&a[0][0]; int i,j,sum=0,*p=&a[0][0]; for(i=0;i<=2;i++) for(i=0;i<=2;i++) for(j=0;j<=3;j++) for(j=0;j<=3;j++) sum+=*(p+i*4+j); sum+=*(p+i*4+j); printf("SUM=%d\n",sum); printf("SUM=%d\n",sum); } }用二维数组用二维数组用二维数组用二维数组a[][]a[][]元素元素元素元素a[0][0]a[0][0]的地址对指针变量的地址对指针变量的地址对指针变量的地址对指针变量p p作初始化作初始化作初始化作初始化,,,,p p++++1 1指向指向指向指向a[0][1]……a[0][1]…… 257257【例【例8-138-13】】 通过函数调用求二行四列矩阵的最大元素值。

      通过函数调用求二行四列矩阵的最大元素值 int max(int (*p)[4]) int max(int (*p)[4]) { { int i,j,m; int i,j,m; m=**p; m=**p; for(i=0;i<=1;i++) for(i=0;i<=1;i++) for(j=0;j<=3;j++) for(j=0;j<=3;j++) if(*(*(p+i)+j)>m) if(*(*(p+i)+j)>m) m=*(*(p+i)+j); m=*(*(p+i)+j); return(m); return(m); } } main() main() { { int a[2][4],i,j; int a[2][4],i,j; printf("Please Input Eight Integers:\n"); printf("Please Input Eight Integers:\n"); for(i=0;i<=1;i++) for(i=0;i<=1;i++) for(j=0;j<=3;j++) for(j=0;j<=3;j++) scanf("%d",&a[i][j]); scanf("%d",&a[i][j]); printf("MAX=%d\n",max(a)); printf("MAX=%d\n",max(a)); } }形参为行形参为行形参为行形参为行指针变量指针变量指针变量指针变量即:即:即:即:*(*(p+0)+0)*(*(p+0)+0)实参为二维数组的实参为二维数组的实参为二维数组的实参为二维数组的数组名数组名数组名数组名 258258 8.4 8.4字符串的指针及其应用字符串的指针及其应用 字符串的指针就是字符串在内存存储区域中的起始地址,字符串的指针就是字符串在内存存储区域中的起始地址,存放该字符串的字符数组名就是其指针。

      存放该字符串的字符数组名就是其指针 例如:定义一字符串:例如:定义一字符串:char s[]="I love China. ";char s[]="I love China. "; 那么,字符数组名那么,字符数组名s s就是该字符串的指针通过指针变量,既可就是该字符串的指针通过指针变量,既可 以访问整个字符串,也可以访问字符串中的某个字符以访问整个字符串,也可以访问字符串中的某个字符 【例【例8-148-14】】 通过字符数组名和指针变量访问字符串通过字符数组名和指针变量访问字符串include#includemain()main() { { char s[]="I love char s[]="I love China.",*p; China.",*p; int i; int i; for(i=0;s[i]!=’\0’;i++) for(i=0;s[i]!=’\0’;i++) printf("%c",s[i]); printf("%c",s[i]); printf("\n"); printf("\n"); puts(s); puts(s); for(p=s;*p!=’\0’;p++) for(p=s;*p!=’\0’;p++) printf("%c",*p); printf("%c",*p); printf("\n") printf("\n") p=s; p=s; puts(p); puts(p);} }使字符指针变量使字符指针变量p p 重新重新指向字符串指向字符串s[]s[]的首地址的首地址 259259 【例【例8-14-18-14-1】通过字符数组名和指针变量访问字符串。

      通过字符数组名和指针变量访问字符串 #include#include main() main() { { char *p= "I love China.",*p1=p; char *p= "I love China.",*p1=p; int i; int i; for(i=0;*(p+i)!=’\0’;i++) for(i=0;*(p+i)!=’\0’;i++) printf("%c",*(p+i)); printf("%c",*(p+i)); printf("\n"); printf("\n"); puts(p); puts(p); for(p=p1;*p!=’\0’;p++) for(p=p1;*p!=’\0’;p++) printf("%c",*p); printf("%c",*p); printf("\n"); printf("\n"); p=p1; p=p1; puts(p); puts(p); } }直接使用字符型指针变量直接使用字符型指针变量p p指向字符串的首地址指向字符串的首地址 260260【例【例8-158-15】】 通过函数调用,将字符串通过函数调用,将字符串1 1中从第中从第m m个字符开始个字符开始 的全部字符复制成字符串的全部字符复制成字符串2 2。

      要求在主函数中输入字要求在主函数中输入字 符串符串1 1和和m m的值,并输出复制结果的值,并输出复制结果 #include#include #include #include void copys(char *,char *,int); void copys(char *,char *,int); main() main() { { int m; int m; char s1[80],s2[80]; char s1[80],s2[80]; printf(“Please input a string:\n”); printf(“Please input a string:\n”); gets(s1); gets(s1); printf(“please input an integer m:\n”); printf(“please input an integer m:\n”); scanf(“%d”,&m); scanf(“%d”,&m); if(strlen(s1)

      针函数 指针函数定义格式:指针函数定义格式:指针函数定义格式:指针函数定义格式: 类型说明符类型说明符 * *函数名函数名( (形参表形参表) ) { { 语句;语句; } } 说明:说明:说明:说明: 格式中的类型说明符表明函数返回的指针所指向的数格式中的类型说明符表明函数返回的指针所指向的数 据类型 263263【例【例8-168-16】】 编一个函数,用以求数组中最小元素,并返回指编一个函数,用以求数组中最小元素,并返回指 向该元素的指针向该元素的指针 int *getmin(int *,int); int *getmin(int *,int); main() main() { { int *p,a[]={6,4,85,1,82,12,66,32,22,211}; int *p,a[]={6,4,85,1,82,12,66,32,22,211}; p=getmin(a,10); p=getmin(a,10); printf("The minimum value is printf("The minimum value is::%d\n",*p);%d\n",*p); } } int *getmin(int *parr,int n) int *getmin(int *parr,int n) { { int *pmin=parr,*pp; int *pmin=parr,*pp; for(pp=parr;pp< parr+n;pp++) for(pp=parr;pp< parr+n;pp++) if(*pmin>*pp) if(*pmin>*pp) pmin=pp; pmin=pp; return pmin; return pmin; } }调用后返回一个指针调用后返回一个指针调用时用指针变量调用时用指针变量接收返回的指针接收返回的指针 264264 8.6 8.6 指针数组指针数组 一个数组,如果其元素均为指针变量,则称之为指针数组。

      一个数组,如果其元素均为指针变量,则称之为指针数组指针数组的定义格式:指针数组的定义格式:指针数组的定义格式:指针数组的定义格式: 类型说明符类型说明符 * *数组名数组名[ [数组长度数组长度];]; 说明:说明:说明:说明: 格式中的类型说明符是指针数组中的指针变量所指向的格式中的类型说明符是指针数组中的指针变量所指向的 数据类型数据类型 例如,语句:例如,语句:int *p[4];int *p[4]; 定义了一个有四个元素组成的数组定义了一个有四个元素组成的数组p p,每一个元素,每一个元素p[i],p[i], (i=0,1,2,3) (i=0,1,2,3) 都是指向整型数据的指针变量都是指向整型数据的指针变量 265265【例【例8-178-17】】 将若干字符串按字母顺序将若干字符串按字母顺序( (由小到大由小到大) )输出 #define N 4#define N 4 #include #include void sort(char *s[],int n) void sort(char *s[],int n) { { char *temp; char *temp; int i,j,k; int i,j,k; for(i=0;i0) if(strcmp(s[k],s[j])>0) k=j; k=j; if(k!=i) if(k!=i) { { temp=s[i]; temp=s[i]; s[i]=s[k]; s[i]=s[k]; s[k]=temp; s[k]=temp; } } } } } }( (后续后续) )形参为指针数组形参为指针数组s[k],s[j]s[k],s[j]为指针变量为指针变量 266266 void out(char *s[],int n)void out(char *s[],int n) { { int i; int i; for(i=0;i

      类型变量的定义及简单应用2.2.基本掌握结构体类型变量参与函数调用的基本掌握结构体类型变量参与函数调用的方法 271271主要内容主要内容•结构体数据类型的概念结构体数据类型的概念 •结构体数组结构体数组 •结构体与函数结构体与函数 2722729.1 9.1 结构体数据类型的概念结构体数据类型的概念 一一. .结构体变量的定义和引用结构体变量的定义和引用1 1.结构体数据类型和结构体变量的定义.结构体数据类型和结构体变量的定义 结构体数据类型则是由不同类型的数据组合而成的结构体数据类型则是由不同类型的数据组合而成的设通过学号、姓名、性别、年龄和入学成绩来描述一个学生:设通过学号、姓名、性别、年龄和入学成绩来描述一个学生:以标识符以标识符number(number(字符串字符串) )表示学号表示学号、、name(name(字符串字符串) )表示姓名表示姓名、、sex(sex(字符字符) )表示性别、表示性别、age(age(整型整型) )表示年龄和表示年龄和score(score(整型整型) )表示表示入学成绩入学成绩 由这些不同类型的数据组合在一起,描述学生这一特定类型由这些不同类型的数据组合在一起,描述学生这一特定类型的对象。

      称这种新的数据类型为结构体类型,根据其所描述的对象称这种新的数据类型为结构体类型,根据其所描述的对象,将其命名为的对象,将其命名为studentstudent结构体类型结构体类型定义结构体类型的格式:定义结构体类型的格式: struct struct 结构体类型名结构体类型名 { { 结构体成员表列结构体成员表列 } };; 273273例如:定义例如:定义studentstudent结构体类型的语句:结构体类型的语句: struct student struct student { { char number[6]; char number[6]; char name[20]; char name[20]; char sex; char sex; int age; int age; int score; int score; }; }; 其中,其中,structstruct为定义结构体类型的关键字,为定义结构体类型的关键字,studentstudent为所定义为所定义的结构体类型名。

      结构体类型名由用户命名,但须符合标识符的结构体类型名结构体类型名由用户命名,但须符合标识符的命名规则花括号内所定义的变量称为结构体成员,它们构的命名规则花括号内所定义的变量称为结构体成员,它们构成了所定义的结构体类型的特征结构体类型成了所定义的结构体类型的特征结构体类型studentstudent的特征的特征由结构体成员由结构体成员number[]number[]、、name[]name[]、、sexsex、、ageage和和scorescore共同描述共同描述最后,以最后,以““;;””表示定义结构体类型语句结束表示定义结构体类型语句结束 274274 定义结构体类型变量定义结构体类型变量 student student是由用户定义的数据类型,与是由用户定义的数据类型,与intint、、 char char、、floatfloat等等类型说明符一样,本身不能直接参与数据处理,必须通过定类型说明符一样,本身不能直接参与数据处理,必须通过定义义studentstudent类型的变量,才能参与程序运行类型的变量,才能参与程序运行 定义结构体类型变量的格式为:定义结构体类型变量的格式为: struct struct 结构体类型名结构体类型名 变量名变量名; ; 例如,语句:例如,语句:struct student s1,s2;struct student s1,s2;定义了二个定义了二个studentstudent类型的变量类型的变量s1s1和和s2s2,并且由,并且由C C编译程序为编译程序为s1s1、、s2s2分配存储单元,假定存储单元的起始地址为分配存储单元,假定存储单元的起始地址为2000H2000H,则,则s1s1的存储情况如图所示:的存储情况如图所示: (转后)(转后) 275275结构体变量结构体变量s1s1在内存中的存储情况在内存中的存储情况 成员成员ageage占占2 2字节字节成员成员numbernumber占占6 6字节字节成员成员sexsex占占1 1字节字节成员成员scorescore占占2 2字节字节成员成员namename占占2020字节字节2000H2000H2005H 2005H 2006H2006H  2019H2019H201AH201AH201BH201BH201CH201CH201DH201DH201EH201EH 276276定义结构体类型的又一种格式定义结构体类型的又一种格式( (定义结构体类型的同时定义定义结构体类型的同时定义 结构体类型的变量结构体类型的变量) ) struct struct 结构体类型名结构体类型名 { { 结构体成员表列结构体成员表列 } }变量名表列;变量名表列; 例如:例如: struct student struct student { { char number[6]; char number[6]; char name[20]; char name[20]; char sex; char sex; int age; int age; int score; int score; }s1,s2; }s1,s2; 277277 在定义结构体类型变量的同时对其初始化在定义结构体类型变量的同时对其初始化 对结构体类型变量的初始化就是用初始化数据对结构体变量对结构体类型变量的初始化就是用初始化数据对结构体变量相应的成员作初始化。

      相应的成员作初始化例【例9-19-1】结构体变量的初始化结构体变量的初始化执行语句:执行语句: struct student struct student { { char number[6]; char number[6]; char name[20]; char name[20]; char sex; char sex; int age; int age; int score; int score; } s1={"00001","Peter",'m',19,250}, s2={"00002", } s1={"00001","Peter",'m',19,250}, s2={"00002", "Betty",'m',18,268}; "Betty",'m',18,268}; 后,结构体变量后,结构体变量s1s1、、s2s2的成员被赋予相应的值。

      的成员被赋予相应的值 例如:例如:s1s1的成员的成员number[]number[]的值为的值为“00001”“00001”,,ageage的值为的值为1919,,结构体变量结构体变量s2s2的成员的成员name[]name[]的值为的值为"Betty""Betty"、、scorescore的值为的值为268268 278278【例【例9-29-2】假设学生的入学成绩由语文成绩、数学成绩和外语】假设学生的入学成绩由语文成绩、数学成绩和外语 成绩构成,分别以标识符成绩构成,分别以标识符score1score1、、score2score2和和score3score3 表示,则可以将入学成绩定义为结构体类型表示,则可以将入学成绩定义为结构体类型scorescore,, 并重新定义结构体类型并重新定义结构体类型studentstudent:: struct score struct score { { int score1; int score1; int score2; int score2; int score3; int score3; }; }; struct student struct student { { char number[6]; char number[6]; char name[20]; char name[20]; char sex; char sex; int age; int age; struct score stscore; struct score stscore; } s1={"00001","Peter",'m',19,{75,82,93}}, } s1={"00001","Peter",'m',19,{75,82,93}}, s2={"00002","Betty",'m',18,{81, 94,93}}; s2={"00002","Betty",'m',18,{81, 94,93}};先定义结构体先定义结构体先定义结构体先定义结构体类型类型类型类型scorescore结构体类型结构体类型结构体类型结构体类型scorescore的变量的变量的变量的变量stscorestscore是结构体类型是结构体类型是结构体类型是结构体类型studentstudent中的成员中的成员中的成员中的成员 2792792 2.结构体变量的引用.结构体变量的引用 在在C C程序中,不允许引用结构体变量整体,只能通过结构体程序中,不允许引用结构体变量整体,只能通过结构体变量访问和引用其成员。

      变量访问和引用其成员 引用结构体变量成员的格式:引用结构体变量成员的格式: 结构体变量名结构体变量名. .成员名成员名 以【例以【例9-19-1】中的结构体变量】中的结构体变量s1s1和和s2s2为例:为例:s1.names1.name的值为字符串常量的值为字符串常量"Peter""Peter",,s2.sexs2.sex的值为字符常量的值为字符常量'm''m' 再以【例再以【例9.29.2】中的结构体变量】中的结构体变量s1s1和和s2s2为例:为例: s1.stscore.score1s1.stscore.score1的值为的值为7575,,s2.stscore.score3s2.stscore.score3的值为的值为93 93 由由由由s1.stscores1.stscore访问访问访问访问s 1s 1的成员的成员的成员的成员stscorestscore,再由,再由,再由,再由stscore.score1stscore.score1访问访问访问访问stscorestscore的成员的成员的成员的成员score1score1 说明:说明: 在在C C程序中,结构体变量成员可以程序中,结构体变量成员可以参与同类型变量所能进行的各种运算参与同类型变量所能进行的各种运算和操作。

      和操作 280280【例【例9-39-3】参考例】参考例9-19-1中中studentstudent类型的定义,以表的形式输出学类型的定义,以表的形式输出学 生的信息生的信息 main()main() { { struct student struct student { { char number[6]; char number[6]; char name[20]; char name[20]; char sex; char sex; int age; int age; int score; int score; } s1={"00001","Peter",'m',19,250}, } s1={"00001","Peter",'m',19,250}, s2={"00002","Betty",'f',18,268}; s2={"00002","Betty",'f',18,268}; printf("Number Name Sex Age Score\n"); printf("Number Name Sex Age Score\n"); printf("__________________________________\n"); printf("__________________________________\n"); printf("%s %s %c printf("%s %s %c %%d %d\n",d %d\n", s1.number,s1.name, s1.sex,s1.age,s1.score); s1.number,s1.name, s1.sex,s1.age,s1.score); printf("%s %s %c printf("%s %s %c %%d %d\n",d %d\n", s2.number,s2.name, s2.sex,s2.age,s2.score); s2.number,s2.name, s2.sex,s2.age,s2.score); ) ) 281281二二. .指向结构体类型数据的指针指向结构体类型数据的指针 C C编译程序为结构体变量分配的存储区域的首地址就是结构体编译程序为结构体变量分配的存储区域的首地址就是结构体变量的指针。

      变量的指针 在在C C程序中,使用取地址运算符程序中,使用取地址运算符“&”“&”就可以获得结构体变量的就可以获得结构体变量的指针 定义结构体类型的指针变量,用于存放结构体变量的指针定义结构体类型的指针变量,用于存放结构体变量的指针 定义结构体类型指针变量的格式为:定义结构体类型指针变量的格式为: struct struct 结构体类型名结构体类型名 * *指针变量名;指针变量名; 例如,定义了结构体类型例如,定义了结构体类型studentstudent以后,下面的语句:以后,下面的语句:struct student s1,s2,*p=&s1;struct student s1,s2,*p=&s1;就定义了就定义了studentstudent类型的二个结构体变量类型的二个结构体变量s1s1、、s2s2和和studentstudent类型类型的指针变量的指针变量p p,并使,并使p p指向结构体变量指向结构体变量s1s1的存储地址的存储地址 如果结构体指针变量已经指向某个结构体变量,则可以通过如果结构体指针变量已经指向某个结构体变量,则可以通过该指针变量访问其指向的结构体变量的成员,使用格式:该指针变量访问其指向的结构体变量的成员,使用格式: 指针变量名指针变量名 --> > 成员名成员名 例如:例如:p -> numberp -> number等价于等价于 s1.number s1.number ,,p-> agep-> age等价于等价于 s1.age s1.age,, p -> score p -> score等价于等价于 s1.score s1.score。

      282282【例【例9-49-4】使用结构体指针变量实现例】使用结构体指针变量实现例9-39-3 main() main() { { struct student struct student { { char number[6]; char number[6]; char name[20]; char name[20]; char sex; char sex; int age; int age; float score; float score; } s1={"00001","Peter",'m',19,250.4}, } s1={"00001","Peter",'m',19,250.4}, s2={"00002","Betty",'f',18,268.6},*p=&s1; s2={"00002","Betty",'f',18,268.6},*p=&s1; printf("Number Name Sex Age Score\n"); printf("Number Name Sex Age Score\n"); printf("__________________________________\n"); printf("__________________________________\n"); printf("%s %s %c printf("%s %s %c %%d %f\n",d %f\n", p->number,p->name, p->sex,p->age,p->score); p->number,p->name, p->sex,p->age,p->score); p=&s2; p=&s2; printf("%s %s %c printf("%s %s %c %%d %f\n",d %f\n", p->number,p->name, p->sex,p->age,p->score); p->number,p->name, p->sex,p->age,p->score); } } 283283 9.2 9.2 结构体数组结构体数组一一. .结构体数组的定义结构体数组的定义 在定义了结构体类型后,可以定义结构体数组。

      在定义了结构体类型后,可以定义结构体数组 定义结构体数组的格式:定义结构体数组的格式: struct struct 结构体类型名结构体类型名 数组名数组名[ [元素个数元素个数] ];; 例如:语句:例如:语句: struct student s[10]; struct student s[10];定义了一个有定义了一个有1010个元素的个元素的studentstudent类型的数组类型的数组s[]s[],数组的每个,数组的每个元素都是元素都是studentstudent类型的结构体变量也可以在定义结构体类类型的结构体变量也可以在定义结构体类型数组的同时对数组元素初始化型数组的同时对数组元素初始化 在在C C程序中,通过数组元素名程序中,通过数组元素名s[i](i=0s[i](i=0、、1 1、、2 2、、……9)……9)引引用相应的结构体成员用相应的结构体成员 284284【例【例9-59-5】参考例】参考例9-29-2中中studentstudent类型的定义,从键盘输入学生类型的定义,从键盘输入学生 信息,输出学生的姓名和成绩总分。

      信息,输出学生的姓名和成绩总分include#includemain()main(){ { int i; int i; struct score struct score { { int score1; int score1; int score2; int score2; int score3; int score3; }; }; struct student struct student { { char name[10]; char name[10]; char sex; char sex; int age; int age; struct score struct score stscore; stscore; }s[2]; }s[2]; for(i=0;i<2;i++)for(i=0;i<2;i++) { { printf("Please Input name printf("Please Input name and scores\n"); and scores\n"); scanf("%s",s[i].name); scanf("%s",s[i].name); scanf("%d",&s[i].stscore. scanf("%d",&s[i].stscore. score1); score1); scanf("%d",&s[i].stscore. scanf("%d",&s[i].stscore. score2); score2); scanf("%d",&s[i].stscore. scanf("%d",&s[i].stscore. score3); score3); } } for(i=0;i<2;i++) for(i=0;i<2;i++) printf("%s: Total Score is printf("%s: Total Score is %d\n", s[i].name, %d\n", s[i].name, (s[i].stscore.score1+ (s[i].stscore.score1+ s[i].stscore.score2+ s[i].stscore.score2+ s[i].stscore.score3)); s[i].stscore.score3));} } 285285二二. .结构体数组的指针结构体数组的指针 结构体数组的指针就是结构体数组存储区域的首地址。

      可以结构体数组的指针就是结构体数组存储区域的首地址可以用结构体类型的指针变量指向该地址用结构体类型的指针变量指向该地址例如,执行语句:例如,执行语句:struct studentstruct student { { char number[6]; char number[6]; char name[20]; char name[20]; char sex; char sex; int age; int age; int score; int score; }s[5],*p=s; }s[5],*p=s; 后,指针变量后,指针变量p p指向结构体数组指向结构体数组s[]s[]的首地址的首地址 则:则:p p指向指向s[0],p+1s[0],p+1指向指向s[1],p+2s[1],p+2指向指向s[2]……s[2]…… 286286【例【例9-69-6】用指针变量实现例】用指针变量实现例9-59-5的功能。

      的功能 #include#includemain()main() { { int i; int i; struct score struct score { { int score1; int score1; int score2; int score2; int score3; int score3; }; }; struct student struct student { { char name[10]; char name[10]; char sex; char sex; int age; int age; struct score struct score stscore;stscore; }s[2],*p=s; }s[2],*p=s; for(i=0;i<2;i++)for(i=0;i<2;i++) { { printf("Please Input name and printf("Please Input name and scores\n"); scores\n"); scanf("%s",(p+i)->name); scanf("%s",(p+i)->name); scanf("%d",&((p+i)->stscore. scanf("%d",&((p+i)->stscore. score1)); score1)); scanf("%d",&((p+i)->stscore. scanf("%d",&((p+i)->stscore. score2)); score2)); scanf("%d",&((p+i)->stscore. scanf("%d",&((p+i)->stscore. score3)); score3)); } } for(p=s;pname,(p->stscore.score1+ p->name,(p->stscore.score1+ p->stscore.score2+ p->stscore.score2+ p->stscore.score3)); p->stscore.score3)); } }此处的括号此处的括号此处的括号此处的括号不可少不可少不可少不可少 此处的括号此处的括号此处的括号此处的括号不可少不可少不可少不可少 287287 9.3 9.3 结构体与函数结构体与函数 结构体变量、结构体成员和结构体类型的指针变量都能够作结构体变量、结构体成员和结构体类型的指针变量都能够作为形参或实参参与函数调用。

      在函数调用过程中,遵循和基本为形参或实参参与函数调用在函数调用过程中,遵循和基本数据类型变量相同的规则数据类型变量相同的规则例【例9-79-7】通过函数调用实现例】通过函数调用实现例9-59-5的功能 struct score struct score { { int score1; int score1; int score2; int score2; int score3; int score3; }; }; struct student struct student { { char name[10]; char name[10]; char sex; char sex; int age; int age; struct score stscore; struct score stscore; }; }; int total(struct student stud); int total(struct student stud);( (转后转后) )形参为形参为形参为形参为studentstudent类型的类型的类型的类型的结构体变量结构体变量结构体变量结构体变量studstud 288288 main() main() { { int i; int i; struct student s[2]; struct student s[2]; for(i=0;i<2;i++) for(i=0;i<2;i++) { { printf("Please Input name and scores\n"); printf("Please Input name and scores\n"); scanf("%s",s[i].name); scanf("%s",s[i].name); scanf("%d",&s[i].stscore.score1); scanf("%d",&s[i].stscore.score1); scanf("%d",&s[i].stscore.score2); scanf("%d",&s[i].stscore.score2); scanf("%d",&s[i].stscore.score3); scanf("%d",&s[i].stscore.score3); } } for(i=0;i<2;i++) for(i=0;i<2;i++) printf("%s: Total Score is %d\n", printf("%s: Total Score is %d\n", s[i].name,total(s[i])); s[i].name,total(s[i])); } } int total(struct student stud) int total(struct student stud) { { return(stud.stscore.score1+ return(stud.stscore.score1+ stud.stscore.score2+stud.stscore.score3); stud.stscore.score2+stud.stscore.score3); } }( (接前接前) )实参为实参为实参为实参为studentstudent类型的类型的类型的类型的结构体变量结构体变量结构体变量结构体变量s[i]s[i] 289289【例【例【例【例9-89-89-89-8】结构体数组指针参与函数调用的例子。

      结构体数组指针参与函数调用的例子结构体数组指针参与函数调用的例子结构体数组指针参与函数调用的例子 本例程序实现从键盘输入学生学号,经搜索后输出本例程序实现从键盘输入学生学号,经搜索后输出本例程序实现从键盘输入学生学号,经搜索后输出本例程序实现从键盘输入学生学号,经搜索后输出 该学生信息该学生信息该学生信息该学生信息 #include #include #include #include struct student struct student struct student struct student { { { { char number[6]; char number[6]; char number[6]; char number[6]; char name[20]; char name[20]; char name[20]; char name[20]; char sex; char sex; char sex; char sex; int age; int age; int age; int age; int score; int score; int score; int score; }; }; }; }; struct student *search(struct student *pp,int struct student *search(struct student *pp,int struct student *search(struct student *pp,int struct student *search(struct student *pp,int n,char *str); n,char *str); n,char *str); n,char *str);( (转后转后) )指针函数,返回指向指针函数,返回指向指针函数,返回指向指针函数,返回指向studentstudent类型变量的指针类型变量的指针类型变量的指针类型变量的指针 290290main()main()main()main() { { { { struct student s[2]={{"00001", struct student s[2]={{"00001", struct student s[2]={{"00001", struct student s[2]={{"00001", "Peter",'m',19,254},{"00002","Betty", "Peter",'m',19,254},{"00002","Betty", "Peter",'m',19,254},{"00002","Betty", "Peter",'m',19,254},{"00002","Betty", 'f' 'f' 'f' 'f',18,289}},*p;,18,289}},*p;,18,289}},*p;,18,289}},*p; char num[6]; char num[6]; char num[6]; char num[6]; printf("Please Input the Number of Student:\n"); printf("Please Input the Number of Student:\n"); printf("Please Input the Number of Student:\n"); printf("Please Input the Number of Student:\n"); scanf("%s",num); scanf("%s",num); scanf("%s",num); scanf("%s",num); p=search(s,2,num); p=search(s,2,num); p=search(s,2,num); p=search(s,2,num); if(p!=NULL) if(p!=NULL) if(p!=NULL) if(p!=NULL) printf("%s,%s,%c,%d,%d\n",p->number,p->name, printf("%s,%s,%c,%d,%d\n",p->number,p->name, printf("%s,%s,%c,%d,%d\n",p->number,p->name, printf("%s,%s,%c,%d,%d\n",p->number,p->name, p->sex,p->age,p->score); p->sex,p->age,p->score); p->sex,p->age,p->score); p->sex,p->age,p->score); else else else else printf("No Such A Student!\n"); printf("No Such A Student!\n"); printf("No Such A Student!\n"); printf("No Such A Student!\n"); } } } }( (接前接前) )( (转后转后) ) 291291struct student *search(struct student *pp,int struct student *search(struct student *pp,int n,char *str) n,char *str) { { int i; int i; for(i=0;inumber),str)==0) if(strcmp(((pp+i)->number),str)==0) return(pp+i); return(pp+i); else else if(i==n-1) if(i==n-1) return(NULL); return(NULL); } }( (接前接前) )指针变量,指向指针变量,指向指针变量,指向指针变量,指向studentstudent类型数组的指针类型数组的指针类型数组的指针类型数组的指针返回返回返回返回studentstudent类型数组类型数组类型数组类型数组第第第第I I个元素的指针个元素的指针个元素的指针个元素的指针返回空指针返回空指针返回空指针返回空指针 292292第第9章结束章结束       文文 件件第第 10 10 章章2021/8/22293 294294学习目标学习目标1.1.掌握有关掌握有关C C语言文件的基本概念。

      语言文件的基本概念2.2.初步熟悉文件读写函数和文件读写出错初步熟悉文件读写函数和文件读写出错检测函数的使用检测函数的使用 295295主要内容主要内容•C C语言文件概述语言文件概述 •文件读写函数文件读写函数 •文件读写出错检测文件读写出错检测 296296C C语言文件的概念语言文件的概念 C C语言中的文件是指存储在外存储器语言中的文件是指存储在外存储器( (主要是磁盘主要是磁盘) )上的数据上的数据的集合,是按字节顺序排列的数据序列的集合,是按字节顺序排列的数据序列 按文件中数据的组织形式,可以将其分为按文件中数据的组织形式,可以将其分为ASCASC文件文件( (文本文文本文件件) )和二进制文件,它们都以字节为存储单位和二进制文件,它们都以字节为存储单位 文件是文件是C C程序的读、写对象,特别地,程序的读、写对象,特别地,C C语言把键盘、显示语言把键盘、显示器等一些计算机外部设备看作特殊的文件器等一些计算机外部设备看作特殊的文件, , 在在C C语言中,键盘语言中,键盘的文件名为的文件名为“CON:”“CON:”或或“KYBD:” “KYBD:” 显示器的文件名为显示器的文件名为“CON:”“CON:”或或“SCRN:”“SCRN:”。

      10.1 10.1 概述概述 文件的读写文件的读写 所谓读文件就是由文件向内存输入数据,而写文件则是由所谓读文件就是由文件向内存输入数据,而写文件则是由内存向文件输出数据内存向文件输出数据 297297文件的属性文件的属性  在对文件进行读、写操作时,必须知道文件的一些属性,比在对文件进行读、写操作时,必须知道文件的一些属性,比如文件名、文件的状态及文件当前的位置等文件的这些属性如文件名、文件的状态及文件当前的位置等文件的这些属性存放在一个由系统定义的结构体类型变量中,该结构体类型名存放在一个由系统定义的结构体类型变量中,该结构体类型名为为“FILE”“FILE” 在对文件进行读写的过程中,用户通过一个指向在对文件进行读写的过程中,用户通过一个指向FILEFILE类型类型( (文文件类型件类型) )的指针变量实现文件的读、写操作的指针变量实现文件的读、写操作 每一个每一个FILEFILE类型的结构体变量只能存放一个文件的属性,如果类型的结构体变量只能存放一个文件的属性,如果要对多个文件进行读、写操作就必须有多个要对多个文件进行读、写操作就必须有多个FILEFILE类型的结构体类型的结构体变量。

      同时,用户程序中必须为每一个文件定义一个变量同时,用户程序中必须为每一个文件定义一个FILEFILE类型类型的指针变量的指针变量 298298 10.2 10.2 文件的读、写文件的读、写一一. .文件的打开、关闭文件的打开、关闭 C C程序在对文件进行读写操作之前,必须先执行打开文件的操程序在对文件进行读写操作之前,必须先执行打开文件的操作,在读写操作结束之后,必须执行关闭文件的操作作,在读写操作结束之后,必须执行关闭文件的操作 打开文件的操作通过调用打开文件的操作通过调用fopen()fopen()函数完成,关闭文件的操函数完成,关闭文件的操作通过调用作通过调用fclose()fclose()函数完成函数完成调用调用fopen()fopen()函数的格式:函数的格式: FILE *fp FILE *fp;; fp=fopen( fp=fopen(文件名,使用文件方式文件名,使用文件方式) );; 如果调用成功,将返回相应文件的指针,否则,返回空值如果调用成功,将返回相应文件的指针,否则,返回空值NULLNULL。

      定义指向该文件的定义指向该文件的FILEFILE类型的指针变量类型的指针变量 注意:注意: 对于用对于用“w”“w”方式打开的文件只能用于写入,若该文件不存在方式打开的文件只能用于写入,若该文件不存在,则在打开时新建该文件,否则,则在打开该文件时将其删去,,则在打开时新建该文件,否则,则在打开该文件时将其删去,并重新建立以原文件名命名的新文件并重新建立以原文件名命名的新文件如果仅仅希望向原文件中如果仅仅希望向原文件中添加新的内容,必须使用添加新的内容,必须使用“a”“a”方式有有r r、、w w和和a a三种方式三种方式 299299 文件使用方式文件使用方式 功功 能能 "r" ( "r" (只读只读) ) 为输入打开一个文本文件为输入打开一个文本文件 "w" ( "w" (只写只写) ) 为输出打开一个文本文件为输出打开一个文本文件 “a” ( “a” (追加追加) ) 向文本文件尾增补向文本文件尾增补 "rb" ( "rb" (只读只读) ) 为输入打开一个二进制文件为输入打开一个二进制文件 "wb" ( "wb" (只写只写) ) 为输出打开一个二进制文件为输出打开一个二进制文件 “ab” ( “ab” (追加追加) ) 向文本文件尾增补向文本文件尾增补 "r+" ( "r+" (读写读写) ) 为读为读/ /写打开一个文本文件写打开一个文本文件 "w+" ( "w+" (读写读写) ) 为读为读/ /写建立一个新的文本文件写建立一个新的文本文件 "a+" ( "a+" (读写读写) ) 为读为读/ /写打开一个文本文件写打开一个文本文件 "rb+" ( "rb+" (读写读写) ) 为读为读/ /写打开一个二进制文件写打开一个二进制文件 "wb" ( "wb" (读写读写) ) 为读为读/ /写建立一个新的二进制文件写建立一个新的二进制文件 "ab+" ( "ab+" (读写读写) ) 为读为读/ /写打开一个二进制文件写打开一个二进制文件文件使用方式及功能说明文件使用方式及功能说明 300300 以下的程序段为某读写文件程序中的一段:以下的程序段为某读写文件程序中的一段: FILE *fp; FILE *fp; if((fp=fopen("myfile","r"))==NULL) if((fp=fopen("myfile","r"))==NULL) { { printf("Cannot open this file!\n"); printf("Cannot open this file!\n"); exit(0); exit(0); } } 程序定义了一个程序定义了一个FILEFILE类型的指针变量类型的指针变量fpfp,在,在ifif语句中,语句中,fpfp接接收调用收调用fopen()fopen()函数后的返回值。

      调用函数后的返回值调用fopen()fopen()函数时,指定以函数时,指定以只读方式打开文件只读方式打开文件myfilemyfile,若失败,将返回空值,若失败,将返回空值NULLNULL,否则返,否则返回文件回文件myfilemyfile的指针 if if条件语句对打开文件失败的情况作出处理,显示出错信息条件语句对打开文件失败的情况作出处理,显示出错信息并调用并调用exit()exit()函数 exit() exit()函数的作用是关闭所有文件,终止正在运行的程序函数的作用是关闭所有文件,终止正在运行的程序 在使用在使用exit()exit()函数之前,必须将相应的头文件函数之前,必须将相应的头文件stdlib.hstdlib.h包含包含进来 301301调用调用fclose()fclose()函数的格式:函数的格式: fclose( fclose(文件指针变量文件指针变量) );; 调用调用fclose()fclose()函数后,原来的函数后,原来的FILEFILE类型的指针变量类型的指针变量不再指向该文件,程序将无法再通过该指针变量访问不再指向该文件,程序将无法再通过该指针变量访问文件。

      如果在进行文件读写后不执行关闭文件的操作,文件如果在进行文件读写后不执行关闭文件的操作,可能导致相关数据的丢失可能导致相关数据的丢失 302302二二. .读写文件的函数及应用读写文件的函数及应用 C C语言提供了若干函数用于对文件的读写操作在使用前,语言提供了若干函数用于对文件的读写操作在使用前,必须通过必须通过“#include”“#include”命令将头文件命令将头文件stdio.hstdio.h包含进来包含进来1. fputc()1. fputc()函数和函数和fgetc()fgetc()函数函数 fputc()fputc()函数的功能是向文件输出一个字符函数的功能是向文件输出一个字符 调用格式:调用格式:fputc(ch,fp)fputc(ch,fp);; 其中,参数其中,参数chch为待输出的字符变量,为待输出的字符变量,fpfp为指向文件的指针为指向文件的指针变量 如果调用成功,将返回该字符,否则,返回非如果调用成功,将返回该字符,否则,返回非0 0值 fgetc()fgetc()函数的功能是从文件读入一个字符函数的功能是从文件读入一个字符 调用格式:调用格式:ch=fgetc(fp)ch=fgetc(fp);; 其中,参数其中,参数chch为接收所读入字符的字符变量,为接收所读入字符的字符变量,fpfp为指向文为指向文件的指针变量。

      件的指针变量 如果调用成功,将返回读入的字符,否则,返回非如果调用成功,将返回读入的字符,否则,返回非0 0值 303303【例【例10-110-1】函数】函数fputc()fputc()和和fgetc()fgetc()的应用  #include#include #include #include main() main() { { char ch,c[4]={ 'A','B‘ char ch,c[4]={ 'A','B‘ ,'C','D'}; ,'C','D'}; int i; int i; FILE *fp; FILE *fp; if((fp=fopen("c:myfile1“ if((fp=fopen("c:myfile1“ ,"w"))==NULL) ,"w"))==NULL) { { printf("Cannot open printf("Cannot open this file!\n"); this file!\n"); exit(0); exit(0); } } for(i=0;i<4;i++) for(i=0;i<4;i++) fputc(ch,fp); fputc(ch,fp); fclose(fp); fclose(fp); if((fp=fopen("c:myfile1",if((fp=fopen("c:myfile1", "r"))==NULL) "r"))==NULL) { { printf("Cannot open this printf("Cannot open this file!\n"); file!\n"); exit(0); exit(0); } } for(i=0;i<4;i++) for(i=0;i<4;i++) { { ch=fgetc(fp); ch=fgetc(fp); printf("%c\n",ch); printf("%c\n",ch); } } fclose(fp); fclose(fp);} } 3043042. fputs()2. fputs()函数和函数和fgets()fgets()函数函数 fputs()fputs()函数的功能是向文件输出一个字符串。

      函数的功能是向文件输出一个字符串 调用格式:调用格式: fputs(str,fp) fputs(str,fp);; 其中,参数其中,参数strstr为待输出的字符串的指针为待输出的字符串的指针( (或是字符串常量或是字符串常量) ),,fpfp为指向文件的指针变量为指向文件的指针变量 如果调用成功,将返回如果调用成功,将返回0 0,否则,返回非,否则,返回非0 0值 fgets()fgets()函数的功能是从文件读入函数的功能是从文件读入n-1n-1个字符,并将其存放个字符,并将其存放到字符数组到字符数组strstr中如果在第中如果在第n-1n-1个字符之前出现了换行符个字符之前出现了换行符“\n”“\n”或文件结束符或文件结束符EOF(EOF(一个非一个非0 0值值) ),则将换行符,则将换行符“\n”“\n”作为读入的最作为读入的最后一个字符后一个字符 调用格式:调用格式: fgets(str,n,fp) fgets(str,n,fp);; 其中,参数其中,参数strstr为接收所读入字符串的字符数组的指针,为接收所读入字符串的字符数组的指针,fpfp为指向文件的指针变量。

      为指向文件的指针变量 如果调用成功,将返回字符数组的指针如果调用成功,将返回字符数组的指针strstr,否则,返回,否则,返回 NULL NULL 305305【例【例10-210-2】函数】函数fputs()fputs()和和fgets()fgets()的应用 #include#include#include #include main()main() { { char c[20]; char c[20]; FILE *fp; FILE *fp; if((fp=fopen("c:myfile2 if((fp=fopen("c:myfile2 .txt“,"w"))==NULL) .txt“,"w"))==NULL) { { printf("Cannot open printf("Cannot open this file!\n"); this file!\n"); exit(0); exit(0); } } printf("Please Input printf("Please Input a String:\n"); a String:\n"); scanf("%s",c); scanf("%s",c); fputs(c,fp); fputs(c,fp); fclose(fp); fclose(fp);  if((fp=fopen("c:myfile2.if((fp=fopen("c:myfile2. txt","r"))==NULL) txt","r"))==NULL) { { printf(Cannot open this printf(Cannot open this file!\n"); file!\n"); exit(0); exit(0); } } printf("%s\n", printf("%s\n", fgets(c,10,fp)); fgets(c,10,fp)); fclose(fp); fclose(fp);} } 306306 3.fprintf() 3.fprintf()函数和函数和fscanf()fscanf()函数函数( (格式化输入输出函数格式化输入输出函数) ) 将需要读写的文件打开以后,将需要读写的文件打开以后,fprintf()fprintf()函数和函数和fscanf()fscanf()函数的使用方法与函数的使用方法与printf()printf()、、scanf()scanf()相似。

      相似 fprintf()fprintf()函数的调用格式:函数的调用格式: fprintf( fprintf(文件指针,格式字符串,输出表列文件指针,格式字符串,输出表列) );; 【例【例10-310-3】函数】函数fprintf()fprintf()的应用 #include#include#include #include main()main() { { char ch='A'; char ch='A'; int i=100; int i=100; FILE *fp; FILE *fp; if((fp=fopen("c:myfile3" if((fp=fopen("c:myfile3" ,"w"))==NULL) ,"w"))==NULL)  { { printf("Cannot open printf("Cannot open this file!\n"); this file!\n"); exit(0); exit(0); } } fprintf(fp,"%c,%d",ch,i); fprintf(fp,"%c,%d",ch,i); fclose(fp); fclose(fp); } } 307307fscanf()fscanf()函数的调用格式:函数的调用格式: fprintf( fprintf(文件指针,格式字符串,输入表列文件指针,格式字符串,输入表列) );; 【例【例10-410-4】函数】函数fscanf()fscanf()的应用。

      的应用include#include#include #include main()main() { { char ch; char ch; int i; int i; FILE *fp; FILE *fp; if((fp=fopen("c:myfile3","r"))==NULL) if((fp=fopen("c:myfile3","r"))==NULL) { { printf("Cannot open this file!\n"); printf("Cannot open this file!\n"); exit(0); exit(0); } } fscanf(fp,"%c,%d",&ch,&i); fscanf(fp,"%c,%d",&ch,&i); fclose(fp); fclose(fp); printf("ch: %c, i: %d\n",ch,i); printf("ch: %c, i: %d\n",ch,i); } } 3083084 4..fwrite()fwrite()函数和函数和fread()fread()函数函数 fwrite() fwrite()函数和函数和fread()fread()函数用于按数据块来读写文件。

      函数用于按数据块来读写文件 fwrite() fwrite()函数的功能是向文件输出若干数据块的数据函数的功能是向文件输出若干数据块的数据 调用格式:调用格式:fwrite(buffer,size,count,fp)fwrite(buffer,size,count,fp);; 其中,其中,bufferbuffer是一个指针是一个指针( (地址地址) ),是需要输出的数据存,是需要输出的数据存 储区的首地址,储区的首地址,sizesize为一个数据块所占的字节数,为一个数据块所占的字节数,countcount为为 要输出的数据块的个数,要输出的数据块的个数,fpfp为指向文件的指针变量为指向文件的指针变量 如果调用成功,将返回实际写入文件的数据块的个数如果调用成功,将返回实际写入文件的数据块的个数 fread()fread()函数的功能是从文件读入若干数据块的数据函数的功能是从文件读入若干数据块的数据 调用格式:调用格式: fread(buffer,size,count,fp) fread(buffer,size,count,fp);; 其中,其中,bufferbuffer是一个指针是一个指针( (地址地址) ),是读入数据块后,这些,是读入数据块后,这些 数据存储区的首地址,数据存储区的首地址,sizesize为一个数据块所占的字节数,为一个数据块所占的字节数, count count为要读入的数据块的个数,为要读入的数据块的个数,fpfp为指向文件的指针变量。

      为指向文件的指针变量 如果调用成功,将返回实际从文件读出的数据块的个数,如果调用成功,将返回实际从文件读出的数据块的个数, 若遇文件结束或出错,返回若遇文件结束或出错,返回0 0 309309【例【例10-510-5】函数】函数fwrite()fwrite()和和fread()fread()的应用include#include#include#includemain()main() { { struct student struct student { { char number[6]; char number[6]; char name[20]; char name[20]; char sex; char sex; int age; int age; int score; int score; } s[2]={{"00001","Peter",'m',19,250}, } s[2]={{"00001","Peter",'m',19,250}, {"00002","Betty",'f',18,268}}; {"00002","Betty",'f',18,268}}; struct student ss[2]; struct student ss[2];( (转后转后) ) 310310(接前接前) int i,j; int i,j; FILE *fp; FILE *fp; if((fp=fopen("c:myfile4","wb+"))==NULL) if((fp=fopen("c:myfile4","wb+"))==NULL) { { printf("Cannot open this file!\n"); printf("Cannot open this file!\n"); exit(0); exit(0); } } j=sizeof(struct student); j=sizeof(struct student); for(i=0;i<=1;i++) for(i=0;i<=1;i++) if(fwrite(&s[i],j,1,fp)!=1) if(fwrite(&s[i],j,1,fp)!=1) printf("File Write Error!\n"); printf("File Write Error!\n"); rewind(fp); rewind(fp);( (转后转后) )获得结构体类型变量所获得结构体类型变量所占存储区域的大小,以占存储区域的大小,以此作为一个数据块此作为一个数据块使文件指针变量使文件指针变量fpfp的指向的指向回到起始位置回到起始位置使用二进制文件读写方式,使用二进制文件读写方式,方式方式“wb+”“wb+”同时支持对二同时支持对二进制文件的读写操作进制文件的读写操作 311311(接前接前) for(i=0;i<=1;i++) for(i=0;i<=1;i++) { { fread(&ss[i],j,1,fp); fread(&ss[i],j,1,fp); printf("%s ,%s ,%c ,%d, %d\n", printf("%s ,%s ,%c ,%d, %d\n", ss[i].number,ss[i].name,ss[i].sex,ss[i].age, ss[i].number,ss[i].name,ss[i].sex,ss[i].age, ss[i].score); ss[i].score); } } fclose(fp); fclose(fp);} } 3123125 5..fseek()fseek()函数、函数、ftell()ftell()函数和函数和rewind()rewind()函数函数 fseek() fseek()函数、函数、ftell()ftell()函数和函数和rewind()rewind()函数用于实现对文件函数用于实现对文件的随机读写。

      的随机读写 fseek()fseek()函数的功能是使函数的功能是使FILEFILE指针变量指向文件中指定的位置指针变量指向文件中指定的位置 调用格式:调用格式: fseek( fseek(文件类型指针变量名文件类型指针变量名, ,位移量位移量, ,起始点起始点) );; 其中,文件类型指针变量名为指向文件的指针变量,起始点其中,文件类型指针变量名为指向文件的指针变量,起始点用数字表示:用数字表示:0 ─ 0 ─ 文件的开始处;文件的开始处;1 ─ FILE1 ─ FILE指针变量指向的当前位置;指针变量指向的当前位置;2 2─ ─ 文件的末尾位移量以字节数表示,如果其大于文件的末尾位移量以字节数表示,如果其大于0 0,表示,表示3 3从文件头部向文件尾部的方向计字节数,不然,按从文件尾部从文件头部向文件尾部的方向计字节数,不然,按从文件尾部4 4向文件的头部方向计字节数向文件的头部方向计字节数 如果调用如果调用fseekfseek()()函数成功,返回函数成功,返回0 0,否则返回非,否则返回非0 0值 313313ftell()ftell()ftell()ftell()函数的功能是了解函数的功能是了解函数的功能是了解函数的功能是了解FILEFILEFILEFILE指针变量的当前指向。

      指针变量的当前指向指针变量的当前指向指针变量的当前指向 调用格式:调用格式:调用格式:调用格式: ftell( ftell( ftell( ftell(文件类型指针变量名文件类型指针变量名文件类型指针变量名文件类型指针变量名) ) ) );;;; 其中,文件类型指针变量名为文件的指针变量其中,文件类型指针变量名为文件的指针变量其中,文件类型指针变量名为文件的指针变量其中,文件类型指针变量名为文件的指针变量 如果调用如果调用如果调用如果调用ftell()ftell()ftell()ftell()函数成功,返回函数成功,返回函数成功,返回函数成功,返回FILEFILEFILEFILE指针变量当前的指向指针变量当前的指向指针变量当前的指向指针变量当前的指向相对于起始位置的位移量,以字节数表示,否则返回相对于起始位置的位移量,以字节数表示,否则返回相对于起始位置的位移量,以字节数表示,否则返回相对于起始位置的位移量,以字节数表示,否则返回-1-1-1-1 说明:说明:说明:说明: 如果仅仅只是要判断文件指针是否已经指向文件末尾如果仅仅只是要判断文件指针是否已经指向文件末尾如果仅仅只是要判断文件指针是否已经指向文件末尾如果仅仅只是要判断文件指针是否已经指向文件末尾, , , , 可可可可 以直接调用以直接调用以直接调用以直接调用feof(fp)feof(fp)feof(fp)feof(fp)函数。

      如果遇到文件结束函数如果遇到文件结束函数如果遇到文件结束函数如果遇到文件结束, , , ,函数返回函数返回函数返回函数返回1,1,1,1, 否则返回否则返回否则返回否则返回0 0 0 0 rewind() rewind() rewind() rewind()函数的功能是使函数的功能是使函数的功能是使函数的功能是使FILEFILEFILEFILE指针变量重新指向文件的开始指针变量重新指向文件的开始指针变量重新指向文件的开始指针变量重新指向文件的开始位置 调用格式:调用格式:调用格式:调用格式: rewind( rewind( rewind( rewind(文件类型指针变量名文件类型指针变量名文件类型指针变量名文件类型指针变量名);););); 其中,文件类型指针变量名为指向该文件的指针变量其中,文件类型指针变量名为指向该文件的指针变量其中,文件类型指针变量名为指向该文件的指针变量其中,文件类型指针变量名为指向该文件的指针变量rewind()rewind()rewind()rewind()函数调用函数调用函数调用函数调用后无返回值。

      后无返回值后无返回值后无返回值 314314【例【例10-610-6】从上例的文件】从上例的文件myfile4myfile4中直接读出中直接读出s[1]s[1]的信息 #include #include #include #include main() main() { { struct student struct student { { char number[6]; char number[6]; char name[20]; char name[20]; char sex; char sex; int age; int age; int score; int score; } s[2]; } s[2]; ( (转后转后) ) 315315 FILE *fp; FILE *fp; if((fp=fopen("c:myfile4","rb+"))==NULL) if((fp=fopen("c:myfile4","rb+"))==NULL) { { printf("Cannot open this file!\n"); printf("Cannot open this file!\n"); exit(0); exit(0); } } fseek(fp,1* sizeof(struct student),0); fseek(fp,1* sizeof(struct student),0); fread(&s[1], sizeof(struct student),1,fp); fread(&s[1], sizeof(struct student),1,fp); printf("%s ,%s ,%c ,%d, %d\n", printf("%s ,%s ,%c ,%d, %d\n", s[1].number,s[1].name,s[1].sex, s[1].number,s[1].name,s[1].sex, s[1].age,s[1].score); s[1].age,s[1].score); printf("%d\n",ftell(fp)); printf("%d\n",ftell(fp)); fclose(fp); fclose(fp); } } (接前接前)使文件指针变量指向使文件指针变量指向s[0]s[0] 的位置。

      若要其指向的位置若要其指向s[1]s[1]则需要从当前位置向尾部则需要从当前位置向尾部移动一个数据块移动一个数据块 316316三三. .文件读写中的出错检测文件读写中的出错检测 在使用各种函数对文件进行读写操作时,可以借助调用函数在使用各种函数对文件进行读写操作时,可以借助调用函数后的返回值判断函数调用的成功与否此外,后的返回值判断函数调用的成功与否此外,C C语言还提供二个语言还提供二个函数函数ferror()ferror()和和clearerr()clearerr(),用以对文件读写操作过程中的出,用以对文件读写操作过程中的出错情况进行检测错情况进行检测 ferror() ferror()函数用于在调用输入、输出函数以后,立即检查调函数用于在调用输入、输出函数以后,立即检查调用的结果,如果用的结果,如果ferror()ferror()的返回值为的返回值为0 0,表示调用输入、输出,表示调用输入、输出函数成功,否则表示出错函数成功,否则表示出错 ferror() ferror()函数的调用格式:函数的调用格式: ferror(fp) ferror(fp);; 其中其中fpfp为指向文件的指针变量为指向文件的指针变量 clearerr() clearerr()函数用于清除文件错误标志并置文件结束标志为函数用于清除文件错误标志并置文件结束标志为0 0。

      在调用在调用ferror()ferror()函数以后,如果出现调用输入、输出函数错函数以后,如果出现调用输入、输出函数错误,将返回一个非误,将返回一个非0 0值作为错误标志,只有对同一文件调用值作为错误标志,只有对同一文件调用clearerr()clearerr()函数或函数或rewind()rewind()函数,或再次调用输入、输出函数函数,或再次调用输入、输出函数才能清除该标志才能清除该标志 clearerr()clearerr()函数的调用格式:函数的调用格式: clearerr(fp) clearerr(fp);; 其中其中fpfp为指向文件的指针变量为指向文件的指针变量 317317第第1010章章 结束结束       。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.