1、第4章数组和字符串,第4章 数组和字符串,4.1 数组的概念 4.2 一维数组 4.3 二维数组 4.4 字符串与字符函数,4.1 数组的概念,1.数组的定义 2.数组的数据类型 3.数组的维数,1.数组的定义,按序排列的同类数据元素的集合就称为数组。 在C语言中,一个数组可以分解为多个数组元素。 按数组元素类型的不同,数组又可分为数值型数组、字符型数组、指针型数组、结构体型数组等各种类别。,2.数组的数据类型,数组的数据类型可以是各种基本数据类型,如int、float、double、char、long等 。还可以指针型、结构体型、共用体型、枚举型(后续章节将介绍)等。 C语言规定,同一数组中
2、的所有元素必须是相同类型的,不允许同一个数组中包含不同的数据类型。,3.数组的维数,一维数组的元素有一个下标、二维数组的元素有两个下标、三维数组有三个下标。 C语言的数组可以是多维的,但一般常用的是一维数组和二维数组。,4.2一维数组,4.2.1一维数组的定义 4.2.2一维数组的初始化 4.2.3一维数组的引用,4.2.1一维数组的定义,一维数组定义的语法格式如下: 类型说明符 数组名 数组长度; 其中: (1)“类型说明符”可以是任何一种基本数据类型或构造数据类型。例如: int m8; /*定义一个整型数组m,有8个元素*/ char c20; /*定义一个字符数组c,有20个元素*/
3、(2)“数组名”是用户定义的数组标识符。其命名规则和变量命名规则相同。,(3)数组名后的“数组长度”表示数组中数据元素的个数,通常是一个整型常量、整型变量或整型表达式。例如在m8中,表示数组m有8个元素,下标从0开始一直到7,这8个数组元素分别是: m0、m1、m2、m3、m4、m5、m6、m7, 注意没有m8。 (4)一个数组定义语句中可以只定义一个数组,也可以定义多个数组,还可以同时定义数组和变量。例如: double a10,b1; /*定义了一个有10个元素的双精度型数组a和一个双精度型变量b1*/ 又例如: char f8,e1; /*定义了一个有8个元素的字符型数组f和一个字符型变
4、量e1*/,4.2.2一维数组的初始化,在定义数组的同时给数组元素赋予初值称为数组的初始化。 初始化赋值的一般形式为: 类型说明符 数组名常量表达式=数据值1, 数据值2,数据值n; 其中在 中的各数据值即为各元素的初值,各值之间用逗号间隔。 语言对数组的初始化赋值还有以下几点规定: (1)可以只给部分元素赋初值。没有赋初值的元素:对于数值型数组,自动赋初值为0;对字符型数组,自动赋初值为空字符。 例如:,int m10=1,2,3,4; 定义的数组m有10个元素,但大括号内只有4个初值,这表示只给前面4个元素赋初值,后6个元素值均为0。 (2)只能给元素逐个赋值,不能给数组整体赋值。 例如:
5、给数组m中的10个元素全部赋值“2”只能用以下形式来表示: int m10=2,2,2,2,2,2,2,2,2,2; 而不能为了方便写成如下的形式: int a10=2; (3)如果给全部元素赋值,则在数组说明中,可以不给出数组元素的个数。其长度等于初值表中数组元素的个数。例如: int m5=1,2,3,4,5; 可写为: int m =1,2,3,4,5;,4.2.3一维数组的引用,数组元素引用的一般形式为: 数组名下标表达式 C语言规定只能逐个引用数组中的元素,而不能一次引用整个数组。,1.引用说明,(1)下标表达式必须放在方括号内,且只能取整型值。下标的下限是0,而上限不能超过该数组定
6、义时的长度值减1(即:数组长度-1)。 (2)数组中的下标只能为整型常量或整型表达式。 (3)在语言中只能单独地使用数组元素,而不能一次引用整个数组。 (4)任何一个数组元素的引用都可以看成是一个变量的使用。,例4.1数组元素的赋值及引用举例。 #include main() int i,m8;for(i=0;i=0;i-)printf(“%d “,mi); ,程序的运行结果如下: 7 6 5 4 3 2 1 0,语言允许用表达式表示下标。 例4.2数组元素用表达式表示下标应用举例。 #include main() int i,m8;for(i=0;i8;)mi+=2*i+2;for(i=0;
7、i=7;i+)printf(“%d “,mi);,程序的最后运行结果如下: 2 4 6 8 10 12 14 16,2.一维数组举例,例4.3用“选择排序法”对一维数组中的整数进行排序,使其数组元素的值按从小到大的顺序排列。 分析:选择排序法是一种简单而且常用的对数据排序的方法,其排序原理为:设有m个数要求从小到大排列,选择排序法排序过程分为m-1个步骤: 第1步、在m个数中找出最小数,然后和第一个数交换,前1个数已经排好序。 第2步、在m-1个数中找出最小数,然后和第2个数交换,前2个数已经排好序。 第k步、在m-k+1个数中找出最小数,然后和第k个数交换,前k个数已经排好序。 这样一值到第
8、m-1步结束。,#include main() int n,i,m,x,min,min_m,a100;printf(“Please input the value of n:“);scanf(“%d”, /* 交换最小数和第m个数的位置 */,amin_m=am;am=x;for(i=0;in;i+)printf(“%d “,ai);printf(“n“); ,程序的运行结果如下: Please input the value of n:6 please input your number: 5 34 56 2 78 40 2 34 40 56 78,4.3 二维数组,4.3.1 二维数组的定
9、义 4.3.2 二维数组的初始化 4.3.3 二维数组的引用,4.3.1二维数组的定义,1. 二维数组定义的一般形式 2. 对二维数组的说明 3. 多维数组的扩展,1.二维数组定义的一般形式,二维数组定义的一般形式为: 类型说明符 数组名行数列数 其中“行数”表示第一维下标的长度,“列数”则表示第二维下标的长度。,例如: int m45;/*定义了一个数组名为m的二维数组,其中行数为4、列数为5*/ 该数组的数组元素共有45=20个,分别为: m00,m01,m02,m03,m04 m10,m11,m12,m13,m13 m20,m21,m22,m23,m23 m30,m31,m32,m33,
10、m34,2.对二维数组的说明,(1)二维数组在概念上是二维的,也就是说其下标在两个方向上变化。 (2)在语言中,二维数组是按行排列的。 (3)数组元素所占的存储位置跟其类型有关系。 (4)一个二维数组可以看成为若干个一维数组。 注意:二维数组中m23中的m0和m1不能当作数组元素使用,因为它们是一维数组名,不是一个单纯的数组元素。,3.多维数组的扩展,多维数组可以由二维数组扩展而得到,例如: int m234; 定义了一个数组名为m的三维数组,按顺序进行展开后的各个元素值分别如下: m000,m001,m002,m003 m010,m011,m012,m013 m020,m021,m022,m
11、023 m100,m101,m102,m103 m110,m111,m112,m113 m120,m121,m122,m123,4.3.2二维数组的初始化,1. 二维数组初始化的一般形式 2. 对二维数组初始化的说明,1.二维数组初始化的一般形式,二维数组初始化的一般形式为: 数据类型说明符 数组名行数列数=数据值,数据值,数据值,数据值,数据值,数据值; 或者 数据类型说明符 数组名行数列数=数据值,数据值,数据值;,2.对二维数组初始化的说明,(1)二维数组初始化和一维数组初始化的方法基本相同,也是在类型说明时给各个数组元素赋以初值。稍微有所区别的是:二维数组可按行分段赋值,也可以不分行连
12、续赋值。 例如对数组m43:按行分段赋值可写为: int m43= 78,65,80,67,89,65,53,68,98,57,88,67 ; 其中,78,65,80是赋给第一行3个数组元素的,这里可以看成是赋给一维数组m0的;67,89,65是赋给第二行3个数组元素的,这里可以看成是赋给一维数组m1的;其他依次类推。,不分行连续赋值可写为: int m43= 78,65,80,67,89,65,53, 68,98,57,88,67 ; 各元素获得的初值和第1种方式的结果完全相同。C语言规定,用这种方式给二维数组赋初值时,是先按行、后按列的顺序进行的。 (2)可以只对部分元素赋初值,未赋初值的
13、元素自动取0值。例如: int m34=1,2,3; 是对每一行的第一列元素赋值,未赋值的元素取0值。赋值后各元素的值依次为: 1 0 0 0 2 0 0 0 3 0 0 0,(3)如果对全部元素赋初值,则第一维的长度可以省略。例如: int m33=1,2,3,4,5,6,7,8,9; 可以写为: int m3=1,2,3,4,5,6,7,8,9; 表示数组m3的第一维长度是3。 需要注意的是:使用这种方法赋初值,必须给出所有数组元素的初值,如果初值的个数不正确,则系统将作出错处理。,例4.4从键盘上输入一个34的矩阵,将其转换后形成43矩阵输出。 分析:矩阵的转置是将矩阵的行和列进行互换,
14、使其行成为列,列成为行,例如: 原矩阵为:,转置后的矩阵为:,#include main() int m34,n43,i,j;printf(“Please enter the number of m34:n“);for(i=0;i3;i+) /* 输入一个34的矩阵存放在数组m中 */for(j=0;j4;j+) scanf(“%d“, ,程序的运行情况为: Please enter the number of m34: 1 1 1 1 2 2 2 2 3 3 3 3 The number of n43 is: 1 2 3 1 2 3 1 2 3 1 2 3,4.3.3二维数组的引用,二维数组
15、元素的引用形式为: 数组名下标表达式1下标表达式2 其中,下标表达式1表示行下标,下标表达式2表示列下标,二者必须分别放在两个方括号内。 关于下标表达式类型的限制及下标越界的处理与一维数组相同。 例如: int a23; a01=a; 其中的“a01=a;”就是对二维数组“a23”中一个元素的引用。,例4.5 求矩阵m34各个元素中的最小值,并输出最小值元素所在的行和列。 #include main() int i,j;int x,y;int m34=12,1,2,4,2,3,4,5,5,6,7,8;int min=m00;for(i=0;imij) min=mij;,x=i; y=j;pri
16、ntf(“The min of m34 is %d.n“,min);printf(“The row of min is %d and the colum of min is %d.“,x,y); ,程序的运行结果为: The min of m34 is 1. The row of min is 0 and the colum of min is 1.,4.4 字符串与字符函数,4.4.1字符数组 4.4.2字符串与字符数组 4.4.3字符串处理函数 4.4.4字符串函数应用举例,4.4.1字符数组,1.字符数组的定义 2.字符数组的初始化 3.字符数组举例,1.字符数组的定义,字符数组定义格式
17、如下: 类型名 数组名数组元素个数; 其中的“类型名”必须是char。 例如: char c10; 定义了一个名为c的字符数组,包含10个元素。 和数值数组一样,字符数组也可以是二维或多维数组。例如: char c89;,2.字符数组的初始化,在定义字符数组时,可以直接对字符数组进行初始化。 给字符数组赋初值时,如果花括号中字符的个数大于字符数组定义的数据元素的个数,则编译系统会报告出错。 如果花括号中数据元素的个数小于字符数组定义的数据元素的个数, C语言规定:初始化中未给出数据元素值得对应元素被自动赋值为空字符0。,例如: char c10=c, , p, r, o, g, r, a,m;
18、 赋值后各元素的值如下所示: c0=c c1= c2=p c3=r c4=o c5=g c6=r c7=a c8=m c9=0,3.字符数组举例,例4.7在计算机屏幕上显示“Hello World”。 #include main() char str13=H, e, l, l, o, , W, o, r, l, d, !;/*定义并初始化数组*/int i; /*用于输出字符数组中字符的个数*/for(i=0;i13;i+) printf(“%c”,stri); /*显示字符数组*/printf(“n“); ,程序运行后的输出结果为: Hello World!,例4.8输出一个钻石图形。 #i
19、nclude main () static char diamond 5= , ,*, ,*, ,*,*, , , ,*, ,*, ,*, , ,*; /*第二维大小不能省略*/ int i,j;for (i=0;i5;i+) /* 逐行 */ for (j=0;j5;j+) /*逐列*/printf(“%c“,diamondij);printf(“n“);,该程序的运行结果如下:,* * * * *,4.4.2字符串与字符数组,1.字符串初始化赋值 2.用二维数组存放多个字符串 3.字符数组的输入/输出 4.字符串大小的比较,1.字符串初始化赋值,语言允许用字符串的方式对数组作初始化赋值。具
20、体有两种方式: (1)按单个字符的方式赋初值,其中必须有一个字符是字符串的结束标记。例如: char s=1, 2,3,0; (2)直接在初值表中写一个字符串常量。 例如: char s=“123“; 其中的“”可以省略,如: char s=“123“; 表示s0的值为1,s1的值为2,s2的值为3,s3的值为0。字符数组s中存放的是一个字符串。,2.用二维数组存放多个字符串,当需要处理多个字符串时,可以采用二维数组,此时二维数组列值取最大字符串的长度。 例如:存放三个字符串”123”、”ab”、”A”可采用如下的形式: char s34=“123“,“ab“,“A“; 表示: s00的值为1
21、, s01的值为2,s02的值为3, s03的值为0; s10的值为a, s11的值为b,s12的值为0; s20的值为A, s21的值为0。,3.字符数组的输入/输出,关于字符数组的输入/输出,C语言有如下规定: (1)逐个字符输入/输出。用格式符“%c“输入/输出一个字符。 (2)将整个字符串一次性输入/输出。用格式符“%s“对整个字符串进行一次性输入/输出。 注意:使用“%s“格式从键盘上向字符数组中输入字符串时,回车换行符或空格符号均作为字符串的结束标记。,例4.9对字符数组中的元素进行逐个输出举例。 #include main() char c7=C, ,H,e,l,l,o;int
22、i;for(i=0;i7;i+)printf(“%c“,ci);printf(“n“); ,程序的运行结果为: C Hello,例4.10字符串方式输出字符数组中的元素举例。 #include main() char c =“How are you“;printf(“%sn“,c); ,程序运行后的输出结果为: How are you,例4.11请输入一个长度小于20的字符串,并将该字符串输出。 #include main() char m20;printf(“input string:n“);scanf(“%s“,m);printf(“%sn“,m); ,注意:当用scanf函数输入字符串时
23、,字符串中不能含有空格,否则将以空格作为串的结束符。 例如,当输入的字符串中含有空格时,运行情况为:input string:hello humanhello 从输出结果可以看出,空格以后的字符都未能输出。为了避免这种情况,可多设几个字符数组分段存放含空格的串。,程序可改写成如下形式: #iclude main() char m16,m26;printf(“input string:n“);scanf(“%s%s“,m1,m2);printf(“%s %s n“,m1,m2); ,修改后的程序运行情况为: input string: abcd efghi abcd efghi,4.字符串大小的
24、比较,字符串可以进行大小比较,比较时按照从前向后的顺序逐个字符比大小。 字符大的对应字符串就大。 例如:“abcd“小于“bcde“。 如果全部字符均相同,则字符串相等。 例如:“abcd“等于“abcd“。 如果字符串长度不等,而前面字符均相同,则长度大的字符串为大。 例如:“abcd“大于“abc“。,4.4.3字符串处理函数,1.字符串输出函数puts 2.字符串输入函数gets 3.测试字符串长度函数strlen 4.字符串连接函数strcat 5.字符串比较函数strcmp 6.字符串拷贝函数strcpy 7.小写变大写函数strupr 8.大写变小写函数strlwr,1.字符串输出
25、函数puts,puts函数调用的一般形式为: puts(字符数组); 该函数的功能是:把字符数组中的字符串输出到显示器,即在屏幕上显示该字符串的内容。其中,字符串的结束标记将转换成回车换行符。,例4.12puts函数的应用举例。 #include“stdio.h“ main() char c=“HellonHuman“;puts(c); ,程序运行后,将在显示器上输出: Hello human,2.字符串输入函数gets,gets函数的一般调用形式为: gets(字符数组); 该函数的功能是:从标准输入设备键盘上输入一个字符串,并存入到指定的字符数组中。,例4.13gets函数的应用举例。 #
26、include“stdio.h“ main() char m20;printf(“input string:n“);gets(m);puts(m); ,程序的运行情况为: Input string: hello human hello human,可以看出当输入的字符串中含有空格时,输出仍为全部字符串。这说明gets函数并不以空格作为字符串输入结束的标志,而只以回车作为输入结束的标志。 注意:gets函数和使用“%s“格式的scanf函数都可以从键盘接受字符串,但在输入时有所区别: (1)对于scanf函数,“回车“或“空格“都看成字符串结束标记; (2)对于gets函数,只有“回车”才作为字
27、符串结束标记,“空格”看成字符串的一部分。 说明:puts函数和gets函数只能输入/输出一个字符串。例如: puts(str1,str2); 和gets(str1,str2,str3);都是错误的。,3.测试字符串长度函数strlen,strlen函数的功能是:测试指定字符串的实际长度(不含字符串结束标志0),并返回字符串的长度。 其一般的调用形式为: strlen(字符数组); 其中,函数的参数可以是字符型数组名或字符串常数,函数的返回值是字符串长度。,例4.14strlen函数的应用举例。 #include #include main() int n;static char m=“Hel
28、lo Human“;n=strlen(m);printf(“The lenth of the string is %dn“,n); ,程序的运行结果如下: The lenth of the string is 11,4.字符串连接函数strcat,strcat函数的调用格式为:strcat(字符数组1,字符数组2); 该函数的功能是:把字符数组2中的字符串连接到字符数组1 中字符串的后面,同时删去字符串1中的串标志0,组成新的字符串。该函数返回值是字符数组1的首地址。,例4.15strcat函数的应用举例。 #include #include main() static char m130=“
29、My name is “;char m210;printf(“input your name:n“);gets(m2);strcat(m1,m2);puts(m1); ,程序的运行情况如下: input your name: human My name is human,5.字符串比较函数strcmp,strcmp函数用来对两个字符串进行比较,其调用格式为 strcmp(字符串1,字符串2); 其中,字符串1和字符串2可以是字符型数组名或字符串常数。 该函数的功能是按照ASCII码顺序比较两个数组中的字符串,并由函数返回值返回如下所示的比较结果: 字符串1等于字符串2时,返回值为:0。 字符串
30、1大于字符串2时,返回值为:字符串1-字符串2的值,大于0。 字符串1小于字符串2时,返回值为:字符串1-字符串2的值,小于0 。,例4.16strcmp函数的应用举例。 #include #include main() int n;static char m115,m2=“hello human“;printf(“input a string:n“);gets(m1);n=strcmp(m1,m2); if(n=0) printf(“m1 equale m2n“);if(n0) printf(“m1m2n“);if(n0) printf(“m1m2n“); ,程序运行情况如下: input
31、a string: abcd m1m2,6.字符串拷贝函数strcpy,字符串拷贝函数strcpy的调用格式为: strcpy(字符数组1,字符数组2); 其功能是:把字符数组2中的字符串拷贝到字符数组1中。串结束标志0也一同拷贝。 说明:字符数组2也可以是一个字符串常量。这时相当于把一个字符串赋予一个字符数组。,例4.17strcpy函数的应用举例。 #include“string.h“ main() char m115,m2=“hello human “;strcpy(m1,m2);puts(m1);printf(“n“); ,程序的运行结果如下: hello human,7.小写变大写函
32、数strupr,strupr函数用来将字符串中的小写字母转换成大写字母,其他字符(包括大写字母和非字母)不转换。 其调用格式为:strupr(字符串); 其中,函数的参数可以是字符型数组名或字符串常数,函数的返回值是转换后的字符串。upr表示uppercase。,例4.18将输入的字符串中的所有小写字母转换成大写字母,并输出。 #include #include main() char str80;puts(“please input a string:“);gets(str);strupr(str);puts(str); ,程序的运行情况为: please input a string: w
33、elcome WELCOME,8.大写变小写函数strlwr,strlwr函数用来将字符串中的大写字母转换成小写字母,其他字符(包括小写字母和非字母)不转换。 其调用格式为strlwr(字符串); 其中,函数的参数可以是字符型数组名或字符串常数,函数的返回值是转换后的字符串。lwr表示lowercase。,例4.19将输入的大写字母字符串转换成小写字母字符串,并输出。 #include #include main() char st80;puts(“please input a string:“);gets(st);strlwr(st);puts(st); ,程序运行情况为: please i
34、nput a string: WELCOME welcome,4.4.4字符串函数应用举例,例4.21 统计输入的文字有多少个单词。 #include “stdio.h“ main () char st80;int i,num=0,word=0;char c;puts(“Please input a string:n“); gets(st); /* 输入一段文字到一维数组st */for(i=0;(c=sti)!=0;i+)if (c= ) word=0; /* c为空格,没出现单词*/,else if (word=0)word=1;num+; /*单词数累加*/printf(“There a
35、re %d words in the linen“, num); ,程序的运行情况如下: Please input a string: hello human ni hao There are 4 words in the line,例4.22利用二维数组,找出三个字符串中的最大者(ASCII值)。 #include main () char st20; char str320; /*每行一个字符串*/int i;puts(“Please enter three string:“); for(i=0;i0)strcpy(st,str0); /* 字符串str0复制到st */ elsestrcpy(st,str1);if(strcmp(str2,st)0) strcpy(st,str2);printf(“nthe largest string is: %s.n“,st); ,该程序的运行情况如下: Please enter three string: hello hi hurry the largest string is:hurry.,