第六章 数组
?构造数据类型之一
?数组,有序数据的集合,用数组名标识
?元素,属同一数据类型,用数组名和下标确定
§ 6.1 一维数组
?一维数组的定义
?定义方式,数据类型 数组名 [常量 表达式 ];
合法标识符 表示元素个数
下标从 0开始
[ ],数组运算符
单目运算符
优先级 (1)
左结合
不能用 ( )
例 int a[6];
a[0]0
1
4
5
a[1]
a[2]
a[3]
a[4]
a[5]
2
3
a
编译时分配连续内存
内存字节数 =数组维数 *
sizeof(元素数据类型 )数组名表示内存首地址,是 地址常量
?一维数组的引用
?数组必须 先定义, 后使用
?只能逐个引用数组元素,不能一次引用整个数组
?数组元素表示形式,数组名 [下标 ]
其中:下标可以是常量或整型表达式
例 int i=15;
int data[i]; (?不能用变量定义数组维数 )
例 int a[10];
printf(“%d”,a); (?)
必须 for(j=0;j<10;j++)
printf(“%d\t”,a[j]); (?)
例 int data[5];
data[5]=10; //C语言对数组不作越界检查,使用时要 注意
?一维数组的初始化
?初始化方式
在定义数组时,为数组元素赋初值
(在编译阶段使之得到初值)
int a[5]={1,2,3,4,5};
等价于,a[0]=1; a[1]=2; a[2]=3; a[3]=4; a[4]=5;
?说明:
?数组不初始化,其元素值为随机数
?对 static数组元素不赋初值,系统会自动赋以 0值
?当全部数组元素赋初值时,可不指定数组长度
如 int a[5]={6,2,3};
等价于,a[0]=6; a[1]=2;a[2]=3; a[3]=0; a[4]=0;
如 int a[3]={6,2,3,5,1}; (?)
static i t ;
等价于,a[0]=0; a[1]=0; a[2]=0; a[3]=0; a[4]=0;
?只给部分数组元素赋初值
int a[]={1,2,3,4,5,6};
编译系统根据初值个数确定数组维数
?程序举例
例 读 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
#include <stdio.h>
#define SIZE 10
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);
}
例 用数组求 Fibonacci数列前 20个数
f[0]
f[1]
f[2]
f[3]
f[4]
f[5]
f[19]
……...
1
1
f[19]
0
1
4
5
2
3
19
2
3
5
#include <stdio.h>
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]);
}
}
例 用冒泡法对 10个数排序
排序过程:
( 1)比较第一个数与第二个数,若为逆序 a[0]>a[1],则交换;然
后比较第二个数与第三个数;依次类推,直至第 n-1个数和第
n个数比较为止 ——第一趟冒泡排序,结果 最大 的数被安置在
最后一个元素位置上
( 2)对前 n-1个数进行第二趟冒泡排序,结果使 次大 的数被安置在
第 n-1个元素位置
( 3)重复上述过程,共经过 n-1趟冒泡排序后,排序结束
例 38
49
65
76
13
27
30
97第


38
49
65
13
27
30
76



38
49
13
27
30
65



38
13
27
30
49



13
27
30
38



13
27
30



49
38
65
97
76
13
27
30初




n=8
38
49
76
9713
9727
9730
97
13
76
76
7627
30
13
6527
6530
65
13
13
49
4930
4927
3827
3830
38
13
27



