数组 梁春燕 华电信息管理教研室
主要内容 数组概念 一维数组 二维数组及多维数组 字符数组和字符串 小结 上机作业
数组概念 C语言数据类型 数组:有序数据的集合,用数组名标识 元素:属同一数据类型,用数组名和下标确定 基本数据类型:整型、字符型、浮点型 构造数据类型:数组、结构体、共用体 数组:有序数据的集合,用数组名标识 元素:属同一数据类型,用数组名和下标确定
一维数组 一维数组的定义 定义方式: 数据类型 数组名[常量表达式]; 例 int a[6]; a [ ] :数组运算符 优先级(1) [ ] :数组运算符 优先级(1) 左结合 不能用( ) 一维数组的定义 定义方式: 数据类型 数组名[常量表达式]; 例 int a[6]; 合法标识符 表示元素个数 下标从0开始 a[0] 1 4 5 a[1] a[2] a[3] a[4] a[5] 2 3 a 编译时分配连续内存 内存字节数=数组维数* sizeof(元素数据类型) 数组名表示内存首地址, 是地址常量
一维数组的引用 例 int i=15; 例 int data[5]; int data[i]; (不能用变量定义数组维数) data[5]=10; //C语言对数组不作越界检查,使用时要 注意 数组必须先定义,后使用 只能逐个引用数组元素,不能一次引用整个数组 数组元素表示形式: 数组名[下标] 其中:下标可以是常量或整型表达式 例 int a[10]; printf(“%d”,a); () 必须 for(j=0;j<10;j++) printf(“%d\t”,a[j]); ()
一维数组的初始化 初始化方式 在定义数组时,为数组元素赋初值 (在编译阶段使之得到初值) int a[5]={1,2,3,4,5}; 等价于:a[0]=1; a[1]=2; a[2]=3; a[3]=4; a[4]=5; 说明: 数组不初始化,其元素值为随机数 对static数组元素不赋初值,系统会自动赋以0值 只给部分数组元素赋初值 当全部数组元素赋初值时,可不指定数组长度 如 int a[5]={6,2,3}; 等价于: a[0]=6; a[1]=2;a[2]=3; a[3]=0; a[4]=0; 如 int a[3]={6,2,3,5,1}; () static int a[5]; 等价于:a[0]=0; a[1]=0; a[2]=0; a[3]=0; a[4]=0; int a[]={1,2,3,4,5,6}; 编译系统根据初值个数确定数组维数
例 用冒泡法对10个数排序 排序过程: (1)比较第一个数与第二个数,若为逆序a[0]>a[1],则交换;然 例 用冒泡法对10个数排序 排序过程: (1)比较第一个数与第二个数,若为逆序a[0]>a[1],则交换;然 后比较第二个数与第三个数;依次类推,直至第n-1个数和第 n个数比较为止——第一趟冒泡排序,结果最大的数被安置在 最后一个元素位置上 (2)对前n-1个数进行第二趟冒泡排序,结果使次大的数被安置在 第n-1个元素位置 (3)重复上述过程,共经过n-1趟冒泡排序后,排序结束
例 用冒泡法对8个数排序(图解) (程序见 P134 例7.3) 13 27 第七趟 49 38 65 97 76 13 27 30 初始关键字 n=8 38 49 65 76 13 27 30 97 第一趟 38 49 13 27 30 65 第三趟 13 27 30 38 第五趟 38 38 49 65 13 27 30 76 第二趟 13 13 27 30 第六趟 例 38 13 27 30 49 第四趟 49 13 27 38 13 27 49 38 30 76 13 27 65 30 49 38 97 13 27 76 30 65 49 27 97 76 30 65 例 用冒泡法对8个数排序(图解) (程序见 P134 例7.3) 97 30 76 97
例 用简单选择法对10个数排序 排序过程: (1)首先通过n-1次比较,从n个数中找出最小的, 将它与第一个数 例 用简单选择法对10个数排序 排序过程: (1)首先通过n-1次比较,从n个数中找出最小的, 将它与第一个数 交换—第一趟选择排序,结果最小的数被安置在第一个元素位置上 (2)再通过n-2次比较,从剩余的n-1个数中找出关键字次小的记录, 将它与第二个数交换—第二趟选择排序 (3)重复上述过程,共经过n-1趟排序后,排序结束
例 用简单选择法对7个数排序 k k k 例 i=1 初始: [ 49 38 65 97 76 13 27 ] 13 49 j j j j 例 用简单选择法对7个数排序 k k k 例 i=1 初始: [ 49 38 65 97 76 13 27 ] 13 49 j j j j j j k k i=2 一趟: 13 [38 65 97 76 49 27 ] 27 38 j j j j j 二趟: 13 27 [65 97 76 49 38 ] 三趟: 13 27 38 [97 76 49 65 ] 四趟: 13 27 38 49 [76 97 65 ] 五趟: 13 27 38 49 65 [97 76 ] 六趟: 13 27 38 49 65 76 [97 ]
二维数组及多维数组 二维数组的定义 定义方式: 数据类型 数组名[常量表达式][常量表达式]; 数组元素的存放顺序 原因:内存是一维的 int c[2][3][4] 1 2 3 4 5 6 7 ………... 20 21 22 23 c[0][0][0] c[0][0][1] c[0][0][2] c[0][0][3] c[0][1][0] c[0][1][1] c[0][1][2] c[0][1][3] c[0][2][0] c[0][2][1] c[0][2][2] c[0][2][3] c[1][0][0] c[1][0][1] c[1][0][2] c[1][0][3] c[1][1][0] c[1][1][1] c[1][1][2] c[1][1][3] c[1][2][0] c[1][2][1] c[1][2][2] c[1][2][3] 二维数组的定义 定义方式: 数据类型 数组名[常量表达式][常量表达式]; 元素个数=行数*列数 列数 行数 数组元素的存放顺序 原因:内存是一维的 二维数组:按行序优先 多维数组:最右下标变化最快 例 int a[3][4]; float b[2][5]; int c[2][3][4]; int a[3,4]; () int a[3][2] a[0][1] a[1][0] a[1][1] a[2][0] a[2][1] 1 4 5 2 3 a[0][0] a[0][0] a[0][1] a[1][0] a[1][1] a[2][0] a[2][1]
二维数组理解 a[0] 例 int a[3][4]; a[1] a[2] 1 4 5 2 3 a[0][1] a[0][2] a[0][3] 1 4 5 2 3 a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[0][0] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3] a[1][2] 6 7 10 11 8 9 a[0] a[1] a[2] 二维数组a是由3个元素组成 例 int a[3][4]; 2016 17 2018 19 2020 21 2022 23 2008 9 2010 11 2012 13 2014 15 2000 1 2002 3 2004 5 20006 7 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[0] a[1] a[2] 行名 每个元素a[i]由包含4个元素 的一维数组组成
二维数组元素的引用 二维数组元素的初始化 形式: 数组名[下标][下标] 分行初始化: 形式: 数组名[下标][下标] 二维数组元素的初始化 分行初始化: 例 int a[2][3]={{1,2,3},{4,5,6}}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 3 4 5 6 全部初始化 例 int a[2][3]={{1,2},{4}}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 4 部分初始化 例 int a[][3]={{1},{4,5}}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 4 5 第一维长度省略初始化 例 int a[2][3]={1,2,4}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 4 部分初始化 按元素排列顺序初始化 例 int a[2][3]={1,2,3,4,5,6}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 3 4 5 6 全部初始化 例 int a[][3]={1,2,3,4,5}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 3 4 5 第一维长度省略初始化
程序举例 例 将二维数组行列元素互换,存到另一个数组中 #include <stdio.h> main() 例 将二维数组行列元素互换,存到另一个数组中 #include <stdio.h> main() { int a[2][3]={{1,2,3},{4,5,6}}; int b[3][2],i,j; 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]); a= 1 2 3 4 5 6 b= 1 4 2 5 3 6
例 求二维数组中最大元素值及其行列号 #include <stdio.h> main() { int a[3][4]={{1,2,3,4}, {9,8,7,6}, {-10,10,-5,2}}; int i,j,row=0,colum=0,max; max=a[0][0]; for(i=0;i<=2;i++) for(j=0;j<=3;j++) if(a[i][j]>max) { max=a[i][j]; row=i; colum=j; } printf("max=%d,row=%d, \ colum=%d\n",max,row,colum); 例 求二维数组中最大元素值及其行列号 max=a[0][0] for i=0 to 2 for j=0 to 3 a[i][j]>max 真 假 max=a[i][j] row=i colum=j 输出:max和row,colum
字符数组和字符串 字符数组 定义 例 char c[10], ch[3][4]; 字符数组的初始化 逐个字符赋值 用字符串常量 字符数组的引用 有问题! 例 char ch[5]={‘H’,’e’,’l’,’l’,’o’}; ch[0] H e l o 逐个字符赋值 ch[1] ch[2] ch[3] ch[4] 例 char ch[5]={‘H’,’e’,’l’,’l’,’o’}; ch[0] H e l o 逐个字符赋值 ch[1] ch[2] ch[3] ch[4] 例 char ch[5]={‘B’,’o’,’y’}; ch[0] B o y \0 逐个字符赋值 ch[1] ch[2] ch[3] ch[4] 例 char ch[5]=“Boy”; ch[0] B o y \0 用字符串常量 ch[1] ch[2] ch[3] ch[4] 例 char ch[6]={“Hello”}; char ch[6]=“Hello”; char ch[]=“Hello”; 用字符串常量 ch[0] H e l o ch[1] ch[2] ch[3] ch[4] \0 ch[5]
二维字符数组初始化 例 char diamond[][5]={{'.', '.','*'},{'.','*','.','*'}, {'*', '.', '.', '.' ,'*'},{'.','*', '.','*'},{'.', '.','*'}}; 二维字符数组初始化 . * \0 diamond[0] diamond[1] diamond[2] diamond[3] diamond[4] 例 char fruit[][7]={“Apple”,”Orange”, ”Grape”,”Pear”,”Peach”}; 二维字符数组初始化 fruit[0] fruit[1] fruit[2] fruit[3] fruit[4] A p l e \0 O r a n g G P c h
h e l l o \0 字符串 字符串及其结束标志 无字符串变量,用字符数组处理字符串 字符串结束标志:‘\0’ 104 101 108 108 111 0 内存存放字符ASCII码
字符串的输入输出 逐个字符I/O: %c 整个字符串I/O: %s 例 用%c main() { char str[5]; int i; 用字符数组名,不要加& 输入串长度<数组维数 遇空格或回车结束 自动加‘\0’ 例 用%c main() { char str[5]; int i; for(i=0;i<5;i++) scanf(“%c”, &str[i]); printf(“%c”, str[i]); } 例 用%s main() { char str[5]; scanf(“%s”, str); printf(“%s”, str); } 用字符数组名, 遇‘\0’结束
例子 main() { int i; char a[5]; scanf("%s",a); for(i=0;i<5;i++) printf("%d,",a[i]); } 例子 输入字符串长度<数组维数 h e l \0 h e l l \0 h e l l o 运行情况: (1)若输入 hel , 正常 (2)若输入 hell , 正常 (3)若输入 hello , 用%s 输出时,会出现问题
例 字符串输入举例 #include <stdio.h> main() { char a[15],b[5],c[5]; 例 字符串输入举例 运行情况: 输入:How are you? 输出:a=How b=are c=you? #include <stdio.h> main() { char a[15],b[5],c[5]; scanf("%s%s%s",a,b,c); printf("a=%s\nb=%s\nc=%s\n",a,b,c); scanf("%s",a); printf("a=%s\n",a); } scanf中%s输入时,遇空格或回车结束 运行情况: 输入:How are you? H o w \0 a r e \0 y o u ? \0
常用的字符串处理函数 例 #include <stdio.h> main( ) { char string[80]; 包含在头文件 string.h 字符串输出函数puts 格式:puts(字符数组) 功能:向显示器输出字符串(输出完,换行) 说明:字符数组必须以‘\0’结束 例 #include <stdio.h> main( ) { char string[80]; printf(“Input a string:”); gets(string); puts(string); } 输入: How are you? 输出: How are you ? 字符串输入函数gets 格式:gets(字符数组) 功能:从键盘输入一以回车结束的字符串放入字符数组中, 并自动加‘\0’ 说明:输入串长度应小于字符数组维数
常用的字符串处理函数(1) 例 char str1[20],str2[20]; str1={“Hello!”}; () 字符串连接函数strcat 格式:strcat(字符数组1,字符数组2) 功能:把字符数组2连到字符数组1后面 返值:返回字符数组1的首地址 说明:字符数组1必须足够大 连接前,两串均以‘\0’结束;连接后,串1的‘\0’取消, 新串最后加‘\0’ 常用的字符串处理函数(1) 字符串拷贝函数strcpy 格式:strcpy(字符数组1,字符串2) 功能:将字符串2,拷贝到字符数组1中去 返值:返回字符数组1的首地址 说明:字符数组1必须足够大 拷贝时‘\0’一同拷贝 不能使用赋值语句为一个字符数组赋值 例 char str1[20],str2[20]; str1={“Hello!”}; () str2=str1; ()
常用的字符串处理函数(2) 例 对于以下字符串,strlen(s)的值为: 字符串比较函数strcmp 功能:比较两个字符串 比较规则:对两串从左向右逐个字符比较(ASCII码), 直到遇到不同字符或‘\0’为止 返值:返回int型整数,a. 若字符串1< 字符串2, 返回负整数 b. 若字符串1> 字符串2, 返回正整数 c. 若字符串1== 字符串2, 返回零 说明:字符串比较不能用“==”,必须用strcmp 常用的字符串处理函数(2) 字符串长度函数strlen 格式:strlen(字符数组) 功能:计算字符串长度 返值:返回字符串实际长度,不包括‘\0’在内 例 对于以下字符串,strlen(s)的值为: (1)char s[10]={‘A’,‘\0’,‘B’,‘C’,‘\0’,‘D’}; (2)char s[ ]=“\t\v\\\0will\n”; (3)char s[ ]=“\x69\082\n”; 答案:1 3 1
例 字符串处理函数举例 How are you?Hello! Len1=6,Len2=12,Len3=18 #include <string.h> #include <stdio.h> main() { char str1[] = ”Hello!", str2[] = ”How are you?”,str[20]; int len1,len2,len3; len1=strlen(str1); len2=strlen(str2); if(strcmp(str1, str2)>0) { strcpy(str,str1); strcat(str,str2); } else if (strcmp(str1, str2)<0) { strcpy(str,str2); strcat(str,str1); } else strcpy(str,str1); len3=strlen(str); puts(str); printf(”Len1=%d,Len2=%d,Len3=%d\n”,len1,len2,len3); } 例 字符串处理函数举例 How are you?Hello! Len1=6,Len2=12,Len3=18
应用举例 例 输入一行字符,统计其中有多少个单词 输入一字符串给 string i=0 num=0 word=0 例 输入一行字符,统计其中有多少个单词 输入一字符串给 string i=0 num=0 word=0 当((c=string[i])!=‘\0’) c==空格 真 假 word=0 word=1 num=num+1 i=i+1 输出:num word==0 #include <stdio.h> main() { char string[81]; int i,num=0,word=0; char c; gets(string); for(i=0;(c=string[i])!='\0';i++) if(c==' ') word=0; else if(word==0) { word=1; num++; } printf("There are %d words \ in the line\n",num); }
例子图解 例 输入:I am a boy. 当前字符=空格 是 否 未出现新单词,使word=0,num不累加 是否空格 否 是 1 是 1 未 否 是 1 2 否 1 未 2 是 1 未 2 否 是 1 3 是 1 未 3 否 是 1 4 否 1 未 4 否 1 未 4 否 1 未 4 word原值 新单词开始否 word新值 num值
例 有十个学生的成绩,求平均分 92 85 68 75 54 88 98 45 61 79 a 例 有三个学生四门课成绩 例 有十个学生的成绩,求平均分 92 85 68 75 54 88 98 45 61 79 a 例 有三个学生四门课成绩 92 85 68 75 54 88 98 45 61 79 81 40 张三 李四 王二 数学 化学 英语 物理 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 92 85 68 54 88 98 45 75 61 79 二维数组 #include <stdio.h> main() { int k , a[10], sum=0; for(k=0;k<10;k++) scanf(“%d”,&a[k]); sum+=a[k]; printf(“Average is %d\n”,sum/10); }
小结
小结 数组:有序数据的集合,用数组名标识;元素属同一数据类型,用数组名和下标确定 一维数组:定义、引用、初始化 排序法:冒泡法,简单选择法 二维数组及多维数组:定义、引用、初始化 字符数组和字符串:定义、引用、初始化 常用的字符串处理函数:gets, puts, strcpy, strcmp, strcat, strlen
上机作业3-小结 编写程序,根据输入的百分制成绩,输出相应的成绩等级A、B、C、D、E (习题5.6) : 猴子吃桃问题(习题6.10): 作业3小结: 编写程序,根据输入的百分制成绩,输出相应的成绩等级A、B、C、D、E (习题5.6) : 要求:分别使用if语句和switch语句来实现;如果输入出错,给出出错信息。 猴子吃桃问题(习题6.10): 题目改为猴子每天吃了前一天剩下的一半后,再吃两个。 C语言基本结构:include,main(),变量定义,变量使用 if 语句:if~else 的配对,{ }的使用,判断条件的边界 switch语句:case后空格、常量表达式、break的使用 循环:循环变量的初始值、终止值和增量,循环体 作业:源文件(.c)、可执行文件(.exe) – 如何查看文件后缀
上机作业4 试验目的 掌握一维数组和二维数组的定义、赋值和输入输出方法; 熟练掌握字符数组和字符串函数的使用; 掌握与数组有关的算法(排序算法)。
上机作业4 试验内容 用选择法对15个整数排序(整数用scanf输入)。然后,输入一个数,用折半查找法找出该数是数组的第几个元素的值。如果该数不在数组中,则输出“无此数”。 在周一12:00之前,将作业(源程序和可执行程序)压缩后提交到此目录下: ftp://202.204.71.134/上机作业4/
END void main() { void sort(int array[], int n); #include<stdio.h> void main() { void sort(int array[], int n); void find(int array[],int n); int a[15],i; printf("Enter the array\n"); for(i=0;i<15;i++) scanf("%d",&a[i]); sort(a,15); printf("The sorted array:\n"); printf("%5d",a[i]); printf("\n"); find(a,15); } void sort(int array[],int n) int i,j,k,t; for(i=0;i<n-1;i++) k=i; for(j=i+1;j<n;j++) if(array[j]<array[k]) k=j; t=array[k];array[k]=array[i];array[i]=t; void find(int array[],int n) int t,low,high,mid,found,m; low=0;high=n-1;found=0; printf("Input a number to be searched:"); scanf("%d",&t); while(low<=high) {mid=(high+low)/2; if(t==array[mid]) {found=1;m=mid;break;} else if (t>array[mid]) low=mid+1; else high=mid-1; if(found==1)printf("Found %d and xiabiao is %d",t,m); else printf("Not found %d",t); } END