计算导论与程序设计:chap6一维数组_第1页
计算导论与程序设计:chap6一维数组_第2页
计算导论与程序设计:chap6一维数组_第3页
计算导论与程序设计:chap6一维数组_第4页
计算导论与程序设计:chap6一维数组_第5页
已阅读5页,还剩101页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 1 第六章第六章 数组数组 内容取自:内容取自:C Primer Plus(第五版)中文版(第五版)中文版 6.11 数组数组 10.1 数组数组 2 6.1 总结与回顾(数据类型与程序设计)总结与回顾(数据类型与程序设计) 6.2 数组作为一种复杂数据类型数组作为一种复杂数据类型 6.3 数组的声明、操作和使用数组的声明、操作和使用 6.4 数组作为函数参数的处理数组作为函数参数的处理 6.5 数组的应用(排序、查找和应用)数组的应用(排序、查找和应用) 提纲提纲 3 1高级语言的基本能力高级语言的基本能力 简单数据类型(整型简单数据类型(整型/实型实型/字符型)字符型) 程序控制结构(顺

2、序程序控制结构(顺序/分支分支/循环、子程序调循环、子程序调 用)用) 2算法与算法设计的基本方法算法与算法设计的基本方法 算法是求解问题的基本思路和步骤。算法是求解问题的基本思路和步骤。 采用自顶向下采用自顶向下/逐步求精的算法设计方法。逐步求精的算法设计方法。 3数据类型数据类型(数据结构数据结构)+算法算法=程序程序 6.1 总结与回顾总结与回顾 4 4数据类型的内涵(三要素)数据类型的内涵(三要素) 数据的抽象(定义,逻辑结构)数据的抽象(定义,逻辑结构) n整数整数/实数实数/字符等是对客观世界事物(数字符等是对客观世界事物(数 据)的抽象,逻辑表达。据)的抽象,逻辑表达。 数据的存

3、储空间(范围,存储结构)数据的存储空间(范围,存储结构) n长整型、短整形、浮点数、字符等数据长整型、短整形、浮点数、字符等数据 所分配的存储空间各不相同。所分配的存储空间各不相同。 数据的操作数据的操作 n算术、逻辑、关系运算。算术、逻辑、关系运算。 6.1 总结与回顾总结与回顾 5 5求解问题的局限:求解问题的局限: 数据抽象的局限数据抽象的局限 n很多客观世界的事物很难抽象到简单很多客观世界的事物很难抽象到简单 的数据类型上。比如:数列或级数的的数据类型上。比如:数列或级数的 抽象。抽象。 存储能力的局限存储能力的局限 处理能力的局限处理能力的局限 n比如对任意数列的排序和查找问题,比如

4、对任意数列的排序和查找问题, 依照目前的能力尚不能够进行处理。依照目前的能力尚不能够进行处理。 解决上述问题的基本思路:解决上述问题的基本思路: 增强数据的表达、存储和处理能力。增强数据的表达、存储和处理能力。 6.1 总结与回顾总结与回顾 6 6.1 总结与回顾(数据类型与程序设计)总结与回顾(数据类型与程序设计) 6.2 数组作为一种复杂数据类型数组作为一种复杂数据类型 6.3 数组的声明、操作和使用数组的声明、操作和使用 6.4 数组作为函数参数的处理数组作为函数参数的处理 6.5 数组的应用(排序、查找和应用)数组的应用(排序、查找和应用) 提纲提纲 7 6.2 数组作为一种复杂数据类

5、型数组作为一种复杂数据类型 引入数组是为了增强对复杂数据的引入数组是为了增强对复杂数据的抽象和表达 能力、存储能力、操作能力。比如某个班学生。比如某个班学生 的成绩、候选人的计票、每天的温度等。的成绩、候选人的计票、每天的温度等。 数组是一种基于简单数据类型构造而成的复杂数组是一种基于简单数据类型构造而成的复杂 数据类型,因此需要了解:数据类型,因此需要了解: 数组的表达对象(数据的抽象)数组的表达对象(数据的抽象) 数组的存储结构数组的存储结构 数组的操作数组的操作 8 6.2 数组作为一种复杂数据类型数组作为一种复杂数据类型 1. 数组的表达对象数组的表达对象 现实世界经常存在这样的数据:

6、某课程一个班级中按现实世界经常存在这样的数据:某课程一个班级中按 学号排列的各个学生考试成绩、一年中各月份的平均学号排列的各个学生考试成绩、一年中各月份的平均 温度温度其特点是这有限个数据元素的类型相同,且其特点是这有限个数据元素的类型相同,且 具有先后顺序关系;具有先后顺序关系; 上述特征的数据可以抽象为上述特征的数据可以抽象为线性表。 线性表是具有相同数据类型的是具有相同数据类型的n(n=0)个数据元素的有个数据元素的有 限序列,通常记为:限序列,通常记为: (a1,a2, ai-1,ai,ai+1, an) 其中其中n为表长,为表长,n0时称为空表。时称为空表。 线性表数据元素之间为线性