输入 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]);
}
例 用简单选择法对 10个数排序
排序过程:
( 1)首先通过 n-1次比较,从 n个数中找出最小的,将它与第一个数
交换 —第一趟选择排序,结果 最小 的数被安置在第一个元素位置上
( 2)再通过 n-2次比较,从剩余的 n-1个数中找出关键字 次小 的记录,
将它与第二个数交换 —第二趟选择排序
( 3)重复上述过程,共经过 n-1趟排序后,排序结束
例 初始,[ 49 38 65 97 76 13 27 ]
k
j
i=1 13 49
一趟,13 [38 65 97 76 49 27 ]i=2 27 38
二趟,13 27 [65 97 76 49 38 ]
三趟,13 27 38 [97 76 49 65 ]
四趟,13 27 38 49 [76 97 65 ]
五趟,13 27 38 49 65 [97 76 ]
六趟,13 27 38 49 65 76 [97 ]
k
kk
k
j j j j j
j j j j j
Ch5_201.c
输入 n 个数给 a[1] 到 a[n]
for i=1 to n-1
for j=i+1 to n
a[j]<a[k]真 假
k=j
输出 a[1] 到 a[n]
k=i
a[i]?a[k]
i != k真 假
#include <stdio.h>
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");
for(i=1;i<11;i++)
printf("%d ",a[i]);
}
#define N 6
main()
{ int a[N],b[?B?-60],c[]={1,2,3,4,5,6},i;
for(i=0;i<N;i++)
scanf(“%d%d”,&a[i],&b[i]);
for(i=0;i<N;i++)
printf(“%d,,a[i]);
printf(“\n”);
for(i=0;i<N;i++)
printf(“%d,,b[i]);
printf(“\n”);
for(i=0;i<N;i++)
c[i]=a[i]+b[N-i-1];
for(i=0;i<N;i++)
printf(“%d,,c[i]);
}
数组定义:必须用 常量 表达式
数组元素引用
Ch6_001.c
§ 6.2 二维数组及多维数组
?二维数组的定义
?定义方式:
数据类型 数组名 [常量表达式 ][常量表达式 ];
?数组元素的存放顺序
?原因,内存是一维的
?二维数组:按行序优先
?多维数组:最右下标变化最快
例 int a[3][4];
float b[2][5];
int c[2][3][4];
int a[3,4]; (?)
行数 列数元素个数 =行数 *列数
int a[3][2]
a[0][1]
a[1][0]
a[1][1]
a[2][0]
a[2][1]
0
1
4
5
2
3
a[0][0]
a[0][0] a[0][1]
a[1][0] a[1][1]
a[2][0] a[2][1]
int c[2][3][4]
0
1
2
34
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]
?二维数组理解
例 int a[3][4];
2016
17
2018
19
2020
21
2022
23
2008
9
2010
11
2012
13
2014
15
2000
1
2002
3
2004
5
20006
7a[0][0] a[0][1] a[0][2] a[0][3]
a[1][0] a[1][1] a[1][2] a[1][3]
a[2][0] a[2][1] a[2][2] a[2][3]
每个元素 a[i]由包含 4个元素
的一维数组组成
二维数组 a是由 3个元素组成
a[0]
a[1]
a[2]
行名
0
1
4
5
2
3
a[0][1]
a[0][2]
a[0][3]
a[1][0]
a[1][1]
a[0][0]
a[1][3]
a[2][0]
a[2][1]
a[2][2]
a[2][3]
a[1][2]6
7
10
11
8
9
a[0]
a[1]
a[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[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 0 4 0 0
部分初始化
例 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 0 0 4 5 0
第一维 长度省略初始化
例 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[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 0 0 0
部分初始化
例 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 0
第一维 长度省略初始化
?程序举例
例 将二维数组行列元素互换,存到另一个数组中
a= 1 2 34 5 6 b= 1 42 5
3 6
#include <stdio.h>
main()
{ 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]);
b[j][i]=a[i][j];
}
printf("\n");
}
printf("array b:\n");
for(i=0;i<=2;i++)
{ for(j=0;j<=1;j++)
printf("%5d",b[i][j]);
printf("\n");
}
}
例 求二维数组中最大元素值及其行列号
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
#include <stdio.h>
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);
}
例 读入下表中值到数组,分别求各行、各列及表中所有数之和
12 4 6
15 7 9
8 23 3
2 5 17
12 4 6 22
15 7 9 31
8 23 3 34
2 5 17 24
37 39 35 111
#include <stdio.h>
main()
{ int x[5][4],i,j;
for(i=0;i<4;i++)
for(j=0;j<3;j++)
scanf("%d",&x[i][j]);
for(i=0;i<3;i++)
x[4][i]=0;
for(j=0;j<5;j++)
x[j][3]=0;
for(i=0;i<4;i++)
for(j=0;j<3;j++)
{ x[i][3]+=x[i][j];
x[4][j]+=x[i][j];
x[4][3]+=x[i][j];
}
for(i=0;i<5;i++)
{ for(j=0;j<4;j++)
printf("%5d\t",x[i][j]);
printf("\n");
}
}
§ 6.3 字符数组和字符串
?字符数组
?定义
?字符数组的初始化
?逐个字符赋值
?用字符串常量
?字符数组的引用
例 char c[10],ch[3][4];
例 char ch[5]={?H?,?e?,?l?,?l?,?o?};
ch[0]
H e l l o
逐个字符赋值
ch[1] ch[2] ch[3] ch[4]
有问题 !
例 char ch[5]={?H?,?e?,?l?,?l?,?o?};
ch[0]
H e l l o
逐个字符赋值
ch[1] ch[2] ch[3] ch[4]
例 char ch[5]={?B?,?o?,?y?};
ch[0]
B o y \0 \0
逐个字符赋值
ch[1] ch[2] ch[3] ch[4]
例 r [ =“Boy”;
[
\ \
用字符串常量
[ [ [ [
例 char ch[6]={“H llo”};
char ch[6]=“Hello”;
char ch[]=“Hello”;
用字符串常量
ch[0]
H e l l o
ch[1] ch[2] ch[3] ch[4]
\0
ch[5]
例 char diamond[][5]={{'.','.','*'},{'.','*','.','*'},
{'*','.','.','.','*'},{'.','*','.','*'},{'.','.','*'}};
二维字符数组初始化
., * \0 \0
,*, * \0
*,,, *
,*, * \0
., * \0 \0
diamond[0]
diamond[1]
diamond[2]
diamond[3]
diamond[4]
例 char fruit[][7]={“Apple”,”Orange”,
”Grape”,”Pear”,”Peach”};
二维字符数组初始化
fruit[0]
fruit[1]
fruit[2]
fruit[3]
fruit[4]
A p p l e \0 \0
O r a n g e \0
G r a p e \0 \0
P e a r \0 \0 \0
P e a c h \0 \0
例 输出一个字符串
#include <stdio.h>
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
0
1
2
3
4
5
6
7
8
9
?字符串
?字符串及其结束标志
?无字符串变量,用字符数组处理字符串
?字符串结束标志:‘ \0’
例 ? hello”共 5个字符,在内存占 6个字节 字符串长度 5
h e l l o \0
104 101 108 108 111 0
内存存放字符 ASCII码
?字符串的输入输出
?逐个字符 I/O,%c
?整个字符串 I/O,%s
例 用 %c
main()
{ char str[5];
int i;
for(i=0;i<5;i++)
scanf(“%c”,&str[i]);
for(i=0;i<5;i++)
printf(“%c”,str[i]);
}
例 用 %s
main()
{ char str[5];
scanf(“%s”,str);
printf(“%s”,str);
}
用字符数组名,不要加 &
输入串长度 <数组维数
遇空格或回车结束
自动加‘ \0?
用字符数组名,
遇‘ \0?结束
例 main( )
{ char a[5]={?H?,?e?,?l?,?l?,?o?};
printf(“%s”,a);
}
例 main( )
{ char a[ ]=“Hello”;
printf(“%s”,a);
}
结果,Hello#-=*
h e l l o
0 2 31 4
结果,Hello
用 ? %s”输出时,遇 ‘ \0?结

main()
{
char a[]={'h','e','l','\0','l','o','\0'};
printf("%s",a);
}

输出,hel h e l \0 l o \0
数组中有多个 ‘ \0?时,
遇第一个结束
main()
{
int i;
char a[5];
scanf("%s",a);
for(i=0;i<5;i++)
printf("%d,",a[i]);
}
运行情况:
( 1)若输入 hel,正常
( 2)若输入 hell,正常
( 3)若输入 hello,用 %s 输出时,会出现问题
h e l \0
h e l l \0
h e l l o
输入字符串长度 <数组维

例 字符串输入举例
H o w \0
a r e \0
y o u? \0
#include <stdio.h>
main()
{ char a[15],b[5],c[5];
scanf("%s%s%s",a,b,c);
printf("a=%s\nb=%s\nc=%s\n",a,b,c);
scanf("%s",a);
printf("a=%s\n",a);
}
运行情况:
输入,How are you?
输出,a=How
b=are
c=you?
输入,How are you?
输出,a=How
scanf中 %s输入时,遇空格
或回车结束
运行情况:
输入,How are you?
例 若准备将字符串,This is a string.”记录下来,
错误 的输入语句为:
( A) scanf(“%20s”,s);
( B) for(k=0;k<17;k++)
s[k]=getchar();
( C) while((c=getchar())!=?\n?)
s[k++]=c;
?常用的字符串处理函数
包含在头文件 string.h
?字符串输出函数 puts
格式,puts(字符数组 )
功能:向显示器输出字符串(输出完,换行)
说明:字符数组必须以‘ \0?结束
?字符串输入函数 gets
格式,gets(字符数组 )
功能:从键盘输入一以 回车结束 的字符串放入字符数组中,
并自动加‘ \0’
说明:输入串长度应小于字符数组维数
例 #include <stdio.h>
main( )
{ char string[80];
printf(“Input a string:”);
gets(string);
puts(string);
}
输入, How are you?
输出, How are you?
?字符串连接函数 strcat
格式,strcat(字符数组 1,字符数组 2)
功能:把字符数组 2连到字符数组 1后面
返值:返回字符数组 1的首地址
说明,?字符数组 1必须足够大
?连接前,两串均以‘ \0’结束 ;连接后,串 1的‘ \0’取消,
新串最后加‘ \0’
?字符串拷贝函数 strcpy
格式,strcpy(字符数组 1,字符串 2)
功能:将字符串 2,拷贝到字符数组 1中去
返值:返回字符数组 1的首地址
说明,?字符数组 1必须足够大
?拷贝时‘ \0’一同拷贝
?不能使用赋值语句为一个字符数组赋值 例 char str1[20],str2[20];str1={“Hello!”}; (?)
str2=str1; (?)
例 strcpy与 strcat举例
#include <string.h>
#include <stdio.h>
void main()
{ char destination[25];
char blank[] = " ",c[]= "C++",
turbo[] = "Turbo";
strcpy(destination,turbo);
strcat(destination,blank);
strcat(destination,c);
printf("%s\n",destination);
}
Turbo C++
T
r
b
o
C
+
+
0
1
2
3
4
5
6
7
8
9
u
\0
24
…….
T
r
b
o
0
1
2
3
4
5
6
7
8
9
u
\0
24
…….
…….
T
r
b
o
\0
0
1
2
3
4
5
6
7
8
9
u
24
…….
…...
?字符串比较函数 strcmp
格式,strcmp(字符串 1,字符串 2)
功能:比较两个字符串
比较规则:对两串从左向右逐个字符比较( ASCII码),
直到遇到不同字符或‘ \0’为止
返值:返回 int型整数,a,若字符串 1< 字符串 2,返回 负整数
b,若字符串 1> 字符串 2,返回 正整数
c,若字符串 1== 字符串 2,返回 零
说明,字符串比较不能用? ==?,必须用 strcmp
?字符串长度函数 strlen
格式,strlen(字符数组 )
功能:计算字符串长度
返值:返回字符串实际长度,不包括‘ \0’在内例 对于以下字符串,strlen(s)的值为:
( 1) char s[10]={?A?,?\0?,?B?,?C?,?\0?,?D?};
( 2) char s[ ]=“\t\v\\\0will\n”;
( 3) char s[ ]=“\x69\082\n”; 答案,1 3 1
#include <string.h>
#include <stdio.h>
main()
{ char str1[] =,Hello!",str2[] =,How are you?”,str[20];
int len1,len2,len3;
len1=strlen(str1); len2=strlen(str2);
if(strcmp(str1,str2)>0)
{ strcpy(str,str1); strcat(str,str2); }
else if (strcmp(str1,str2)<0)
{ strcpy(str,str2); strcat(str,str1); }
else strcpy(str,str1);
len3=strlen(str);
puts(str);
printf(”Len1=%d,Len2=%d,Len3=%d\n”,len1,len2,len3);
}
例 strcmp与 strlen举例
How are you?Hello!
Len1=6,Len2=12,Len3=18
Ch6_23.c
?应用举例
例 输入一行字符,统计其中有多少个单词
输入一字符串给 string
i=0 num=0 word=0
当 ((c=string[i])!=?\0?)
c=空格真



word=0 word=1
num=num+1
i=i+1
输出,num
word==0
#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);
}
当前字符 =空格


未出现新单词,使 word=0,num不累加
前一字符为空格 (word==0),新单词出现,
word=1,num加 1
前一字符为非空格 (word==1),未出现新单词,num不变

0

1
1

1

0
1

0

1
2

1

1
2

1

0
2

0

1
3

1

0
3

0

1
4

1

1
4

1

1
4

1

1
4
例 输入,I ?am ?a ?boy.
当前字符
是否空格
word原值
新单词开始否
word新值
num值
? ? ?I a m a b o y,
例 有三个字符串,找出其中最大者
H o w \0
H e l l o \0
H i g h \0
str[0]
str[1]
str[2]
#include <stdio.h>
#include <string.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);
}
例 有十个学生的成绩,求平均分
92 85 68 75 54 88 98 45 61 79
92
85
68
54
88
98
45
75
61
79
a[0]
a[1]
a[2]
a[3]
a[4]
a[5]
a[6]
a[7]
a[8]
a[9]
a#include <stdio.h>
main()
{ int k,a[10];
for(k=0;k<10;k++)
scanf(“%d”,&a[k]);
for(k=0;k<10;k++)
sum+=a[k];
printf(“Average is %d\n”,sum/10);
}
例 有三个学生四门课成绩
92 85 68 75
54 88 98 45
61 79 81 40
张三
李四
王二
数学 化学英语 物理
二维数组
例 比较 int a[2][3]={{5,6},{7,8}};
与 int a[2][3]={5,6,7,8};
5 6 0
7 8 0
5 6 7
8 0 0
例 int a[][10];
float f[2][]={1.2,2.2};
例 int a[5];
a={2,4,6,8,10};
例 int a[10];
float i=3;
a[i]=10;
例 char name[0];
float weight[10.3];
int array[-100];
例 char str[]=“Hello”;
char str[]={?H?,?e?,?l?,?l?,?o?};
h e l l o
0 2 31 4
h e l l o \0
0 2 31 4 5