Top Banner
第7第 第第
46

第 7 章 数组

Mar 15, 2016

Download

Documents

maia-watts

第 7 章 数组. 主要内容 : 1 、一维数组 2 、二维数组 3 、字符数组和字符串 重点: 数组的定义和数组元素的引用. 数组概述. 数组:用于保存一批相同类型的数据 属构造类型 数组名:一批同类型数据共有的名字。 下标:数组中的各个数据用下标来区分。 例如,一组实验数据、一批学生成绩、表、矩阵等的处理,均用数组数据类型表示。. …. 7.1 一维数组. 例 7.1 输入 50 个整数,按逆序输出。 main() - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 第 7 章   数组

第 7 章 数组

Page 2: 第 7 章   数组

主要内容主要内容 ::

11 、一维数组、一维数组22 、二维数组、二维数组33 、字符数组和字符串、字符数组和字符串重点:重点:数组的定义和数组元素的引用数组的定义和数组元素的引用

Page 3: 第 7 章   数组

数组概述 数组:用于保存一批相同类型的数据数组:用于保存一批相同类型的数据 属构造类型属构造类型 数组名:一批同类型数据共有的名字。数组名:一批同类型数据共有的名字。 下标:数组中的各个数据用下标来区分。下标:数组中的各个数据用下标来区分。 例如,一组实验数据、一批学生成绩、表、矩阵等例如,一组实验数据、一批学生成绩、表、矩阵等的处理,均用数组数据类型表示。的处理,均用数组数据类型表示。

Page 4: 第 7 章   数组

7.1 一维数组例例 7.1 7.1 输入输入 5050 个整数,按逆序输出。个整数,按逆序输出。main()main(){ int a[50], i; /* { int a[50], i; /* 定义数组定义数组 aa 和循环变量和循环变量 i */i */for(i=0; i<50; i++)for(i=0; i<50; i++) /* /* 从键盘输入从键盘输入 5050 个整数 个整数 */*/scanf("%d", &a[i]);scanf("%d", &a[i]); for (i=49; i>=0; i--)for (i=49; i>=0; i--) /* /* 逆序输出逆序输出 5050 个整数 个整数 */*/ printf("%4d", a[i]);printf("%4d", a[i]); }} a[0] a[1] a[2] a[3] a[4]……a[49]a[0] a[1] a[2] a[3] a[4]……a[49]

…..

Page 5: 第 7 章   数组

一维数组:每个数组元素只带有一个下标一维数组:每个数组元素只带有一个下标 一维数组的一般形式 :一维数组的一般形式 : 类型说明符类型说明符 数组名数组名 [[ 常量表达式常量表达式 ]] 如:如: float score[30]float score[30] ;; floatfloat 是是类型说明符类型说明符,,定义了该数组中元素的类型。定义了该数组中元素的类型。 scorescore 是是数组名数组名,是这一组数据共有的的名字;,是这一组数据共有的的名字;3030 是是常量表达式常量表达式,,表示数组的长度,即数组元素的个表示数组的长度,即数组元素的个数。数。也就是说:数组也就是说:数组 score score 可以保存可以保存 3030 个个 floatfloat 型的数据。型的数据。注意注意:定义数组时长度必须是确定的值。:定义数组时长度必须是确定的值。 例如 例如 : : int aa[ ];int aa[ ]; (error) (error) int n; float xs[n];int n; float xs[n]; (error) (error)

Page 6: 第 7 章   数组

数组元素的引用:数组元素的引用: 数组名数组名 [[ 下标下标 ]] 如:如: a[i]a[i] 是数组 是数组 a a 中下标为 中下标为 i i 的数组元素的数组元素 ; ; a[0]a[0] 是下标为 是下标为 0 0 的数组元素。的数组元素。CC 语言的规定:数组的下标从语言的规定:数组的下标从 00 开始开始。。比如数组比如数组 a[50]a[50] 包含包含 5050 个数组元素,分别是:个数组元素,分别是: a[0] aa[0] a

[1] a[2] …… a[49][1] a[2] …… a[49]即下标的范围为即下标的范围为 0~490~49 ,不存在数组元素,不存在数组元素 score[50]score[50] 。。若使用若使用 a[50]a[50] 是危险的,为什么?是危险的,为什么?一维数组的存储格式一维数组的存储格式:每个数组占用一片连续的存储单:每个数组占用一片连续的存储单元,按下标次序依次存放各元素。元,按下标次序依次存放各元素。如 如 int data[10]; int data[10]; 数组数组 datadata 占占 2*10=202*10=20 个字节个字节

data[0] data[1] data[2] …… data[9]

Page 7: 第 7 章   数组

例例 7.37.3 编程实现:输入某门课编程实现:输入某门课 3030 人的成绩(人的成绩( 0~100~1000 ),要求将高于平均分的那些成绩打印出来。),要求将高于平均分的那些成绩打印出来。

