Presentation is loading. Please wait.

Presentation is loading. Please wait.

第六章 数组 西安工程大学.

Similar presentations


Presentation on theme: "第六章 数组 西安工程大学."— Presentation transcript:

1 第六章 数组 西安工程大学

2 本章内容: 6.1 一维数组的定义和引用 6.2 二维数组的定义和引用 6.3 字符数组 请做练习

3 6.1 一维数组的定义和引用 基本数据类型有: 整型 实型 字符型 C语言还提供了构造类型的数据: 数组类型 结构体类型 共用体类型
6.1 一维数组的定义和引用 基本数据类型有: 整型 实型 字符型 C语言还提供了构造类型的数据: 数组类型 结构体类型 共用体类型 构造类型数据是由基本类型数据按一定规则组成的,也称 “导出类型”。 数组是有序数据的集合,数组中的每一个元素属于同一数据类型,用数组名和下标唯一标识数组元素。

4 6.1.1 一维数组的定义 定义方式: 数据类型 数组名[常量表达式]; 例如:   int a[6]; 它表示数组名为a,此数组有6个元素。

5 a 数组名表示数组首地址, 是地址常量 编译时分配连续内存 内存字节数=数组维数* sizeof(元素数据类型) a[0] 1 4 5
1 4 5 a[1] a[2] a[3] a[4] a[5] 2 3 a 数组名表示数组首地址, 是地址常量 编译时分配连续内存 内存字节数=数组维数* sizeof(元素数据类型)

6 [说明]: (1) 数组名定名规则和变量名相同,遵循标识符定名规则。 (2) 数组名后是用方括弧括起来的常量表达式,不能用圆括弧,下面用法不对:int a(6);

7 (3) 常量表达式表示元素的个数,即数组长度。 例如:
在int a[6]中,6表示a数组有6个元素,下标从0开始,这6个元素是,a[0],a[1],a[2],a[3],a[4],a[5]。 [注意]: 不能使用数组元素a[6]。

8 (4) 常量表达式中可以包括常量和符号常量,不能包含变量。
例如: 下面这样定义数组是不行的: int n; scanf("%d",&n); int a[n];

9 6.1.2 一维数组元素的引用 数组必须先定义,后使用。c语言规定只能逐个引用数组元素而不能一次引用整个数组。 数组元素的表示形式为: 数组名 [下标] 下标可以是整型常量或整型表达。例如: a[0]=a[5]+a[7]-a[2*3]

10 #include “stdio.h” void main() { int i,a[10]; for (i=0; i<=9;i++) a[i]=i; for(i=9;i>=0; i--) printf("%d ",a[i]); } 运行结果如下:

11 例如: int a[10]={0,1,2,3,4,5,6,7,8,9};
6.1.3 一维数组的初始化 对数组元素的初始化可以用以下方法实现: (1) 在定义数组时对数组元素赋以初值。 例如: int a[10]={0,1,2,3,4,5,6,7,8,9}; a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 1 2 3 4 5 6 7 8 9

12 (2) 可以只给一部分元素赋值。 例如: int a[10]={0,1,2,3,4}; (3) 如果想使一个数组中全部元素值为 0, 可以写成:   int a[5]={0,0,0,0,0};   或写成:   int a[5]={0};

13 (4) 在对全部数组元素赋初值时,可以不指定数组长度。
例如:   int a[5]={1,2,3,4,5};  可以写成:   int a[]={1,2,3,4,5} 在第二种写法中,花括弧中有5个数,系统就会据此自动定义a数组的长度为5。

14 但若被定义的数组长度与提供初值的个数不相同,则数组长度不能省略。例如:
想定义数组长度为10,就不能省略数组长度的定义,而必须写成 int a[10]={1,2,3,4,5}; 只初始化前5个元素,后5个元素为0。

15 6.1.4 一维数组程序举例 例6.1 输入10个整数,找出其中最大值和最小值。 步骤: 1. 输入:for循环输入10个整数 2. 处理:
#include <stdio.h> #define SIZE 10 void main() { int x[SIZE],i,max,min; printf("Enter 10 integers:\n"); for(i=0;i<SIZE;i++) { printf("%d:",i+1); scanf("%d",&x[i]); } max=min=x[0]; for(i=1;i<SIZE;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); 一维数组程序举例 例6.1 输入10个整数,找出其中最大值和最小值。 步骤: 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

