1 / 53

数组:一种数据类型

第 7 章 数 组. 数组:一种数据类型. C 语言的数据类型. 整型 实型 字符型. 单精度型 双精度. 基本类型 构造类型 指针类型 空类型. 数组 结构 联合 枚举. 数据类型. 引言. 整型 int 、字符型 char 、实型 float 、 double 是简单变量 , 相互之间无 任何联系 , 要表示数学上的矢量、矩阵、下标变量等比较困难。. 例如 一个班级 30 个学生 , 求某门课的平均分数 float a0,a1,a2,a3,...,a29,average; ……..

Télécharger la présentation

数组:一种数据类型

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第7章 数 组 数组:一种数据类型 C语言的数据类型 整型 实型 字符型 单精度型 双精度 基本类型 构造类型 指针类型 空类型 数组 结构 联合 枚举 数据类型

  2. 引言 整型int、字符型char、实型float、double是简单变量,相互之间无 任何联系,要表示数学上的矢量、矩阵、下标变量等比较困难。 例如 一个班级30个学生,求某门课的平均分数 float a0,a1,a2,a3,...,a29,average; …….. average=(a0+a1+a2+a3+a4+...+a29)/30 average=0; average= average+a0; average= average+a1; average= average+a2; ……. average= average+a29; average= average/30; average= average+ai; i=0,1,2,…,29

  3. 数组由许多元素组成 每个元素对应一个存储单元 数组元素有共同的名,访问数组元素通过下标实现 用下标表示数组元素之间的联系。 若改用数组 average= average+a[i]; i=0,1,2,…,29 程序得到简化 float a[30],average=0; …….. for(i=0;i<30;i++) average=average+a[i] average=average/30 其中 a是数组名,a[i]是数组元素,i是数组的下标,

  4. §7.1 一维数组 7.1.1 一维数组的定义和引用 1.定义 格式 类型名 数组名[数组长度] 其中 类型名定义数组元素的类型 数组名 按标识符规则取名 数组长度表示该数组的元素个数,及 元素的下标范围0~数组长度-1之间 操作 定义数组名、全体元素的类型、元素的个数、数组元素的 下标取值范围,分配相应的内存单元 例 int a[10]; float f[5]; 表示 a是数组名,有10个元素,下标取值在0~9之间,即a[0],a[1], a[2]~a[9],全部为整型。 f是数组名,有5个元素,下标取值在0~4之间,即f[0],f[1], f[2], f[3],f[4],全部为实型。

  5. 2.引用 格式 数组名[下标] 其中 数组名在说明部分已定义过 下标可以是整型常量、变量、表达式,下标值必须在定 义的取值范围 ,即0~数组长度-1之间 例 int a[10],k=3; a[0]=a[1]+a[k]-a[2*3]; 数组元素的使用方法与同类型的变量相同 • 例 scanf("%d", &a[i]); • temp = a[i]; a[i]= a[k]; a[k] = temp; • printf("%d ",a[i]); 其优点,数组的下标是可变的

  6. i a[i]=i 0 a[0]=0 1 a[1]=1 … 8 a[8]=8 9 a[9]=9 例 voidmain() {int i,a[10]; for (i=0;i<=9;i++) a[i]=i; for (i=9;i>=0;i--) printf("%3d",a[i]); } i a[i] 9 a[9]9 8 a[8]8 … 0 a[0]0 输出 9 8 7 6 5 4 3 2 1 0 注数组使用之前必须先定义 只能引用单个的数组元素,不能一次引用整个数组 数组元素下标不要越界 例 int a[9]; a[1]=2*a[9]; 错误(语法不错)

  7. 7.1.2 使用一维数组编程 例7-2求Fibonacci(斐波那契)数列的前20个数 1, 1, 2, 3, 5, 8, 13, ... 用f数组存放。  f[0]=1 i=0 f[1]=1 i=1 f[i]=f[i-2]+f[i-1] 2≤i≤19 1 1 2 3 5 8 13 … f[0] f[1] f[2] f[3] f[4] f[5] f[6] #include "stdio.h" void main() {int i, f[20];f[0]=1;f[1]=1; for(i=2;i<20;i++) f[i]=f[i-2]+f[i-1]; for(i=0;i<20;i++) {printf("%d ",f[i]); if((i+1)%5==0) printf("\n"); } } f[0]=1 f[1]=1 i=2 f[2]=f[0]+f[1]=1+1=2 i=3 f[3]=f[1]+f[2]=1+2=3 i=4 f[4]=f[2]+f[3]=2+3= 5 i=5 f[5]=f[3]+f[4]=3+5= 8 …… i=19 f[19]=f[17]+f[18]=6765

  8. 输入数组a 输入x i=0,n-1,1 1 x==a[i] 0 输出i i 0 i>=n 1 Not Found 停 例7-3输入n个互异的整数,将它们存入数组中,再输入1个数x,然后在数组中找x。如果找到,输出相应的下标,否则输出“Not Found”。 算法 将x与数组元素依次比较。 无序数据序列的查找(遍历算法) #include "stdio.h" void main() {int i,n,a[20]; scanf("%d",&n); for(i=0;i<n;i++) scanf("%d",&a[i]); for(i=0;i<n;i++) if(x==a[i]) {printf("i=%d\n",i);break;} if(i>=n) printf(" Not Found\n"); }

  9. a,b, c,d 输入 min=a 0 min>b 1 0 i=1,n-1,1 min=b min>x 1 0 min>a[i] min=x 0 1 min>c min=a[i] 1 min=c 0 min>d i 1 min=d min 输出 停 例7-4 输入一个正整数n(1<n≤10),再输入n个整数,存入数组a中。 (1)输出最小值和它所对应的下标。 (2)将最小值与第一个数交换,输出交换后的n个数。 index=0 min=a[0] index=i i=a[index] a[index]=a[0] a[0]=i

  10. #include "stdio.h" void main() {int i,index=0,n,a[10]; scanf("%d",&n); for(i=0;i<n;i++) scanf("%d",&a[i]); for(i=1;i<n;i++) if(a[index]>a[i])index=i; printf("%d %d\n", index,a[index]); i=a[index];a[index]=a[0];a[0]=i; for(i=0;i<n;i++) printf("%d",a[i]);} index=0 i=1,n-1,1 0 a[index]>a[i] 1 index=i i i=a[index] a[index]=a[0] a[0]=i 设输入 5 6 3 1 8 9 a[0] a[1] a[2] a[3] a[4] index i a[index]>a[i] index=i a[index] 0 1 6>31 1 3 1 2 3>11 2 1 2 3 1>80 2 4 1>90 输出 2 1 1 3 6 8 9

  11. 例7-1选择法排序 对n个数小到大排序 算法 (1)在n个数(a[0]~a[n-1])中找到最小数,将它与a[0]交换。 (2)在未排序的n-1个数(a[1]~a[n-1])中找到最小数,将它与a[1]交换。 …… (n-1)未排序的2个数(a[n-2]~a[n-1])中找到最小数,将它与a[n-2]交换 确定第1最小1与a[0]对换 如 2 6 1 8 7 4 5 确定第2小值2与a[1]对换 1 6 2 8 7 4 5 确定第3小值4与a[2]对换 1 2 6 8 7 4 5 确定第4小值5与a[3]对换 1 2 4 8 7 6 5 确定第5小值6与a[4]对换 1 2 4 5 7 6 8 确定第6小值 1 2 4 5 6 7 8

  12. i=0,1,...,n - 2 index= i j=i+1,i+2,...,n - 1 0 a[j]<a[ index] 1 index= j j t=a[i] a[i]=a[ index] a[ index] =t i 把思路用流程图描述n个数先存入a数组a[0]~a[n-1]中 n个数 (a[0]~a[n-1]) 中找最小数,与 a[0] 交换 n-1个数 (a[1]~a[n-1]) 中找最小数,与 a[1] 交换 2个数 (a[n-2]~a[n-1]) 中找最小数,与 a[n-2] 交换 …

  13. #include "stdio.h" void main() {int i,j,n, index; float a[10],t; scanf("%d",&n); for(i=0;i<n;i++) scanf("%f",&a[i]); for(i=0;i<n-1;i++) {index=i; for(j=i+1;j<n;j++) if(a[j]<a[index]) index=j; t=a[i];a[i]=a[index];a[index]=t; } for(i=0;i<n;i++) printf("%f ",a[i]); printf("\n"); } i=0,1,...,n-2 index=i j=i+1,i+2,...,n-1 0 a[j]<a[index] 1 index=j j t=a[i] a[i]=a[index] a[index]=t i

  14. 7.1.3 一维数组的初始化 在定义数组的同时即给数组元素赋值 格式 类型名 数组名[数组长度]={常量表达式序列} 其中 常数表达式序列:常数表达式1,常数表达式2,...即初值 操作 将常数表达式序列的初值依次赋值于数组各元素 如 int a[10] ={0,1,2,3,4,5,6,7,8,9}; 经过定义初始化后 a[0]=0,a[1]=1,...a[9]=9 注当定义数组的长度省略,则数组个数由初值个数决定 如 int a[]={1,2,3,4,5}; 即为 int a[5]; a[0]=1,a[1]=2,a[2]=3,a[3]=4,a[4]=5

  15. 注ANSI C 规定只有静态存储的数组才能初始化 static int a[10] ={0,1,2,3,4,5,6,7,8,9}; 但一般的C编译系统允许自动型数组也能初始化 auto int a[10] ={0,1,2,3,4,5,6,7,8,9}; 省略auto的,即为自动型 static型与auto型区别 存储单元分配: static分配固定存储空间 auto动态分配存储空间 存储单元缺省值:static为0 auto为随机值 例static int a[5]; a数组的5个元素全为0 auto int b[5]; b数组的5个元素均是不定值

  16. 注当数组指明的元素个数大于初值个数时,初值只赋予数组开注当数组指明的元素个数大于初值个数时,初值只赋予数组开 始若干个元素,余下部分为相响应类型的缺省值。 例 static int a[10]={0,1,2,3,4}; 即为 a[0]=0,a[1]=1,a[2]=2,a[3]=3,a[4]=4;a[5]~a[9]=0 int b[10]={0,1,2,3,4}; 即为 b[0]=0,b[1]=1,b[2]=2,b[3]=3,b[4]=4;b[5]~b[9]=不定值 实际上,TC或VC b[5]~b[9]仍为0

  17. 例验证哥德巴赫猜想:任何一个大于6的偶数均可表示为两个素数之和。例如6=3+3,8=3+5,…,18=7+11。要求将6~100之间的偶数都表示成两个素数之和,打印时一行打印5组。例验证哥德巴赫猜想:任何一个大于6的偶数均可表示为两个素数之和。例如6=3+3,8=3+5,…,18=7+11。要求将6~100之间的偶数都表示成两个素数之和,打印时一行打印5组。 #include<stdio.h> void main() {int num[26]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,91,97}; int i,j,m,line=0; for(i=6;i<=100;i+=2) for(j=0;j<26;j++) for(m=j;m<26;m++) if(num[m]+num[j]==i) {line++; printf("%d=%d+%d ",i,num[j],num[m]); if(line%5==0) printf("\n"); }}

  18. §7.2 二维数组 7.2.1 二维数组定义和引用 1.定义 格式 类型说明符 数组名[数组长度1] [数组长度2] 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] 与一维数组比较,多了一个下标,一般称前个下标为行, 第二个称为列 例 float a[3][4]; 定义了 a数组 3行4列 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] 1 2 3 4 5 6 7 8 9 10 11 12 数组元素在内存排序,按行存放

  19. 多维数组定义 格式 类型说明符 数组名[数组长度1] ...[数组长度n] n个数组长度为n维数组 例 float a[2][3][4]; 定义了 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 多维数组元素在内存排序,靠右的维数先变,依次向左变化

  20. 2.二维数组元素的引用 格式 数组名[下标1] [下标2] 多维数组 数组名[下标1] [下标2]...[下标n] 其中 数组名在说明部分已定义过 下标可以是整型常量、变量、表达式,各下标值必须在定 义的取值范围,即0~定义下标的数组长度-1 如 float a[3][4]; a[1][2]=a[2][3]/2;

  21. 0 1 1 2 2 3 7.2.2 使用二维数组编程 例7-6定义32的二维数组a,数组元素的值由下式给出 a[i][j]=i+j (0≤i≤2,0 ≤j≤1) 将该数组元素按矩阵的形式输出 i j a[i][j]=i+j #include "stdio.h" void main() {int i,j,a[3][2]; for(i=0;i<3;i++) for(j=0;j<2;j++) a[i][j]=i+j; for(i=0;i<3;i++) {for(j=0;j<2;j++) printf("%4d",a[i][j]); printf("\n"); } } • 0 0 a[0][0]=0+0=0 • 0 1 a[0][1]=0+1=1 • 1 0 a[1][0]=1+0=1 • 1 1 a[1][1]=1+1=2 • 0 a[2][0]=2+0=2 • 2 1 a[2][1]=2+1=3 输出: 0 1 1 2 2 3

  22. #include "stdio.h" void main() {char a[3][2],i,j; for(i=0;i<3;i++) for(j=0;j<2;j++) a[i][j]=i+j; for(i=0;i<3;i++) for(j=0;j<2;j++) printf("%d ",a[i][j]); printf("\n"); for(j=0;j<6;j++) printf("%d ",a[0][j]); } a[0][0]=0 a[0][1]=1 a[1][0]=1 相同于 a[0][2] a[1][1]=2 a[0][3] a[2][0]=2 a[0][4] a[2][1]=3 a[0][5] 说明: 行下标*列长度+列下标<行长度*列长度 输出 0 1 1 2 2 3 0 1 1 2 2 3 如a[0][5], 0*2+5<3*2

  23. 例7-5将1个3*2的矩阵存入1个3*2的二维数组中,找出最大值以及它的行下标和列下标,并输出该矩阵。例7-5将1个3*2的矩阵存入1个3*2的二维数组中,找出最大值以及它的行下标和列下标,并输出该矩阵。 算法 遍历矩阵全部元素,比较,找出最大值 设 row 记录最大值的行下标 col 记录最大值的列下标 a[row][col] 就是最大值 void main( ) { int col, i, j, row;int a[3][2]; for(i=0;i<3;i++) for(j=0;j<2;j++) scanf("%d", &a[i][j]); row = col = 0; for(i = 0; i < 3; i++) for(j = 0; j < 2; j++) if(a[i][j] > a[row][col]) {row = i; col = j; } printf("max=a[%d][%d]=%d\n",row,col,a[row][col]); }

  24. 例7-7输入一个正整数n(1<n≤6),再输入nn的方阵,然后将该方阵转置(行列互换)后输出。例7-7输入一个正整数n(1<n≤6),再输入nn的方阵,然后将该方阵转置(行列互换)后输出。 例 n=3 分析 方阵转置 a[i][j] => b[j][i] i=0,1,…n-1 j=0,1,…n-1 #include "stdio.h" void main() {int i,j,n,a[6][6],b[6][6]; scanf("%d",&n); for(i=0;i<n;i++) for(j=0;j<n;j++) scanf("%d",&a[i][j]); for(i=0;i<n;i++) for(j=0;j<n;j++) b[j][i]=a[i][j]; for(i=0;i<n;i++) for(j=0;j<n;j++) a[i][j]=b[i][j]; for(i=0;i<n;i++) {for(j=0;j<n;j++) printf("%4d",a[i][j]); printf("\n"); } }

  25. 转置(行列互换)即为对角线为界a[i][j] <=> a[j][i] a[0][1] <=> a[1][0] a[0][2] <=> a[2][0] a[1][2] <=> a[2][1] 遍历上三角阵 遍历下三角阵 • i<=j • i>=j for(i=0;i<n-1;i++) for(j=i+1;j<n;j++) {t=a[j][i]; a[j][i]=a[i][j]; a[i][j]=t; } for(i=1;i<n;i++) for(j=0;j<i;j++) {t=a[j][i]; a[j][i]=a[i][j]; a[i][j]=t; }

  26. 例7-7 利用对角线为界a[i][j] <=> a[j][i] ,程序得到简化 #include "stdio.h" void main() {int i,j,n,t,a[6][6]; scanf("%d",&n); for(i=0;i<n;i++) for(j=0;j<n;j++) scanf("%d",&a[i][j]); for(i=0;i<n-1;i++) for(j=i+1;j<n;j++) {t=a[j][i]; a[j][i]=a[i][j]; a[i][j]=t; } for(i=0;i<n;i++) {for(j=0;j<n;j++) printf("%4d",a[i][j]); printf("\n"); } }

  27. 7.2.3二维数组的初始化 两种形式 1.按顺序赋初值 格式 类型说明符 数组名[数组长度1][数组长度2] ={常量表达式序列} ; 操作 将常数表达式序列的初值依次赋值于数组各元素,数组元素 按行排序(内存单元排序) 例 int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; 即 a[0][0]=1 a[0][1]=2 a[0][2]=3 a[0][3]=4 a[1][0]=5 a[1][1]=6 a[1][2]=7 a[1][3]=8 a[2][0]=9 a[2][1]=10 a[2][2]=11 a[2][3]=12

  28. 2.分行赋初值 格式 类型说明符 数组名[数组长度1][数组长度2] ={{常量表1},{常量表2},...,{常量表n}} ; 操作 将常数表1赋值于数组第一行元素, 将常数表2赋值于数组第 二行元素,..., 将常数表n赋值于数组第n行元素 例 int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; 获得同上结果 注(1)方法比较, 后者优越,一行数据对一行数组元素,界限清楚;特 别当行尾有零元素不必在初值表中列出 例 int a[3][3]={{1,2,5},{0,0,0},{4,5,0}}; 简化为 int a[3][3]={{1,2,3},{},{4,5}};

  29. 注(2)数组元素赋初值时,定义第一维的长度可以缺省注(2)数组元素赋初值时,定义第一维的长度可以缺省 例 int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12}; 即 int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; 又例 int a[][4]={{0,0,3},{},{0,10,0}} 即

  30. 例7-8定义一个函数day_of_year(year,month,day)计算并返回year、month和day是该年的第几天。例7-8定义一个函数day_of_year(year,month,day)计算并返回year、month和day是该年的第几天。 例如,调用day_of_ year(2000,3,1)返回61, 2000年是闰年 调用day_of_year(1999,3,1)返回60 , 1999年不是闰年 显然,对1~month-1的月天数累加,再加上当月的day。但2月的天数根据是否闰年取29天或28天 用数组tab[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31}};存放 显然 非闰年使用tab[0][k] 闰年使用tab[1][k] 其中 k代表月份

  31. 算法 定义数组tab[2][13] 初始化各月份的天数 根据年份year确定是否闰年 (判别闰年的条件为能被4整除但不能被100整除,或能被400整除) 根据月份month累加1~ month-1月份的天数 最后加上当月的天数 int day_of_year(int year,int month,int day) {int k,leap,s=0; int tab[2][3]={ {0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31}}; leap=(year%4==0&&year%100!=0)||year%400==0; for(k=1;k<month;k++) s+=tab[leap][k]; s+=day; return s;} 程序

  32. §7.3 字符串与数组 printf("I am happy\n"); 在C语言中,字符串的存储和运算可以用一维字符数组来实现。 7.3.1一维字符数组 一维字符数组用于存放字符型数据。它的定义、初始化和引用与其他类型的一维数组一样。 1.定义 例 char c[10]; c[0]='I'; c[1]=' '; c[2]='a'; c[3]='m'; c[4]=' '; c[5]='h'; c[6]='a'; c[7]='p'; c[8]='p'; c[9]='y'; 定义 c数组名,包含10个元素,是字符型 在内存存放

  33. 2.初始化 例 char c[10]={'I',' ','a','m',' ','h','a','p','p','y'}; 注 (1)初值的个数不能超过元素的个数 如 char a[5]={'I',' ','a','m',' ','h','a','p','p','y'}; 不允许 (2)初值的个数少于元素的个数,将数值赋于前面的数组元素 余下元素以字符\0充填 如 char c[11]={'I',' ','a','m',' ','h','a','p','p','y'}; c: I am happy\0 \0 ASCII为0的字符,作为字符串的结束 等价于 char c[11]={'I',' ','a','m',' ','h','a','p','p','y','\0'}; char c[11]={'I',' ','a','m',' ','h','a','p','p','y',0}; 注:在字符数组'\0'与0等价

  34. (3)当数组长度缺省,由初值个数决定数组元素的个数(3)当数组长度缺省,由初值个数决定数组元素的个数 如 char c[ ]= {'c',' ','p','r','o','g','r','a','m'}; 自动定义c数组9个元素,即 c[9] (4)多维数组的初始化 如 char c[2][3]={{'a','b','c'},{'1','2','3'}}; 3.引用 格式 数组名[下标] 例 main() {char c[10]={'I',' ','a','m',' ','h','a','p','p','y'}; int i; for(i=0;i<10;i++) printf("%c",c[i]);/*putchar(c[i]);*/ printf("\n"); }

  35. 7.3.2字符串 1.字符串定义 字符串 “字符序列” 每个字符串后都有字符串结束标志'\0' ,控制字符串的操作 例 printf("this is a C program.\n"); 例 char c[10]={'I',' ','a','m',' ','b','o','y','\0'}; c是字符串 2.字符串初始化 C语言用字符数组存放字符串,字符串可以赋初值于字符数组 例 char s[10]={"Happy"}; 或 char s[10]="Happy"; 或 char s[ ]="Happy"; char s[10]={'H','a','p','p','y'}; 自动加上'\0' 但char s[5]={'H','a','p','p','y'}; 或char s[]={'H','a','p','p','y'}; s不是字符串 注 字符串不能在语句中对数组赋值 如 char s[10]; s="Happy"; 不允许 而只能 s[0]='H';s[1]='a'; s[2]='p';s[3]='p'; s[4]='y';s[6]='\0'; 或用库函数 strcpy(s, "Happy"); 该库函数在string.h

  36. 3.字符串的输入和输出 (1)字符串输出 用putchar()或printf()的%c的输出 void main() {int i=0;char c[11]={"I am happy"}; while(c[i]!='\0') putchar(c[i++]);/*或 printf("%c",c[i++]);*/ } printf()的%s的输出 例 char c[ ]="I am happy"; printf("%s\n",c); 输出 I am happy 注 输出的对象是地址,字符数组仅写数组名 遇到'\0',输出结束,而'\0'不作输出

  37. (2)字符串输入 用getchar()或scanf()的%c的输入 void main() {int i=0;char c[20]; while((c[i]=getchar())!='\n') i++; c[i]= '\0'; /*使c成为字符串*/ printf("%s\n",c); } void main() {int i=0;char c[20]; scanf("%c",&c[0]); while(c[i]!='\n') {i++; scanf("%c",&c[i]); } c[i]='\0'; /*使c成为字符串*/ printf("%s\n",c); }

  38. scanf()的%s的输入 例 char ch[6];scanf("%s",ch); 输入 China 得 ch="China\0" 注 输入的对象是内存地址。字符数组仅写名 输入字符个数少于定义的字符数组元素的个数,系 统自动在输入的字符串后加上\0结束符,因此定义字符数组 数组长度>=字符个数+1 空格符是输入字符串的结束符 例 char str1[5],str2[5],str3[5]; scanf("%s%s%s",str1,str2,str3); 输入数据 How are you? 得 str1="How" str2="are" str3="you?"

  39. 例7-11输入一个以回车结束的字符串(少于80个字符),统计其中数字字符的个数。 分析:由于字符串少于80个字符,数组长度就取其上限80,以'\n'作为输入结束符。 输入:9b465 str #include "stdio.h" void main() {int i=0,count=0;char str[80]; while((str[i]=getchar())!='\n') i++; str[i]='\0'; for(i=0;str[i]!='\0';i++) if(str[i]<='9'&&str[i]>='0') count++; printf("count=%d\n",count); } i: 0 1 2 3 4 5 输出: count=4 #include "stdio.h" void main() {int i=0,count=0;char str[80]; scanf("%s",str); for(i=0;str[i]!='\0';i++) if(str[i]<='9'&&str[i]>='0') count++; printf("count=%d\n",count); } /*输入一行中不能有空格*/

  40. 4.字符串有效长度与字符数组的长度 字符串有效长度:字符串的字符的个数,不包括'\0' 字符数组的长度:字符数组定义的长度,数组元素的个数 例 #include "stdio.h" #include "string.h" void main() {char s[10]="Happy"; int l1,l2; l1=strlen(s);l2=sizeof(s); printf("s=%s l1=%d l2=%d\n",s,l1,l2); l1=strlen("Happy");l2=sizeof("Happy"); printf("s=%s l1=%d l2=%d\n",s,l1,l2); } 运行s=Happy l1=5 l2=10 s=Happy l1=5 l2=6 注:'\0'赋值数组元素,将改变字符串长度 strlen():计算字符串有效长度 sizeof():计算字节数 如上例 s[3]='\0'; 则 s的有效长度为3

  41. 5.字符串应用——进制转换 例7-9输入一个以回车结束的字符串(少于10个字符),它由数字字符组成,将该字符串转换成整数后输出。 例 12345 1×104 +2×103+3×102+4×101+5×100 12345 即为多项式计算 a0xn-1+a1xn-2+… +an-3x2 +an-2x+an-1 x表示数进制 (a0xn-2+a1xn-3+… +an-3x1 +an-2)x+an-1 ((a0xn-3+a1xn-4+… +an-3)x +an-2)x+an-1 …… 改写为 (… ((a0x+a1)x+ a2)x +…+an-2)x+an-1 如 12345 (((1×10+2)×10+3)×10+4)×10+5 程序为: d=0; for(i=0;i<n;i++) d=d*x+a[i];

  42. 由于a[i]是字符 转成数值 a[i]-’0’ 进制 x=10 ,则 程序为: d=0; for(i=0;i<n;i++) d=d*10+a[i]-'0'; 算法 n=0 (a[n]=getchar())!='\n' 0 1 #include "stdio.h" void main() {int n=0,i; long d=0; char a[10]; while((a[n]=getchar())!='\n') n++; a[n]='\0'; for(i=0;a[i]!='\0';i++) d=d*10+a[i]-'0'; printf("%ld\n",d); } n++ d=0 i=0,n-1,1 d=d*10+a[i]-'0' i 输出d

  43. 例 两个数组a、b比较大小 #include "stdio.h" void main() {int a[10],b[10],i,j,n=0,m=0; scanf("%d",&j); for(i=0;i<j;i++) scanf("%d",&a[i]); for(i=0;i<j;i++) scanf("%d",&b[i]); for(i=0;i<j;i++) {if(large(a[i],b[i])==1)m=m+1; else if(large(a[i],b[i])==-1)n=n+1; } if(m>n) printf("a>b\n"); else if(m<n) printf("a<b\n"); else printf("a=b\n"); } large(int x,int y) {int flag; if(x>y)flag=1; else if(x<y) flag= -1; else flag=0; return(flag); } 7.4数组作为函数参数 1.形参是变量,实参可以是数组元素,形参与实参结合是单值传递 数组元素

  44. aver= aver/10; 程序 float average(float a[10]) {int i; float aver=a[0]; for(i=1;i<10;i++) aver= aver +a[i]; aver= aver/10; return(aver); } 2.形参是数组,实参应为数组名 例有一维数组x内放10个学生的成绩,求平均成绩 #include "stdio.h" void main() {float x[10],aver;int i; for(i=0;i<10;i++) scanf("%f",&x[i]); printf("\n"); aver=average(x); printf("average= %f",aver); } 数组 数组名

  45. (1)数组名是数组内存的首地址,数组的虚实结合是地址传递,把实参数组的起始地址传递形参数组,两个数组共占一段内存单元 如 形参a [10]与实参x[10]结合 xa a [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] 起始地址 存储单元 x [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] 由此可见实际实参数组在运行,因而函数执行完毕实参数组的内 容可能被改变。利用这点可以使函数返回更多的值。

  46. 编一函数,用选择法对数组(10个元素)小→大排序 #include "stdio.h" void 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]); printf("\n"); } void sort(int x[10],int n) {int i,j,k,t; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(x[j]<x[k]) k=j; t=x[k];x[k]=x[i];x[i]=t; } } 当sort(a,10)执行完毕,a数组的数据被改变,小→大排序

  47. (2)形、实参数组的类型一致,否则编译出错 (3)形参可以是可调数组,不确定数组元素的个数 一维数组 省略定义元素大小 多维数组 只能省略第一维定义元素大小 如 void sort(int a[],int n) 、int fun(float b[][3][4]) 例 编一函数,用选择法对数组小→大排序 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]); printf("\n"); } void sort(int x[],int n) {int i,j,k,t; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(x[j]<x[k]) k=j; t=x[k];x[k]=x[i];x[i]=t; } } void sort(int x[100],int n) {int i,j,k,t; if(n>100)exit(1); for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(x[j]<x[k]) k=j; t=x[k];x[k]=x[i];x[i]=t; } } 函数的形参省略维数定义数组适应程序的通用性

  48. 例 有一个3×4矩阵,求其中的最大元素 max_value(int a[][4],int n) {int i,j,k,max; max=a[0][0]; for(i=0;i<n;i++) for(j=0;j<4;j++) if(a[i][j]>max)max=a[i][j]; return(max); } main() {static int b[3][4]={{1,3,5,7},{2,4,6,8},{15,17,34,12}}; printf("max_value is %d\n",max_value(b,3)); }

  49. 4.形参、实参的数组元素个数、维数可以不一致,原因是编译不检4.形参、实参的数组元素个数、维数可以不一致,原因是编译不检 查,只是起始地址的传递。原则上实参数组元素个数≥形参数组 元素个数。 main() {int a[3][4]={{1,3,5,7}, {2,4,6,8},{15,17,34,12}}; print(a,12); } void print(int a[],int n) {int i; for(i=0;i<n;i++) {printf("%d ",a[i]); if((i+1)%4==0)printf("\n"); }} 形参 [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] 实参 [0][0] [0][1] [0][2] [0][3] [1][0] [1][1] [1][2] [1][3] [2][0] [2][1] [2][2] [2][3]

  50. 作业:第7章作业 下载http://www.ccea.zju.edu.cn/clearn/ 实验:第7次实验

More Related