分析数据结构:分析数据结构: 3030 人的成绩,类型相同,可用一人的成绩,类型相同,可用一维数组来保存。维数组来保存。分析算法:分析算法:S1:S1: 输入输入 3030 人的成绩并累加,用循环实现,循环体人的成绩并累加,用循环实现,循环体为“输入第 为“输入第 k k 个人的成绩、并累加入部分和”;个人的成绩、并累加入部分和”;S2S2 :求平均:求平均S3 :S3 : 求高于平均分的成绩。也用循环实现,循环体求高于平均分的成绩。也用循环实现,循环体为“将第 为“将第 k k 个成绩平均分比较,若高,则输个成绩平均分比较,若高,则输出”;循环条件为“出”;循环条件为“ k<30"k<30" ,, kk 的初值为的初值为 00 ,增,增值为“值为“ k++”.k++”.

Page 8: 第 7 章   数组

#define N 3#define N 3main() main() { { float score[N]float score[N], sum, average; int k;, sum, average; int k; printf("\n enter %d scores:", N);printf("\n enter %d scores:", N); sum=0; sum=0; for(k=0;k<N;k++) /*for(k=0;k<N;k++) /* 输入输入 NN 个成绩,存入数组,并累加个成绩,存入数组,并累加 */*/ { scanf("%f",&score[k]); sum=sum+score[i]; }{ scanf("%f",&score[k]); sum=sum+score[i]; } average=sum/N; /*average=sum/N; /* 求平均求平均 */*/ printf("\n average=%6.1f" , average);printf("\n average=%6.1f" , average); for(k=1;k<N;k++)for(k=1;k<N;k++) if(score[k]> average) if(score[k]> average) printf("\n %6.1f", score[k]);printf("\n %6.1f", score[k]); } }

Page 9: 第 7 章   数组

例例 7.4 7.4 用用起泡法起泡法对对 NN 个整数由小到大排序。个整数由小到大排序。 起泡排序的基本思想是:相邻两个元素比较,按要求的顺序起泡排序的基本思想是:相邻两个元素比较,按要求的顺序排放,比较一遍后,最大的元素被换到待排序数列的最后位排放,比较一遍后,最大的元素被换到待排序数列的最后位置。对待排序序列依次重复上述过程,直至全部排完为止。置。对待排序序列依次重复上述过程,直至全部排完为止。数据结构:数据结构: NN 个整数用一维整型数组保存。个整数用一维整型数组保存。算法: (设算法: (设 N=5,N=5, 待排序的数据为:待排序的数据为: 3 2 10 8 13 2 10 8 1 ))起泡排序过程为起泡排序过程为 : : 第一遍:第一遍: 2 3 8 1 2 3 8 1 1010第二遍:第二遍: 2 3 1 2 3 1 88 10 10 第三遍:第三遍: 2 1 2 1 3 3 8 10 8 10第四遍:第四遍: 1 1 22 3 3 8 10 8 10 分析:当待排序数据个数分析:当待排序数据个数 n=5n=5 时,共排时,共排 n-1=4n-1=4 遍,第遍,第 ii 遍待遍待排序序列是从第 排序序列是从第 11 个元素到第个元素到第 n-i+1n-i+1 个元素。用双重循环实个元素。用双重循环实现。现。流程图:流程图:

Page 10: 第 7 章   数组

例例 7.4 7.4 起泡排序。起泡排序。#define N 5#define N 5main()main(){ int { int a[ ]={0, 3, 2, 10, 8, 1}a[ ]={0, 3, 2, 10, 8, 1}; int t,i,j;; int t,i,j; for(i=1;i<=for(i=1;i<=N-1N-1;i++);i++) for(j=1;j<for(j=1;j<N-i+1N-i+1;j++);j++) if(a[j]>a[j+1]) /*if(a[j]>a[j+1]) /* 若相邻两数逆序,则交换若相邻两数逆序,则交换 */*/ {t=a[j];a[j]=a[j+1];a[j+1]=t;} {t=a[j];a[j]=a[j+1];a[j+1]=t;} printf("\n");printf("\n"); for(i=1;i<=N;i++)for(i=1;i<=N;i++) printf("%d ",a[i]);printf("%d ",a[i]);}} 数组数组 aa 的长度为的长度为 1111 ,由初始值的个数决定。其中,由初始值的个数决定。其中 a[1]a[1] 至至 a[1a[1

0]0] 为有效数据,为有效数据, a[0]a[0] 未用,主要是为了符合我们的计数习惯。未用,主要是为了符合我们的计数习惯。

Page 11: 第 7 章   数组

例例 7.5 7.5 求某数列的前求某数列的前 2020 项。该数列的特点:项。该数列的特点: ff11=0 ( n=1)=0 ( n=1)

ff22=1 (n=2)=1 (n=2)

ffnn=f=fn-1n-1+f+fn-2n-2(n is odd)(n is odd) 、、 ffnn=| f=| fn-1n-1 - f - fn-2 n-2 | (n is even)| (n is even)

分析:分析:数据结构: 该数列中的数据均为整型,可用整型的一数据结构: 该数列中的数据均为整型,可用整型的一维数组来保存。维数组来保存。算法:算法:S1:S1: 从第三项开始,每一项都是前两项的和或差,可用从第三项开始,每一项都是前两项的和或差,可用循环实现:每循环一次计算出一项。求出前循环实现:每循环一次计算出一项。求出前 2020 项,项,分别存入数组中相应位置。 分别存入数组中相应位置。 S2:S2: 输出数组中的每一个元素,用循环实现。输出数组中的每一个元素,用循环实现。

