160 likes | 278 Views
授课目的: 掌握一维数组、二维数组和字符数组的定义、初始化和应用 授课内容: 第一节 数组程序的概念 第二节 一维数组 第三节 二维数组 第四节 字符数组 第五节 数组作函数的参数 要点、要求及作业. 第七章 数组的程序设计. 第一节 数组程序的概念. 一、数组的基本概念 数组:就是确定了顺序的相同数据类型数据的集合。 数组元素:组成数组的各个变量 数组的维:数组名后 [] 的个数 如: a[1],b[2][3],c[1][2][3] 二、数组解决的问题
E N D
授课目的: 掌握一维数组、二维数组和字符数组的定义、初始化和应用 授课内容: 第一节 数组程序的概念 第二节 一维数组 第三节 二维数组 第四节 字符数组 第五节 数组作函数的参数 要点、要求及作业 第七章 数组的程序设计
第一节 数组程序的概念 • 一、数组的基本概念 • 数组:就是确定了顺序的相同数据类型数据的集合。 • 数组元素:组成数组的各个变量 • 数组的维:数组名后[]的个数 • 如:a[1],b[2][3],c[1][2][3] • 二、数组解决的问题 • 在许多情况下,程序要考虑一组数据的集合,数组是程序用来处理成组出现的同一类相关数据的有效工具。
一、定义 形式: 类型说明符 数组名[常量表达式]; 例:int a[10]; 说明:⑴数组名用标识符表示。 ⑵数组名代表该数组的首地址。 ⑶[]内的常量表达式代表数组的长度,不代表最大下标。 如上例中有十个元素:a[0]……a[9] ⑷[]内一定为常量,不能包含变量,即不能动态定义数组的长度。如: int n; scanf(“%d”,&n); int a[n]; →错误 二、引用 C语言规定,对数值型数组,只能逐个引用数组元素。 数组元素:数组名[下标] 下标:常量、变量、表达式(整型) 如:a[3],a[3+2],a[i](i为整型) 例:main() {int i,a[10]; for(i=0;i<=9;i++) a[i]=i; for(i=9;i>=0;i--) printf(“%d ”,a[i]); } 第二节 一维数组
三、初始化 概念:在编译时,使数组得到初值。 方法: 1、全部初始化 static int a[5]={0,1,2,3,4}; 则:a[0]=0,a[1]=1,……a[4]=4。 注意:static表示“静态存储” 2、部分初始化 static int a[5]={0,1}; 则:a[0]=0,a[1]=1,其余全为0。 3、全部初始化为0 static int a[5]={0,0,0,0,0}; 或:static int a[5]; 4、全部初始化时,数组长度可省略。 static int a[]={0,1,2,3,4}; 四、程序举例 1、用数组求Fibonacci数列的前20项 main() {int i; static int f[20]={1,1}; for(i=2;i<=19;i++) f[i]=f[i-2]+f[i-1]; for(i=0;i<20;i++) {if(i%5==0) printf(“\n”); printf(“%12d”,f[i]); } } 2、用起泡法对10个数排序(由小到大) 思路:将相邻两个数比较,将小的调到前头(如图)。 第二节 一维数组
于是:如果有n个数,则要进行n-1趟比较;在j趟比较中要进行n-j次两两比较。于是:如果有n个数,则要进行n-1趟比较;在j趟比较中要进行n-j次两两比较。 设n=10,为符合人们习惯,定义数组长度为11,程序如下: main() {int a[11],i,j,t; printf(“input 10 numbers:\n”); for(i=1;i<11;i++) scanf(“%d”,&a[i]); for(j=1;j<10;j++) for(i=1;i<=10-j;i++) if(a[i]>a[i+1]) {t=a[i];a[i]=a[i+1];a[i+1]=t;} printf(“the sorted numbers:\n”); for(i=1;i<11;i++) printf(“%d ”,a[i]); } 3、选择法排序 思路:每趟从未经排序的数中找出最小的数,与该趟的第一个数对换。 3,5,-1,6,0,1,2,12,-5 -5,5,-1,6,0,1,2,12,3 -5,-1,5,6,0,1,2,12,3 …… 于是:如有n个数,则要进行n-1趟比较,第i趟中a[i]与其后逐个相比,将最小值与a[i]将换。(程序自已完成) 第二节 一维数组 9 8 5 4 2 0 8 9 5 4 2 0 8 5 9 4 2 0 8 5 4 9 2 0 8 5 4 2 9 0 8 5 4 2 0 9
一、定义 1、定义形式: 类型 数组名[常量1][常量2] 例:float a[3][4],b[4][6]; 数组a用12个元素: 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可看作是三个一维数组,即相当于 float a[0][4],a[1][4],a[2][4]; 2、内存中的存放:按行存放 对多维数组:以最右边的下标先变化为规律,如有:int a[2][3][4]; 则: a[0][0][0] a[0][0][1] a[0][0][2] a[0][0][3] a[0][1][0] a[0][1][1] a[0][1][2] a[0][1][3] a[0][2][0] a[0][2][1] a[0][2][2] a[0][2][3] a[1][0][0] a[1][0][1] a[1][0][2] a[1][0][3] a[1][1][0] a[1][1][1] a[1][1][2] a[1][1][3] a[1][2][0] a[1][2][1] a[1][2][2] a[1][2][3] 二、引用 元素形式:数组名[下标][下标] 注意:下标的范围 三、初始化 1、分行初始化 static int a[2][3]={{1,2,3},{4,5,6}}; 第三节 二维数组
2、不分行 static int a[2][3]={1,2,3,4,5,6}; 3、部分初始化 static int a[3][4]={{1},{5},{9}}; 4、如果全部初始化,定义时第一维长度可以省略,但不可省略第二维长度。 static int a[][3]={1,2,3,4,5,6}; static int a[][4]={{1},{},{0,0,3}}; 四、程序举例 1、求一矩阵的转置矩阵。例: 1 0 0 0 5 0 0 0 9 0 0 0 1 0 0 0 0 6 0 0 0 0 9 0 1 2 3 4 5 6 1 4 2 5 3 6 a= b= 1 0 0 0 5 6 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 9 0 第三节 二维数组 static int a[3][4]={{1},{0,6},{0,0,9}}; static int a[3][4]={{1},{5,6}}; 程序如下: main() {static int a[][3]={{1,2,3},{4,5,6}}; int b[3][2],i,j; static int a[3][4]={{0,2},{},{0,0,9}};
printf(“array a:\n”); for(i=0;i<=1;i++) {for(j=0;j<=2;j++) {printf(“%5d”,a[i][j]); b[j][i]=a[i][j]; } printf(“\n”); } printf(“array b:\n”); for(i=0;i<=2;i++) {for(j=0;j<=1;j++) printf(“%5d”,b[i][j]); printf(“\n”); } } 2、有一个3×4的矩阵,求其中值最大的元素的值,以及其所在的行号和列号。 思路:设第一个最大,与所有元素逐个相比,程序如下: main() {int i,j,row=0,colum=0,max; static int a[3][4]={{1,2,3,4},{9,8,7,6} {-10,10,-5,2}}; 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;colum=j;} printf(“max=%d,row=%d,colum=%d”, max,row,colum); } 第三节 二维数组
一、定义 char c[10]; c[0]=‘A’;c[1]=‘B’;…c[9]=‘Z’; 也可:int c[10]; 二、初始化 1、用字符逐个初始化 static char c[5]={‘C’,’h’,’i’,’n’,’a’}; 数组长度>字符个数:其余为‘\0’; 数组长度<字符个数:出错; 数组长度=字符个数:长度可省略。 2、用字符串整体初始化 static char c[]=“China”; 说明: ⑴字符串结束标志:‘\0’ ①ASCII码为0; ②占一个字节; ③由系统自动加上;④空操作符; ⑤对字符串的各种操作到此结束。 printf(“How are you!\n”); ⑵此时数组长度为6,但人们往往关 心字符串的实际长度。 3、初始化二维数组 第四节字符数组 * * * * * * * * static char d[5][5]= {{‘⊔’,’⊔’,‘*’}, {‘⊔’,‘*’,‘⊔’,‘*’},{‘*’ ,‘⊔’, ‘⊔’, ‘⊔’,‘*’}, {‘⊔’, ‘*’,‘⊔’, ‘*’}, {‘⊔’, ‘⊔’,‘*’}}; 三、引用: for(i=0;i<=4;i++) printf(“%c”,c[i]);
for(i=0;i<5;i++) {for(j=0;j<5;j++) printf(“%c”,d[i][j]); printf(“\n”); } 四、输入和输出 1、逐个字符输入和输出,用“%c”。 2、整个字符串输入和输出,用“%s”。 例:printf(“%s”,c); scanf(“%s”,c); 输出时注意: ⑴输出项为数组名,而不是数组元素。 ⑵输出遇‘\0’结束,且‘\0’不输出。 static char c[10]=“china”; printf(“%s”,c); ⑶如果有多个‘\0’,遇第一个结束。 static char c[]=“very good”; 如再次赋值:“china”, 则 c h i n a \0 \0 \0 \0 \0 v e r y g o o d \0 c h i n a \0o o d \0 第四节字符数组 输入时注意: ⑴输入项为数组名,前不加‘&’。 ⑵输入串的长度应小于数组长度, 系统自动在后面加一个‘\0’。 ⑶输入串中不可有空格。 char str[10]; scanf(“%s”,str); 如输入:very ⊔ good ↙
main() {char s1[20],s2[20]; int i=0,res; printf(“请输入第一个串:”); gets(s1); printf(“请输入第二个串:”); gets(s2); while(s1[i]==s2[i]&&s1[i]!=‘\0’) i++; res=s1[i]-s2[i]; printf(“比较的结果为:%d\n”,res); } 如输入为:“china”和“chinb” 则:比较结果为-1 2、输入一行字符,统计其中有多少 个单词,单词间以空格分隔开。 分析:单词的个数与空格个数有关。 此时:char s1[5],s2[5]; scanf(“%s%s”,s1,s2); 五、字符串处理函数(P94) 函数puts,gets使用时要加如下命令: #include “stdio.h” 其它应加:#include “string.h” 说明:库函数并非C语言本身的组成部分,不同系统会有差异,故这些函数名不是C的关键字。 六、应用举例 1、写程序,实现两个字符串的比较 #include “stdio.h” v e r y \0 第四节字符数组
#include “stdio.h” main() {char str[81],c; int i,num=0,word=0; gets(str); for(i=0;(c=str[i])!=‘\0’;i++) if(c==‘’) word=0; else if(word==0) {num++;word=1;} printf(“there are %d words”,num); } 输入:I am a boy. ↙ 3、有三个字符串,要求找出最大者 #include “stdio.h” #include “string.h” main() {char s[3][20],str[20]; int i; for(i=0;i<3;i++) gets(s[i]); if(strcmp(s[0],s[1])>0) strcpy(str,s[0]); else strcpy(str,s[1]); if(strcmp(s[2],str)>0) strcpy(str,s[2]); printf(“the largest is %s”,str); } 是 未出现新的单词,使word=0,num不累加 当前字符=空格 前字符为空格(word=0),新单词出现,num++,word=1 否 前字符为非空格(word=1),未出现新单词,num不变 第四节字符数组
一、数组元素作函数的实参 传送方式:单向的值传送 其对应的形参用普通变量,程序略。 二、数组名作函数的参数 此时,实参和形参都用数组名。 例1:有一数组score,内放10个学生成绩,求平均成绩。 说明:⑴实参和形参数组要分别定义 ⑵实参与形参数组类型要相同,维数要相等。 ⑶实参与形参的长度可不同,C编译对形参数组的大小不作检查。此时,一般另设一变量,传递数组元素的个数,如例2: 第五节 数组作函数的参数 main() {float score[10],aver; int i; for(i=0;i<10;i++) scanf(“%f”,&score[i]); aver=average(score); printf(“average score is %.2f”,aver); } float average(float array[10]) {int i; float aver,sum=0; for(i=0;i<10;i++) sum=sum+array[i]; aver=sum/10; return(aver); }
float average( array,n) float array[]; int n; {int i; float aver,sum=0; for(i=0;i<n;i++) sum=sum+array[i]; aver=sum/n; return(aver); } main() {static float s1[5]={98,…,45}; static float s2[10]={88,…78.5}; printf(“aver1= %f”,average(s1,5)); printf(“aver2=%f” ,average(s2,10)); } ⑷传送方式:地址传送(隐含双向) 其实质为:形参与实参两个数组共占一段内存单元。 a[0] a[1] a[2] a[3] a[4] 1000 98 77 67 88 95 a b b[0] b[1] b[2] b[3] b[4] 第五节 数组作函数的参数 例3、写一函数对10个数排序 viod sort(int b[],int n) {int i,j,k,t; for(i=0;i<n-1;i++) {k=i; for(j=i+1;j<n;j++) if(b[j]<b[k]) k=j; t=b[i];b[i]=b[k];b[k]=t; } }
main() {int a[10],i; for(i=0;i<10;i++) scanf(“%d”,&a[i]); sort(a,10); for(i=0;i<10;i++) printf(“%d ”,a[i]); } 三、多维数组作参数 1、其数组元素作实参 2、其数组名作参数 要求:实参与形参数组类型和维数都相同,但形参数组只可省略第一维长度。 例4:有一3×4矩阵,求其中最大值 max_value(array) int arrar[][4]; {int i,j,max=array[0][0]; for(i=0;i<3;i++) for(j=o;j<4;j++) if(a[i][j]>max) max=a[i][j]; return(max); } main() {static int a[3][4]={{1,3,5,4}, {3,5,8,9},{10,6,3,0}}; printf(“max=%d\n”,max_value(a)); } 小结:main() {变量说明[→输入] →调用→输出} 第五节 数组作函数的参数
要点、要求及作业 • 要点: • 一维数组的定义、引用、初始化及应用 • 二维数组的定义、引用、初始化及应用 • 字符数组的定义、引用、初始化及应用 • 要求: • 掌握一维数组的使用及常用的算法 • 掌握字符数组的应用,会用它处理字符串 • 作业: • 课本第133页