《C语言程序设计教程(第2版)PPT课件第7章.ppt》由会员分享,可在线阅读,更多相关《C语言程序设计教程(第2版)PPT课件第7章.ppt(55页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第第7章章 数数 组组 本章要点本章要点一维数组一维数组二维数组二维数组字符数组字符数组 先看一个例子:先看一个例子:例例:给出一个学生给出一个学生10门功课的成绩,要求计算门功课的成绩,要求计算平均成绩平均成绩 并打印出低于平均成绩的数值。并打印出低于平均成绩的数值。用变量来解决问题:main() int w1, w2, w3, w4, w5, w6, w7, w8, w9, w10; int t; scanf( %d%d%d%d%d%d%d%d%d%d,&w1, &w2, &w3, w4, &w5 , &w6, &w7, &w8, &w9, &w10); t=(w1+w2+w3+w4+w5
2、+w6+w7+w8+w9+w10)/10; if( w1 t ) printf( %dn, w1 ); if( w2 t ) printf( %dn, w2 ); if( w3 t ) printf( %dn, w3 ); if( w4 t ) printf( % dn, w4 ); if( w5 t ) printf( %dn, w5 ); if( w6 t ) printf( %dn, w6 ); if( w7 t ) printf( %dn, w7 ); if( w8 t ) printf( %dn, w8 ); if( w9 t ) printf( %dn, w9 ); if( w10
3、 t ) printf( %dn, w10 );用数组来解决问题:main() int w10; /* 定义 1 个整型数组存放成绩 */ int t, i; for( i=0; i10; i+ ) scanf( %d, &wi ); for( t=0; i=0; i10; i+ ) t = t + wi; t = t/10; for( i=0; i10; i+ ) if( wi t )printf( %dn, wi );数组及其相关概念数组及其相关概念 数组数组是一组有序的、类型相同的数据的集合,是一组有序的、类型相同的数据的集合,这些数据被称为这些数据被称为数组的元素数组的元素。数组下标数
4、组下标 每个数组都有一个名字,我们称之为每个数组都有一个名字,我们称之为数组名数组名。 为标识数组中的每个元素,我们需要对它们进行为标识数组中的每个元素,我们需要对它们进行编号,这种编号我们称之为编号,这种编号我们称之为数组元素的下标数组元素的下标。 由于有了下标,元素在数组中的位置(或排列由于有了下标,元素在数组中的位置(或排列顺序)就被唯一地确定下来。我们用数组名加上顺序)就被唯一地确定下来。我们用数组名加上下标就可以准确地访问数组中的某个元素了。下标就可以准确地访问数组中的某个元素了。如:如:w0代表数组代表数组w中的第一个元素中的第一个元素 w9代表数组代表数组w中的第十个元素中的第十
5、个元素 注意:注意:C语言规定下标从语言规定下标从0开始。开始。说明说明:数组名代表数组的起始地址。数组名代表数组的起始地址。 数组元素在内存中是连续存储的。数组元素在内存中是连续存储的。7.1 一维数组7.1.1 一维数组的定义与引用一维数组的定义与引用 定义一维数组的一般方式:定义一维数组的一般方式: 类型说明符类型说明符 数组名数组名常量表达式常量表达式;指明数组元素指明数组元素的数据类型的数据类型指明数组所含指明数组所含的元素个数的元素个数例如:例如:int a10; /*定义的整型数组定义的整型数组a含含10个元素个元素*/ float b20; /*定义的实型数组定义的实型数组b含
6、含20个元素个元素*/说明:说明: 数组名的命名规则同变量名的命名规则一样;数组名的命名规则同变量名的命名规则一样;数组名后用方括号数组名后用方括号 ,不能用(),不能用()常量表达式必须是常量表达式必须是大于大于0的整型常量表达式的整型常量表达式,不不 能包含变量能包含变量。即。即C语言不允许对数组的大小作动语言不允许对数组的大小作动 态定义,即定义数组时,数组的长度必须是确态定义,即定义数组时,数组的长度必须是确 定的,其大小不依赖程序运行过程中变量的值。定的,其大小不依赖程序运行过程中变量的值。int a(10); 例如:例如:int n;int anchar name0; float
7、weight10.3;float array-100;一维数组引用的一般方式:一维数组引用的一般方式: 数组名数组名 下标下标;例例 数组元素的引用。数组元素的引用。main()int a9;for(i=0;i=0;i-)printf(“%d”,ai);/*按下标的格式对数组元素引用按下标的格式对数组元素引用*/运行结果:运行结果:8 7 6 5 4 3 2 1 0 7.1.2 一维数组的初始化与引用一维数组的初始化与引用1 .1 .定义时初始化定义时初始化在定义时赋予初值在定义时赋予初值 如:如: int a5= 2 , 4 , 6 , 8 , 10 ;存储形式:存储形式:存储单元可知初始化
8、的一般形式为:可知初始化的一般形式为:类型说明符类型说明符 数组名数组名常量表达式常量表达式=值,值,值,值,值值; 可以只给部分元素赋值可以只给部分元素赋值例如:例如:int a10=0,1,2,3,4; 这表示只给前这表示只给前5个元素赋值,后个元素赋值,后5个个元素值全为元素值全为0。如果想给一个数组中如果想给一个数组中全部元素值全部元素值为为0,可以写成可以写成int a10=0,0,0,0,0,0,0,0,0,0;或或 int a10=0;在对全部数组元素赋初值时,在对全部数组元素赋初值时,可以可以不指定数组长度不指定数组长度。例如:。例如:int a5=1,2,3,4,5; 也可以
9、写成也可以写成int a=1,2,3,4,5;说明:说明:如果在定义一维数组时给出了全部元素的初值,如果在定义一维数组时给出了全部元素的初值, 则数组的下标允许省略。此时编译系统将自动则数组的下标允许省略。此时编译系统将自动 根据初始化数据的个数来确定数组的长度。根据初始化数据的个数来确定数组的长度。如:如: int a = 2 , 4 , 6 , 8 , 10 ; int a ; 初始化的数据个数初始化的数据个数允许少于数组的长度允许少于数组的长度,但,但不不能多于数组的长度能多于数组的长度。当初始化的数据个数(至。当初始化的数据个数(至少要有一个)少于数组的长度时,未初始化部少要有一个)少
10、于数组的长度时,未初始化部分将被编译系统自动用分将被编译系统自动用 0 赋值。赋值。如:如:int a5= 2 , 4 ; 相当于:相当于:a0=2, a1=4, a2=0, a3=0, a4=0 int a5=1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ; 2 .2 .使用其它方法初始化使用其它方法初始化利用输入语句初始化main() char as26; int i ; for(i=0; i26; i+) scanf(%c,&asi); .利用赋值语句初始化main() char as26,ch; for(ch=A;ch=Z;ch+) asch-A=ch; .3. 一维数组
11、的引用一维数组的引用 数组元素类似于单个变量,可以自由地存取。数组元素类似于单个变量,可以自由地存取。但是,它与一般变量相比,有以下特殊之处:但是,它与一般变量相比,有以下特殊之处:数组元素是通过数组名加上该元素在数组中数组元素是通过数组名加上该元素在数组中的位置(即数组元素的下标)来访问的。的位置(即数组元素的下标)来访问的。 表示形式: 数组名下标 如: a3 其中,其中,下标可以是整型常量、整型变量或整下标可以是整型常量、整型变量或整型表达式型表达式。如: int a10 ; float i=3 ; ai=10 ;数组元素的下标是从数组元素的下标是从0开始的。开始的。如:int a2;
12、scanf(“%d,%d”,&a1,&a2); 数组元素的赋值是逐个元素进行的,不允数组元素的赋值是逐个元素进行的,不允许把一个数组作为一个整体赋给另一个数组。许把一个数组作为一个整体赋给另一个数组。除了数组初始化外,也不允许用在花括号中列除了数组初始化外,也不允许用在花括号中列表的方式对数组整体赋值。表的方式对数组整体赋值。例1: int a5= 2 , 4 , 6 , 8 , 10 , b5 ; b5=a5 ;例2 :int a5 ; a5= 2 , 4 , 6 , 8 , 10 ;数组名数组名a代表的是数组代表的是数组a在内存中的首地址,在内存中的首地址,因此,可以用数组名因此,可以用数
13、组名a来代表数组元素来代表数组元素a0的地址。的地址。 等价于等价于scanf(“%d”,&a0); scanf(“%d”,a); 一维数组应用举例一维数组应用举例例例1 1:从键盘上输入:从键盘上输入1010个实型数存入数组,然个实型数存入数组,然 后按输入顺序的逆序输出这后按输入顺序的逆序输出这1010个数。个数。main() float a10; int i; for(i=0 ; i=0 ; i-) printf(“%10.2f”,ai);例:用数组来处理求斐波纳契数列:例:用数组来处理求斐波纳契数列: 1 1,1 1,2 2,3 3,5 5,8 8的前的前2020个数。个数。main(
14、) int f20=1,1; for(i=2 ; i20 ; i+) /*f2是数组第3个元素*/ fi=fi-2+fi-1; for(i=0 ; i20 ; i+) printf(“%10d”,fi); if(i%2=0) printf(“n”); /*每行打印2个数*/ 数学表示:数学表示:f(0)=f(1)=1, f(n)=f(n-2)+f(n-1)例:用冒泡法对例:用冒泡法对1010个数排序(由小到大)。个数排序(由小到大)。冒泡法的思路是:冒泡法的思路是:将相邻两个数比较,将小的将相邻两个数比较,将小的 调到前头。调到前头。 9 8 8 8 8 8 8 9 5 5 5 5 5 5 9
15、 4 4 4 4 4 4 9 2 2 2 2 2 2 9 0 0 0 0 0 0 9 第一轮排序,比较了第一轮排序,比较了5次次 ,获得第一次结果,获得第一次结果。剩数 轮数 5 1 4 2 3 3 2 4 1 5 main() int a11, i , j , t ; printf(“Input 10 numbers : n”); for(i=1 ; i11 ; i+) scanf(“%d”,&ai); printf(“n”); for(j=1 ; j=9 ; j+) /* 控制9轮排序 */ for(i=1 ; iai+1) t=ai; ai=ai+1; ai+1=t; for(i=1 ;
16、 i=10 ; i+) printf(%d,ai);7.2 二维数组先看一个例子:先看一个例子: 某校近三年招收各专业毕业生情况如下:某校近三年招收各专业毕业生情况如下: 计算机 电子 管理 数学 1999 90 40 80 30 2000 100 50 90 40 2001 95 45 100 50 要把这些数据组织起来,可以有两种选择:要把这些数据组织起来,可以有两种选择: 按从左到右从上到下的顺序存入一个一维数按从左到右从上到下的顺序存入一个一维数 组中。(查询困难)组中。(查询困难) 每年用一个一维数组,把这些数据分别存入每年用一个一维数组,把这些数据分别存入 三个数组中。三个数组中。
17、 (增加一年数据困难)(增加一年数据困难)7.2.1 二维数组的定义与引用二维数组的定义与引用 定义二维数组的一般方式:定义二维数组的一般方式:类型说明符类型说明符 数组名数组名 常量表达式常量表达式11常量表达式常量表达式22; 如: int a34; 存储形式:存储形式: 二维数组在内存中是按行的顺序存放的,即先存放第一行的元素,再存放第二行的元素。 说明:说明:二维数组除了维数比一维数组多一维外,二维数组除了维数比一维数组多一维外, 其它性质与一维数组是全部类似的。其它性质与一维数组是全部类似的。 看看下面写法是否正确?看看下面写法是否正确? int a03; 用于定义数组长度的常量表达
18、式的值必须用于定义数组长度的常量表达式的值必须是大于是大于0的正整数。的正整数。 int i=3 , j=4 ; int aij ; 定义数组元素的个数必须使用常量表达式,定义数组元素的个数必须使用常量表达式,而不能使用变量。而不能使用变量。 二维数组的引用二维数组的引用 与引用一维数组元素一样,是用下标法引用二维数组元素的。表示形式:表示形式: 数组名行下标列下标 其中,行下标和列下标是整型常量、整型变量或整型表达式。其编号是从0开始的。例如:若有 int a2*53*4, i=15; 则使用 a3*30, a1i-5都是合法的。说明:数组名a代表的是数组a在内存中的首地址, 因此,可以用数
19、组名a来代表数组元 素 a00的地址。7.2.2 二维数组的初始化二维数组的初始化 这里主要介绍定义时初始化,其它方法初始化和一维数组类似。定义时初始化有两种方法: 分行初始化分行初始化 例如:例如:int a23=1 , 2 , 3 , 4 , 5 , 6 ; 线性初始化线性初始化 即按数组元素在内存中排列的顺序赋初值。即按数组元素在内存中排列的顺序赋初值。 例如:例如:int a23=1 , 2 , 3 , 4 , 5 , 6 ;(3)只对部分赋值只对部分赋值int a34=1,4,3,1,2;这种赋值方法相当于:这种赋值方法相当于:int a34=1,0,0,0,4,3,0,0,1,2,
20、0,0;系统自动将没有赋值的元素赋值成系统自动将没有赋值的元素赋值成0。int a34=1,4;相当于相当于int a34=1,0,0,0,4,0,0,0,0,0,0,0;对于没有大括号的,系统自动将此行元素赋值为对于没有大括号的,系统自动将此行元素赋值为0。(4)如果将数组的所有元素全部赋值的话,可以省如果将数组的所有元素全部赋值的话,可以省掉第一维的长度掉第一维的长度。例如:。例如:int a4=1,2,3,4,5,6,7,8,9,10,11,12;说明:说明: 在对二维数组初始化时,也可以只对部分数组在对二维数组初始化时,也可以只对部分数组元素初始化,未被初始化的数组元素将自动赋元素初始
21、化,未被初始化的数组元素将自动赋 0 。int a23=5,6,7,8;int a23=5,6,7,8;如:得到的数组为: 5 6 0 7 8 0得到的数组为: 5 6 7 8 0 0在对二维数组初始化时,如果对全部元素都赋初值,在对二维数组初始化时,如果对全部元素都赋初值,或分行赋初值或分行赋初值(每行至少一个数据每行至少一个数据),则可以省略第一,则可以省略第一维数组长度。但是,维数组长度。但是,第二维数组长度不允许省略第二维数组长度不允许省略。如:int a3=1,2,3,4,5,6,7,8,9;int a4=1,2,3,4,5,6,7;系统按3行处理 int a10=1,0; floa
22、t f2=1.1,2.2; 7.2.3 二维数组应用举例二维数组应用举例例1:使用数组保存“九九表”,然后输出。main() int a991010, i, j ; for(i=1; i 10; i+) for(j=1; j=i; j+) a99ij=i*j; for(i=1; i10; i+) for(j=1;j=i; j+) printf(“%6d,a99ij); printf(“n”); 例:矩阵的转置。(书中例例:矩阵的转置。(书中例7.4)a=1 2 34 5 6b=1 4 2 53 6转换成main() int a23=1,2,3,4,5,6; int b32, i,j; prin
23、tf( array a:n); for(i=0;i=1;i+) for(j=0;j=2;j+) printf(%5d,aij); bji=aij; printf(n); printf(n array b:n); for(i=0;i3;i+) for(j=0;j2;j+) printf(%6d,bij); printf(n); 例:求例:求3*4数组中的最大值及其下标。数组中的最大值及其下标。main() int max,row,colum,i,j; int a4=1,2,3,4,9,8,7,6,-10,10,-5,2; max=a00; for(i=0;i3;i+) for(j=0;jmax)
24、 max=aij; row=i; colum=j; printf(max=%d,row=%d,colum=%d,max,row,colum);7.3 多维数组介绍例如:我们定义一个三维数组:例如:我们定义一个三维数组:int m234;其中常量表达式由原来的两个变为三个,把这个三维数组其中常量表达式由原来的两个变为三个,把这个三维数组按顺序进行展开如下:按顺序进行展开如下: m000,m001,m002,m003m010,m011,m012,m013m020,m021,m022,m023m100,m101,m102,m103m110,m111,m112,m113m120,m121,m122,m
25、123 定义多维数组的一般方式:定义多维数组的一般方式:类型说明符类型说明符 数组名数组名 表达式表达式11表达式表达式22 表达式表达式nn;7.4 字符数组和字符串7.4.1 字符数组的定义与初始化字符数组的定义与初始化 当数组的元素类型为字符型时,被称为当数组的元素类型为字符型时,被称为字符数组字符数组。如:char c10; 则c为字符数组。 字符数组的定义、初始化和元素的引用与字符数组的定义、初始化和元素的引用与一般的数组相同。一般的数组相同。如:main() char ch5=c, h , i , n , a; for(i=0; i5; i+) printf(“%c”,chi);
26、说明:说明:定义字符数组的类型说明符一般为定义字符数组的类型说明符一般为char, 如:如: char c10; 由于字符型与整型的互相通用性,由于字符型与整型的互相通用性, 因此,上面定义也可改为:因此,上面定义也可改为:int c10;初始化的字符个数初始化的字符个数允许少于字符数组的长度允许少于字符数组的长度, 但但不能多于字符数组的长度不能多于字符数组的长度。当初始化的字。当初始化的字 符(至少要有一个)少于字符数组的长度时,符(至少要有一个)少于字符数组的长度时, 未初始化部分将被编译系统自动用空字符未初始化部分将被编译系统自动用空字符0 赋值。赋值。如:int c8=H,e,l,l
27、,o; 则:c0=H, c1= e, c2= l, c3= l, c4= ,o c5=0, c6=0, c7=07.3.3 字符串与字符数组字符串与字符数组 字符串常量字符串常量是用双引号括起来的一串字符,由系统自动加上一个字符串结束标志0。它占内存,但不记入字符串长度。如:“china” 占内存6个字节,但字符串长度是5 在在C语言中用字符数组来处理字符串,每个语言中用字符数组来处理字符串,每个元素存放一个字符型数据。元素存放一个字符型数据。 字符型数组可用一般数组的初始化方式初始化字符型数组可用一般数组的初始化方式初始化外,还可以使用字符串常量初始化:外,还可以使用字符串常量初始化:如:c
28、har message=“Hello”; 或 char message=“Hello”; (这时,字符数组长度是6,字符串长度是5。)注意注意:它与一般初始化方式:它与一般初始化方式: char message=H, e, l, l, o; 初始化的结果是不同的。初始化的结果是不同的。 用一般初始化方式结果: H e l l o用字符串常量初始化 : H e l l o 0说明说明:字符数组本身并不要求它的最后一个元素一定是0,例如:char ch2=A, B;是合法的。当定义字符数组用字符串常量赋初值时,最后有一个元素其值为0。为了使处理方法一致,在字符数组中也常常人为地加上一个值为0的元素
29、。如:char message=H, e, l, l, o, 0;例例 输出一个钻石图形输出一个钻石图形main() char diamond5=,*,*,*,*,”*, ,*,*,*; int i,j; for(i=0;i5;i+) for(j=0;j5;j+) printf(“%c”,diamondij); printf(“n”); * * * * * * * *main() char a5; int i=0; while(i0; 串串1串串2 则:则:n= n=0; 串串1=串串2 n0; 串串10) puts(str1);注意:注意:不能写成不能写成 if(str1str2)strcm
30、p(“China”,”Korea”);6. 字符串复制字符串复制strcpy()函数函数 使用形式使用形式: strcpy(字符数组1,字符串2 )功能功能:将字符串2复制到字符数组1中 (其后自动加一个0)。例如:char str120, str210 ; strcpy(str1,“hello world”); strcpy(str2,str1); 其中,字符串2可以是字符串常量或字符数组。 说明:说明:字符数组字符数组1必须足够大以便能够容纳被必须足够大以便能够容纳被 复制的字符串。复制的字符串。 不能用赋值语句将一个字符串常量或字符不能用赋值语句将一个字符串常量或字符 数组直接赋值给一个
31、字符数组。数组直接赋值给一个字符数组。 例如:char str120, str220; str1=“hello”; str2=str1 ;7.将字符串中大写字母换成小写字母将字符串中大写字母换成小写字母strlwr()函数函数 使用形式使用形式: strlwr(字符串 )8.将字符串中小写字母换成大写字母将字符串中小写字母换成大写字母strupr函数函数使用形式使用形式: strupr(字符串 )例1:统计字符串中的单词数。 #include main() char string81,c; int i,num=0,word=0; gets(string); for(i=0;stringi!=0
32、;i+) if(stringi= ) word=0; else if(word= =0)word=1;num+; printf(“nThere are %d words.”, num);I am a boy7.4 数组综合实例数组综合实例 例例2: 3个字符串求最大的字符串个字符串求最大的字符串 。#include #includemain() char s320,s120; int i,j; for(i=0;i0) strcpy(s1,s0); else strcpy(s1,s1) if(strcmp(s2,s1)0) strcpy(s1,s2); puts(s1);CHINA HOLLAN
33、D AMERICA例例3:两种常用排序方法。:两种常用排序方法。1冒泡排序法冒泡排序法(5个杂乱无章的整数冒泡法的基本思想是个杂乱无章的整数冒泡法的基本思想是 :)a0 a1 a2 a3 a4 9 8 7 6 10 第一趟比较结果 8 7 6 9 10 第二趟比较结果 7 6 8 9 10 第三趟比较结果 6 7 8 9 10第四趟比较结果,即最后排序结果程序如下程序如下:#includemain()int i,j,t,a5;for(i=0;i5;i+)printf(“enter No.%2d:”,i+1);scanf(“”%d),&ai);for(i=0;i4;i+)for(j=0;jaj+
34、1t=aj;aj=aj+1;aj+1=t;for(i=0;i5;i+)printf(“%d,ai);2.选择排法选择排法 选择排序实现的思想是:选择排序实现的思想是: 经过两两比较后,并不马上交换数的位置,而是找经过两两比较后,并不马上交换数的位置,而是找到最小的数后,记下数的位置,待一趟比较完后,在到最小的数后,记下数的位置,待一趟比较完后,在将最小的数一次交换到位。将最小的数一次交换到位。 程序如下程序如下:#includemain()int i,j,t,p,a5;for(i=0;i5;i+)printf(“enter No.%2d:”,i+1);scanf(“%d”,&ai);for(i
35、=0;i4;i+)p=i;for(j=i+1;jaj)p=j;if(p!=i) t=ap;ap=a i;ai=t; /*数组元素一次交换到位*/for(i=0;i4;i+)printf(“%d,ai);学习数组这一章要注意的几个问题:学习数组这一章要注意的几个问题:1.1.在在C C语言中数组的下标是从语言中数组的下标是从0 0开始;开始;2.2.C C语言不进行下标的越界检查,不论是在编译阶段还是语言不进行下标的越界检查,不论是在编译阶段还是 在运行阶段,这个问题交给程序员。这样就给初学者在运行阶段,这个问题交给程序员。这样就给初学者 带来一定的风险。带来一定的风险。3 3. .数组名是地址
36、,这在字符串处理中已经看到,这个我数组名是地址,这在字符串处理中已经看到,这个我 们要先强记,以后在讲指针时在详细讲。们要先强记,以后在讲指针时在详细讲。4.4.字符数组在定义时必须考虑到串结束符的位置,因为字符数组在定义时必须考虑到串结束符的位置,因为 它要占一个字符的位置它要占一个字符的位置. .5.5.要注意数组初始化的方法与简单变量的区别,特别是要注意数组初始化的方法与简单变量的区别,特别是 字符数组的初始化方法。字符数组的初始化方法。6.6.字符串的操作有许多专用函数,请注意掌握并运用字符串的操作有许多专用函数,请注意掌握并运用。小小 结结 (1)(1)数组是可以通过下标访问的相同类
37、型数据元素的集合,数组是可以通过下标访问的相同类型数据元素的集合,而下标则是用于标识数组元素位置的整数。而下标则是用于标识数组元素位置的整数。 (2)(2)一维数组。一维数组。 (3)(3)数组中的每个元素带有两个下标时,称这样的数组为二维数组中的每个元素带有两个下标时,称这样的数组为二维数组。其中存放的是有规律地按行列排列的同一类型数据。数组。其中存放的是有规律地按行列排列的同一类型数据。 (4)(4)字符数组是用来存放字符的数组,其定义和引用与前面字符数组是用来存放字符的数组,其定义和引用与前面讨论的一维数组类似。讨论的一维数组类似。C C语言中没有直接提供字符串类型,语言中没有直接提供字符串类型,字符串被定义为一个字符数组。字符串被定义为一个字符数组。 (5)(5)字符串处理函数有:字符串处理函数有:getsgets函数函数,putsputs函数,函数,strcatstrcat函数,函数,strcpystrcpy函数,函数,strlenstrlen函数函数) )(6)字符串数组就是数组中的每个元素又都是一个存放字符字符串数组就是数组中的每个元素又都是一个存放字符串的数组。串的数组。
限制150内