Page 12: 第 7 章   数组

#include <math.h>#include <math.h>main()main(){ int { int f[21]f[21], k;, k; f[1]=0; f[2]=1;f[1]=0; f[2]=1; for(k=3; k<=20; for(k=3; k<=20; k+=2k+=2)) { f[k]=f[k-1]+f[k-2]; f[k+1]=abs(f[k]-f[k-1]); }{ f[k]=f[k-1]+f[k-2]; f[k+1]=abs(f[k]-f[k-1]); } printf("\n number list:\n");printf("\n number list:\n"); for(k=1; k<=20; k++)for(k=1; k<=20; k++) {printf("%10d", f[k]);{printf("%10d", f[k]); if(k %6==0) printf("\n"); if(k %6==0) printf("\n"); /*/* 控制每行输出控制每行输出 66 个数个数 **// }}}}

Page 13: 第 7 章   数组

一维数组的初始化一维数组的初始化:定义数组时可以给部分或全一维数组的初始化:定义数组时可以给部分或全部数组元素赋初值,即数组的初始化。部数组元素赋初值,即数组的初始化。数组元素的初值依次放在一对花括号内数组元素的初值依次放在一对花括号内。。(( 11 )只给部分元素赋初值。)只给部分元素赋初值。如: 如: int x[20]={ 1,2}; int x[20]={ 1,2}; 只给数组元素只给数组元素 x[0],x[1]x[0],x[1] 赋赋初值。初值。(( 22 )对全部数组元素赋初值,数组长度可以省)对全部数组元素赋初值,数组长度可以省略,由初值的个数决定。如:略,由初值的个数决定。如: int int a[ ]={0, 3, 2, 10, 8, 1}a[ ]={0, 3, 2, 10, 8, 1}; ;

Page 14: 第 7 章   数组

7.2 二维数组 用于描述类似矩阵、表之类的数据结构用于描述类似矩阵、表之类的数据结构 特点:特点: 11 ))所有数据同类型,并且是由个数相等的几组数据所有数据同类型,并且是由个数相等的几组数据组成。组成。 22 )每组数据表示一个完整的含义,可看作是一个整体)每组数据表示一个完整的含义,可看作是一个整体。。 比如,比如, 2*32*3 的矩阵,共有的矩阵,共有 66 个数据,分成两组,每组个数据,分成两组,每组 33 个数个数据,表示一行。可定义数组: 据,表示一行。可定义数组: int bb[2][3];int bb[2][3]; 又如,某班又如,某班 3030 人,期末考人,期末考 44 门课,他们的成绩都是门课,他们的成绩都是 floatfloat 型,型,共有共有 120120 个成绩,分成个成绩,分成 3030 组,每组组,每组 44 个,即表示某一个人的个,即表示某一个人的成绩;或分成成绩;或分成 44 组,每组组,每组 3030 个,即表示某一门课的成绩。个,即表示某一门课的成绩。 如定义数组:如定义数组:float score[30][4];float score[30][4]; 可表示可表示 3030 人的成绩,每人人的成绩,每人 44 门课。门课。float sc[4][30];float sc[4][30]; 可表示可表示 44 门课,每门可有门课,每门可有 3030 人的成绩。人的成绩。比较:若用一维数组,能表示所有的数据,但不能表示出数据比较:若用一维数组,能表示所有的数据,但不能表示出数据之间的分组关系。之间的分组关系。

Page 15: 第 7 章   数组

例例 7.67.6 输入某班(输入某班( 3030 人)期末考试人)期末考试 44 门课的成绩,门课的成绩,计算出每人的平均成绩,按每行计算出每人的平均成绩,按每行 1010 个数据输出平均个数据输出平均成绩。成绩。 分析数据结构:分析数据结构: 3030 人人 44 门课的成绩用二维数组表示,门课的成绩用二维数组表示,

3030 人的平均成绩可用一维数组表示。人的平均成绩可用一维数组表示。 算法:算法:S1:S1: 输入输入 3030 人(每人人(每人 44 门课)的成绩。门课)的成绩。S2:S2: 计算每人的平均成绩。计算每人的平均成绩。S3:S3: 输出每个人的平均成绩。输出每个人的平均成绩。分别分析每一步如何实现?分别分析每一步如何实现?循环结构循环结构 程序:程序:

Page 16: 第 7 章   数组
Page 17: 第 7 章   数组

for(i=0;i<30;i++) /*for(i=0;i<30;i++) /* 输出每人的平均成绩输出每人的平均成绩 */*/ { if(i%10==0)printf(“\n”); /*{ if(i%10==0)printf(“\n”); /* 控制每行控制每行 1010 个数据个数据 */*/ printf("%5.1f", aver[i]);printf("%5.1f", aver[i]); } } }}

Page 18: 第 7 章   数组

