第七章 数组
数组,有序数据的集合,用数组名标识
元素,属同一数据类型,用数组名和下标确定
构造数据类型之一
§ 7.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
编译时分配连续内存内存字节数 =数组维数 *数组名表示内存首地址,
是 地址常量
一维数组的引用
数组必须先定义,后使用
只能逐个引用数组元素,不能一次引用整个数组
数组元素表示形式,数组名 [下标 ]
其中:下标可以是常量或整型表达式例 int i=15;
int data[i]; (?不能用变量定义数组维数 )
例 int a[10];
printf(“%d”,a); (?)
必须 for(j=0;j<10;j++)
printf(“%d\t”,a[j]); (?)
一维数组的初始化
初始化方式在定义数组时,为数组元素赋初值
(在编译阶段使之得到初值)
int a[5]={1,2,3,4,5};
等价于,a[0]=1; a[1]=2; a[2]=3; a[3]=4; a[4]=5;
说明:
数组不初始化,其元素值为随机数
当全部数组元素赋初值时,可不指定数组长度如 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}; (?)
只给部分数组元素赋初值
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
输入 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]);
}
§ 7.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");
}
}
§ 7.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]={?B?,?o?,?y?};
ch[0]
B o y \0 \0
逐个字符赋值
ch[1] ch[2] ch[3] ch[4]
例 r [ =“Boy”;
[
\ \
用字符串常量
[ [ [ [
例 char ch[6]={“Hello”};
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’在内
char str[10]={“china”};
printf(“%d”,strlen(str));
答案,5
#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
张三李四王二数学 化学英语 物理二维数组