1 / 36

第 9 章 数组

第 9 章 数组. 第 1 部分: 一维数组的定义 一维数组在内存中的存放 一维数组元素的引用 一维数组的应用. 第 2 部分 二维数组的定义 二维数组的数组名 二维数组表达式 二维数组的应用. 3.100 个数排序? a1,a2,a3,….a100. 讨论:如何用简单的方法表示变量集合 : a1,a2,a3,….a100 ,不能用省略号! 引入一维数组概念 。. 问题导入. 排序问题. 1. 两个数排序? a ,b. if ( a < b ) { t = a; a = b; b = t; }. if ( a < b )

maddy
Download Presentation

第 9 章 数组

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. 第9章 数组 • 第1部分: • 一维数组的定义 • 一维数组在内存中的存放 • 一维数组元素的引用 • 一维数组的应用 • 第2部分 • 二维数组的定义 • 二维数组的数组名 • 二维数组表达式 • 二维数组的应用

  2. 3.100个数排序?a1,a2,a3,….a100 讨论:如何用简单的方法表示变量集合: a1,a2,a3,….a100,不能用省略号! 引入一维数组概念。 问题导入 排序问题 1.两个数排序?a ,b if ( a < b ) { t = a; a = b; b = t; } if ( a < b ) { t = a; a = b; b = t; } if ( a < c ) { t = a; a = c; c = t; } if ( b < c ) { t = b; b = c; c = t; } 2.三个数排序?a, b, c

  3. 数组: 有序数据的表示 数组基本概念: 1.数组: 一组具有相同数据的有序集合。 2.数组元素: 构成数组的成员称为数组单元,即数组元素 3.数组维数 数组下标的个数

  4. §9.1.1 一维数组的定义 1、定义一维数组 类型说明 数组名[exp], 数组名[exp],…其中:exp为常量表达式 例如:int a[100]; 包含变量: a[0],a[1],a[2],….a[99] char c[8]; float x[20]; y[4*M+1];(M是符号常量) float s1[75]; • 注意: • int a[10];不能表示为: int a(10); • 数组名定名规则和简单变量名相同;数组名后是用方括弧括起来的常量表达式,决定了数组元素个数; • 3 数组元素的下标从0开始,最大下标值为数组元素个数减1;

  5. 下标可以是 • 整型常量或 • 整型表达式, 9.2.2、一维数组元素的引用 • 数组必须先定义,后引用,C规定只能引用数组 • 元素,不能一次引用整个数组 • 数组元素的表示形式为: 数组名[下标] 例: int a[8]; //先声明 a[0] = a[5] + a[7] - a[3*2]; //后引用

  6. 9.1.3、一维数组的初始化 1. 在定义数组时对数组元素赋初值 例如: int a[5] = {1, 2, 3, 4, 5}; char c[5]={‘@’,’\n’,’a’,’b’,’\0’}; 2.可以只给部分元素赋初值 例如: int b[5] = {1, 2, 3}; 3.在对全部数组元素赋初值时,可省略数组长度 例如: int c[ ] = {1, 2, 3, 4, 5}; 4.静态数组元素具有自动初始值0 例如: static int d[5];

  7. 例9.1定义30个元素的整型数组,顺序存放1,3,5…奇数,先顺序输出,再逆序输出.例9.1定义30个元素的整型数组,顺序存放1,3,5…奇数,先顺序输出,再逆序输出. #include <stdio.h> #define M 30 main ( ) { int s[M],i,k=1; for ( i = 0; i <M; i++ ) {s[i]=k; k+=2;} for ( i = 9; i<M; i++ ) { printf ("%4d", s[i]); if((i+1)%10==0)printf(“\n”); } }

  8. a=&x; a++; P109:数组名相当于地址常量,不可重新赋值! 首地址 数组名+整数 9.2 一维数组和指针 例: float a[10],*p,x; a表示数组的首地址:&a[0] a[0]表示第一个元素 p=&a[0]; p=a; for(k=0;k<10;k++) p=a+k; for(p=a,k=0;k<10;k++){scanf(“%d”,p);p++;} for(p=a,k=0;k<10;k++) scanf(“%d”,p++); for(p=a;p-a<10;p++) scanf(“%d”,p);

  9. 9.2 首地址的引用, 指针引用一维数组 2) 数组名表示首地址, a (即a+0)等价于&a[0] 类似: a+1: &a[1] a+i : &a[i] for(k=0;k<10;k++) printf(“%4d”,*(a+k)); 等价于: for(k=0;k<10;k++) printf(“%4d”,a[k]); 3) float a[10],*p,k; p=a; for(k=0;k<10;k++)printf(“%4d”,*(p+k));

  10. for(p=a,k=0;k<10;k++) printf(“%4d”,*p);p++); for(p=a,k=0;k<10;k++) printf(“%4d”,*p++); for(p=a,p-a<10;p++) printf(“%4d”,*p); 4) 用带下标的指针变量引用一维数组 例: int *p, s[10], i; p=s; 等价的表达式: (1)s[i] (2)*(s+i) (3) *(p+i) (4) p[i] 非法: s++; s=p; p=&s s不可变,p可变!

  11. §9-3 函数与一维数组及元素的引用 1.数组元素作实参 2.数组名作实参 例9-2 编程,通过一个函数为主函数输入若干大于或等于0的整数,用负数作结束标志;调用另外一个函数输出数组中数据. #include <stdio.h> #define M 100 int arrin(int *); void arrout(int *,int); main ( ) { int s[M],k; k=arrin(s); arrout(s,k); } void arrout(int *a,int n) { int i; for(i=0;i<n;i++) printf(((i+1)%5==0)?”%4d”:”%4d”,*(a+i)); printf(“\n”); } int arrin(int *a) { int i,x; i=0; scanf(“%d”,&x); while(x>=0) { *(a+i)=x; i++; scanf(“%d”,&x); } return i; }

  12. void setstar(char *,int); void arrout(char *a,int n); 例9-3 编写函数,把具有10个元素的char类型数组元素中的除前4个外的其他元素变成*. #include <stdio.h> #define M 10 #define B 4 main( ) { char c[M]={‘A’,’B’,’C’,’D’,’E’,’F’,’G’,’H’,’I’,’J’; setstar(&c[4],M-B); arrout(c,M); } void arrout(char *a,int n) { int i; for(i=0;i<n;i++) printf(“%c”,a[i]); printf(“\n”); } void setstar(char *a,int n) { int i; for(i=0;i<n;i++) *(a+i)=‘*’; }

  13. 9.4 一维数组的应用举例 p115 例9-4 编写函数,定义15个元素的数组,完成以下功能: 1)调用C库函数的随机函数给所有元素赋以0~49的随机数 2)输出数组元素值 3)按顺序对每隔3个数求一个和数,传回主函数 4)最后输出所有求出的和值 main( ) { int x[SIZE],w[SIZE/N]={0}; getrand(x,SIZE); printf(“Output %d random numbers:\n”,SIZE); priarr(x,SIZE); getave(x,w,SIZE); priarr(w,SIZE/N); } #include <stdio.h> #include “stdlib.h” #define SIZE 15 #define N 3 void getrand(int *,int); void getave(int *,int *,int); void priarr(int *,int);

  14. void getrand(int *a,int n) { int i; for(i=0;i<n;i++) a[i]=rand()%50; } void getave(int *a,int *b,int n) { int i,j,sum; for(sum=0,i=0,j=0;i<=n;i++) {sum+=a[i]; if(i+1)%3==0) {b[j]=sum; sum=0; j++; } } } void priarr(int *a,int n) { int i; for(i=0;i<n;i++) {printf(“%5d”,a[i]); if((i+1)%5==0)printf(“\n”); }printf(“\n”); }

  15. 例 9.5 将数组中的数重新按颠倒的顺序存放 void priout(int s[ ],int n) { int i; for(i=0;i<n;i++) printf("%4d",s[i]); printf("\n"); } void invert(int *a,int n) { int i,j,t; i=0; j=n-1; while(i<j) { t=a[i]; a[i]=a[j]; a[j]=t; i++; j--; } } #include <stdio.h> #include "stdlib.h" #define NUM 8 void invert(int *,int); void priout(int *,int); main( ) { int a[NUM]={10,20,30, 40,50,60,70,80}; printf("Output primary data:"); priout(a,NUM); invert(a,NUM); printf("Output inverse data:"); priout(a,NUM); }

  16. e9.6 已知整型数组中的值在0~9的范围,统计每个整数的个数 void outdata(int *c) { int i; for(i=0;i<N;i++) printf("%d:%4d",i,c[i]); } main( ) { int a[M],c[N]; getdata(a); stat(a,c); printf("Output the result:\n"); outdata(c); } #include <stdio.h> #include "stdlib.h" #define M 50 #define N 10 void getdata(int *s) { int i; for(i=0;i<M;i++) s[i]=rand()%10; } void stat(int *a,int *c) { int i; for(i=0;i<N;i++) c[i]=0; for(i=0;i<M;i++) c[a[i]]++; }

  17. 例 9.7 在元素不同的数组a中查找x值相同元素的位置。若找到输出该值和位置;没找到输出相应信息。 #include <stdio.h> #define M 30 int arrin(int *a) { int i, n; do{ printf("输入元素数n<%d:",NUM); scanf(%d”,&n); }while((n<1)||n>NUM)); printf(“输入%d个元素”); for(i=0;i<M;i++) scanf(“%d”,a+i); return n; } main() { int a[NUM],x,n,p; n=arrin(a); printf(“输入要查找的元素x=”); scanf(%d”,&x); p=search(a,x,n); if(p!=-1) printf(“%d的序号%d”,x,p); else printf(“%d没找到”,x); }

  18. 例 9.7 search()函数 int search(int *a,int x,int n) {int i=0,p; a[n]=x; while(x!=a[i])i++; if(i==n)p=-1; else p=i; return p; } 例 9.8 p119 自学

  19. 9-9 用选择法或冒泡法对 6 个数排序(由小到大) 冒泡法的思路是:将相邻两个数比较,将小的调到前头 ㈠ ㈡ ㈢ ㈣ ㈤ 结果 序列 4 8 5 9 8 5 4 2 0 9 8 9 9 8 5 4 2 0 5 8 8 5 4 2 0 9 4 2 0 5 8 9 2 0 4 5 8 9 2 0 2 4 5 8 9 0 2 4 5 8 9 2 9 8 5 4 5 9 4 8 4 9 2 8 2 9 0 8 0 9 共循环多少次? 每次循环进行了多少次比较?什么时候结束? 如果序列为5、8、9、4、2、0,先排在最后的还是 9 吗? 如果要求先将最大的数排在最前面,该如何操作?

  20. 输入n个数给a[1]到a[n] for j=1 to n-1 for i=1 to n-j a[i]>a[i+1] 真 假 a[i] a[i+1] 输出 a[1]到a[n]

  21. #include <stdio.h> #define N 6 void main ( ) { int a[7]; int i , j, t ; printf ("input %d numbers:\n", N); for ( i = 1; i <N; i++) scanf ("%d", &a[i] ); for ( j = 1; j <=N-1; j++) for ( i = 1; i <= N - 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 <= N; i++) printf ("%d ", a[i] ); printf ("\n"); } 注:数组a的第一个元素a[0]没有被使用,请修改程序以便节省内存空间

  22. #include <stdio.h> #define N 6 void main ( ) { int a[N+1]; int i , j, t ; printf ("input %d numbers:\n", N); for ( i = 1; i <= N; i++) scanf ("%d", &a[i] ); for ( j = 1; j < N; j++) for ( i = j + 1; i <= N ; i++) if ( a[j] < a[i] ) { t = a[j]; a[j] = a[i]; a[i] = t; } printf ("the sorted numbers:\n"); for ( i = 1; i <= N; i++) printf ("%d ", a[i] ); printf ("\n"); }

  23. §9-5 二维数组 1、定义二维数组 类型名 数组名[exp1][exp2] 其中,exp1为行数,exp2为列数 如: int a[3][4], b[4][M]; 注:不能写成int a[3, 4], b[4, M]; 或 int a (3, 4), b(4, M);

  24. 二维数组的存储 可把二维数组看作是一种特殊的一维数组:它的元素又是一个一维数组 例如,可把 a[3][4] 看作是一个一维数组,有3个组元素:a[0]、a[1]、a[2],每个组元素中又包含 4 个元素的一维数组。见下图: a[0][0] a[0][1] a[0][2] a[0][3] a[0] a[1] a[2] [4] [4] [4] a[1][0] a[1][1] a[1][2] a[1][3] a a[2][0] a[2][1] a[2][2] a[2][3] 二维数组中元素排列的顺序是按行存放 试写出b[2][3]中元素?

  25. 9.5.2、二维数组的引用 二维数组的元素的表示为:数组名[下标][下标] 如: a[2][3] a[2-1][2*2-1] b[1][2] = a[2][3] / 2 下标可以是整型表达式 注意:1.数组定义和数组元素引用的区别 例如 int a[3][4]; 第一个元素是a[0][0],最后一个元素是 2.下标的最大取值 a[2][3]

  26. 9.5.3、二维数组的初始化 1 2 3 4 5 6 1 2 0 4 0 0 0 0 9 0 6 0 结果为:x[0][0]=0,x[0][1]=0,x[0][2]=9 x[1][0]=0, x[1][1]=6, x[1][2]=0 4)省略第一维长度; 例: int e[][3] = {1, 2, 3, 4, 5, 6}; 注意:不能省略第二维的长度。为什么? 2行3列 1)按行存放 例:int a[2][3] = {{1, 2, 3}, {4, 5, 6}}; 2)按存放顺序 例:int b[2][3] = {1, 2, 3, 4, 5, 6}; 3) 只给部分元素赋初值 例: int c[2][3] = {{1, 2}, {4}}; int x[2][3] = {{0, 0, 9}, {0, 6}};

  27. 例9-10从键盘给2×3二维数组输入数据: 1,2,3, 9.5.5 二维数组定义和引用举例 10,20,30 #include <stdio.h> main() {int a[2][3],i,j; printf("Enter data by line:\n"); for ( i=0;i<2; i++) for (j=0;j<3;j++) scanf("%d",&a[i][j]); printf("output data by line:\n"); for(i=0;i<2;i++) {for(j=0;j<3;j++) {printf("%4d",a[i][j]);} printf("\n"); } }

  28. int *p, a[3][4]; • a[0],a[1],a[2]一维数组名,行指针,是常量a[0]+ +× • 基类型: p与a[i] 同, p与a 是不同的 • p+1,相当于a[i]+1移动1个元素 • a+1,相当于移动一行 • 二维数组元素的地址 • 1)&a[i][j] • 2) a[i]+j • 3)*(a+i)+j • 4)&a[0][0]+4*i+j • 5)a[0]+4*i+j 9.6 二维数组和指针 二维数组元素的引用 1) a[i][j] 2)*(a[i]+j) 3)*(*(a+i)+j) 4)(*(a+i))[j] 5)*(&a[0][0]+4*i+j)

  29. #define M 3 #define N 4 main() {double s[M][N],*ps[M]; f(s); } (1) f(double *a[M]) (2) f(double *a[]) (3) f(double **a) #define M 3 #define N 4 main() {double s[M][N]; f(s); } (1) f(double (*a)[N]) (2) f(double a[][]) (3) f(double a[][]) 9.7 二维数组名和指针数组作实参

  30. /*例9-13 输出二维数组中每行的最小值 及其行、列号*/ #include <stdio.h> main ( ) {int a[5][5]={{22,11,32,42,53}, {51,41,31,21,11}, {44,54,24,34,74}, {93,59,17,64,74}, {96,45,39,65,58}}; int i,j,col; for(i=0;i<5; i++) { col=0; for ( j = 0; j < 5; j++) {if (a[i][j] <a[i][col]) col=j;} printf("row:%d,min:%d,col:%d\n",i+1,a[i][col],col+1); } getch(); }

  31. /*例9-13b 有一个3行4列矩阵,求出其中最大值 及所在的行号和列号*/ #include <stdio.h> main ( ) { int i,j,row=0,colum=0,max; int a[3][4]={{1,2,3,4},{9,8,7,6},{-10,10,-5,2}}; 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); }

  32. 多维数组,参考二维数组 • int a[2][3][4]; • a为整型三维数组,元素个数为2×3×4=24 • 内存中的排列顺序为: • 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、按存储顺序:int a[2][2][2] = {1, 2, 3, 4, 5}; 2、按下标顺序: int a[2][2][2] = {{{1, 2}, {3, 4}},{{5,0},{0,0}}};

  33. 补充例2:任输入一行字符,统计其中有多少个单词(以空格分隔)。补充例2:任输入一行字符,统计其中有多少个单词(以空格分隔)。 算法: ① 输入字符串; ② 找第一个非空字符; ③ 计数; ④ 跳过本单词,即寻找空格或‘\0’; ⑤ 未结束则转②; ⑥ 否则打印个数。 输入: ---We-are----students.

  34. /* 输入一行字,统计其中有多少个单词,单词间是空格分开*/ 书例P139 算法1: 1.空格决定单词数目,空格不 是单词word=0 2.如果字符为非空格,前面 是空格,则一个单词出现 word=1,num++ 3. 如果word=1,c!=‘ ‘,说明还是 刚才单词的字符,num不累加 #include <stdio.h>void main ( ) { char c; int i = 0 ,num = 0 ,word=0; char str[81]; gets ( str ); for(i=0;(c=str[i])!='\0';i++) if ( c == ' ') word=0; else if(word==0) { word=1; num++; } printf ("共 %d 个单词\n", num); }

  35. 0 1 2 3 4 5 6 7 8 W e a r e /* 算法2:输入一行字,统计其中有多少个单词,单词间是空格分开*/ #include <stdio.h> void main ( ) { char c; int i = 0 , num = 0; char str[100]; gets ( str ); do { while ( ( c = str[i] ) == ' ') i++; if ( c != '\0' ) { num++; i++;} while ( ( c = str[i] ) != ' ' && c != '\0') i++; } while ( c != '\0' ); printf ("共 %d 个单词\n", num); } 输入: ---We-are----students.--回车 -表示 空格

  36. 补充:找出1000以内的完数 例如:6=1+2+3 if(m==0) { printf(“%d is a wanshu\n”,j); for(i=0;i<n-1;i++) printf(“%d,”,a[i]); printf(“%d\n”,a[n-1]); } } getch(); } #include<stdio.h> main( ) { int a[100]; int i,j,n,m; for(j=2;j<1000;j++) { n=0; m=j; for(i=1;i<j;i++) { if((j%i)==0) { m=m-i; a[n]=i; n++; } } }

More Related