360 likes | 499 Views
第 6 章 数 组. § 6.1.1 一维数组的定义和引用. 一、一维数组的定义 ⒈ 定义方式: 类型说明符 数组名 [ 整型常量表达式 ] ; 例: int a[10]; ⒉ 说明: ① 数组名的定名规则和变量名相同,遵循标识符定名规 则。 ② 数组名后的常量表达式用[ ]括起来。 ③ 常量表达式表示数组元素的个数,即数组长度。 例: a[10] 表示数组 a 中包括10个元素,分别为
E N D
第6章 数 组 §6.1.1 一维数组的定义和引用 一、一维数组的定义 ⒈ 定义方式: 类型说明符 数组名[整型常量表达式]; 例:int a[10]; ⒉ 说明: ① 数组名的定名规则和变量名相同,遵循标识符定名规 则。 ② 数组名后的常量表达式用[ ]括起来。 ③ 常量表达式表示数组元素的个数,即数组长度。 例: a[10]表示数组a中包括10个元素,分别为 a[0]~a[9] a[0] a[2] a[4] a[6] a[8] a[1] a[3] a[5] a[7] a[9]
int n; scanf("%d",&n); int a[n]; ④ 常量表达式中可以包括常量和符号常量,不能包含变 量,即定义时必须确定数组的大小。 二、一维数组元素的引用 数组必须先定义,然后使用。C语言规定只能逐个引用数组元素而不能一次引用整个数组。 引用形式为: 数组名[下标] 整型常量或整型表达式 (数组元素的表示形式) 例1.1 main( ) {int i,a[10]; for (i=0;i<=9;i++) a[i]=i; for (i=0;i<=9;i++) printf("%4d",a[i] ); } 通过赋值语句给 数组元素赋值 (i=9;i>=0;i- - ) (i=0;i<=9;i++) a[i]); a[9-i]);
例1.2 main( ) {int i,a[10]; for (i=0;i<=9,i++) scanf("%d",&a[i]); for (i=0;i<=9;i++) printf("%4d",a[9-i] ); } 通过输入语句给 数组元素赋值 三、一维数组的初始化 可以用赋值语句或输入语句使数组中的元素得到值,但占运行时间,同时也可以使数组在程序运行之前初始化,即在编译期间使之得到初值。
对数组元素的初始化可以用以下方法实现: ⒈ 在定义数组时,对数组元素赋以初值。 如: int a[10]={0,1,2,3,4,5,6,7,8,9}; ⒉ 可以只给一部分元素赋值。 如: int a[10]={0,1,2,3,4}; 表示只给前5个元素赋初值,后5个元素自动赋以0值。 ⒊ 对static数组不赋初值,系统会对所有元素自动赋以0值。 即, 如果想使数组a中全部元素值为0,可以这样定义数组: staticint a[5] a[0] a[2] a[4] a[1] a[3] 也可以 int a[5]={0}; 0 0 0 0 0
⒋ 在对全部数组元素赋初值时,可以不指定数组长度。 int a[5]={1,2,3,4,5}; int a[ ]={1,2,3,4,5}; static static 例2.用数组来处理求Fibonacci数列问题(求前40项) f[0] f[1] f[2] f[3] f[4] f[5] f[6] f[7] f[8] f[9] ............. ......... 1 1 2 0 3 0 5 0 8 0 13 0 21 0 34 0 55 0
main( ) { int i; static long int f[40]={1,1}; for(i=2;i<40;i++) f[i]=f[i-2]+f[i-1]; for(i=0;i<40;i++) { if(i%5= =0) printf("\n"); printf("%12ld",f[i]); } }
3 45 2 6 17 66 50 例3.将n个整数按逆序重放在数组中(n<=50)。 算法: 设n=7 x[0] x[1] x[2] x[3] x[4] x[5] x[6] t=x[i]; x[i]=x[n-i-1]; x[n-i-1]=t; 66 2 45 3 50 3 45 17 2 6 17 66 50 2 3 45 t
main( ) { int x[50],t,n,i; scanf("%d",&n); for(i=0;i<n;i++) scanf("%d",&x[i]); for(i=0;i<=(n-1)/2;i++) { t=x[i]; x[i]=x[n-1-i]; x[n-1-i]=t; } for(i=0;i<n;i++) printf("%5d",x[i]); printf("\n"); } 程序:
main( ) { int x[50],t,n,i,j; scanf("%d",&n); for(i=0;i<n;i++) scanf("%d",&x[i]); for(i=0,j=n-1;i<j;i++,j--) { t=x[i]; x[i]=x[j]; x[j]=t; } for(i=0;i<n;i++) printf("%5d",x[i]); printf("\n"); } 程序:
(1)从数组A[1]到A[10],把相临的两个数两两进行比较。即A[1]和A[2]比较,比较完后,A[2]再与A[3]比较,……最后是A[9]和A[10]比较。(1)从数组A[1]到A[10],把相临的两个数两两进行比较。即A[1]和A[2]比较,比较完后,A[2]再与A[3]比较,……最后是A[9]和A[10]比较。 (2)在每次进行比较的过程中,如果前一个数比后一个数大,则对调两个数,也就是说把较大的数调到后面,较小的调到前面。比如在第一次的比较中,如果A[1]比A[2]大则A[1]和A[2]的值就互换。下图用6个数据来说明以上的算法。 §6.1.2 一维数组的应用1.冒泡排序算法 :用冒泡法对10个数排序
假设6个数据是: A[1] A[2] A[3] A[4] A[5] A[6] 5 7 4 3 8 6 第一次,A[1]和A[2]比较,5<7 ,不进行对调。 5 7 4 3 8 6 第二次,A[2]和A[3]比较,7>4,进行对调, 5 4 7 3 8 6 第三次,A[3]和A[4]比较,7>3,进行对调, 5 4 3 7 8 6 第四次,A[4]和A[5]比较,7<8,不进行对调。 5 4 3 7 8 6 第五次,A[6]和A[5]比较,8>6,进行对调, 5 4 3 7 6 8 由上例可以看出,对于6个数,排好一个数(最大的数)需要进行5次比较,可以推断出,对于N个数,一趟(排好一个数的过程)需要N-1次比较操作。
上述算法已经把N个数中最大的数放到了A[N]中,再重复上述算法,把A[1]到A[N-1]中最大的数放到A[N-1]中,这样A[N-1]中存放的就是第二大的数,接着把A[1]到A[N-2]中最大的数放到A[N-2]中,……最后把A[1]到A[2]中大的那个数放到A[2]中,每重复一次两两比较后,比较的范围就朝前移动一个位置,此算法经过N-1次就完成了A[1]到A[N]中的的数由小到大的排列。 注意:如果要由大到小排列则在比较时前一个数比后一个数小就进行对调,方法相反。 由此可以看出,冒泡法的基本思想就是:在待排序的数据中,先找到最大的数据将它放到最后面,再从第二个数据开始,找到第二大的数据将它放到第二个位置,以此类推,直到只剩下最后一个数为止。这种排序方法在排序的过程中,是小的数就如气泡一样逐层上浮,而使大的数逐个下沉,于是就形象地取名为起泡排序,又名冒泡排序。
输入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] #include <stdio.h> main() { int a[11],i,j,t; printf("Input 10 numbers:\n"); for(i=1;i<11;i++) scanf("%d",&a[i]); printf("\n"); for(j=1;j<=9;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]); }
2.打擂法:求10个数最大值和最小值 #include <stdio.h> main() { int x[10],i,max,min; for(i=0;i<10;i++) scanf("%d",&x[i]); max=min=x[0]; for(i=1;i<10;i++) { if(max<x[i]) max=x[i]; if(min>x[i]) min=x[i]; } printf("Maximum value is %d\n",max); printf("Minimum value is %d\n",min); } 步骤: 1. 输入:for循环输入10个整数 2. 处理: (a) 先令max=min=x[0] (b) 依次用x[i]和max,min比较(循环) 若max<x[i],令max=x[i] 若min>x[i],令min=x[i] 3. 输出:max和min
② 二维数组在内存中按行存放 §6.2 二维数组的定义和引用 一、二维数组的定义 类型说明符数组名[常量表达式][常量表达式] 例:float a[3][4],b[5][10]; 说明: ① 可以把二维数组看作是一种特殊的一维数组。 a[0] a[0][0] a[0][1] a[0][2] a[0][3] a[1] a[1][0] a[1][1] a[1][2] a[1][3] a[2] a[2][0] a[2][1] a[2][2] a[2][3] a[0][0] a[0][2] a[1][0] a[1][2] a[2][0] a[2][2] a[0][1] a[0][3] a[1][1] a[1][3] a[2][1] a[2][3]
③ 多维数组定义方式与二维数组类似 int x[3][4][2]; float y[4][2][3]; 二、二维数组的引用 引用形式为: 数组名[下标][下标] 注:下标可以是整型表达式,但应在已定义的数组大小的 范围内。 三、二维数组的初始化 ⒈ 分行给二维数组赋初值。如: int a[3][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} ⒊ 可以对部分元素赋初值,不赋的为0。如: int a[3][4]={{1},{5},{9}} int a[3][4]={{1},{0,6},{0,0,11}}; ⒋ 如果对全部元素都赋初值,则定义数组时对第一维的长 度可以不指定,但第二维的长度不能省。 int a[3][3]={1,0,3,4,0,0,0,8,0} int a[ ][3]={1,0,3,4,0,0,0,8,0} int a[ ][3]={{1,0,3},{4,0,0},{0,8,0}}
a a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] b b[0][0] b[0][1] b[1][0] b[1][1] b[2][0] b[2][1] 例1.将一个二维数组行和列元素互换,放到另个二 维数组中。 for(i=0;i<=1;i++) for( j=0;j<=2;j++) b[j][i]=a[i][j];
main( ) {static 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]); printf("\n"); } for(i=0;i<=1;i++) for( j=0;j<=2;j++) b[j][i]=a[i][j]; printf("array b:\n"); for(i=0;i<=2;i++) {for(j=0;j<=1;j++) printf("%5d",b[i][j]); printf("\n"); } }
i j i j max 1 i j i j i j i j i j i j i j i j i j i j 例2.有一个3×4的矩阵,编程求出其中值最大的那个元素,以及其所在的行号和列号。(最大值唯一) a 4 9 1 2 3 4 3 2 10 9 8 7 10 -10 6 -5 2
main( ) {int i,j,row=0,colum=0,max; static int a[3][4]={{1,2,3,4},{9,8,7,10},{-10,6,-5,2}}; for(i=0;i<3;i++) { for(j=0;j<4;j++) printf("%3d",a[i][j]); printf("\n");} 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\n",max,row,colum); }
§6.3 字符数组 一、字符数组的定义 char字符数组名[整型常量表达式] 例:char c[10], d[2][3]; 二、字符数组的初始化 例: char c[10]={'I','a','m', ' ','h','a','p','p','y'}; char c[3][2]={{' ','*'},{'*',' '},{' ','*'}}; 注: 对静态字符数组未被赋值的元素系统自动将其赋值为空('\0')。 三、字符数组元素的引用 同简单变量
例1.输出一个字符串 I am a boy main() { char c[10]={'I',' ','a','m',' ','a',' ','b','o','y'}; int i; for (i=0;i<10;i++) printf("%c",c[i]); printf("\n"); } I a m a b o y
例2.输出一个图形 main() { static char c[5][5]; int i,j; for (i=0;i<5;i++) { c[i][0]='*'; c[i][i]='*'; } for (i=0;i<5;i++) {for (j=0;j<5;j++) printf("%c",c[i][j]); printf("\n"); } } * * * * * * * * *
I a m h a p p y \0 四、字符串和字符串结束标志 在C语言中,用字符数组来处理字符串,同时,C语言规定以字符'\0‘(null)作为字符串结束标志。 对字符数组初始化,可以用字符串常量来使字符数组初始化。如: char c[ ]={“I am happy”};(可以不指定数组长度,其 char c[ ]=“I am happy”; 长度由系统检测+1确定) char c[14]={“I am happy”};(也可以指定数组长度 但应保证其长度至少比其字符个数+1要大 ,多 余部分自动赋予null(\0)
c h i n a \0 五、字符数组的输入输出 ⒈ 输入输出控制字符有两种"%c"和"%s" %c 逐个字符输入/输出 %s一次输入/输出整个字符串 ⒉ 输出应注意的问题 用"%s"格式输出字符时,输出遇'\0'时结束,printf函数中的输出项是字符数组名,而不是数组元素。 例: char c[11]={"china"}; printf("%s",c); 也可写成 char c[]=“china”;int i; for(i=0;i<=9;i++) printf(“%c”,c[i]); 不能写成c[0] 输出china
I \0 3. 输入时应注意: 在使用scanf函数时,若用"%s"格式输入字符串,则后面跟数组名,且不带"&"符号,数组名指向该数组的起始地址。 例: char c[11]; scanf("%s", c); printf(“%s”,c); 输入I am happy 注:用函数scanf输入(格式字符%s)无法输入空格,必须用字符串处理函数完成。
六、字符串处理函数 • 所有函数都包含在头文件"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’ 说明:输入串长度应小于字符数组维数
⒊strcat(字符数组1,字符数组2) 连接两个字符数组中的字符串,把字符串2接到字符串 1的后面,结果放到字符数组1中,函数调用后得到一个函数值—字符数组1的地址。 说明: ① 字符数组1必须足够大,以便容纳连接后的新字符串。 ② 连接时,自动取消数组1后的'\0',只在新串最后保留一个'\0'。
⒋strcpy(字符数组1,字符串2) 作用:将字符串2拷贝到数组1中去。 说明: ① 字符数组1必须足够大,以便容纳被拷贝的字符串。 ② “字符数组1”必须写成数组名形式,“字符串2”可以是字符数组名,也可以是一个字符串常量。 ③ 拷贝时连同字符串后面的'\0'一起拷贝到字符数组1中 ④ 不能用赋值语句将一个字符串常量或字符数组直接赋给一个字符数组。(str1=str2;str1={“HELLo”}) ⑤ 可以用strcpy函数将字符串2中前面若干个字符拷贝到字符数组1中去。 strcpy(str1,str2,2) (有些系统不支持) 拷贝str2的前2个字符,然后再加一个'\0'
⒌ strcmp(字符串1,字符串2) 作用: 比较字符串1和字符串2 对两个字符串自左至右逐个相比,直到出现不同的字符或遇到‘\0’为止,如全部字符相同,则认为相等;若出现不相同的字符,则以第一个不相同的字符的比较结果为准,比较的结果由函数值带回。(以字符的ASCII码为准) 字符串1==字符串2,函数值为0 字符串1>字符串2, 函数值为一正整数 字符串1<字符串2, 函数值为一负整数 ⒍ strlen(字符数组) 测试字符串长度的函数,函数的值为字符串的实际长度,不包括‘\0’在内。Strlen(“China”) 函数返回值是5。 字符串是数组类型而非简单类型,不能用关系运算进行大小比较 if("ABC">"DEF") /*错误的字符串比较*/
例1.有三个字符串(长度不超过20),要求找出其中最大者。 例1.有三个字符串(长度不超过20),要求找出其中最大者。 string str[0] 大 str[1] str[2] 大
#include "stdio.h" main( ) {char string[20],str[3][20]; int i; for(i=0;i<3;i++) gets(str[i]); if (strcmp(str[0],str[1])>0) strcpy(string,str[0]); else strcpy(string,str[1]); if (strcmp(str[2],string)>0) strcpy(string,str[2]); printf("\nthe largest string is:\n%s\n",string); }
例2.编一程序,将两个字符串连接起来,不使用strcat函数。 main( ) {char s1[80],s2[80]; int i=0,j=0; scanf("%s",s1); scanf("%s",s2); while(s1[i]!='\0') i++; while(s2[j]!='\0') {s1[i]=s2[j];i++;j++;} s1[i]='\0'; printf("%s\n",s1); } /*求s1中的有效字符个数*/ /*将s2接到s1后*/