16 例6.2 用数组求Fibonacci数列前20个数。
1 f[0] 2 1 1 f[1] 2 3 f[2] 2 5 3 f[3] 3 4 f[4] 5 f[5] ……... 19 f[19]

17 void main() { int i; int f[20]={1,1}; for(i=2;i<20;i++)
f[i]=f[i-2]+f[i-1]; for(i=0;i<20;i++) if(i%5==0) printf("\n"); printf("%12d",f[i]); }

18 例6.3 用冒泡法对10个数排序 动画演示 排序过程: (1)比较第一个数与第二个数,若为逆序a[0]>a[1],则交换;然后比较第二个数与第三个数;依次类推,直至第n-1个数和第n个数比较为止——第一趟冒泡排序,结果最大的数被安置在 最后一个元素位置上。 (2)对前n-1个数进行第二趟冒泡排序,结果使次大的数被安置在第n-1个元素位置上。 (3)重复上述过程,共经过n-1趟冒泡排序后,排序结束。

19 输入n 个数给a[1] 到 a[n] for i=1 to n-1 for j=1 to 10-i a[j]>a[j+1] 真 假
Ch5_201.c 输入n 个数给a[1] 到 a[n] for i=1 to n-1 for j=1 to 10-i a[j]>a[j+1] 交换a[j]和a[j+1] 输出a[1] 到 a[n]