7、关系,通俗讲就是线性表数据元素之间为线性关系,通俗讲就是“一个一个 接一个的排列接一个的排列”。 数组是线性表的一种存储结构。 9 2. 数组是一组数组是一组连续的存储单元(存储结构)的存储单元(存储结构) 连续的含义:这些存储单元的含义:这些存储单元位置相邻位置相邻(一个(一个 接一个),可以容纳多个具有接一个),可以容纳多个具有相同数据类型相同数据类型 的数据元素的数据元素(数据项数据项),这些数据元素,这些数据元素具有相同具有相同 的名字的名字 存储位置的相邻性体现了存储位置的相邻性体现了 线性表数据元素之间的线性表数据元素之间的 相邻性。相邻性。 6.2 数组作为一种复杂数据类型数组作

8、为一种复杂数据类型 数组名(数组中的所有元素具有相同的名字数组名(数组中的所有元素具有相同的名字c) 10 3. 数组元素的访问(操作)数组元素的访问(操作) 数组名元素序号。其中元素序号又称下标。其中元素序号又称下标。 注意:第一个元素的序号为注意:第一个元素的序号为0,因此,因此c0引用数组引用数组c 的第一个元素。的第一个元素。ci-1引用第引用第i个元素。个元素。 6.2 数组作为一种复杂数据类型数组作为一种复杂数据类型 数组名数组名 元素下标元素下标 11 (3.续)下标运算符续)下标运算符“ ”(数组操作)(数组操作) 在赋值语句在赋值语句右边右边时,该操作从数组时,该操作从数组

9、元素中检索数据;元素中检索数据; 例:例:x=c1;/读取下标为读取下标为1的数组的数组 元素的值,赋给变量元素的值,赋给变量x; 在左边时,指对数组元素的赋值。在左边时,指对数组元素的赋值。 例:例:c2=x*3+5;/将赋值表达式右将赋值表达式右 边的值赋给下标为边的值赋给下标为2的数的数 组元素组元素 6.2 数组作为一种复杂数据类型数组作为一种复杂数据类型 切记:数组是一种存储结构。 12 6.1 总结与回顾(数据类型与程序设计)总结与回顾(数据类型与程序设计) 6.2 数组作为一种复杂数据类型数组作为一种复杂数据类型 6.3 数组的声明、操作和使用数组的声明、操作和使用 6.3.1

10、数组的声明数组的声明 6.3.2 数组的初始化数组的初始化 6.3.3 数组逐元素操作数组逐元素操作 6.3.4 字符数组字符数组 6.4 数组作为函数参数的处理数组作为函数参数的处理 6.5 数组的应用(排序、查找和应用)数组的应用(排序、查找和应用) 提纲提纲 C语言中如何使用数组呢? 13 一、数组的声明:一、数组的声明: (C99标准之前标准之前) 语法格式:语法格式:元素类型名元素类型名 数组名数组名整型整型常量常量表达式表达式; 元素类型名元素类型名 可以是整型、字符型、浮点型、结构和指针。可以是整型、字符型、浮点型、结构和指针。 常量表达式常量表达式说明数组元素的个数,运算结果必

11、须为整型。说明数组元素的个数,运算结果必须为整型。 6.3.1 数组的声明数组的声明 2000H 200CH 2008H 2004H score0 存储空间存储空间 score1 score2 score3 例如:例如: main() int score4; 或者或者 #define SIZE 4 main() int scoreSIZE; 6.3.1 数组的声明数组的声明 一、数组的声明:一、数组的声明:(C99标准) 允许声明变长数组 元素类型名元素类型名 数组名数组名整型表达式整型表达式; int n; scanf(%d, int scoren;/数组长度为变量 14 15 1. 数组中

12、各元素的类型相同;数组中各元素的类型相同; 2. C语言中数组下标语言中数组下标从从0开始开始,score0表表 示第示第1个数组元素,个数组元素,scorei表示第表示第i+1个数个数 组元素组元素(i是变量是变量)。 3. 允许在同一个类型说明中,说明多个数允许在同一个类型说明中,说明多个数 组和多个变量。例如:组和多个变量。例如: int num, students150, score4; 但注意数组名不能和其他变量名相同。但注意数组名不能和其他变量名相同。 6.3.1 数组的声明数组的声明 2000H 200CH 2008H 2004H score0 存储空间存储空间 score1 s

13、core2 score3 数组元素的引用: 数组名下标,如score0; 下标必须是整数或者整数表达式。注意:表 达式中的操作数可以是常量、变量、函数调用 或表达式。 16 6.3.2 数组的初始化数组的初始化 二二. 数组的初始化数组的初始化 C语言中可利用声明语句对数组元素的值进行初始化语言中可利用声明语句对数组元素的值进行初始化: 元素类型名元素类型名 数组名数组名 整型表达式整型表达式=值,值值,值值值 ; 例如:例如: int score4=65, 78, 54, 91; 数组初始化是在编译阶段数组初始化是在编译阶段 进行的。这样将减少运行进行的。这样将减少运行 时间,提高效率。时间