二维数组定义的一般格式:二维数组定义的一般格式: 类型名 数组名类型名 数组名 [[ 常量表达式常量表达式 1][1][ 常量表达式常量表达式 2]2]如 如 float score[30][4];float score[30][4];其中的数组元素为:其中的数组元素为: score[0][0], score[0][1], score[0][2],score[0][3]score[0][0], score[0][1], score[0][2],score[0][3] score[1][0], score[1][1], score[1][2],score[1][3]score[1][0], score[1][1], score[1][2],score[1][3] score[2][0], score[2][1], score[2][2],score[2][3]score[2][0], score[2][1], score[2][2],score[2][3] …… …… score[29][0], score[29][1], score[29][2],score[29][3]score[29][0], score[29][1], score[29][2],score[29][3] 如表示如表示 2*32*3 矩阵的数组矩阵的数组 bbbb 的定义:的定义: int bb[2][3];int bb[2][3];其中的数组元素为:其中的数组元素为: bb[0][0],bb[0][1],bb[0][2]bb[0][0],bb[0][1],bb[0][2] bb[1][0],bb[1][1],bb[1][2]bb[1][0],bb[1][1],bb[1][2]说明:数组每一维的下标均从说明:数组每一维的下标均从 00 开始。开始。 ( 二维数组可看 ( 二维数组可看作特殊的一维数组,每个数组元素又是一维数组)作特殊的一维数组,每个数组元素又是一维数组)

Page 19: 第 7 章   数组

存储格式存储格式:二维数组同一维数组一样,也占用一片:二维数组同一维数组一样,也占用一片连续的存储单元,且连续的存储单元,且按行存放按行存放。。 数组名代表整个数组名代表整个数组的起始地址数组的起始地址,数组名与第一维,数组名与第一维下标代表下标代表某一行的起始地址某一行的起始地址。如。如 scorescore&score[0], sc&score[0], sc

ore[i]ore[i]&score[i][0]&score[i][0] 例例 7.77.7 求已知矩阵求已知矩阵 a= a= 的转置矩阵 的转置矩阵 b= b=

分析两个矩阵元素的对应关系:分析两个矩阵元素的对应关系: a[i][j] a[i][j] 对应 对应 b[j][i]. b[j][i].

987654321

9 6 38 5 27 4 1

Page 20: 第 7 章   数组

/*/* 例例 7.7 */7.7 */main()main(){int a[3][3]={ {1,2,3}, {4,5,6}, {7,8,9} }; /*{int a[3][3]={ {1,2,3}, {4,5,6}, {7,8,9} }; /* 数组数组 aa 初始化初始化 */*/ int b[3][3], i, j;int b[3][3], i, j; for(i=0;i<3;i++) /*for(i=0;i<3;i++) /* 求转置矩阵求转置矩阵 b*/b*/ for(j=0;j<3;j++)for(j=0;j<3;j++) b[j][i]=a[i][j];b[j][i]=a[i][j]; printf(“\n matrix a:\n”); /*printf(“\n matrix a:\n”); /* 输出矩阵输出矩阵 aa (按行输出)(按行输出) */*/ for(i=0;i<3;i++)for(i=0;i<3;i++) { for(j=0;j<3;j++){ for(j=0;j<3;j++) printf("%5d",a[i][j]);printf("%5d",a[i][j]); printf(“\n”); /*printf(“\n”); /* 输出一行后,换行输出一行后,换行 */*/ }}  /*/* 接下页接下页 */*/

Page 21: 第 7 章   数组

/*/* 上接页上接页 */*/printf(“matrix b:\n”);printf(“matrix b:\n”); /* /* 输出矩阵输出矩阵 b*/b*/ for(i=0;i<3;i++)for(i=0;i<3;i++) {for(j=0;j<3;j++){for(j=0;j<3;j++) printf("%5d",b[i][j]);printf("%5d",b[i][j]); printf("\n");printf("\n"); }}}}

Page 22: 第 7 章   数组

二维数组的初始化二维数组的初始化::(( 11 )给全部数组元素赋初值:)给全部数组元素赋初值: int a[3][3]={{1,2,3},{4,5,6},{7,8,9}}; int a[3][3]={{1,2,3},{4,5,6},{7,8,9}}; 等价于等价于 int a[3][3]={1,2,3,4,5,6,7,8,9}; int a[3][3]={1,2,3,4,5,6,7,8,9}; 或或 int a[ ][3]={1,2,3,4,5,6,7,8,9}; int a[ ][3]={1,2,3,4,5,6,7,8,9}; 其中第一维的长度可省略。其中第一维的长度可省略。 (( 按行存储按行存储 ))(( 22 )给部分数组元素赋初值:如)给部分数组元素赋初值:如 int b[2][4]={{1,2},{6,8}};int b[2][4]={{1,2},{6,8}};结果只给结果只给 44 个元素赋值为: 个元素赋值为: b[0][0]=1, b[0][1]=2,b[0][0]=1, b[0][1]=2, b[1][0]=6, b[1][1]=8b[1][0]=6, b[1][1]=8

Page 23: 第 7 章   数组

例例 7.8 7.8 求求 N*NN*N 矩阵的两条对角线元素之和。矩阵的两条对角线元素之和。 (( 以以 44*4*4 矩阵为例矩阵为例 ))

