第六章 数组应用程序设计授课老师,危孟君
Email,weimengjun@163.com
C语言程序设计 (第 2版 )
中南大学出版社成奋华 陈松乔 著祝各位同学:
构造数据类型之一
数组,有序数据的集合,用数组名标识
元素,属同一数据类型,用数组名和下标确定
§ 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”,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;
说明:
数组不初始化,其元素值为随机数
当全部数组元素赋初值时,可不指定数组长度如 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>
main()
{ int x[10],i,max,min;
for(i=0;i<10;i++)
scanf("%d",&x[i]);
max=min=x[0];
for(i=1;i<10;i++)
{ if(max<x[i]) max=x[i];
if(min>x[i]) min=x[i];
}
printf("Max %d\n",max);
printf("Min %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趟冒泡排序后,排序结束输入 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;
for(i=1;i<11;i++)
scanf("%d",&a[i]);
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;}
for(i=1;i<11;i++)
printf("%d ",a[i]);
}
§ 6.3 多维数组
二维数组的定义
定义方式:
数据类型 数组名 [常量表达式 ][常量表达式 ];
数组元素的存放顺序
原因,内存是一维的
二维数组:按行序优先
多维数组:最右下标变化最快例 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]
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;
for(i=0;i<=1;i++)
{ for(j=0;j<=2;j++)
b[j][i]=a[i][j];
}
for(i=0;i<=2;i++)
{ for(j=0;j<=1;j++)
printf("%5d",b[i][j]);
printf("\n");
}
}
§ 6.4 字符数组和字符串
字符数组
定义
字符数组的初始化
1、逐个字符赋值
2、用字符串常量例 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]
例 char ch[5]=“Boy”;
ch[0]
B o y \0 \0
用字符串常量
ch[1] ch[2] ch[3] ch[4]
例 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 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 ch[10];
int i;
for(i=0;i<=9;i++)
scanf("%c",&ch[i]);
for(i=0;i<10;i++)
printf("%c",ch[i]);
}
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()
{ 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);
}
输出,a=How
b=are
c=you?
scanf中 %s输入时,遇空格或回车结束运行情况:
输入,How are you?
常用的字符串处理函数包含在头文件 <string.h>
字符串输出函数 puts
格式,puts(字符数组 )
功能:向显示器输出字符串(输出完,换行)
说明:字符数组必须以‘ \0?结束
字符串输入函数 gets
格式,gets(字符数组 )
功能:从键盘输入一以 回车结束 的字符串放入字符数组中,
并自动加‘ \0’
说明:输入串长度应小于字符数组长度例 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必须足够大
连接前,两串均以‘ \0’结束 ;连接后,串 1的‘ \0’取消,
新串最后加‘ \0’
字符串拷贝函数 strcpy
格式,strcpy(字符数组 1,字符串 2)
功能:将字符串 2,拷贝到字符数组 1中去说明,?字符数组 1必须足够大
拷贝时‘ \0’一同拷贝
不能使用赋值语句为一个字符数组赋值例 strcpy与 strcat举例
#include <string.h>
main()
{ char de [25];
char blank[] = " ",c[]= "C++",
turbo[] = "Turbo";
strcpy(de,turbo);
strcat(de,blank);
strcat(de,c);
printf("%s\n",de);
}
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\062”; 答案,1 3 2
#include <string.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(”%d,%d,%d \n”,len1,len2,len3);
}
例 strcmp与 strlen举例
How are you?Hello!
6,12,18
练习编程输入一个字符串,回车键结束,统计其中一共有多少个空格,
设计步骤
1、用 gets输入字符串;
2、用循环判断字符串中的每个字符是否空格 ;
3、用 puts输出该字符串。
练习编程输入一个字符串,回车键结束,将其中所有的大写字母改为小写字母,而所有的小字字母全部改成大写字母,然后输出,
设计步骤
1、用 gets输入字符串;
2、用循环判断字符串中的每个字符是大写还是小写,
若是大写要转换成小字,是小写要转换成大写;
3、用 puts输出该字符串。
例 输入一行字符,统计其中有多少个单词输入一字符串给 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
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 <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);
}
还记得上个学期学的内容吗?
1,以下程序段 ( )
int a=10; while (a); - -a;
A.是死循环 B,循环执行 10次
C,循环执行一次 D,有语法错误,
2,若有说明 int a[3][4]={0}; 则下面正确的说法是 ( )
A,只有元素 a[0][0]可得到初值 B,此说明语句不正确.
C,a中各元素都可得到初值,但其值不一定是 0.
D,a中每个元素都可得到初值0.
3,若有说明,int a[ ][3]={1,2,3,4,5,6,7};则第一维的大小是( )
A,2 B,3 C,4 D,无确定值
B
D
B
4,C语言提供的合法关键字是( )。
A.next B.string C.do case D.struct
5,若二维数组 a有 m列,则计算任一元素 a[i][j]在数组中位置的公式为 ( )。
A,i*m+j B,j*m+i C,i*m+j-1 D,i*m+j+1
6,对关系表达式,1<=x<=2 的正确描述是 ( )。
A,表达式语法错 ; B,当 X的值在 1和 2之间,表达式为真;
C,若 X的值 >2,表达式为假; D.无论 X是何值,表达式为真;
7,若希望当 A的值为奇数时,表达式的值为,真,,A的值为偶数时,表达式的值为,假,,则以下不能满足要求的表达式是 ( ) 。
A,A%2= =1 B,!(A%2= =0) C,!(A%2) D,A%2
D
D
D
C
作 业请给我写一封信,问候、意见、建议、总结皆可格式为:
危老师:
你好!我是 XX班 XXX,……
作业可发到我的邮箱 weimengjun@163.com,或者用完整的材料纸写给我,务必在 2月 29日(本周星期五)下午
17,00之前上交。
这是本学期第一次作业,价值 3-5分。
1.设有数组定义 char a[ ]="China"; 则数组 a所占的空间为
A) 4个字节 B) 5个字节 C) 6个字节 D) 7个字节
2,给出以下定义:
char x[]="abcdefg";
Char y[]={'a','b','c','d','e','f','g'};
则正确的叙述为 ( )
A)数组 X和数组 Y等价 B)数组 x和数组 Y的长度相同
C)数组 X的长度大于数组 Y的长度 D)数组 X的长度小于数组 Y的长度
3,执行下面的程序段后,变量 k中的值为
int k=3,s[2];
s[0]=k; k=s[1]*10;
A) 不定值 B) 33 C) 30 D) 10
A
C
内容回顾
C
4,不能把字符串,Hello!赋给数组 b的语句是
A) char b[10]={'H','e','l','l','o','!'};
B) char b[10];strcpy(b,"Hello!");
C) char b[10];b="Hello!"; D) char b[10]="Hello!";
5,若有以下说明,
int a[12]={1,2,3,4,5,6,7,8,9,10,11,12};
char c='a',d,g;
则数值为 4的表达式是
A)a[g-c] B)a[4] C)a['d'-'c'] D)a['d'-c]
C
D
作业
1、看书,复习第六章,预习 7.1-7.3节;
2、将 P142页的?习题六?做好;
3、将 P144页 三 2,3题做练习一