《C语言08Array课件》由会员分享,可在线阅读,更多相关《C语言08Array课件(22页珍藏版)》请在金锄头文库上搜索。
1、数组数组C语言08-Array提纲提纲数组概述一维数组二维数组字符数组字符数组的定义、引用和初始化字符串处理函数运算符小结结束C语言08-Array数组概述数组概述 数组是一种构造类型。数组是一种构造类型。 所谓的构造类型是所谓的构造类型是由基本数据类型按一定规则组成由基本数据类型按一定规则组成的,也称的,也称“ “导出类型导出类型” ”。 数组由一系列元素构成,这些数组由一系列元素构成,这些元素均属同一数据类型元素均属同一数据类型。 数组是有序数据的集合,数组是有序数据的集合,在内存中是连续存放在内存中是连续存放的,数组元素的,数组元素之间的序由其在内存中的前后关系来表现。之间的序由其在内存
2、中的前后关系来表现。 可以用一个统一的可以用一个统一的数组名数组名和和下标下标来唯一地来唯一地定位定位数组中的元素。数组中的元素。其中,其中,数组名代表了数组在内存中的首地址数组名代表了数组在内存中的首地址。 返回LD01234in下标为下标为下标为下标为i i的元素(第的元素(第的元素(第的元素(第i+1i+1个元素)个元素)个元素)个元素)的的的的首地址首地址首地址首地址D Di i=D+i=D+i L L根据数组的组成规则,可分为一维数组、二维数组和多维数组。根据数组的组成规则,可分为一维数组、二维数组和多维数组。C C语言中把字符串定义为字符数组,即数组元素为字符型的数组。语言中把字符
3、串定义为字符数组,即数组元素为字符型的数组。C语言08-Array一维数组(一维数组(1):定义):定义定义形式:定义形式:类型类型 数组名数组名 常量表达式常量表达式; ;说明说明 数组名是标识符,符合标识符命名规则和作用域规则。数组名是标识符,符合标识符命名规则和作用域规则。 常量表达式值表示元素个数,即常量表达式值表示元素个数,即数组长度数组长度。 常量表达式既不能缺省,其中也不能包含变量。常量表达式既不能缺省,其中也不能包含变量。C C要求在要求在定义数组的时候明确指定数组长度。定义数组的时候明确指定数组长度。示例示例 int a20;int a20; #define MAXLEN 2
4、0#define MAXLEN 20int bMAXLEN;int bMAXLEN; int maxlen=20;int maxlen=20;int cmaxlen, d;int cmaxlen, d;C语言08-Array一维数组(一维数组(2):引用):引用C C语言规定只能逐个引用数组元素而语言规定只能逐个引用数组元素而不能一次引用整个不能一次引用整个数组数组(如,不能对数组进行整体赋值)。(如,不能对数组进行整体赋值)。数组元素引用形式:数组名数组元素引用形式:数组名 下标下标 数组元素引用中的方括号是一个特殊的运算符号数组元素引用中的方括号是一个特殊的运算符号下下标运算符。标运算符。
5、下标运算符的优先级是最高的下标运算符的优先级是最高的,所以,所以+ai+ai等价于等价于+(ai)+(ai)下标运算符的结合性是从左向右结合。下标运算符的结合性是从左向右结合。下标下标是整型表达式,表达式中可包含变量。是整型表达式,表达式中可包含变量。原则上说,原则上说,如果数组的长度为如果数组的长度为n n则下标的范围应该界于则下标的范围应该界于0 0和和n-1n-1。但但C C编译系统没有对下标进行越界检查。编译系统没有对下标进行越界检查。数组定义和数组元素引用的形式相似,但意义不同。数组定义和数组元素引用的形式相似,但意义不同。示例示例C语言08-Array一维数组(一维数组(3):初始
6、化):初始化要点要点 定义数组时可对数组元素赋初值。如:定义数组时可对数组元素赋初值。如:int a3=0,1,2;int a3=0,1,2; 如果数组没有初始化,系统会用默认值对它初始化。即外如果数组没有初始化,系统会用默认值对它初始化。即外部数组或静态数组赋部数组或静态数组赋0 0值,自动数组赋随机值。值,自动数组赋随机值。 初始化可以只针对数组中的前面一部分元素,未初始化的初始化可以只针对数组中的前面一部分元素,未初始化的部分元素将自动被初始化为部分元素将自动被初始化为0 0。如:。如:int a10=0,1,2,3,4;int a10=0,1,2,3,4;或或int a10=0;int
7、 a10=0; 如果对全部数组元素赋初始值时,可以不指定数组长度。如果对全部数组元素赋初始值时,可以不指定数组长度。例如:例如:int a5=0,1,2,3,4;int a5=0,1,2,3,4; 等价于等价于int a=0,1,2,3,4;int a=0,1,2,3,4; 对数组进行初始化时,不允许初始化的元素个数较已定义对数组进行初始化时,不允许初始化的元素个数较已定义的数组长度大,如:的数组长度大,如:int a5=0,1,2,3,4,5;int a5=0,1,2,3,4,5;是错的。是错的。问题问题两个例子两个例子及教材及教材8.1.48.1.4、8.1.58.1.5、8.1.68.1
8、.6返回C语言08-Array二维数组(二维数组(1):定义与引用):定义与引用二维数组的定义二维数组的定义类型类型类型类型 数组名数组名数组名数组名 常量表达式常量表达式常量表达式常量表达式11常量表达式常量表达式常量表达式常量表达式2;2; 例如:例如:float a34;float a34;说明了一个说明了一个3 3行行4 4列的数组。列的数组。 C C的二维数组事实上是一种特殊的一维数组:的二维数组事实上是一种特殊的一维数组:每个元素都是每个元素都是一个一维数组的一维数组一个一维数组的一维数组。 C C的二维数组在内存中是的二维数组在内存中是按行存放按行存放。引用:数组名引用:数组名
9、下标下标11下标下标22C C还允许使用多维数组还允许使用多维数组 类型类型 数组名数组名 常量表达式常量表达式11常量表达式常量表达式n;n; 其元素在内存中的排列顺序是:第一维的下标变化最慢,最其元素在内存中的排列顺序是:第一维的下标变化最慢,最后一维的下标变化最快。例如,后一维的下标变化最快。例如,已知已知int a222;int a222;则数组则数组a a的元素在内存中的排列为:的元素在内存中的排列为:a000a000a001a001a010a010a011a011a100a100a1a10101a110a110a111a111C语言08-Array二维数组(二维数组(2):初始化和
10、应用):初始化和应用初始化可以按分行赋初值的方式,也可以按不分行赋初始化可以按分行赋初值的方式,也可以按不分行赋初值的方式,分行赋初值程序更清晰。例如:初值的方式,分行赋初值程序更清晰。例如: int a34=1,2,3,4,5,6,7,8,9,10,11,12;int a34=1,2,3,4,5,6,7,8,9,10,11,12;等价于等价于int a34=1,2,3,4,5,6,7,8,9,10,11,12;int a34=1,2,3,4,5,6,7,8,9,10,11,12;也可只对部分元素赋初值。例子:也可只对部分元素赋初值。例子: int a34=1,5,9;int a34=1,5,
11、9; int a34=1,0,6,0,0,11;int a34=1,0,6,0,0,11; int a34=1,5,6;int a34=1,5,6; int a34=1, ,9; int a34=1, ,9; int a34=1,0,9;int a34=1,0,9;如果初始化提供了足够的信息(如,全部初始化或分如果初始化提供了足够的信息(如,全部初始化或分行初始化),则定义数组时可以省略行初始化),则定义数组时可以省略第一维第一维的长度。的长度。 二维数组使用示例二维数组使用示例(求最值)(求最值) 例例8.2.18.2.1(距阵的转置)(距阵的转置) 例例8.2.38.2.3(打印杨辉三角)
12、也可以用一维数组实现。(打印杨辉三角)也可以用一维数组实现。返回C语言08-Array字符数组的定义、引用和初始化(字符数组的定义、引用和初始化(1)字符数组的定义方法和普通数组的定义方式相同。例如:char c10;定义了包含10个元素的字符数组。对字符数组也可以采用普通数组的初始化方式。例如:char c5=H,e,l,l,o;也可以定义和初始化一个二维字符数组。可以使用和与普通数组类似的方式引用字符数组中的元素,得到一个字符。示例C语言08-Array字符数组的定义、引用和初始化(字符数组的定义、引用和初始化(2)在在C C语言中,语言中,将字符串作为字符数组来处理将字符串作为字符数组来
13、处理。有时,有效字符串的长度和字符数组的长度不相同。有时,有效字符串的长度和字符数组的长度不相同。为测定字符串的实际长度,为测定字符串的实际长度,C C规定了一个规定了一个“ “字符串结字符串结束标志束标志” ”,以字符,以字符00代表代表。例如,如果有一个字。例如,如果有一个字符串中第一次出现符串中第一次出现00的是其第的是其第1010个字符(对应字个字符(对应字符数组的第符数组的第9 9个元素),则字符串的有效字符为个元素),则字符串的有效字符为9 9个。个。系统对字符串常量自动加了一个系统对字符串常量自动加了一个00作为结束符。作为结束符。可以用字符串常量来使字符数组初始化。例如,可以用
14、字符串常量来使字符数组初始化。例如,char c =“Hello”; char c =“Hello”; 或或 char c =“Hello”; char c =“Hello”;应该注意到,这样初始化,数组应该注意到,这样初始化,数组c c的长度是的长度是6 6,等价于,等价于char c6=H, e, l, l, o, 0;char c6=H, e, l, l, o, 0;字符数组并不要求最后一个字符为字符数组并不要求最后一个字符为00。输入输出可以使用输入输出可以使用%c%c逐个字符处理,也可以用逐个字符处理,也可以用%s%s整体整体处理。处理。返回C语言08-Array字符串处理函数(字符
15、串处理函数(1):输出):输出使用使用printfprintf 用用“%s”“%s”格式符。格式符。 对应的输出项是字符数组名。对应的输出项是字符数组名。例如:例如:char str=Hello World!;char str=Hello World!;printf(%s, str);printf(%s, str); 输出过程会在遇到第一个输出过程会在遇到第一个00时停止。时停止。例如:例如:char str=Hello0World!;char str=Hello0World!;printf(%s, str);printf(%s, str);putsputs 原型:原型:#include #i
16、nclude int puts (const char * s);int puts (const char * s); 说明:将一个以说明:将一个以00结束的字符序列输出到终端。结束的字符序列输出到终端。 注意,注意,putsputs输出时,将字符串结束标志输出时,将字符串结束标志00转换成转换成nn。C语言08-Array字符串处理函数(字符串处理函数(2):输入):输入使用使用scanfscanf 用用“%s”“%s”格式符格式符 对应的输入项是字符数组名。对应的输入项是字符数组名。不必加上不必加上& &。例如:例如:char str255;char str255;scanf(%s“, s
17、tr);scanf(%s“, str); 遇到空格、遇到空格、tabtab键或回车键为止,系统会自动在接受到的字键或回车键为止,系统会自动在接受到的字符后面加一个符后面加一个00getsgets 原型:原型:#include #include char * gets (char * string);char * gets (char * string); 说明:从终端输入一个字符串到字符数组说明:从终端输入一个字符串到字符数组stringstring中,输入的中,输入的结束标志是回车,最后换行符将转化为结束标志是回车,最后换行符将转化为00。 返回值:返回值:stringstring的起始地址
18、。的起始地址。getsgets与与scanfscanf的区别是其能接受带空格的字符串的区别是其能接受带空格的字符串。C语言08-Array字符串处理函数(字符串处理函数(3) 原型:原型:#include #include char * strcpy (char * dest, const char * src);char * strcpy (char * dest, const char * src);说明:将字符串说明:将字符串srcsrc复制到字符数组复制到字符数组destdest中中注意:字符数组注意:字符数组destdest必须定义得足够大。必须定义得足够大。字符串复制绝对不能用简单
19、赋值(字符串复制绝对不能用简单赋值(= =)的形式)的形式。 原型:原型:#include #include int strcmp (const char * s1, const char * s2);int strcmp (const char * s1, const char * s2);说明:比较字符串说明:比较字符串s1s1和和s2s2,其比较规则就是,自左向右逐,其比较规则就是,自左向右逐个比较对应字符,直到出现不同的字符或遇到个比较对应字符,直到出现不同的字符或遇到00。全。全部相同则返回部相同则返回0 0,否则返回第一对不同字符之间的差值。,否则返回第一对不同字符之间的差值。注意
20、:注意:比较字符串不能用简单比较(比较字符串不能用简单比较(=)的形式)的形式。 原型:原型:#include #include int strlen (const char * s);int strlen (const char * s);说明:测试字符串说明:测试字符串s s长度,长度,不计字符串最后的不计字符串最后的00。C语言08-Array字符串处理函数(字符串处理函数(4)原型:原型:#include #include char * strcat (char * dest, const char * src);char * strcat (char * dest, const ch
21、ar * src);说明:连接两个字符数组中的字符串,将字符串说明:连接两个字符数组中的字符串,将字符串srcsrc接接到字符串到字符串destdest之后,并将结果放在字符数组之后,并将结果放在字符数组destdest中。中。注意:字符数组注意:字符数组destdest必须足够长。必须足够长。字符串字符串destdest结束标志将被删除。结束标志将被删除。原型:原型:#include #include char * strlwr (char * s);char * strlwr (char * s);说明:将字符串说明:将字符串s s中的大写字母转换成小写字母,其他中的大写字母转换成小写字母
22、,其他字符不变。字符不变。原型:原型:#include #include char * strupr (char * s);char * strupr (char * s);说明:将字符串说明:将字符串s s中的小写字母转换成大写字母,其他中的小写字母转换成大写字母,其他字符不变。字符不变。例见例见8.3.1 8.3.1 、8.3.28.3.2、8.3.38.3.3返回C语言08-Array运算符小结运算符小结返回运算符运算符结合方向结合方向备注备注自左向右自左向右! !、- -、+、- -、( (类型类型) )自右向左自右向左此处的此处的- -为负号运算符为负号运算符* *、/ /、%自左向
23、右自左向右此处的此处的* *为乘法运算符为乘法运算符+ +、- -自左向右自左向右此处的此处的- -为减法运算符为减法运算符 、=、 自左向右自左向右=、!=!=自左向右自左向右&自左向右自左向右|自左向右自左向右? :? :自右向左自右向左唯一的三目运算符唯一的三目运算符= =、+=+=、-=-=、*=*=、/=/=、%=%= 自右向左自右向左, ,自左向右自左向右高高低低C语言08-Array示例:一维数组的引用示例:一维数组的引用void main () int i, a10; for (i=0; i=0; i-) printf (%d , ai); printf(n);返回注意到,对数
24、组元素的引用(如ai)即可以作为左值,也可以作为右值。C语言08-Array问题:一维数组的初始化问题:一维数组的初始化下面诸组程序片段是否等价?返回片段片段1 1片段片段2 2等价否等价否int a=3;int a=3;int a;int a;a=3;a=3;int a3=0,0,0;int a3=0,0,0;int a3=0;int a3=0;int a3=0;int a3=0;int a3;int a3;int a3=0,1,2;int a3=0,1,2;int a3;int a3;a3=0,1,2;a3=0,1,2;int a3=0,1,2;int a3=0,1,2;int a3;in
25、t a3;a=0,1,2;a=0,1,2; C语言08-Array示例:示例:Fibonacci数列问题数列问题 FibonacciFibonacci数列的定义如下:数列的定义如下:1 1n=1n=1F Fn n= = 1 1n=2n=2F Fn-1n-1+F+Fn-2n-2n3n3 打印打印FibonacciFibonacci数列前数列前2020项项void main()void main() int f1,f2; int i; int f1,f2; int i; f1=1; f2=1; f1=1; f2=1; for (i=1;i=10;i+) for (i=1;i=10;i+) prin
26、tf ( printf (%12d %12d ,f1,f2);%12d %12d ,f1,f2); if (i%2=0) printf (n); if (i%2=0) printf (n); f1=f1+f2; f2=f1+f2; f1=f1+f2; f2=f1+f2; 打印打印FibonacciFibonacci数列前数列前2020项项 void void main ()main () int i,f20=1,1; int i,f20=1,1; for (i=2;i20;i+) for (i=2;i20;i+) fi=fi-1+fi-2; fi=fi-1+fi-2; for (i=0;i20
27、;i+) for (i=0;i20;i+) if (i%5=0) printf (“n”); if (i%5=0) printf (“n”); printf (“%12d”,fi); printf (“%12d”,fi); C语言08-Array示例:起泡法排序示例:起泡法排序void main()void main() int a10; int a10; int i,j,t; int i,j,t; printf(intput 10 numbers:n);printf(intput 10 numbers:n); for(i=0;i10;i+) scanf(%d,&ai); for(i=0;i1
28、0;i+) scanf(%d,&ai); for(j=1;j=9;j+)for(j=1;j=9;j+) for(i=0;i= for(i=0;iai+1) if(aiai+1) t=ai;ai=ai+1;ai+1=t; t=ai;ai=ai+1;ai+1=t; printf(the sorted numbers:n);printf(the sorted numbers:n); for(i=0;i10;i+) printf(%d ,ai); for(i=0;i10;i+) printf(%d ,ai); printf(n); printf(n); 返回这个程序还可以改进:如果一轮两两比较下来没有
29、发生元素交换,则停止下一轮的比较。C语言08-Array示例:二维数组的使用示例:二维数组的使用 求一个求一个3434的矩阵中最大的元素。的矩阵中最大的元素。 void main()void main() int a34=1,2,3,4, int a34=1,2,3,4, 9,8,7,6, 9,8,7,6, -10,10,-5,2; -10,10,-5,2; int i,j; int i,j; int row=0,colum=0,max=a00; int row=0,colum=0,max=a00; for(i=0;i=2;i+) for(i=0;i=2;i+) for(j=0;j=3;j+)
30、 for(j=0;jmax) if(aijmax) max=aij; row=i; colum=j; max=aij; row=i; colum=j; printf(max=%d, row=%d, colum=%dn, printf(max=%d, row=%d, colum=%dn, max, row, colum); max, row, colum); 返回请注意体会在若干个数中寻找最请注意体会在若干个数中寻找最大(小)值的一般做法:大(小)值的一般做法:(1) (1) 假设第一个元素为所求,将假设第一个元素为所求,将其值记录为当前最大(小)值其值记录为当前最大(小)值(2) (2) 从第
31、二个(或第一个)元素从第二个(或第一个)元素起,逐个判断,如果发现它比当起,逐个判断,如果发现它比当前最大(小)值大(小),则将前最大(小)值大(小),则将其值记录为新的当前最大(小)其值记录为新的当前最大(小)值值C语言08-Array示例:字符数组按逐个字符输出示例:字符数组按逐个字符输出void main() char c5=H,e,l,l,o; int i; for(i=0;i5;i+) printf(%c,ci); printf(n);C语言08-Array示例:使用二维字符数组示例:使用二维字符数组 输出一个钻石图形输出一个钻石图形 void main()void main() char diamond5= , ,*, char diamond5= , ,*, ,*, ,*, ,*, ,*, *, , , ,*, *, , , ,*, ,*, ,*, ,*, ,*, , ,*; , ,*; int i,j; int i,j; for(i=0;i5;i+) for(i=0;i5;i+) for(j=0;j5;j+) for(j=0;j5;j+) printf(%c,diamondij); printf(%c,diamondij); printf(n); printf(n); 返回C语言08-Array