分析:对角线有两条,每条有两个对角线元素,第分析:对角线有两条,每条有两个对角线元素,第 kk行的两个对角线元素为行的两个对角线元素为 a[k][k], a[k][n-k-1]a[k][k], a[k][n-k-1] 设设 s1s1 、、 s2s2 分别表示两条对角线元素的部分和,则对分别表示两条对角线元素的部分和,则对于矩阵的每一行,都要将其对角线元素加入对应的于矩阵的每一行,都要将其对角线元素加入对应的部分和变量中。因此用循环结构。部分和变量中。因此用循环结构。 循环体:循环体: s1+=a[k][k]; s2+=a[k][n-k-1]s1+=a[k][k]; s2+=a[k][n-k-1] 条件:条件: k<Nk<N kk 的初值:的初值: 0 0 kk 的增值:的增值: k++k++

Page 24: 第 7 章   数组

#define N 4#define N 4main()main(){ int a[N][N], i, j, s1, s2;{ int a[N][N], i, j, s1, s2; printf(“\n enter matrix :”); /*printf(“\n enter matrix :”); /* 提示信息提示信息 */*/ for(i=0; i<N; i++)for(i=0; i<N; i++) for(j=0; j<N; j++) /*for(j=0; j<N; j++) /* 输入一行输入一行 */*/ scanf("%d",&a[i][j]);scanf("%d",&a[i][j]); s1=s2=0;s1=s2=0; for(i=0;i<N;i++)for(i=0;i<N;i++) {s1+=a[i][i]; s2+=a[i][N-i-1]; }{s1+=a[i][i]; s2+=a[i][N-i-1]; } printf("\n sum=%d",s1+s2); printf("\n sum=%d",s1+s2); }}

Page 25: 第 7 章   数组

7.3 字符数组和字符串 一维字符数组常用来表示字符串,每个数组元素保存一维字符数组常用来表示字符串,每个数组元素保存一个字符。一个字符。 例例 7.97.9 下面程序将从字母‘下面程序将从字母‘ b’b’ 开始的开始的 55 个字符存入一个字符存入一个字符数组,并察看数组中的个元素。个字符数组,并察看数组中的个元素。#include "stdio.h"#include "stdio.h"main()main(){ char ss[5],ch='b'; int i;{ char ss[5],ch='b'; int i; for(i=0;i<5;i++)for(i=0;i<5;i++) { ss[i]=ch; ch++;}{ ss[i]=ch; ch++;} for(i=0;i<5;i++) /*for(i=0;i<5;i++) /* 输出每个字符数组元素输出每个字符数组元素 */ */ putchar(ss[i]); putchar(ss[i]); } } 运行结果:运行结果: bcdefbcdef

Page 26: 第 7 章   数组

本例还可以用数组初始化的方式给数组元素赋值本例还可以用数组初始化的方式给数组元素赋值#include "stdio.h"#include "stdio.h"main()main(){ char ss[5]{ char ss[5]={'b','c','d','e','f'}={'b','c','d','e','f'}; int i;; int i; for(i=0;i<5;i++)for(i=0;i<5;i++) putchar(ss[i]);putchar(ss[i]);}}结论:字符数组的定义、初始化及数组元素的引用方法与一般结论:字符数组的定义、初始化及数组元素的引用方法与一般数组基本相同。数组基本相同。不同点:字符数组通常用于保存字符串,此时整个数组可以整不同点:字符数组通常用于保存字符串,此时整个数组可以整体输入体输入 // 输出。而整型、实型等数组只能引用其中的数组元输出。而整型、实型等数组只能引用其中的数组元素。素。字符串存储时,系统自动在其末尾加上一个字符串结束标志:字符串存储时,系统自动在其末尾加上一个字符串结束标志:‘‘ \0’\0’ ,因此当用字符数组保存字符串时,字符数组的长,因此当用字符数组保存字符串时,字符数组的长度至少应定义为:度至少应定义为:字符串长度字符串长度 +1+1 。。

Page 27: 第 7 章   数组

例例 7.11 7.11 输入一个字符串输入一个字符串 (( 设长度不超过设长度不超过 8080 ),统计其长度,),统计其长度,并输出该字符串。并输出该字符串。#include "stdio.h"#include "stdio.h"main()main(){ char str[80]; int i,n=0;{ char str[80]; int i,n=0; printf("\n enter a line character:");printf("\n enter a line character:"); gets(str); /*gets(str); /* 字符串输入函数字符串输入函数 */*/ i=0;i=0; while(str[i]!='\0') {n++;i++;}while(str[i]!='\0') {n++;i++;} printf(“\n string:%s”,str); /*printf(“\n string:%s”,str); /* 输出字符串输出字符串 strstr ,用,用 %s*/%s*/ printf("\n length:%d",n);printf("\n length:%d",n);}}运行时若输入:运行时若输入: Turbo c Turbo c 则输出: 则输出: strng:Turbo c strng:Turbo c length:7length:7

Page 28: 第 7 章   数组

