720 likes | 826 Views
第六章 数组. 引例. 一维数组的使用. 二维数组的使用. 字符串及字符数组的使用. 数组作函数参数. 引 例. 例:读入三个数,按大小排序,并打印出来。. 读入 a , b , c. 流 程 图. a>b. F. T. a>c. b>c. F. T. F. T. b>c. a>c. F. T. F. T. 打印 b,a,c. 打印 a,b,c. 打印 c,b,a. 打印 c,a,b. 打印 a,c,b. 打印 b,c,a. 程序:.
E N D
第六章 数组 • 引例 • 一维数组的使用 • 二维数组的使用 • 字符串及字符数组的使用 • 数组作函数参数
引 例 例:读入三个数,按大小排序,并打印出来。 读入a,b,c 流 程 图 a>b F T a>c b>c F T F T b>c a>c F T F T 打印 b,a,c 打印 a,b,c 打印 c,b,a 打印 c,a,b 打印 a,c,b 打印 b,c,a
程序: #include <stdio.h> void main( ) 流程图: { int a, b, c; scanf("%d,%d,%d", &a, &b, &c); 读入a,b,c if(a>b) a>b F T {if(b>c) printf("%d,%d,%d\n",a,b,c); a>c b>c F T F T else if(a>c) printf("%d,%d,%d\n",a,c,b); b>c a>c T F F T 打印 b,a,c 打印 a,b,c 打印 c,b,a 打印 c,a,b 打印 a,c,b else printf("%d,%d,%d\n",c,a,b); } 打印 b,c,a else {if(a>c) printf("%d,%d,%d\n",b,a,c); else if(b>c) printf("%d,%d,%d\n",b,c,a); 运行: 4,2,9 else printf("%d,%d,%d\n",c,b,a);} } 9,4, 2
第十讲 引 例 对于三个数按大小排序 有6种情况 3! 对于十个数按大小排序 有10!种情况 ? 3628800
引 例 将10个数按大小排序 用a[1],a[2],a[3]…,a[10]来存放这10个数 1. 从10个数中找出最大的,放在 a[1]中; 2. 从9个数中找出最大的,放在a[2]中; … 9. 从2个数中找出最大的,放在a[9]中。 j= …10 i+1 如何找? a[1]与a[2],a[3] …,a[10] a[2]与a[3],a[4] …,a[10] i=1…10-1 … a[9]与a[10]
引 例 #include <iostream.h> void main( ) { int i, j, temp, a[11]; for(i=1; i<=10; i++) cin>>a[i]; for(i=1; i<10; i++) for(j=i+1; j<=10; j++) if(a[i]<a[j]) { temp=a[i]; a[i]=a[j]; a[j]=temp; } for(i=1; i<=10; i++) cout<<a[i]<<" "; } 流程图: 输入要排序的数 for i=1 to 10-1 for j=i+1 to 10 a[i]<a[j] T F a[i]<=>a[j] 输出排好序的数 数组是具有相同数据类型的变量的有序集合。 数组中的每一个变量称为该数组的元素。
一维数组的使用 • 数组的定义 类型名 数组名[整型常量]; char c[200]; float f[5]; 例如: int a[11]; 注意:数组长度必须是一个常量,不允许出现变量。 const int N=10; int a[N]; int n; cin>>n; int a[n]; 错! ok #define N 10 int a[N];
一维数组的使用 • 数组的引用 只能引用单个的数组元素,不能一次引用整个数组。 数组名[下标] - 引用数组元素的格式: 下标是整型表达式,可以是变量、常量、表达式。 下标的合理取值范围是0~数组长度-1。 a[0]=23; a[k-2]=a[0]+1; cin>>a[8]; scanf("%d",&a[8]); 例如: int a[11]; 11个元素: … a[0] a[1] a[10] 没有a[11] 数组元素的使用方法与同类型的变量完全相同。 注意:数组下标不能越界。
一维数组的使用 数组a • 一维数组的存储结构 a[0] 数组在内存中占据一片连续的存储单元,数组元素的存放顺序与下标的顺序一致。 a[1] ...... 例如: int a[11]; a[10] 数组元素对号入座,顺序存储 int a0, a1, a2, …, a10; 变量无序
数组b b[0] b[1] b[4] 一维数组的使用 类型名 数组名[数组长度] = {初值表}; • 数组的初始化 数组b int b[5]={0, 1, 2, 3, 4}; 例1: b[0] 0 int b[5]; b[0]=0; b[1]=1; b[2]=2; b[3]=3; b[4]=4; 等价于: b[1] 1 ...... b[4] 4 1 int b[5]={1}; 例2: 0 int b[5]={1, 0, 0, 0, 0}; 等价于: ...... int b[ ]={1, 2, 3, 4, 5}; 例3: 0 等价于: int b[5]={1, 2, 3, 4, 5};
举 例 例4:利用数组计算斐波那契数列的前10个数, 即1, 1, 2, 3, 5, …,55, 并按每行打印5个数的格式输出。 分析: #include <stdio.h> void main( ) { int a[10]={1, 1}, i; for(i=2; i<10; i++) a[i]=a[i-1]+a[i-2]; for(i=0; i<10; i++) { printf("%4d", a[i]); if((i+1)%5==0) printf("\n"); } } 用数组a计算并存放前10个数 a[0] = a[1] = 1 a[i] = a[i-1] + a[i-2] (2≤i≤9) a[0]=1 a[1]=1 for i=2 to 9 a[i]=a[i-1]+a[i-2] for i=0 to 9 输出a[i]
举 例 输入n 例6:输入一个整数n(1<n<=10) 再输入n个整数,将它们存入数组a中。 输出最小值和它所对应的下标,将最小值与第一个数交换,输出交换后的n个数。 for i=0 to n-1 输入a[i] mini=0 for i=1 to n-1 a[mini]>a[i] T F mini=i 输出mini a[mini] 交换a[0]和a[mini] for i=0 to n-1 输出a[i]
#include <stdio.h> void main() { int a[10], n, i, temp, mini; scanf("%d", &n); for(i=0; i<n; i++) scanf("%d", &a[i]); mini=0; for(i=1; i<n; i++) if(a[mini]>a[i]) mini=i; printf("%d:%d\n",mini,a[mini]); temp=a[0]; a[0]=a[mini]; a[mini]=temp; for(i=0; i<n; i++) printf("%d ", a[i]); } 输入n for i=0 to n-1 输入a[i] mini=0 for i=1 to n-1 a[mini]>a[i] T F mini=i 输出mini a[mini] 交换a[0]和a[mini] for i=0 to n-1 输出a[i]
找最大值和最小值 例2:输入n个数,找其中的最大值与最小值。 #include <iostream.h> void main() { int a[50], i, n, maxi, mini; cin>>n; for(i=0; i<n; i++) cin>>a[i]; maxi=0; mini=0; for(i=1; i<n; i++) { if(a[maxi]<a[i]) maxi=i; if(a[mini]>a[i]) mini=i; } cout<<a[maxi]<<" " <<a[mini]<<endl; }
查 找 例3:查找一个数是否在某数组中出现。 #include <iostream.h> void main() { int a[50], i, n, x, flag; cin>>n; for(i=0; i<n; i++) cin>>a[i]; cin>>x; while(i<n&&flag==0) if(a[i]==x) flag=1; else i++; if(flag) cout<<"YES:"<<i; else cout<<"NO"; } • 顺序查找法 设数组为a,待查找的数为x 把x与数组a中的元素从头到尾一一进行比较 flag=0; i=0; 输入n, a, x flag:标志 flag=0 i=0 1:查到 i<n && flag==0 0:没查到 a[i]==x T F i:数组元素 的下标 flag=1 i++
折半查找法 基本思想:假设数组a已经按由小到大的顺序排好序,设三个变量low, high和mid分别代表首元素,最后一个元素以及中间元素的下标,初值分别为:low=0、high=n-1、mid=(low+high)/2。从中间元素开始查找,用x和a[mid]比较,此时有三种情况: 1) 若a[mid] == x,则查找成功; 2) 若a[mid] > x,则令high=mid-1 3) 若a[mid] < x,则令low=mid+1
5 13 19 21 37 56 64 75 80 88 92 low mid high 5 13 19 21 37 56 64 75 80 88 92 low mid high 5 13 19 21 37 56 64 75 80 88 92 low mid high 例:数组元素为:{5, 13, 19, 21, 37, 56, 64, 75, 80, 88, 92} 1.查找x=21 的情况 (1) low=0; high=10; mid=(0+10) / 2=5 0 1 2 3 4 5 6 7 8 9 10 因为a[mid]>x,所以向左找,令high=mid-1=4 (2) low=0; high=4; mid=(0+4) / 2=2 0 1 2 3 4 5 6 7 8 9 10 因为a[mid]<x,所以向右找,令low=mid+1=3 (3) low=3; high=4; mid=(3+4) / 2=3 0 1 2 3 4 5 6 7 8 9 10 因为a[mid]==x,查找成功,所查元素的下标为mid
5 13 19 21 37 56 64 75 80 88 92 low mid high 5 13 19 21 37 56 64 75 80 88 92 low mid high 5 13 19 21 37 56 64 75 80 88 92 low mid high 2.查找x=85 的情况 (1) low=0; high=10; mid=(0+10) / 2=5 0 1 2 3 4 5 6 7 8 9 10 因为a[mid]<x,所以向右找,令low=mid+1=6 (2) low=6; high=10; mid=(6+10) / 2=8 0 1 2 3 4 5 6 7 8 9 10 因为a[mid]<x,所以向右找,令low=mid+1=9 (3) low=9; high=10; mid=(9+10) / 2=9 0 1 2 3 4 5 6 7 8 9 10 因为a[mid]>x,所以向左找,令high=mid-1=8 此时low>high,查找失败
选择排序法 #include <iostream.h> void main( ) { int a[50], i, j, n, maxi, temp; cin>>n; for(i=0; i<n; i++) cin>>a[i]; for(i=0; i<n-1; i++) maxi=i; for(j=i+1; j<n; j++) if(a[maxi]<a[j]) maxi=j; temp=a[i]; a[i]=a[maxi]; a[maxi]=temp; } for(i=0; i<=n-1; i++) cout<<a[i]<<" "; } 例4:将任意n个数由大到小排序。 #include <iostream.h> void main( ) { int a[50], i, j, n, temp; cin>>n; for(i=0; i<n; i++) cin>>a[i]; for(i=0; i<n-1; i++) for(j=i+1; j<n; j++) if(a[i]<a[j]) { temp=a[i]; a[i]=a[j]; a[j]=temp; } for(i=0; i<=n-1; i++) cout<<a[i]<<" "; } {
a[1] a[2] a[3] a[4] a[5] 由小到大排序 3 8 4 2 1 j=1 to 4 3 4 2 1 8 3 4 8 2 1 3 4 2 8 1 3 8 4 2 1 3 8 4 2 1 第一轮 3 4 2 1 8 3 4 2 1 8 3 2 1 4 8 3 2 4 1 8 j=1 to 3 第二轮 第三轮 3 2 1 4 8 2 1 3 4 8 2 3 1 4 8 j=1 to 2 2 1 3 4 8 1 2 3 4 8 j=1 to 1 第四轮
a 0 1 2 3 a0 1 3 4 9 8 5 2 3 5 2 4 6 a0 a1 a1 a2 a2 [0] [1] [2] [3] a a[0] a[1] a[2] 二维数组的定义、 引用、 存储结构、 初始化、 输入\输出
二维数组的使用 • 数组的定义 类型名 数组名[行长度] [列长度]; 例如: int a[3][4]; 定义一个二维数组a, 3行 4列, 共12个整型元素 数组名[行下标] [列下标] • 数组元素的引用 行下标的合理取值范围是0~行长度-1 列下标的合理取值范围是0~列长度-1 a[0] [0] a[0] [1] a[0] [2] a[0] [3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3] 注意:元素下标不能越界。
二维数组的使用 • 存储结构 按行存储 数组a a[0][0] a[0] [0] a[0] [1] a[0] [2] a[0] [3] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] a[1][3] a[0][3] a[1][0] a[2][0] a[2][1] a[2][2] a[2][3] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3]
a[0][0] a[0][0] a[0][1] a[0][1] a[0][2] a[0][2] a[1][0] a[1][0] a[1][1] a[1][1] a[1][2] a[1][2] 1 2 0 4 0 0 a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 二维数组的分行初始化 例 int a[2][3]={{1,2,3},{4,5,6}}; 全部初始化 1 2 3 4 5 6 例 int a[2][3]={{1,2},{4}}; 部分初始化 1 2 0 4 0 0 例 int a[ ][3]={{1,2},{4}}; 行长度可以省略
a[0][0] a[0][0] a[0][0] a[0][1] a[0][1] a[0][1] a[0][2] a[0][2] a[0][2] a[1][0] a[1][0] a[1][0] a[1][1] a[1][1] a[1][1] a[1][2] a[1][2] a[1][2] 按存储顺序初始化 全部初始化 例 int a[2][3]={1,2,3,4,5,6}; 1 2 3 4 5 6 部分初始化 例 int a[2][3]={1,2,4}; 1 2 4 0 0 0 行长度可以省略 例 int a[ ][3]={1,2,3,4,5}; 1 2 3 4 5 0
二维数组的输入和输出 例6:将一个3×4矩阵输入到数组中并按行输出。 1 0 9 7 for i=0 to 2 i=0~2 4 6 8 3 for j=0 to 3 j=0~3 12 3 3 5 输入a[i][j] #include <stdio.h> void main( ) { int a[3][4], i, j; for(i=0; i<=2; i++) 1□0□9□7 for(j=0; j<=3; j++) 4□6□8□3 scanf("%d", &a[i][j]); 12□3□3□5 for(i=0; i<=2; i++) □□1□□0□□9□□7 { for(j=0; j<=3; j++) □□4□□6□□8□□3 □1 2□□3□□3□□5 printf("%3d",a[i][j]); printf("\n"); } }
二维数组的输入和输出 for(i=0; i<3; i++) { for(j=0; j<=i; j++) printf("%3d",a[i][j]); printf("\n"); } 0 1 2 1 2 3 4 5 6 7 8 9 0 1 2 for(i=0; i<3; i++) for(j=0; j<i; j++) printf(" "); for(j=i; j<3; j++) printf("%3d",a[i][j]); printf("\n"); } 0 1 2 { 1 2 3 4 5 6 7 8 9 0 1 2 三个空格
举 例 1 4 2 5 3 6 1 2 3 4 5 6 a= b= 例2:将二维数组行列元素互换,存到另一个数组中。 #include <iostream.h> #include <iomanip.h> void main( ) { int a[2][3]={{1, 2, 3}, {4, 5, 6}}; int b[3][2], i, j; for(i=0; i<2; i++) for(j=0; j<3; j++) b[j][i]=a[i][j]; for(i=0; i<3; i++) { for(j=0; j<2; j++) cout<<setw(4)<<b[i][j]; cout<<endl; } }
例3:求二维数组中最大元素值及其行列号。 #include <stdio.h> void main( ) { int a[3][4]={ {1, 2, 3, 4}, {9, 8, 7, 6}, {-10, 10, -5, 2} }; int i, j, row, column, max; max=a[0][0]; for(i=0; i<3; i++) for(j=0; j<4; j++) if(a[i][j]>max) { max=a[i][j]; row=i; column=j; } printf("max=%d,row=%d,column=%d",max,row,column); } row=0; column=0;
例4:程序功能是求二维数组每列元素的平均值,修改程序中的错误。例4:程序功能是求二维数组每列元素的平均值,修改程序中的错误。 #include <iostream.h> #define M 3 void main( ) { int a[M][M]={1,2,3,4,5,6,7}; int i, j; float ave[M] ; for(i=0; i<M; i++) { for(j=0; j<M; j++) ave[i]=ave[i]+a[j][i]; ave[i]=ave[i]/M; } for(j=0; j<M; j++) cout<<" "<<ave[j]; } #include <iostream.h> #define M 3; void main( ) { int a[M][M]={1,2,3,4,5,6,7} int i, j; for(i=0; i<M; i++) { for(j=0; j<M; j++) ave[i]=ave[i]+a[i][j]; ave[i]=ave[i]/M; } for(j=0; j<M; j++) cout<<" "<<ave[j]; } ={0}
12 4 6 8 23 3 15 7 9 2 5 17 12 4 6 22 8 23 3 34 15 7 9 31 2 5 17 24 373935111 例5:将下表的数据读到数组中,分别计算各行、各列以及表中所有数之和。 0 1 2 3 for(j=0; j<3; j++) a[4][j]=0; for(i=0; i<4; i++) a[i][3]=0; a[4][3]=0; 0 1 2 3 4 输入 赋初值 求和 输出 各行之和: 各列之和: 所有元素之和: for(i=0; i<4; i++) for(j=0; j<3; j++) a[i][3]+=a[i][j]; for(j=0;j<3;j++) for(i=0;i<4;i++) a[4][j]+=a[i][j]; for(j=0;j<3;j++) for(i=0;i<4;i++) a[4][3]+=a[i][j];
12 4 6 8 23 3 15 7 9 2 5 17 12 4 6 22 8 23 3 34 15 7 9 31 2 5 17 24 373935111 例5:将下表的数据读到数组中,分别计算各行、各列以及表中所有数之和。 #include <iostream.h> #include <iomanip.h> void main( ) { int a[5][4]={0}, i, j; for(i=0; i<4; i++) for(j=0; j<3; j++) cin>>a[i][j]; for(i=0; i<4; i++) for(j=0; j<3; j++) { a[i][3]+=a[i][j]; a[4][j]+=a[i][j]; a[4][3]+=a[i][j]; } 0 1 2 3 0 1 2 3 4 初始化 输入 累加 输出 for(i=0; i<5; i++) { for(j=0; j<4; j++) cout<<setw(5)<<a[i][j] ; cout<<endl; } }
字符串及字符数组的使用 字符数据 字符串 字符数组 字符串处理函数
字 符 数 据 • 字符常量 '一个字符' 如:'a','b','1','?','' 字符常量的特点: 字符常量只能用单引号括起来。 字符常量只能是单个字符。 字符可以是数字,但数字被定义为字符型之后就不能再表示原来的数值了。 转义字符: 一种特殊的字符常量 以反斜杠"\"开头,后跟一个或多个字符。
如:'\101' 代表ASCII值是65的字符 A '\x6a' 代表ASCII值是106的字符 j
字 符 数 据 • 字符变量 如:char a, b, ch; 赋值: ch = 'A'; ch A ch = 65; 输入输出: cin>>ch; cout<<ch; scanf("%c",&ch); printf("%c",ch); ch=getchar( ); putchar(ch); <iostream.h> <stdio.h> <stdio.h>
字 符 串 "字符序列" • 字符串常量 如:"", "A", "string", "thank you", "OK\n" 字符串的存储: '\0'是字符串结束标志 s t r i n g \0 #include <iostream.h> void main( ) { char c; c="A"; cout<<c; } 注意"A"和'A'的区别: "A" A \0 'A' A
字 符 数 组 • 定义方式 char 数组名[常量]; c[0] c[1] c[9] 例: char c[10]; …… • 初始化 ①逐个数组元素赋初值 a r t y \0 char c[6] = {'P','a','r','t','y','\0'}; P ②使用字符串常量赋初值 char c[6] = {"Party"}; char c[5] = "Party"; char c[6] = "Party";
字 符 数 组 例6:确定数组元素的值及长度。 #include <iostream.h> void main( ) { char t1[ ]="student"; char t2[ ]={'s', 't', 'u', 'd', 'e', 'n', 't'}; …… } s t u d e n t \0 t1 s t u d e n t t2
字符数组的输入和输出 • 逐个字符输入输出 #include <iostream.h> void main( ) { char str[50]; int i, n; cin>>n; for(i=0; i<n; i++) cin>>str[i]; str[n]='\0'; for(i=0; i<n; i++) cout<<str[i]; } 这种方法并不常用
… 字符数组的输入和输出 • 整个字符串输入输出 scanf("%s", 数组名); cin>>数组名; printf("%s", 数组名); cout<<数组名; 例7 写结果 遇到空格或回车 就结束读操作, 自动加'\0' bei fang #include <iostream.h> void main( ) { char str[20]; cin>>str; cout<<str; } bei str[0] str[19] b e i \0 • 输入字符串时,字符串的长度最大是字符数组的长度-1。 • 遇到'\0'就结束输出,如果一个字符数组包含多个'\0'时, • 则遇到第一个'\0'就结束输出操作。
… 字符数组的输入和输出 • 整个字符串输入输出 例8 写结果 gets(数组名); #include <stdio.h> void main( ) { char str[20]; gets(str); puts(str); } puts(数组名); 输入时遇到回车符结束读操作,自动加'\0' 输出时遇到'\0'结束输出, 自动换行。 bei fang bei fang gets: '\n'变 '\0' str[19] str[0] puts: '\0'变 '\n' b e i f a n g \0
程序举例 例9计算字符串的有效长度。字符串的有效长度就是有效 字符的个数,即第一个'\0'前面的字符个数 。 0 1 2 3 4 5 … a str p p H y \0 #include <iostream.h> void main( ) { char str[80]="Happy"; int i; for(i=0; str[i]!='\0'; i++); cout<<str<<"有效长度是:"<<i; } 字符串一般通过'\0'来控制循环
… … … 程序举例 例10将两个字符串首尾相接后输出。 (1)检测字符串的长度 str1: How a str2: re you? (2)连接 str1 H o w a \0 len=0 str2 r e y o u ? \0 当str1[len]!='\0' len++ 连接后: i=0 str1: How are you? 当str2[i]!='\0' str1[len]=str2[i] H o w a r e y o u ? \0 len++,i++ str1[len]='\0'
程序举例 #include <stdio.h> void main() { len=0 char str1[40],str2[20]; 当str1[len]!='\0' int i=0,len=0; len++ gets(str1); i=0 gets(str2); 当str2[i]!='\0' while(str1[len]!='\0') str1[len]=str2[i] len++; len++,i++ while(str2[i]!='\0') str1[len]='\0' str1[len++]=str2[i++]; str1[len]='\0'; puts(str1); }
… 字符数组的输入和输出 • 整个字符串输入输出 scanf("%s", 数组名); cin>>数组名; printf("%s", 数组名); cout<<数组名; 例7 写结果 遇到空格或回车 就结束读操作, 自动加'\0' bei fang #include <iostream.h> void main( ) { char str[20]; cin>>str; cout<<str; } bei str[0] str[19] b e i \0 • 输入字符串时,字符串的长度最大是字符数组的长度-1。 • 遇到'\0'就结束输出,如果一个字符数组包含多个'\0'时, • 则遇到第一个'\0'就结束输出操作。
… 字符数组的输入和输出 • 整个字符串输入输出 例8 写结果 gets(数组名); #include <stdio.h> void main( ) { char str[20]; gets(str); puts(str); } puts(数组名); gets遇到回车符结束读操作,自动加'\0' puts遇到'\0'结束输出, 自动换行。 bei fang bei fang gets: '\n'变 '\0' str[19] str[0] puts: '\0'变 '\n' b e i f a n g \0
程序举例 例9计算字符串的有效长度。字符串的有效长度就是有效 字符的个数,即第一个'\0'前面的字符个数 。 0 1 2 3 4 5 … a str p p H y \0 #include <iostream.h> void main( ) { char str[80]; int len; cin>>str; for(len=0; str[len]!='\0'; len++); cout<<str<<"有效长度是:"<<len; } 字符串一般通过'\0'来控制循环
… … … 程序举例 例10将两个字符串首尾相接后输出。 (1)检测字符串1的长度 str1: How a str2: re you? (2)连接 str1 H o w a \0 len=0 str2 r e y o u ? \0 当str1[len]!='\0' len++ 连接后: i=0 str1: How are you? 当str2[i]!='\0' H o w a r e y o u ? \0 str1[len]=str2[i] len++ i++ str1[len]='\0'
程序举例 #include <stdio.h> void main() len=0 { char str1[40], str2[20]; 当str1[len]!='\0' int i=0, len=0; len++ gets(str1); i=0 gets(str2); 当str2[i]!='\0' while(str1[len]!='\0') len++; str1[len]=str2[i] len++ while(str2[i]!='\0') i++ str1[len++]=str2[i++]; str1[len]='\0' str1[len]='\0'; puts(str1); }