14、,提高效率。 2000H 2004H 2002H 2005H 2007H 2006H 2003H 2001H score0 存储空间存储空间 score1 score2 score3 65 78 54 91 17 6.3.2 数组的初始化数组的初始化 例如:例如:int score4=80; 2000H 2004H 2002H 2005H 2007H 2006H 2003H 2001H score0 存储空间存储空间 score1 score2 score3 80 0 0 0 注意注意:整型数组各元素不:整型数组各元素不 会自动初始化为会自动初始化为0,只有对,只有对 多个元素(可以为零个)多

15、个元素(可以为零个) 进行初始化赋值后,进行初始化赋值后,才能才能 使剩下的元素自动初始化使剩下的元素自动初始化 为为0。 18 6.3.2 数组的初始化数组的初始化 float score4=85.5; 19 6.3.2 数组的初始化数组的初始化 3. 如果初始化元素个数大于数组长度,则编译会报如果初始化元素个数大于数组长度,则编译会报 错,例如:错,例如: int score4=65, 78, 54, 91,60; 4. 如果在声明带有初始化值列表的数组时省略数组如果在声明带有初始化值列表的数组时省略数组 的大小,那么数组元素的个数就是初始化值列表的大小,那么数组元素的个数就是初始化值列表

16、 中的元素个数。中的元素个数。 int score=65, 78, 54, 91,60;/score有有5个元素个元素 5. C99新特性:新特性:在初始化列表中使用带有方括号在初始化列表中使用带有方括号 的元素下标可以初始化某个特定的元素的元素下标可以初始化某个特定的元素 int score=4=60;/把把score4初始化为初始化为60 int daysMONTHS=31,28,4=31,30,31,1=29; /days元素依次为:元素依次为:31,29,0,0,31,30,31,0,0,0,0,0 20 21 6.3.3 数组的逐元素操作数组的逐元素操作 数组元素和普通的基本类型变量

17、一样,对基本数组元素和普通的基本类型变量一样,对基本 类型变量的所有操作类型变量的所有操作(读、赋值、取地址等读、赋值、取地址等)同同 样适用于数组元素,基本变量能出现的地方数样适用于数组元素,基本变量能出现的地方数 组元素也可以出现。组元素也可以出现。 6.3.3 数组的逐元素操作数组的逐元素操作 C语言规定数组元素不能整体引用,每次只能语言规定数组元素不能整体引用,每次只能 引用数组的一个元素。例如,不能用赋值运算引用数组的一个元素。例如,不能用赋值运算 对数组进行整体赋值。因为在对数组进行整体赋值。因为在C语言中,语言中,数组数组 名具有特殊含义,它代表数组的首地址名具有特殊含义,它代表

18、数组的首地址。 int a5; a = 1,2,3,4,5;/错误错误 22 23 三、数组的逐元素操作:三、数组的逐元素操作: 例例1:读入:读入10个分数然后进行处理个分数然后进行处理 请同学们体会下标运算符的使用,以及数组元素请同学们体会下标运算符的使用,以及数组元素 的值和数组元素下标的区别。的值和数组元素下标的区别。 6.3.3 数组的逐元素操作数组的逐元素操作 #include #define SIZE 10 #define PAR 72 int main(void) int index, scoreSIZE; int sum = 0; float average; printf(