字符串输入字符串输入 // 输出函数的使用:输出函数的使用: (1)gets(str)(1)gets(str) ::从终端输入从终端输入一个一个字符串,送入字符数组字符串,送入字符数组strstr 。其中。其中 strstr 代表数组代表数组 str[80]str[80] 的首地址。的首地址。用用 getsgets 输入字符串时输入字符串时,,以回车作为字符串的结束,并以回车作为字符串的结束,并将回车符转换成字符串结束标志‘将回车符转换成字符串结束标志‘ \0’\0’ 。。 (2)scanf():(2)scanf(): 输入输入不含空格不含空格的一个或多个字符串。的一个或多个字符串。如例如例 7.3.27.3.2 中将中将 gets(str)gets(str) 改为:改为: scanf(“%s”,str);scanf(“%s”,str);若输入:若输入: Turbo c Turbo c 则输出:则输出: string:Turbostring:Turbo length:5length:5Note:Note: 用用 scanfscanf 输入时,空格、回车均为数据的分隔符;输入时,空格、回车均为数据的分隔符;当输入多个字符串时,每个字符串末尾自动当输入多个字符串时,每个字符串末尾自动加上字符串结束标记‘加上字符串结束标记‘ \\0’0’ 。 。

Page 29: 第 7 章   数组

(3)printf()(3)printf() 和 和 puts(str) :puts(str) :例例 7.117.11 输出两个字符串(分别用输出两个字符串(分别用 printf printf 和和 puts)puts) 。。#include "stdio.h"#include "stdio.h"main()main(){ char s1[30]="abcde", s2[20]="ghi";{ char s1[30]="abcde", s2[20]="ghi"; printf("\n%s,%s",s1,s2);printf("\n%s,%s",s1,s2); puts(s1); puts(s2);puts(s1); puts(s2);} } 运行结果:运行结果: abcde,ghiabcdeabcde,ghiabcde ghighi Printf Printf 可用控制符 可用控制符 %s %s 输出一个或多个字符串输出一个或多个字符串 ,, Printf Printf 输出字符串时,字符串的结束标志‘输出字符串时,字符串的结束标志‘ \0’\0’ 并不输出,并不输出,也不会转换成‘也不会转换成‘ \n’\n’ 。。 puts(s1) ; puts(s1) ; 输出字符数组输出字符数组 s1s1 中的一个字符串,且将字符串结中的一个字符串,且将字符串结束标记束标记‘‘ \0’\0’ 转换成转换成‘‘ \n’\n’ 输出输出。。

Page 30: 第 7 章   数组

最常用的字符串操作函数 Strcpy(s1,s2):Strcpy(s1,s2): 拷贝字符串拷贝字符串 s2s2 到到 s1s1 。。 Strcat(s1,s2):Strcat(s1,s2): 把字符串把字符串 s2s2 接到接到 s1s1 的末尾。的末尾。 Strlen(s1):Strlen(s1): 返回字符串返回字符串 s1s1 的长度。的长度。 Strcmp(s1,s2):Strcmp(s1,s2): 比较字符串比较字符串 s1s1 和和 s2s2 的大小。若的大小。若 s1s1 、、 ss

22 相等,则返回相等,则返回 00 ;若;若 s1>s2s1>s2 则返回值大于则返回值大于 00 ;若;若 s1s1<s2<s2 则返回值小于则返回值小于 00 。。

such assuch as :: "abcdef" less than "abkdeg""abcdef" less than "abkdeg" Note: Note: 以上参数均为待处理字符串的以上参数均为待处理字符串的首地址首地址。。

Page 31: 第 7 章   数组

例例 7.12 7.12 输入两个字符串,分别测试其长度,输入两个字符串,分别测试其长度,并比较两个字符串的大小。并比较两个字符串的大小。 分析:分析:11 )输入两个字符串,分别存入字符数组)输入两个字符串,分别存入字符数组 str1str1 、、 ss

tr2tr2 ,用,用 getsgets 实现。实现。22 )用函数)用函数 strlenstrlen 测试两个字符串的长度。测试两个字符串的长度。 33 )用函数)用函数 strcmpstrcmp 比较两个字符串的大小。比较两个字符串的大小。

Page 32: 第 7 章   数组

#include “stdio.h“ /*#include “stdio.h“ /* 字符串函数的综合使用字符串函数的综合使用 */*/#define N 80#define N 80#include “string.h“ /*#include “string.h“ /* 字符串处理函数的头文件字符串处理函数的头文件 */ */ main()main(){ char str1[N],str2[N]; int cmp;{ char str1[N],str2[N]; int cmp; printf("\n input first string:"); gets(str1); printf("\n input first string:"); gets(str1); printf(" input second string:"); gets(str2);printf(" input second string:"); gets(str2); printf("\n length1=%d, length2=%d", strlen(str1),strlen(str2));printf("\n length1=%d, length2=%d", strlen(str1),strlen(str2)); cmp=strcmp(str1,str2);cmp=strcmp(str1,str2); if(cmp==0) printf("\n equal.");if(cmp==0) printf("\n equal."); else if(cmp>0) printf("\n str1 >str2.");else if(cmp>0) printf("\n str1 >str2."); else printf("\n str1<str2.");else printf("\n str1<str2.");}}

Page 33: 第 7 章   数组

