530 likes | 608 Views
第 7 章 数 组. 数组:一种数据类型. C 语言的数据类型. 整型 实型 字符型. 单精度型 双精度. 基本类型 构造类型 指针类型 空类型. 数组 结构 联合 枚举. 数据类型. 引言. 整型 int 、字符型 char 、实型 float 、 double 是简单变量 , 相互之间无 任何联系 , 要表示数学上的矢量、矩阵、下标变量等比较困难。. 例如 一个班级 30 个学生 , 求某门课的平均分数 float a0,a1,a2,a3,...,a29,average; ……..
E N D
第7章 数 组 数组:一种数据类型 C语言的数据类型 整型 实型 字符型 单精度型 双精度 基本类型 构造类型 指针类型 空类型 数组 结构 联合 枚举 数据类型
引言 整型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
数组由许多元素组成 每个元素对应一个存储单元 数组元素有共同的名,访问数组元素通过下标实现 用下标表示数组元素之间的联系。 若改用数组 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是数组的下标,
§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],全部为实型。
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]); 其优点,数组的下标是可变的
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.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
输入数组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"); }
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
#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>31 1 3 1 2 3>11 2 1 2 3 1>80 2 4 1>90 输出 2 1 1 3 6 8 9
例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
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] 交换 …
#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
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
注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个元素均是不定值
注当数组指明的元素个数大于初值个数时,初值只赋予数组开注当数组指明的元素个数大于初值个数时,初值只赋予数组开 始若干个元素,余下部分为相响应类型的缺省值。 例 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
例验证哥德巴赫猜想:任何一个大于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"); }}
§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 数组元素在内存排序,按行存放
多维数组定义 格式 类型说明符 数组名[数组长度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 多维数组元素在内存排序,靠右的维数先变,依次向左变化
2.二维数组元素的引用 格式 数组名[下标1] [下标2] 多维数组 数组名[下标1] [下标2]...[下标n] 其中 数组名在说明部分已定义过 下标可以是整型常量、变量、表达式,各下标值必须在定 义的取值范围,即0~定义下标的数组长度-1 如 float a[3][4]; a[1][2]=a[2][3]/2;
0 1 1 2 2 3 7.2.2 使用二维数组编程 例7-6定义32的二维数组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
#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
例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]); }
例7-7输入一个正整数n(1<n≤6),再输入nn的方阵,然后将该方阵转置(行列互换)后输出。例7-7输入一个正整数n(1<n≤6),再输入nn的方阵,然后将该方阵转置(行列互换)后输出。 例 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"); } }
转置(行列互换)即为对角线为界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; }
例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"); } }
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
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}};
注(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}} 即
例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代表月份
算法 定义数组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;} 程序
§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个元素,是字符型 在内存存放
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等价
(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"); }
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
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'不作输出
(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); }
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?"
例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); } /*输入一行中不能有空格*/
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
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];
由于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
例 两个数组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.形参是变量,实参可以是数组元素,形参与实参结合是单值传递 数组元素
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); } 数组 数组名
注 (1)数组名是数组内存的首地址,数组的虚实结合是地址传递,把实参数组的起始地址传递形参数组,两个数组共占一段内存单元 如 形参a [10]与实参x[10]结合 xa a [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] 起始地址 存储单元 x [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] 由此可见实际实参数组在运行,因而函数执行完毕实参数组的内 容可能被改变。利用这点可以使函数返回更多的值。
例 编一函数,用选择法对数组(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数组的数据被改变,小→大排序
(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; } } 函数的形参省略维数定义数组适应程序的通用性
例 有一个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)); }
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]
作业:第7章作业 下载http://www.ccea.zju.edu.cn/clearn/ 实验:第7次实验