20 void main() { int i,j, a[11],temp; printf("\n input 10 numbers:\n"); for(i=1;i<=10;i++) scanf("%d",&a[i]); for(i=1;i<10;i++) for(j=1;j<=10-i;j++) if (a[j]>a[j+1]) { temp=a[j]; a[j]=a[j+1]; a[j+1]=x; } printf("%d",a[i]);

21 例6.4 用选择排序法对10个数排序 k k k 例 i=1 初始: [ 49 38 65 97 76 13 27 ] 13 49 j j
例6.4 用选择排序法对10个数排序 i=1 初始: [ ] 13 49 j j j j j j k k i=2 一趟: [ ] 27 38 j j j j j 二趟: [ ] 三趟: [ ] 四趟: [ ] 五趟: [ ] 六趟: [97 ]

22 输入n 个数给a[1] 到 a[n] for i=1 to n-1 k=i for j=i+1 to n a[j]<a[k] 真 假
Ch5_201.c 输入n 个数给a[1] 到 a[n] for i=1 to n-1 k=i for j=i+1 to n a[j]<a[k] k=j i != k a[i]a[k] 输出a[1] 到 a[n]

23 #include <stdio.h>
void main() { int a[11],i,j,k,x; printf("Input 10 numbers:\n"); for(i=1;i<11;i++) scanf("%d",&a[i]); printf("\n"); for(i=1;i<10;i++) { k=i; for(j=i+1;j<=10;j++) if(a[j]<a[k]) k=j; if(i!=k) { x=a[i]; a[i]=a[k]; a[k]=x;} } printf("The sorted numbers:\n"); printf("%d ",a[i]);

24 6.2 二维数组的定义和引用 6.2.1 二维数组的定义 二维数组定义的一般形式为: 例如: float a[3][4],b[5][10];
6.2 二维数组的定义和引用 二维数组的定义 二维数组定义的一般形式为: 类型说明符 数组名[常量表达式][常量表达式] 例如: float a[3][4],b[5][10]; a为3行4列的数组,b为5行10列的数组。 [注意]:不能写成 float a[3,4],b[5,10];

25 C语言对二维数组采用这样的定义方式,使我们可以把二维数组看作是一种特殊的一维数组:它的元素又是一个一维数组。
例如: 可以把a看作是一个一维数组,它有3个元素:a[0]、a[1]、a[2]。每个元素又是一个包含4个元素的一维数组。可以把a[0]、a[1]、a[2]看作是3个一维数组的名字。 如图:

26 例 int a[3][4]; 二维数组a是由3个元素组成 a[0] a[1] a[2] a[0][0] a[0][1] a[0][2]
行名 每个元素a[i]由包含4个元素 的一维数组组成

27 数组元素的存放顺序 原因:内存是一维的 二维数组:按行序优先 多维数组:最右下标变化最快 a[0][1] a[1][0] a[1][1]
1 4 5 2 3 a[0][0] int a[3][2] a[0][0] a[0][1] a[1][0] a[1][1] a[2][0] a[2][1]

28 1 2 3 int c[2][3][4] 4 5 6 7 ………... 20 21 22 23 c[0][0][0] c[0][0][1]
1 2 3 4 5 6 7 ………... 20 21 22 23 c[0][0][0] c[0][0][1] c[0][0][2] c[0][0][3] c[0][1][0] c[0][1][1] c[0][1][2] c[0][1][3] c[0][2][0] c[0][2][1] c[0][2][2] c[0][2][3] c[1][0][0] c[1][0][1] c[1][0][2] c[1][0][3] c[1][1][0] c[1][1][1] c[1][1][2] c[1][1][3] c[1][2][0] c[1][2][1] c[1][2][2] c[1][2][3]

29 6.2.2 二维数组的引用 二维数组元素的引用形式: 二维数组元素的初始化 数组名[下标][下标] 分行初始化:
二维数组的引用 二维数组元素的引用形式: 数组名[下标][下标] 二维数组元素的初始化 分行初始化: 例 int a[2][3]={{1,2,3},{4,5,6}}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 3 4 5 6 全部初始化 例 int a[][3]={1,2,3,4,5}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 3 4 5 第一维长度省略初始化 例 int a[2][3]={1,2,4}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 4 部分初始化 例 int a[][3]={{1},{4,5}}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 4 5 第一维长度省略初始化 例 int a[2][3]={{1,2},{4}}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 4 部分初始化 例 int a[2][3]={1,2,3,4,5,6}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 3 4 5 6 全部初始化 按元素排列顺序初始化

30 6.2.3 二维数组程序举例 例6.5 将二维数组行列元素互换,存到另一个数组中。 a= b= 1 4 2 5 3 6 程序如下: void main() { int a[2][3]={{1,2,3},{4,5,6}}; int b[3][2],i,j;

31 printf("array a:\n"); for (i=0;i<=1;i++) { for (j=0;j<=2;j++) printf("%5d",a[i][j]); b[j][i]=a[i][j]; } printf("\n"); printf("array b:\n");

32 for (i=0;i<=2,i++) { for(j=0;j<=1;j++) printf("%5d",b[i][j]); printf("\n"); } 运行结果如下: array a:

33 例6.6 求二维数组中最大元素值及其行列号 max=a[0][0] for i=0 to 2 for j=0 to 3
a[i][j]>max max=a[i][j] row=i colum=j 输出:max和row,colum

34 #include <stdio.h>
void main() { int a[3][4]={{1,2,3,4}, {9,8,7,6}, {-10,10,-5,2}}; int i,j,row=0,colum=0,max; 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); }

35 6.3 字符数组 用来存放字符数据的数组是字符数组。字符数组中的一个元素存放一个字符。 6.3.1 字符数组的定义
6.3.1 字符数组的定义 字符数组的定义方法与前面介绍的类似。 例如:char c[10]; c[0]='I';c[1]=' ';c[2]='a'; c[3]='m';c[4]=' ';c[5]='h'; c[6]='a';c[7]='p';c[8]='p'; c[9]='y';

36 定义c为字符数组,包含10个元素。在赋值以后数组的状态如下图所示:
也可以用整型数值来存放字符型数据,因此上面第一行也可以改用: int c[10];/*合法,但浪费存储空间*/

37 字符数组的初始化 逐个字符赋给数组中各元素。 例如: char c[10]={'I',' ','a','m',' ','h','a','P','P','y'}; 如果花括弧中提供的初值个数(即字符个数)大于数组长度,则按语法错误处理。 如果初值个数小于数组长度,则只将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符(即‘\0’)。

38 例如:  char c[10]={'c',' ','P','r','o','g','r','a','m'}; 数组状态如下图所示:

39 如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度。
例如: char c[]={'I',' ','a','m',' ','h','a','p','p','y'}; 用这种方式可以不必人工去数字符的个数,尤其在赋初值的字符个数较多时,比较方便。

40 6.3.3 字符数组的引用 例6.7 输出一个钻石图形。 main() { char diamond[][5]={{'','','*'},{'','*','','*'},{'*','','','','*'},{'','*','','*'},{'','','*'}}; int i,j; for (i=0;i<5;i++) {for (j=0;j<5;j++) printf("%c",diamond[i][j]); printf("\n"); }

41 字符串和字符串结束标志 在c语言中,将字符串作为字符数组来存放。 字符‘\0’代表 “字符串结束标志” ,即遇到字符‘\0’时,表示字符串结束,由它前面的字符组成字符串。 在程序中往往依靠检测‘\0’ 的位置来判定字符串是否结束,而不是根据数组的长度来决定字符串长度。

42 系统对字符串常量也自动加一个‘\0’作为结束符。
例如: “c Program”共有9个字符,但在内存中占10个字节,最后一个字节‘\0’ 是由系统自动加上的。 ‘\0’代表ASCII码为0的字符,它不是一个可以显示的字符,而是一个“空操作符” 。用它来作为字符串结束标志不会产生附加的操作或增加有效字符,只起一个供辨别的标志。

43 字符数组初始化方法1: 例 char ch[5]={‘B’,’o’,’y’}; ch[0] ch[1] ch[2] ch[3] ch[4]
逐个字符赋值 例 char ch[5]={‘B’,’o’,’y’}; ch[0] B o y \0 ch[1] ch[2] ch[3] ch[4]

44 字符数组初始化方法2: 可以用字符串常量初始化字符数组: 例如: char c[]={"I am happy"};
也可以省略花括弧,直接写成: char c[]="I am happy";

45 上面的初始化与下面的初始化等价: char c[] ={'I',' ','a','m',' ','h','a','p','p','y','\0'}; 而不与下面的等价: char c\[]={'I',' ','a','m',' ','h','a','p','p','y'}; 前者的长度为11,后者的长度为10。

46 注意字符数组和字符串的区别: 字符数组并不要求它的最后一个字符为‘\0’,甚至可以不包含‘\0’。例如:  char c[5]={'c','h','i','n','a'}; 字符数组也可以包含 ‘\0’。如:  char c[6]={'c','h','i','n','a','\0'};

47 printf("%S",c); 6.3.5 字符数组的输入输出 字符数组的输入输出可以有两种方法: 逐个字符输入输出。
6.3.5 字符数组的输入输出 字符数组的输入输出可以有两种方法: 逐个字符输入输出。 用格式符“%c”输入或输出一个字符。 (2) 将整个字符串一次输入或输出。 用“%S”格式符,意思是输出字符串。 例如: char c[]={"china"}; printf("%S",c);

48 在内存中数组c的状态如图所示。 输出结果为: China

49 [注意]: (1)用“%S”格式符输出字符串时,遇结束符‘\0’就停止输出,输出字符不包括结束符‘\0’。
(2) 用“%S”格式符输出字符串时,printf函数中的输出项是字符数组名,而不是数组元素名。 (3) 如果数组长度大于字符串实际长度,也只输出到遇‘\0’结束。例如: char c[10]={"china"};  printf("%S",c); (4) 如果一个字符数组中包含一个以上的 ‘\0’,则遇第一个‘\0’时输出就结束。

50 (5)可以用scanf函数输入一个字符串。从键盘输入的字符串应短于已定义的字符数组的长度。
例如: scanf("%S",c); [注意]: scanf函数中的输入项是字符数组名。输入项为字符数组名时,不要再加地址符&,因为在c语言中数组名代表该数组的起始地址。 下面写法不对: scanf("%S",&c);

51 (6)如果利用一个scanf函数输入多个字符串,则以空格分隔。
例如: char strl[5],Str2[5],Str3[5]; scanf("%S%S%S",Str1,Str2,Str3); 输入数据: How are you?  输入后Str1、Str2、Str3数组状态见图。

52 例如: char str[13]; scanf("%S",Str); 如果输入以下12个字符 How are you?  则只将空格前的字符“How”送到str中,由于把“How”作为一个字符串处理,因此在其后加‘\0’。

53 用Puts函数输出的字符串中可以包含转义字符。
字符串处理函数 1. puts(字符数组) 功能: 将一个字符串(以‘\0’结束的字符序列)输出到终端。 用Puts函数输出的字符串中可以包含转义字符。 例如: char str[]={“china\nbeijing"}; puts(str); 输出: china beijing

54 2. gets(字符数组) 功能: 从终端输入一个字符串到字符数组,返回一个函数值,该函数值是字符数组的起始地址。例如:
gets(str); 从键盘输入:computer 则将 “computer”送给字符数组Str(请注意送给数组的共有9个字符,而不是8个字符),函数值为字符数组Str的起始地址。

55 例如: 3. strcat(字符数组1,字符数组2) 功能:连接两个字符数组中的字符串,返回值是字符数组1的地址。
char str1[30]={"people's republic of "}; char str2[]={"china"}; printf("%s",strcat(str1,str2)); 输出: people's republic of china

56 连接前后的状况如图所示: [说明]: 字符数组1必须足够大,以便容纳连接后的新字符串。
(2) 连接前两个字符串的后面都有一个‘\0’,连接时将字符串1后面的‘\0’取消,只在新串最后保留一个‘\0’。

57 4.strcpy(字符数组1,字符串2) 功能:将字符串2复制到字符数组1中去。 例如: strcpy(Str1,Str2);
char str1[10],Str2[]={"china"}; strcpy(Str1,Str2); 执行后,str1的状态如图所示:

58 说明: (1) 字符数组1的长度应大于字符串2的长度。 (2) “字符数组1”必须写成数组名形式(如Str1),“字符串2”可以是字符数组名,也可以是一个字符串常量。例如 Strcpy(Str1,“china”); (3) 复制时连同字符串后面的‘\0’一起复制到字符数组1中。

59 (4)不能用赋值语句将一个字符串常量或字符数组直接给一个字符数组。如下面两行都是不合法的:
Str1={"china"}; Str1=Str2; 而只能用strcpy函数处理。 (5) 可以用Strcpy函数将字符串2中前面若干个字符复制到字符数组1中去。 例如: Strcpy(Str1,Str2,2); 作用是将Str2中前面2个字符复制到Str1中去,取代Str1中最前面2个字符。

60 strcmp("china","Korea"); strcmp(Str1,"beijing");
功能:比较字符串1和字符串2。 例如: strcmp(Str1,Str2); strcmp("china","Korea"); strcmp(Str1,"beijing"); [注意]: 对两个字符串比较,不能用以下形式: if(Str1==Str2) printf(“yes"); 而只能用: if(strcmp(Str1,Str2)==0)printf(“yes”); 字符串比较规则 函数返回值

61 功能: 求字符串的实际长度(不包括‘\0’)。 例如: char str[10]={"china"};
6. strlen(字符数组) 功能: 求字符串的实际长度(不包括‘\0’)。 例如: char str[10]={"china"}; printf("%d",strlen(str)); strlen("china"); 输出结果???

62 7. strlwr(字符串) 功能: 将字符串中大写字母换成小写字母。 8. struPr(字符串) 功能:将字符串中小写字母换成大写字母。

63 6.3.7 字符数组应用举例 例1 输入一行字符,统计其中有多少个单词。

64 输入一字符串给 string i=0 num=0 word=0 当((c=string[i])!=‘\0’) c=空格 word==0 word=0 word=1 num=num+1 i=i+1 输出:num

65 #include <stdio.h>
main() { char string[81]; int i,num=0,word=0; char c; gets(string); for(i=0;(c=string[i])!='\0';i++) if(c==' ') word=0; else if(word==0) { word=1; num++; } printf("There are %d words in the line\n",num); }

66 例2 有3个字符串,要求找出其中最大者。 思路:设一个二维的字符数组Str,大小为3×20,即有3行20列,每一行可以容纳20个字符。 下图表示此二维数组的情况。

67 main ( ) { char string[20]; char 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); }

68 练习1: 以下错误的定义语句是 A int x[][3]={{0},{1},{1,2,3}};
B int x[4][3]={{1,2,3},{1,2,3},{1,2,3},{1,2,3}} C int x[4][ ]={{1,2,3},{1,2,3},{1,2,3},{1,2,3}} D int x[][3]={1,2,3,4} C

69 练习2: 有以下程序 #include <string.h> main()
{char  p[20]={‘a’,’b’,’c’,’d’},q[]=”abc”, r[]=”abcde”; strcpy(p+strlen(q),r);  strcat(p,q); printf(“%d%d\n”,sizeof(p),strlen(p)); } 程序运行后的输出结果是 A)20 9   B)9  9   C)20  11  D)11  11 C


Download ppt "第六章 数组 西安工程大学."

Similar presentations


Ads by Google