例例 7.14 7.14 输入一行字符,统计其中有多少个单词(单词输入一行字符,统计其中有多少个单词(单词之间用空格分隔)。之间用空格分隔)。思路:输入一行字符串,存入一维字符数组;然后对思路:输入一行字符串,存入一维字符数组;然后对每一个字符进行如下判断:每一个字符进行如下判断: 当前字符当前字符 == 空格?空格?若是,则未出现新单词,使若是,则未出现新单词,使 word=0word=0 。。若不是,则根据前一字符是否为空格判断:若是若不是,则根据前一字符是否为空格判断:若是 (( 即 即

word=0)word=0) ,则新单词出现,,则新单词出现, numnum 加加 11 ,, word=1;word=1; 否则(即否则(即 word=1),word=1), 未出现新单词。未出现新单词。程序:程序: x7_13.cx7_13.c

Page 34: 第 7 章   数组

#include "stdio.h“ /*x7_13.c*/#include "stdio.h“ /*x7_13.c*/main()main(){ char str[81],c;{ char str[81],c; int i,num=0,word=0;int i,num=0,word=0; printf("\n enter a line character:");printf("\n enter a line character:"); gets(str);gets(str); for(i=0;(c=str[i])!='\0';i++)for(i=0;(c=str[i])!='\0';i++) if(c==' ') word=0;if(c==' ') word=0; else if(word==0)else if(word==0)

{ word=1; num++;}{ word=1; num++;} printf("\n there are %d words in the line.",num);printf("\n there are %d words in the line.",num);}}

Page 35: 第 7 章   数组

特别提示11 )同一般数组一样,)同一般数组一样,字符串也不能整体赋值,字符串也不能整体赋值,只能逐个引用数组元素只能逐个引用数组元素。。如如 char s1[10],s2[40];char s1[10],s2[40];则 则 s1=“ghhkji”; /*error*/s1=“ghhkji”; /*error*/ s2=s1; /*error*/s2=s1; /*error*/可以用可以用 strcpystrcpy 实现,或逐个数组元素赋值。实现,或逐个数组元素赋值。22 )用字符数组存储字符串时,其元素的个数至)用字符数组存储字符串时,其元素的个数至少应比字符串的长度多少应比字符串的长度多 11 ;; 字符串处理时,以‘字符串处理时,以‘ \0’\0’ 为字符串结束,无需为字符串结束,无需关心字符数组的实际长度。 例如:关心字符数组的实际长度。 例如: k=0; while(s[k]!='\0') k++;k=0; while(s[k]!='\0') k++;

Page 36: 第 7 章   数组

上机调试Errors:Errors: 11 )注意数组访问越界,或漏掉下标为)注意数组访问越界,或漏掉下标为 00的元素。因为下标从的元素。因为下标从 00 开始。开始。 22 )数组不能整体赋值。)数组不能整体赋值。 33 )定义数组时长度不确定。)定义数组时长度不确定。

Page 37: 第 7 章   数组

练习1. main()1. main(){ int y[2][3]={2,34,6,8,10,12};{ int y[2][3]={2,34,6,8,10,12}; int i;int i; for(i=0;i<2;i++)for(i=0;i<2;i++) printf("%d,",y[1-i][i+1]);printf("%d,",y[1-i][i+1]);}}注意:二维数组的存储格式,下标从注意:二维数组的存储格式,下标从 00 开始。开始。

Page 38: 第 7 章   数组

2. #include "stdio.h"2. #include "stdio.h"#define N 6#define N 6main()main(){ char c[N];{ char c[N]; int i;int i; for(i=0;i<N;i++) c[i]=getchar();for(i=0;i<N;i++) c[i]=getchar(); for(i=0;i<N;i++) putchar(c[i]);printf("\n");for(i=0;i<N;i++) putchar(c[i]);printf("\n");} /*} /* 注意:注意:读取字符时回车符的处理。读取字符时回车符的处理。 */*/若运行时输入:若运行时输入: abab cc def def 结果为:结果为:

Page 39: 第 7 章   数组

3. main()3. main(){ int n[3],i,j,k;{ int n[3],i,j,k; for(i=0;i<3;i++) n[i]=0;for(i=0;i<3;i++) n[i]=0; k=2;k=2; for(i=0;i<k;i++)for(i=0;i<k;i++) for(j=0;j<k;j++)for(j=0;j<k;j++) n[j]=n[i]+1;n[j]=n[i]+1; printf("\n%d",n[1]);printf("\n%d",n[1]);}/*}/* 注意下标的变化注意下标的变化 */*/运行结果为:运行结果为: 33

Page 40: 第 7 章   数组

4. #include "stdio.h"4. #include "stdio.h"main()main(){char ch[3][4]={"123","456","78"};{char ch[3][4]={"123","456","78"}; int i;int i; for(i=0;i<3;i++)for(i=0;i<3;i++) {printf("%s",ch[i]);puts(ch[i]);}{printf("%s",ch[i]);puts(ch[i]);}} /*} /* 注意:字符串输出时‘注意:字符串输出时‘ \0’\0’ 的处理。的处理。 */*/运行结果为:运行结果为:12312312312345645645645678787878

Page 41: 第 7 章   数组

5.5. 输入输入 NN 位学生的成绩,统计各分数段的人数,统计位学生的成绩,统计各分数段的人数,统计结果存入数组,并输出。(统计原则:结果存入数组,并输出。(统计原则: <60,60~69,70<60,60~69,70~79,80~89,90~99~79,80~89,90~99 ,, 100100 各为一段各为一段 ,N,N 为符号常量)为符号常量)

分析:数据结构:分析:数据结构: NN 个学生的成绩、各分数段的人数个学生的成绩、各分数段的人数分别用一维数组分别用一维数组 sc[N],count[11]sc[N],count[11] 存放。存放。算法:算法: 11 )输入)输入 NN 个成绩个成绩 22 )) count count 数组各元素清数组各元素清 00 33 )统计:对每一个成绩,判断其属于哪一分数)统计:对每一个成绩,判断其属于哪一分数段,然后将对应段,然后将对应 countcount 数组元素加数组元素加 11 。。 44 )输出)输出 count count 中的各元素,即各分数段的人数。中的各元素,即各分数段的人数。

