第 7章 数组课堂教学 4学时上机操作2学时教学累计20学时上机累计6学时
数组是有序数据的集合,数组中的每一个元素都属于同一个数据类型
用一个统一的数组名和下标来唯一地确定数组中的元素
数组专用于处理大量同类型数据
每一个数组元素都可以当做单个变量来使用一维数组的定义和引用
一维数组的定义类型说明符 数组名[常量表达式];
例如,
int a[10];
表示,a为数组名,有10个元素
下标从0开始:
a[0],a[1],a[2],a[3],a[4],
a[5],a[6],a[7],a[8],a[9]
注意
不允许动态定义数组如,int n;
scanf(“%d”,&n); 随机输入大小
int a[n];
思考:
a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]

a0,a1,a2,a3,a4,a5,a6,a7,a8,a9有什么不同?
定义举例,
float b[1+4],c[N]; double d1[11],e5[7],x,y,z;
一维数组的引用
1,先定义后引用
2,数组中的每一个元素都可以作为一个变量来访问
3,不能一次引用整个数组
数组元素的表示形式数组名[下标]
注:下标可以是整型表达式 (常量、变量)
应用形式比较
a[n] 与 a[5] 及 int a[n] 与 int a[5]
应用举例:
scanf(“%d”,&n);
a[n]=a[5]+a[n-7]-a[2*3];
例 7.1数组元素的引用
main( )
{ 注意,i的变化
int i,a[10];
for(i=0;i<=9;i++)
a[i]=i;
for(i=9;i>=0;i--)
printf(“%2d",a[i]);
}
运行结果,9 8 7 6 5 4 3 2 1 0
课堂练习
修改例 7.1对 a数组各元素求和
修改例 7.1找出 a数组中能被3整除的元素答案
main( )
{
int i,a[10],s=0;
for(i=0;i<=9;i++)
a[i]=i;
for(i=9;i>=0;i--)
s=s+a[i];
printf("%d",s);
}
运行结果,45
答案
main( )
{
int i,a[10],s=0;
for(i=0;i<=9;i++)
a[i]=i;
for(i=9;i>=0;i--)
if(a[i]%3==0)
printf(“%2d",a[i]);
}
运行结果:9630
@@@自学
一维数组的初始化数组元素和变量一样,可以在定义时赋予初值,称为数组的初始化
1,在定义数组时对数组元素赋以初值如,int a[10]={1,3,5,7,9,2,4,6,8,0};
初始化后,a[0]=1,a[1]=3,a[2]=5,a[3]=7,
a[4]=9,a[5]=2,a[6]=4,a[7]=6,a[8]=8,a[9]=0
2,可以只给一部分元素赋初值如,int a[10]={0,1,2,3};
@@@自学
3,使数组中全部元素值为0
如,int a[10]={0};
4,对数组中全部元素赋初值时,可以不指定数组长度如,int a[5]={1,2,3,4,5};
可以,int a[ ]={1,2,3,4,5};
一维数组程序举例例,7.2用数组处理求 Fibonacci数列
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”); /*一行控制为5个数 */
printf("%12d",f[i]);}}
例 7.3用起泡法对 10个数排序 (由小到大 )
思路,将相邻两个数比较,将小的调到前头
若有 6个数,9 8 5 4 2 0
9
8
5
4
2
0
8
9
5
4
2
0
8
5
9
4
2
0
8
5
4
9
2
0
8
5
4
2
9
0
8
5
4
2
0
9
1 结果2 3 4 5
8
5
4
2
0
5
8
4
2
0
5
4
8
2
0
5
4
2
8
0
5
4
2
0
8
1 3 4 结果2
1,main( )
2,{ int a[11];
3,int i,j,t;
4,printf("input 10 numbers,\n”);
5,for(i=1;i<11;i++)
6,scanf("%d",&a[i]);
7,printf("\n”);
8,for(j=1;j<=9;j++)
9,for(i=1;i<=10-j;i++)
10,if (a[i]>a[i+1])
11,{t=a[i];a[i]=a[i+1];a[i+1]=t;}
12,printf("the sorted numbers,\n”);
13,for(i=1;i<11;i++)
14,printf("%d",a[i]);}
N-S流程图输入 n个数给 a[1]到 a[n]
真 a[i]>a[i+1] 假
a[i] a[i+1]
输出 a[1]到 a[n]
for j=1 to n-1
for i=1 to n-j
*****
例:统计字符,数字0-9各多少,看不见的空格、回车,tab及其他字符出现的次数
1,#include"stdio.h"
2,main( )
3,{int c,i,nwh,nother,ndig[10]={0};
4,nwh=nother=0;
5,while((c=getchar( ))!=EOF)
6,if(c>='0'&&c<='9') ++ndig[c-'0'];
7,else if(c==' '||c=='\n'||c=='\t') ++nwh;
8,else ++nother;
9,for(i=0;i<10;i++)
10,printf("\n%d:%d,",i,ndig[i]);
11.printf("white
space=%d,other=%d\n",nwh,nother);}
*****? 运行时输入,00 111 3434 56789
运行结果:
0:2
1:3
2:0
3:2
4:2
5:1
6:1
7:1
8:1
9:1 while space=3,other=0
Ctrl z
二维数组的定义和引用
二维数组的定义
一般形式:
类型说明符 数组名 [常量表达式 ] [常量表达式 ]
例如:
float a[3][4],b[5][10];
注意:不能写成 float a[3,4],b[5,10];
C语言把二维数组看作是一种特殊的一维数组:它的元素又是一个一维数组
float a[3][4]
可以看成,float a[0][4],a[1][4],a[2][4];
a[0]---------a00 a01 a02 a03
a a[1]---------a10 a11 a12 a13
a[2]---------a20 a21 a22 a23
a00 a01 a02 a03
a10 a11 a12 a13
a20 a21 a22 a23
按行存储三个一维数组名二维数组的引用
二维数组的元素的表示形式数组名 [下标 ][下标 ]
如,a[2][3],b[2-1][2*2],str[i][j]
下标可以是整型表达式
数组元素可出现在表达式中,也可以被赋值
如,b[1][2]=a[2][3]/2+a[0][0]
常出的错误,
1,a[2,3] 格式问题
2,int [3][4]; 超出范围

a[3][4]=3;
@@@
二维数组的初始化
1,分行给二维数组初始化
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
2,按数组排列的顺序对各元素赋初值
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
3,对部分元素赋初值
int a[3][4]={{1},{5},{9}};
1 0 0 0
5 0 0 0
9 0 0 0
初始化后数组元素取值情况,
@@@
对各行中的某一个元素赋初值
int a[3][4]={{1},{0,6},{0,0,11}};
1 0 0 0
0 6 0 0
0 0 11 0
int a[3][4]={{1},{5,6}};
1 0 0 0
5 6 0 0
0 0 0 0
初始化后数组元素取值情况,
初始化后数组元素取值情况,
@@@
如果对全部元素都赋初值,则定义数组时对第一维的长度可以不指定,但第二维的长度不能省如,int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
等价,int a[ ][4]={1,2,3,4,5,6,7,8,9,10,11,12};
也可以只对部分元素赋初值
int a[ ][4]={{0,0,3},{ },{0,10}};
0 0 3 0
0 0 0 0
0 10 0 0
初始化后数组元素取值情况,
二维数组程序举例
例 7.4将一个二维数组行和列元素互换,存到另一个二维数组中
1 2 3 1 4
4 5 6 2 5
3 6
a= b=
1,main( )
2,{int a[2][3]={{1,2,3},{4,5,6}};
3,int b[3][2],i,j;
4,printf("array a:\n”);
5,for(i=0;i<=1;i++)
6,{ for(j=0;j<=2;j++)
7,{ printf("%5d",a[i][j]);
8,b[j][i]=a[i][j]; }
9,printf(“\n”);}
10,printf("array b:\n”);
11,for(i=0;i<=2;i++)
12,{for(j=0;j<=1;j++)
13,printf("%5d",b[i][j]);
14,printf("\n");}}
运行结果:
array a:
1 2 3
4 5 6
array b:
1 4
2 5
3 6
例 7.5 有一个 3× 4的矩阵,求出其中最大的元素值,以及其所在的行号和列号
N-S流程图输出,max 和 row,colum
max=a[i][j]
row=I
colum=j
真 a[i][j]>max 假
max=a[0][0]
for i=0 to 2
for j=0 to 3
main( )
{int i,j,row=0,colum=0,max;
int a[3][4]={{1,2,3,4},{9,8,7,6},{-10,10,-5,2}};
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);}
运行结果,max=10,row=2,colum=1
课堂练习读程序写出运行结果:
main( )
{int data[ ][3]={{1,2,9},{9,5,3},{0,9,8}};
int i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
if(data[j][i]==9) 注意 i,j的位置
printf("i=%d:j=%d\n",i,j);
}
运行结果,
i=0,j=1
i=1,j=2
i=2,j=0
字符数组
字符数组是存放字符型数据的数组,其中每个数组元素存放的值都是单个字符
字符数组的定义
如,char c[2],string[5][10];
c[0]=?o?;c[1]=?k?;
字符型也可用整型定义
int c[2],string[5][10];
o k
c[0] c[1]
字符数组的初始化
如,char c[5]={?H?,?E?,?L?,?L?,?O?};
把 5个字符分别赋给 c[0],c[1],c[2],c[3],c[4]
字符个数大于字符长度,则出错
字符个数小于字符长度,则后补’ \0?
如,char c[7]={?H?,?E?,?L?,?L?,?O?};
H E L L O \0 \0
初值与数组长度相同时可省略数组长度
如,char c[ ]={?o?,?k?};
字符数组的引用
例 7.6 输出一个字符串
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 am a boy
*****
例 7.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");
}
}
运行结果,
*
* *
* *
* *
*
字符串和字符串结束标志
字符串是 C语言的一种数据类型,由于它是由若干个字符组成的 (其最后一个字符是字符串结束标记’ \0?),因此,一维数组可以存放一个字符串。用二维字符型数组就可以存放多个字符串
有了结束标志’ \0?后,字符数组的长度就显得不那么重要了。在程序中是依靠测试’ \0?
的位置来判定字符串是否结束
系统对字符串常量也自动加一个’ \0?作为结束符
补充,字符数组的初始化
char c[ ]={“I am happy”};
或,char c[ ]=“I am happy”;
以上等价于,(11)
char c[ ]={?I?,,?a?,?m?,?
,?h?,?a?,?p?,?p?,?y?,?\0?};
与下面的不等价,(10)
char c[ ]={?I?,,?a?,?m?,,?h?,?a?,?p?,?p?,?y?};
字符数组并不要求它的最后一个字符为‘ \0?,但有了‘ \0?方便操作字符数组的输入输出
两种方法,
1,逐个字符输入输出 %c
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");
2,将整个字符一次输入输出 %s
如,char c[ ]=“China”;
printf(“%s”,c);
输出时遇结束符’ \0?就停止,输出结果为,
China
注意,
1,输出字符不包括结束符’ \0?
2,用‘ %s?输出字符串时,输出项对应的是数组名,或字符串
C h i n a \0
3,如果数组长度大于字符串实际长度,也只输出到遇’ \0?结束 (?\0?
的优越性)
如,char c[10 ]=“China”;
printf(“%s”,c); 后5个为
‘ \0?
输出结果,China
4.一个字符数组中若包含一个以上
‘ \0?,则遇第一个’ \0?时输出就结束
用 scanf函数输入字符串
scanf(“%s”,c);
键入,China
用 scanf函数输入多个字符串
char atr1[5],str2[5],str3[5];
scnaf(“%s%s%s”,str1,str2,str3);
输入数据,How are you?
讨论,str赋值情况
char str[13];
scanf(“%s”,str);
输入数据,How are you?
a r e \0
H o w \0
y o u? \0
str 赋值情况:
注意:
1,输入项为数组名时,不要再加地址符 &
2,?\0?字符串结束符占一个字节
3,一维字符数组可用数组名整体处理字符串,
因此相当于字符串变量
H o w \0
字符串处理函数
为了简化程序方便使用,在 C的函数库中提供了一些字符串处理函数,可直接调用
字符串输出函数
[调用格式 ] puts(字符数组名 )
[参数 ] 字符数组名(已存放字符串)
[功能 ] 输出字符数组中存放的字符串,其中的结束标记转换为回车换行例,char str[ ]=“China\nBeijing”;
puts(str); 对照 printf(“%s”,str);
结果,China
Beijing
字符串输入函数
[调用格式 ] gets(字符数组名 )
[参数 ] 字符数组名
[功能 ] 从键盘接受一个字符串 (以回车符结束 )
[返回值 ] 字符数组的首地址例,gets(str);
入,computer
字符串连接函数
[调用格式 ] strcat(字符数组名,字符串 )
[参数 ] 字符数组名 长度足够大字符串 字符串常量或字符数组名
[功能 ] 连接将两个字符串,取消第一个字符串结束标志例,char str1[30]=“People?s Republic of,;
char str2[ ]=“China”;
puts(strcat(str1,str2));
结果,People?s Republic of China
字符串复制函数
[调用格式 ]
strcpy(字符数组名,字符串,整型表达式 )
[参数 ] 字符数组名字符串 字符串常量或已存放字符串的字符数组名整型表达式 任何类型表达式。可省略
[功能 ] 取“字符串”的前“整型表达式”个字符组成新字符串存入“字符数组”中。若省略“整型表达式”,则将整个“字符串”存入字符数组中覆盖
例,char str1[10],str2[ ]=“China”;
strcpy(str1,str2); 结果,China
或 strcpy(str1,str2,2); 结果,Ch
不合法:
str1=str2
str1=“China”
字符串比较函数
[调用格式 ] strcmp(字符串 1,字符串 2)
[参数 ] 字符串 1、字符串 2已存放字符串的字符数组名或字符串常量
[功能 ]
“字符串 1”<“字符串 2”,函数值为小于 0的整数 ;
“字符串 1”=“字符串 2”,函数值为 0;
“字符串 1”>“字符串 2”,函数值为大于 0的整数
[返回值 ] 带符号的整数
比较规则:
两个字符串从左到右逐个字符相比 (按 ASCII
码值大小比较 ),直到出现不同的字符或遇到
‘ \0?为止。如全部字符相同,则认为相等;若出现不相同的字符,则以第一个不相同的字符的比较结果为准如,“A”大于,B”,“a”大于,A”,“computer”大于
,compare”
如,if(strcmp(str1,str2)==0) printf(“yes”);
以下不正确:
if(str1==str2) printf(“yes”);
测试字符串长度函数
[调用格式 ] strlen(字符串 )
[功能 ] 测试字符串的长度 (除 \0之外 )
字符串中小写字母改大写字母函数
[调用格式 ] strupr(字符串 )
[功能 ] 将字符串中所有小写字母换成大写字母
字符串中大写字母改小写字母函数
[调用格式 ] strlwr(字符串 )
[功能 ] 将字符串中所有大写字母换成小写字母字符数组应用举例
#include "stdio.h"
#include "stdio.h"
main( )
{char a[40],b[80];
gets(a);
strcpy(b,a);
strupr(b); /*小转大 */
strcat(b,a); /*连接 */
if(strcmp(a,b)<0) printf("a<b\n");
else if (strcmp(a,b)>0)printf("a>b\n");
else printf("a=b\n");
printf("length of a(%s)=%d\n",a,strlen(a));
printf("length of b(%s)=%d\n",b,strlen(b));
puts(a);
puts(b);}
运行时输入,China
运行结果:
a>b
length of a(China)=5
length of b(CHINAChina)=10
China
CHINAChina
功能,
输入一个字符串存入数组 a,将其复制到数组 b,然后将数组 b中的所有小写字母改为大写字母,再将 a中的字符串连接到 b。比较并输出 a,b中字符串的大小,
统计并输出 a,b中的字符串。
读程序
1,#include "stdio.h"
2,main( ) /*加密、解密 */
3,{char a[80],b[80],c[80];
4,int i=0;
5,gets(a);
6,while(a[i]!='\0')
7,b[i]=a[i++]+3;
8,b[i]=a[i];
9,i=0;
10.while(b[i]!=?\0?) 运行时输入,China
11,c[i]=b[i++]-3; 运行结果,Fklqd
12.c[i]=b[i]; China
13.puts(b);
14.puts(c);}
例 7.8输入一行字符,统计其中有多少个单词,单词之间用空格分隔开
解体思路:
未出现新单词,使 word=0,num不累加当前字符=空格前一个字符为空格 (word=0),新单词出现,num加1,word=1
前一个字符为非空格 (word=1 ),未新单词出现,num不加1
Y
N
算法流程图
i=0
输入一个字符串给 string
当 ((c=string[i])≠?\0?)
真 c=空格 假真 word=0 假Word=0
word=1
num++
i=i+1
输出,num
程序如下:
1,#include<stdio.h>
2,main( )
3,{char string[81];
4,int i,num=0,word=0;
5,char c;
6,gets(string);
7,for(i=0;(c=string[i]!='\0';i++)
8,if(c==' ')word=0;
9,else if(word==0)
10,{ word=1;
11,num++;}
12,printf("There are %d words in the line.\n",num);}
运行时输入,I am a boy.
运行结果,There are 4 words in the line.