19、Enter %d golf scores:n, SIZE); for (index = 0; index SIZE; index+) scanf(%d, / read in the ten scores 24 PrimerP141 定义常量定义常量SIZE,用于表示数组长度,用于表示数组长度, 便于程序的阅读和修改。便于程序的阅读和修改。 注意书写习惯:常量名全部大写,注意书写习惯:常量名全部大写, 变量名小写变量名小写 6.3.3 数组的逐元素操作数组的逐元素操作 printf(The scores read in are as follows:n); for (index = 0; ind

20、ex SIZE; index+) printf(%5d, scoreindex); / verify input printf(n); for (index = 0; index SIZE; index+) sum += scoreindex; / add them up average = (float) sum / SIZE; / time-honored method printf(Sum of scores = %d, average = %.2fn, sum, average); printf(Thats a handicap of %.0f.n, average - PAR); r

21、eturn 0; 25 6.3.3 数组的逐元素操作数组的逐元素操作 26 6.3.3 数组的逐元素操作数组的逐元素操作 注意注意越界控制越界控制:不要引用超出数组范围的数组元素。出:不要引用超出数组范围的数组元素。出 于执行速度的考虑,系统运行时不会自动检测元素下标于执行速度的考虑,系统运行时不会自动检测元素下标 是否越界,因此编写程序时要格外小心,由编程人员自是否越界,因此编写程序时要格外小心,由编程人员自 己确保对元素的正确引用,以免因下标越界对其他存储己确保对元素的正确引用,以免因下标越界对其他存储 单元中数据造成破坏。单元中数据造成破坏。 如:如: int score4=65, 78

22、, 54, 91; printf(“%d”, score4); /*编译编译 不会报错,但是输出结果是未不会报错,但是输出结果是未 知的知的*/ 2000H 2004H 2002H 2005H 2007H 2006H 2003H 2001H score0 存储空间存储空间 score1 score2 score3 65 78 54 91 ? 2009H 2008H 27 6.3.3 数组的逐元素操作数组的逐元素操作 例例3. 40位学生为餐厅打分,分数分为位学生为餐厅打分,分数分为110的的10个等个等 级,要求统计出各个分值的打分人数;级,要求统计出各个分值的打分人数; 分析:分析: 40个

23、学生的打分分值构成了一个线性表,可以个学生的打分分值构成了一个线性表,可以 用一个长为用一个长为40的整型数组来存放;的整型数组来存放; int response40 假设假设ai代表分值为代表分值为i的票数,则的票数,则(a1,a2,a10)构成构成 一个线性表,可以用一个长度为一个线性表,可以用一个长度为10的整型数组的整型数组 来存放。来存放。int frequency10 #include #define RESPONSE_SIZE 40 #define FREQUENCY_SIZE 11 int main(void) int responseRESPONSE_SIZE; /存放学生评

24、分存放学生评分 int frequencyFREQUENCY_SIZE=0;/*存放存放110之间各之间各 种等级分值的统计票数种等级分值的统计票数*/ int answer,rating; for(answer=0;answerRESPONSE_SIZE;answer+) scanf(%d,/读取打分读取打分 28 6.3.3 数组的逐元素操作数组的逐元素操作 for(answer=0;answerRESPONSE_SIZE;answer+) +frequencyresponseanswer;/统计统计 for(rating=1;ratingFREQUENCY_SIZE;rating+) p

25、rintf(%d-%dn,rating,frequencyrating);/输出结果输出结果 return 0; 29 6.3.3 数组的逐元素操作数组的逐元素操作 30 1.int responseRESPONSE_SIZE 存放存放40个学生的评分个学生的评分 int frequencyFREQUENCY_SIZE 存放存放110之间各之间各 种等级分值的统计票数种等级分值的统计票数 2.responseanswer 某个学生的评分值,取值为某个学生的评分值,取值为110 3.frequencyrating 某一分值的统计结果某一分值的统计结果 4.+frequencyresponsean

26、swer 根据某个学生的评分根据某个学生的评分 值将该分值的统计结果加值将该分值的统计结果加1。 5.为什么要将为什么要将FREQUENCY_SIZE定义为定义为11呢?呢? “将数组的下标值与评分值对应将数组的下标值与评分值对应”。使用。使用 frequency1frequency10 6.3.3 数组的逐元素操作数组的逐元素操作 31 四、字符数组(字符串)四、字符数组(字符串) 假设有一个字符串假设有一个字符串“firstfirst”,能否用一个变量存,能否用一个变量存 放?放? 在语言中没有专门的字符串变量。通常用一个在语言中没有专门的字符串变量。通常用一个 字符数组来存放一个字符串字

27、符数组来存放一个字符串, ,并以字符并以字符00作为作为 字符串的结束符。字符串的结束符。0对应的对应的ASCII码为码为0。 在声明一个容纳字符串的字符数组时,数组的大在声明一个容纳字符串的字符数组时,数组的大 小应足以容纳字符串中的字符以及字符串结束符小应足以容纳字符串中的字符以及字符串结束符 00。 6.3.4 字符数组字符数组 32 字符数组初始化字符数组初始化 三种方式:三种方式: 也可写为:也可写为: 或去掉或去掉写为:写为: 内存中存放形式为:内存中存放形式为: 后两种初始化情况中,后两种初始化情况中,00是系统自动加上的。是系统自动加上的。 上述声明中没有指定数组的长度,编译器

28、会根据字符串上述声明中没有指定数组的长度,编译器会根据字符串 的长度来确定数组的长度(字符串长度的长度来确定数组的长度(字符串长度+1+1)。)。 6.3.4 字符数组字符数组 33 注意:对一个字符数组,如果不作初始化赋值,注意:对一个字符数组,如果不作初始化赋值, 则则必须必须说明数组长度说明数组长度, ,否则编译出错否则编译出错! ! 在采用字符串方式后,字符数组的输入输出有以下在采用字符串方式后,字符数组的输入输出有以下 几种方式:几种方式: 1.1.定义字符数组时进行初始化。定义字符数组时进行初始化。 2.2.使用循环语句逐个地输入、输出每个字符。使用循环语句逐个地输入、输出每个字符

29、。 3.3.用用printfprintf函数函数/scanf/scanf函数、函数、getsgets函数函数/puts/puts函数一函数一 次性输出、输入一个字符数组中的所有字符。次性输出、输入一个字符数组中的所有字符。 6.3.4 字符数组字符数组 34 用用printfprintf函数和函数和scanfscanf函数一次性输出、函数一次性输出、 输入一个字符数组中的所有字符输入一个字符数组中的所有字符 void main()void main() char char stst200;200; printfprintf(input string:n);(input string:n); s

30、canfscanf( (“%s%s”, ,stst); ); / /* *注意注意: :是是stst而不是而不是 ); / /* *注意:转换说明符是注意:转换说明符是%s%s* */ / scanfscanf函数读取用户键入的字符到字符数组,直到遇到函数读取用户键入的字符到字符数组,直到遇到空空 格、格、制表符制表符、回车、或文件结束符(、回车、或文件结束符(EOFEOF)为止。为止。空格空格、 制表符制表符、回车或文件结束符被丢弃,最后一个字符读入回车或文件结束符被丢弃,最后一个字符读入 后往字符数组中写入结束符后往字符数组中写入结束符00。 PrintfPrintf输出时输出时 00不输

31、出。不输出。 注意:注意:scanfscanf不关心字符数组的大小,所以它往数组中写不关心字符数组的大小,所以它往数组中写 字符时,所写入的字符可能超出数组的范围。程序员必字符时,所写入的字符可能超出数组的范围。程序员必 须自己控制。须自己控制。 35 input string: aaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaa请按任意键继续. . . 遇空遇空 格结格结 束读束读 取取 a a a a a0 input string: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

32、aaaa a aaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa a aaaaaaaaaaaaa请按任意键继续. . . 遇回遇回 车结车结 束读束读 取取 6.3.4 字符数组字符数组 36 scanf(scanf(“%s%s”, , /); /* *将输入存放到字符数将输入存放到字符数 组第二个单元起的连续单元中组第二个单元起的连续单元中* */ / printf( printf(“%s%s”,/);/* *输出字符数组中从第输出字符数组中从第 二个字符开始的所有字符。二个字符开始的所有字符。注意必须有注意必须

33、有 从标准输入设备(如键盘)读取字符到从标准输入设备(如键盘)读取字符到s所指向的所指向的 数组中,直到读到文件末尾或者新行符数组中,直到读到文件末尾或者新行符n。 新行符从键盘缓冲区中丢弃,新行符从键盘缓冲区中丢弃,最后一个字符读入最后一个字符读入 后写入一个后写入一个 0。若成功则返回。若成功则返回s,若无字符读,若无字符读 入数组或者读取失败返回空指针入数组或者读取失败返回空指针NULL。 int puts(const char * s); 将将s所指向的字符串输出到标准输出设备(如显示所指向的字符串输出到标准输出设备(如显示 器),并在输出中添加一个新行符器),并在输出中添加一个新行符

34、n 。终止。终止 字符串的字符串的 0不被输出。不被输出。 38 6.3.4 字符数组字符数组 void main() char st15; printf(input string:n); gets(st); /读一行字符读一行字符 puts(st);/写一行字符写一行字符 system(pause); return 0; input string: hello hello 请按任意键继续. . . h e l lo0 39 6.3.4 字符数组字符数组 scanfscanf和和getsgets在读取一行数据时的区别:在读取一行数据时的区别: main()main() char str10;

35、gets(str); if (str0=0) printf(is null); system(pause); is null请按任意键继续请按任意键继续. . . 使用使用gets,若只是输入回车,则,若只是输入回车,则 未读取任何字符到数组。未读取任何字符到数组。 0 40 6.3.4 字符数组字符数组 main()main() char str10; scanf(%s,str); if (str0=n) printf(is enter); else if (str0=0) printf(is null); system(pause); 使用使用scanf,若只是输入回车,若只是输入回车 或

36、者空格,则程序一直在等或者空格,则程序一直在等 待,直到输入一个非回车、待,直到输入一个非回车、 非空格字符。非空格字符。 即:即:scanf无法实现空行的读无法实现空行的读 取!取! W 请按任意键继续. . . 41 printfprintf和和putsputs在输出一行数据时的区别:在输出一行数据时的区别: puts在输出字在输出字 符数组内容之后还会额外输出一个换行符,而符数组内容之后还会额外输出一个换行符,而printf不不 会。会。 main() char str50=hello world; puts(str); printf(%s,str); system(pause); he

37、llo world hello world请按任意键继续. . . 42 字符数组的特点总结:字符数组的特点总结: 1、字符数组用来存放字符串,以、字符数组用来存放字符串,以0作为字符串的结束字作为字符串的结束字 符。符。 2、由于、由于0,字符数组实际能存放的其他字符个数比数组,字符数组实际能存放的其他字符个数比数组 长度少长度少1;且在处理字符数组时,既可以用;且在处理字符数组时,既可以用数组的长度数组的长度也可也可 以用以用0来判断字符串是否结束。来判断字符串是否结束。 3、对字符数组输入输出时,除了用循环语句逐个地对数组、对字符数组输入输出时,除了用循环语句逐个地对数组 元素进行输入输

38、出之外,还元素进行输入输出之外,还可用可用scanf/printfscanf/printf函数、函数、 gets/putsgets/puts函数进行一次性函数进行一次性整体输入输出整体输入输出; 4、1)初始化字符串时,如果是逐个字符的赋值,)初始化字符串时,如果是逐个字符的赋值,2)使用)使用 循环结构逐个对字符数组元素赋值时,当赋值结束时,程序循环结构逐个对字符数组元素赋值时,当赋值结束时,程序 员必须将员必须将0赋值给字符数组。赋值给字符数组。 6.3.4 字符数组字符数组 43 6.3.4 字符数组字符数组 练习练习2:从键盘读取:从键盘读取 一个长度不超过一个长度不超过50的字符串(

39、以的字符串(以 结束)存放到一个字符数组中,然后将字符串逆序,结束)存放到一个字符数组中,然后将字符串逆序, 并输出。并输出。 如输入为:如输入为:“hello world”,则输出为:,则输出为: dlrow olleh. 问题分析:问题分析: 实现逆序的手段是第实现逆序的手段是第i个元素和倒数第个元素和倒数第i个元素个元素ax交换。交换。 交换次数:交换次数:len/2次(次(len为字符串长度),故为字符串长度),故 i的变化的变化 范围是:范围是:0 len/2-1 ai与与ax交换,则由交换,则由 i-0=len-1-x,得,得x=len-1-i 0i len-1x 44 字符数组逆

40、序字符数组逆序 #include main() char string50,ch; int pos, i, len; /从键盘读取字符串到字符数组中,直到结束符从键盘读取字符串到字符数组中,直到结束符#, pos=0; scanf(%c, while(ch!=#) stringpos=ch; pos+; scanf(%c, stringpos=0;/字符串结束符字符串结束符 45 字符数组逆序字符数组逆序 /输出字符数组输出字符数组 printf(the original string is:%sn,string); /将字符数组中的元素逆序,并输出将字符数组中的元素逆序,并输出 len =

41、pos;/字符数组中有效字符的个数,不包括字符数组中有效字符的个数,不包括0 for(i=0;i=len/2-1;i+) /交换交换 stringi和和 stringlen-1-i ch=stringi; stringi=stringlen-1-i; stringlen-1-i=ch; /输出逆序后的字符数组输出逆序后的字符数组 printf(the string after converse is:%sn,string); 46 字符数组逆序字符数组逆序 /输出逆序后的字符数组输出逆序后的字符数组 :逐个字符输出逐个字符输出 printf(the string after converse

42、is:); pos = 0; while (stringpos!=0) printf(%c,stringpos); pos+; system(pause); return 0; 47 6.1 总结与回顾(数据类型与程序设计)总结与回顾(数据类型与程序设计) 6.2 数组作为一种复杂数据类型数组作为一种复杂数据类型 6.3 数组的声明、操作和使用数组的声明、操作和使用 6.4 数组作为函数参数的处理数组作为函数参数的处理 6.5 数组的应用(排序、查找和应用)数组的应用(排序、查找和应用) 提纲提纲 48 数组用作函数参数有两种形式,数组用作函数参数有两种形式, 1 1、将、将数组元素数组元素(

43、 (下标变量下标变量) )作为实参传递给函数;作为实参传递给函数; 2 2、将、将数组名数组名作为实参传递给函数,目的是让被调作为实参传递给函数,目的是让被调 用函数能访问、操作该数组。用函数能访问、操作该数组。 数组名实际上是数组的首元素地址数组名实际上是数组的首元素地址 int main(void) char array5; printf(array = %p 6.4 数组作为函数参数的处理数组作为函数参数的处理 array = FFF0 函数调用函数调用:y= modifyElement (a3); 51 二、二、将将数组名数组名作为函数的实参作为函数的实参 目的:数组名作为函数的实参时

44、,传递的是数组的首地址目的:数组名作为函数的实参时,传递的是数组的首地址 (第一个元素的地址)。(第一个元素的地址)。使得被调用函数能够访问、操使得被调用函数能够访问、操 作原数组!作原数组! 方法:方法:要求形参和相对应的实参都必须是类型相同的数组,要求形参和相对应的实参都必须是类型相同的数组, 都必须有明确的数组说明,此时都必须有明确的数组说明,此时被调函数实际操作的是被调函数实际操作的是 原数组原数组。同时,通常要将数组的大小传递给函数。同时,通常要将数组的大小传递给函数。 机理:将数组名作为实参传递给函数,函数就获得了数组机理:将数组名作为实参传递给函数,函数就获得了数组 的的首地址首

45、地址,根据首地址能计算出原数组各个元素的内存根据首地址能计算出原数组各个元素的内存 地址,从而访问这些数组元素地址,从而访问这些数组元素。 6.4 数组作为函数参数的处理数组作为函数参数的处理 52 a首地址首地址主调函数主调函数 被调函数被调函数 实参实参a(数组名)(数组名) 形参形参b 调用时调用时 实参实参a 形参形参b 执行被调函数执行被调函数 a首地址首地址 a首地址首地址 实参实参a 形参形参b 从被调函数返回从被调函数返回 修改修改 已改变已改变 数组数组a a首地址首地址 a首地址首地址 a首地址首地址 1 22 4 2 4 void modifyArray(int b,in

46、t size) int j; for (j=0;j=size-1;j+) bj*=2; 函数调用:函数调用:y= modify(a, SIZE); 如果函数要接收一个数组进行处如果函数要接收一个数组进行处 理,则形参中必须有一个是同理,则形参中必须有一个是同 类型的数组,如类型的数组,如int b,用于,用于 接收调用函数中数组的首地址。接收调用函数中数组的首地址。 通常还要设计一个形参用于接通常还要设计一个形参用于接 收数组的大小,如收数组的大小,如int size。 形参的形参的“ ”中不必包含数组大中不必包含数组大 小;如果包括了,编译器会将小;如果包括了,编译器会将 其忽略掉。同理:函

47、数原型其忽略掉。同理:函数原型 bj的内存地址是:b+j*sizeof(int) aj的内存地址是:a+j*sizeof(int) 而a和b的值相等,所以aj和bj 是同一个元素 #include #define SIZE 5 void modifyArray(int ,int);/*函数原型中数组类型的参数,函数原型中数组类型的参数, 中不必包含数组的长度中不必包含数组的长度*/ void modifyElement(int); main() int aSIZE=0,1,2,3,4; int i; printf(Effects of passing entire array call by

48、reference:n The value of the original array are :nn); 53 6.4 数组作为函数参数的处理数组作为函数参数的处理 for(i=0; i=SIZE-1; i+) printf(%3d,ai); modifyArray(a,SIZE);/*数组名称作为实参数组名称作为实参,以传引用方式传以传引用方式传 递数组递数组a*/ printf(nThe value of the modifed array are :n); for(i=0; i=SIZE-1; i+) printf(%3d,ai); printf(nnEffects of passin

49、g array element call by value:nn the value of a3 is %d n,a3); modifyElement(a3); 54 6.4 数组作为函数参数的处理数组作为函数参数的处理 printf(The value of a3 is %d,a3); return 0; 55 6.4 数组作为函数参数的处理数组作为函数参数的处理 /*数组作为函数形参,数组作为函数形参,中不必包含数组的长度,如果包括了中不必包含数组的长度,如果包括了 ,编译器会将其忽略掉;,编译器会将其忽略掉; 将数组传递给函数时,通常要将数将数组传递给函数时,通常要将数 组的大小传递给函

50、数组的大小传递给函数*/ void modifyArray(int b,int size) int i; for(i=0; i=size-1; i+) bi*=2; void modifyElement(int e) printf(Value in modify element is %dn,e*=2); 56 6.4 数组作为函数参数的处理数组作为函数参数的处理 57 函数定义:函数定义:void modifyArray( int b, int size) /*数组作为函数形参,数组作为函数形参,中不必包含数组的长度,如果中不必包含数组的长度,如果 包括了,编译器会将其忽略掉;包括了,编译器

51、会将其忽略掉; 将数组传递给函数时,将数组传递给函数时, 通常要将数组的大小传递给函数通常要将数组的大小传递给函数*/ 函数原型:函数原型:void modifyArray( int , int); /*函数原型中数组类型的参数,函数原型中数组类型的参数,中不必包含数组的长中不必包含数组的长 度度*/ 函数调用:函数调用: modifyArray( a, SIZE); /*数组名称作为实参数组名称作为实参,以传引用方式传递数组以传引用方式传递数组a*/ 6.4 数组作为函数参数的处理数组作为函数参数的处理 58 6.4 数组作为函数参数的处理数组作为函数参数的处理 由于数组总是通过模拟传引用的

52、方式传递的,由于数组总是通过模拟传引用的方式传递的, 所以难以防范函数修改数组的值。为了限制函所以难以防范函数修改数组的值。为了限制函 数对数组的修改,可以使用数对数组的修改,可以使用const限定符。限定符。 void tryToModifyArray(const int b,int size) int i; for(i=0;isize;i+) bi=2*bi; /编译报错编译报错 ,bi不能修改不能修改 59 练习:设计一个函数练习:设计一个函数outputArray,用于输出一,用于输出一 个整数数组中的元素个整数数组中的元素 void outputArray(const int dat

53、a, int size) int i; for(i = 0;i 0) someFunction( printf(%4d, b0); 注意:数组不能作为函数的返回值;注意:数组不能作为函数的返回值; 6.4 数组作为函数参数的处理数组作为函数参数的处理 65 6.1 总结与回顾(数据类型与程序设计)总结与回顾(数据类型与程序设计) 6.2 数组作为一种复杂数据类型数组作为一种复杂数据类型 6.3 数组的声明、操作和使用数组的声明、操作和使用 6.4 数组作为函数参数的处理数组作为函数参数的处理 6.5 数组的应用(插入、删除、排序、查找)数组的应用(插入、删除、排序、查找) 提纲提纲 66 线性

54、表处理可抽象出一些基本操作,如:线性表处理可抽象出一些基本操作,如: 增加增加/删除表中的元素删除表中的元素 查找查找/修改表中的某个元素修改表中的某个元素 输入输入/输出表输出表 排序排序 一般地,线性表的程序设计采用模块化思想一般地,线性表的程序设计采用模块化思想 (C语言的函数),通过定义和调用模块,完语言的函数),通过定义和调用模块,完 成线性表的各种应用。在设计模块(函数)时,成线性表的各种应用。在设计模块(函数)时, 应遵循应遵循“高内聚、低耦合高内聚、低耦合”的设计原则。的设计原则。 6.5 数组的应用数组的应用 67 6.5 数组的应用数组的应用1查找元素查找元素 线性表的基本

55、操作线性表的基本操作1 设计一个函数,查找某个元素在数组中的下标并返回。设计一个函数,查找某个元素在数组中的下标并返回。 若存在多个符合条件的元素,则只返回第一个符合条若存在多个符合条件的元素,则只返回第一个符合条 件元素的下标。件元素的下标。 函数设计考虑:函数设计考虑: 数组名为参数传入数组名为参数传入 查找起始位置作为参数传入;查找起始位置作为参数传入; 查找结束位置作为参数传入;查找结束位置作为参数传入; 要查找的值作为参数传入;要查找的值作为参数传入; :若找到,则返回元素下标,否则返回:若找到,则返回元素下标,否则返回-1 ; 68 6.5 数组的应用数组的应用1查找元素查找元素

56、/* 函数功能:在数组的函数功能:在数组的datastartLocdataendLoc这段数组元素中这段数组元素中 查找某个元素查找某个元素 ,如果找到则返回该元素的下标,否则返回,如果找到则返回该元素的下标,否则返回-1。*/ int findElement(const int data,int startLoc, int endLoc, int element) int i; i = startLoc; while ( i = endLoc if ( i = endLoc)/*若找到,思考:能否写成若找到,思考:能否写成if(datai=element)? */ return i; els

57、e return -1; i未越界且未越界且ai不符合查找要求不符合查找要求 i+ i = 下标初始值下标初始值 69 请判断下面整型数组请判断下面整型数组a的状态是否合理?的状态是否合理? 将将50、40、30分别存放到下标为分别存放到下标为0、1、3的的 数组元素中数组元素中(未往下标为未往下标为2的元素中存放值的元素中存放值)。 不合理!数组用于存储线性表,线性表中的元素不合理!数组用于存储线性表,线性表中的元素 是相邻的,这就要求它们在数组中的存储单元也是相邻的,这就要求它们在数组中的存储单元也 要相邻。如果它们在数组中不是使用连续的存储要相邻。如果它们在数组中不是使用连续的存储 空间

58、,那就无法标识哪些是有效的数组元素。空间,那就无法标识哪些是有效的数组元素。 6.5 数组的应用数组的应用2插入元素插入元素 70 所以用数组存放值时,只能出现如下状态所以用数组存放值时,只能出现如下状态 而不应该出现下列状态而不应该出现下列状态 在对数组进行操作时,必须保证数组处于第一在对数组进行操作时,必须保证数组处于第一 种状态种状态 6.5 数组的应用数组的应用2插入元素插入元素 71 6.5 数组的应用数组的应用2插入元素插入元素 练习练习2. 定义一个能容纳定义一个能容纳10个元素的整形数组个元素的整形数组a, 从键盘读取从键盘读取9个整数存放到前个整数存放到前9个数组元素中。个数

59、组元素中。 1)从键盘读取一个整数)从键盘读取一个整数n和位置和位置p(0=p=8),插,插 入入n到数组到数组a中,插入位置:下标中,插入位置:下标p。要求插入点。要求插入点 及后续的数组元素都要后移动。及后续的数组元素都要后移动。 2)然后,从键盘再次读取位置)然后,从键盘再次读取位置p(0=p=p;i-)/9个元素,个元素,下标为下标为8p的数组元素依次后挪的数组元素依次后挪 ai+1=ai; ap=num;/插入插入num到下标为到下标为p的数组元素中的数组元素中 /删除下标为删除下标为p的数组元素中内容的数组元素中内容 for(i=p+1;i=9;i+)/下标为下标为p+19的数组元

60、素依次前挪的数组元素依次前挪 ai-1=ai; 74 线性表的基本操作线性表的基本操作2 6.5 数组的应用数组的应用2插入元素插入元素 若数组未满,且插入位若数组未满,且插入位 置合理,则先逐个后移置合理,则先逐个后移 元素,再插入元素。元素,再插入元素。 若数组未满,但插入位置若数组未满,但插入位置 不合理不合理(包括数组越界包括数组越界), 则不允许插入元素!则不允许插入元素! 若数组已满,则不允若数组已满,则不允 许插入元素!许插入元素! 75 函数设计考虑:函数设计考虑: 数组名、数组的大小作为参数传入;数组名、数组的大小作为参数传入; 数组中已存放的元素个数作为参数传入;数组中已存

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论