Page 42: 第 7 章   数组

66 : 插入一个数到已排好序的数组中,使之仍然有: 插入一个数到已排好序的数组中,使之仍然有序。序。 分析算法:设待插入的数为分析算法:设待插入的数为 x,x, 数组名为数组名为 ss ,已按由,已按由小到大的顺序排列。小到大的顺序排列。S1:S1:找插入位置,方法是将找插入位置,方法是将 x x 与数组中的第一个元素与数组中的第一个元素比较,若比较,若 s[0]>x,s[0]>x, 则则 xx 应插在应插在 s[0]s[0] 处;否则,继续与处;否则,继续与下一个元素比较,直至找到第一个比下一个元素比较,直至找到第一个比 xx 大的元素(大的元素( xx应插在该处)或数组中所有的元素都比较完(应插在该处)或数组中所有的元素都比较完( xx 应应插在最后)。插在最后)。S2:S2:移动部分元素,为移动部分元素,为 xx腾出位置:若腾出位置:若 xx 的插入位置不的插入位置不在最后,则应将插入位置开始的数组元素后移一个在最后,则应将插入位置开始的数组元素后移一个位置。位置。S3:S3:插入。流程图:插入。流程图:

Page 43: 第 7 章   数组

#define N 5 /* program l7_1_4.c */#define N 5 /* program l7_1_4.c */main() /*main() /* 设原数组中有设原数组中有 55 个元素。个元素。 */*/{ int { int s[N+1]s[N+1]={4,7,9,10,30}; int i,j,x; ={4,7,9,10,30}; int i,j,x; printf("\n enter a integer for insert:");printf("\n enter a integer for insert:"); scanf("%d",&x);scanf("%d",&x); for(i=0;i<N;i++) /*for(i=0;i<N;i++) /* 找插入位置找插入位置 */*/ if(x<s[i]) break;if(x<s[i]) break; if(i<N) /*if(i<N) /* 后移插入位置开始往后的元素后移插入位置开始往后的元素 */*/ for(j=N-1;j>=i;j--) s[j+1]=s[j];for(j=N-1;j>=i;j--) s[j+1]=s[j]; s[i]=x ;s[i]=x ; /* /* 插入插入 */*/ for(i=0;i<N+1;i++) /*for(i=0;i<N+1;i++) /* 输出插入后的数组各元素输出插入后的数组各元素 */*/ printf("%d ",s[i]);printf("%d ",s[i]);}}

Page 44: 第 7 章   数组

7. 7. 输入输入 10 10 个字符串(长度不超过个字符串(长度不超过 3030 ),按由小到大),按由小到大的顺序排序。的顺序排序。分析:分析: 1010 个字符串,用二维字符数组表示;个字符串,用二维字符数组表示; 11 )输入(用循环))输入(用循环) 22 )排序(同)排序(同 1010 个整数排序,用双重循环)个整数排序,用双重循环) 33 )输出。)输出。注意注意 ::两个字符串交换时不能直接赋值,需用两个字符串交换时不能直接赋值,需用 strcpy()strcpy() 函数。函数。程序:程序:

Page 45: 第 7 章   数组

综合练习11 、足球彩票系统:、足球彩票系统: 1)1) 单注式:输入本期彩票的正确结单注式:输入本期彩票的正确结果,输入若干单注式彩票,判断每一注是否中得一等果,输入若干单注式彩票,判断每一注是否中得一等或二等奖。(或二等奖。( 22 )复式:输入本期正确结果,输入任)复式:输入本期正确结果,输入任意一张选票的选项,判断是否中得一等(十三场全猜意一张选票的选项,判断是否中得一等(十三场全猜对)、二等奖(猜错一场)。对)、二等奖(猜错一场)。22 、自动阅卷系统 (、自动阅卷系统 ( 11 )单选题的批阅,每题)单选题的批阅,每题 22 分。分。 (2)(2) 多选题的批阅多选题的批阅 : (A): (A)错选一个即全错。错选一个即全错。 (B)(B) 多选一个多选一个即全错,少选时选对一个的一分。每题 即全错,少选时选对一个的一分。每题 44 分。分。

Page 46: 第 7 章   数组

exercise

11 、上机调试题、上机调试题 22 、习题 、习题 1 1 、 、 33 、、 66 、、 77