第 6 章 数 组
6.1 一维数组的定义
6.2 一维数组元素的引用
6.3 一维数组的初始化
6.4 二维数组的定义
6.5 二维数组的引用
6.6 二维数组的初始化
6.7 字符数组
第 6 章 数 组
6.1 一维数组的定义
语句形式,
类型说明符 数组名 [常量表达式 ]
说明,
? 数组名定名规则和变量名相同 。
?常量表达式表示数组元素的个数, 即数组的长度 。 如,
int a[10];
表示 a数组有 10个元素,a[0],a[1],a[2],?,a[9],没
有 a[10]。
注意,数组的下标是从 0 开始的 。
? C不允许对数组进行动态定义 。 以下作法是错误的 。
int n;
scanf(“%d”,&n);
int a[n];
6.2 一维数组元素的引用
数组必须先定义,然后再使用。 C的数组元素只能
逐个引用而不能一次引用整个数组。
一维数组元素的表示形式为:
数组名 [下标 ]
下标可以是整型常量或整型表达式 。
例 6.1
main( )
{ int i,a[10];
for (i=0; i<=9; i++)
a[i]=i+1;
for (i=9; i>=0; i--)
printf(“%2d”,a[ i]);
}
输出结果:
10 9 8 7 6 5 4 3 2 1
6.3 一维数组的初始化
赋值语句和输入语句均可使数组中的元素赋初值, 但占用运
行时间 。 简捷的方法是在程序运行之前使数组初始化 。
对数组元素初始化的方法有:
1,在定义数组时对数组元素赋以初值
如,static int a[10] = { 0,1,2,3,4,5,6,7,8,9 };
说明,? 依次赋予数组元素的初值必须用 { } 括起来 。
?,static”是 C的一个关键字,意为“静态存储”。 C规定只有
静态存储 (static)数组和外部存储 (extern)数组才能初始化。
2,可以只给一部分元素赋值
如,static int a[10] = { 0,1,2,3,4 };
3,在 C中系统会自动对所定义的静态数组的每个元素赋初值 0
4,对全部数组元素赋初值时, 可以不指定数组长度
如,static int a[5] = { 1,2,3,4,5 };
可以写成:
static int a[ ] = { 1,2,3,4,5 };
main( )
{ int i,k,r,x,b[16];
printf(“Enter an integer x,”); scanf(“%d”,&x);
printf(“%6d binary number is,\n”,x);
k = -1;
do
{ r = x%2; b[++k]= r ; x/=2; }
while (x != 0);
for ( i=k; i>=0; i--)
printf(“%1d”,b[i]);
printf(“\n”);
}
例 6.2 将一个十进制整数转换成二进制数 。
例 6.3 用冒泡法将 10 个数按 从小到大 排序。
冒泡法的思路是,将相邻两个数进行比较,将小的调到前头。
若有这样一组数,9 8 4 5 2 0,则按如下图所示进行操作。
9 8 4 5 2 0
比较 交换
98
比较 交换
94
比较与交换的操作直到数字 9 调到最后的位置,然后将剩下
的 5个数 8 4 5 2 0 进行下一轮比较与交换,直至排好序为止。
当有 n个数时需要作 n–1
趟这样的搜索,每趟搜索
要作 n–1次比较。
main( )
{int i,j,t,a[11];
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]);
}
6.4 二维数组的定义
定义形式,
类型说明符 数组名 [常量表达式 1] [常量表达式 2]
如,float a[3][4];
定义 a是一个 3x4(3行 4列 )的数组, 即 a数组有 12个元素 。
但不得写成,float a[3,4];
注意:
? C允许定义多维数组 。
?二维数组中元素的排列顺序为 按行按列 。 即存放完第
1 行的元素后再接着存放第 2 行的元素, 依次类推 。
float a[3][4][5];
如:
6.5 二维数组的引用
二维数组元素的表示形式为,
数组名 [下标 1][下标 2]
如,a[0][0] 表示二维数组 a中第 1行的第 1个元素。
a[2][3] 表示二维数组 a中第 3行的第 4个元素。
下标可以是整型常量或整型表达式,但其值不得超过上限
6.6 二维数组的初始化
二维数组的初始化可用下列方法之一:
?按行给二维数组赋初值。 如:
static int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
这种赋初值的方法比较直观,一行对一行,不易遗漏,
易于检查。
?顺序按行按列给二维数组赋初值。 如:
static int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
?可以对部分元素赋初值。 如:
static int a[3][4]={{1},{5},{9}};
给每一行的第
一个元素赋值
static int a[3][4]={{1},{5,6} };
赋给第一行的第
一个元素和第二
行的第 1,2个元素static int a[3][4]={{1},{ },{9} };
赋给第一行和第
三行的第一个元
素第二行未赋值注意,所赋给的值是 按行按列 对号入座的。
?对二维数组的全部元素赋初值时,可以不指定第一维
的长度,但不得省去第二维的长度。 如:
static int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
可以写成:
static int a[ ][4]={1,2,3,4,5,6,7,8,9,10,11,12};
同样,
static int a[ ][4]={{0,0,3},{ },{0,10} };
也是正确的。
例 6.4 将一个二维数组行和列的元素互换后存到另一个数组中。
a = 1 2 34 5 6 b = 1 42 5
3 6
如,
main( )
{ static int a[2][3]={{1,2,3},{4,5,6}};
static int b[3][2],i,j;
printf(“arraya:\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(“arrayb:\n”);
for (i=0; i<=2; i++)
{ for ( j=0; j<=1; j++) printf(“%5d”,b[i][ j]);
printf(“\n”);
}
}
元素互换
a 数组 行 的元素变
成 b 数组 列 的元素
a 数组 列 的元素变
成 b 数组 行 的元素
例 6.5 输出一个 3?4数组中每行中的最大元素之值及其位置。
main( )
{ int i,j,c,max ;
static int a[3][4]={{6,-5,11,3},{8,9,4,7},{2,13,1,-10}};
for (i=0; i<=2; i++)
{ max=a[ i][0]; c=0;
for ( j=0; j<=3; j++)
if (a [i][j]>max) { max=a[i][j]; c=j; }
printf(“max=%2d,row=%d,colum=%d\n”,max,i+1,c+1);
}
}
输出结果:
max=11,row=1,colum=3
max= 9,row=2,colum=2
max=13,row=3,colum=2
假定每一行的第一个元素
最大并将其存放在 max中
在被查找的行中只要
有元素的值比 max大
将其存放
在 max中
并将其列
号赋给 c
6.7 字符数组
1,字符数组的定义
char c[10];
以上都是定义 c 有 10个元素的字符数组。
注,字符数组的每个元素只能存放 1 个字符。
2,字符数组的初始化
对字符数组初始化的方法是逐个给各元素赋予 1个字符。
如, static char c[10]={?I?,? ?,?a?,?m?,? ?,?h?,?a?,?p?,?p?,?y?};
?如果赋予的字符个数多于字符数组元素的个数,将产生
语法错误。
?如果赋予的字符个数少于字符数组元素的个数,则多
余的元素自动赋空字符 ( ?\0? )。
?如果赋初值的字符个数等于字符数组元素的个数,则
在定义时可省略数组长度。系统将自动根据初值个数
确定数组长度。
或 int c[10];
?可以定义和初始化一个二维字符数组。 如:
static char d[3][3] = {{?*?,? ?,?* ?},{? ?,?*?,? ?},{?*?,? ?,?*?}};
3,字符数组的引用
引用字符数组中的一个元素将得到一个字符。 如:
d[0][1] 取得第一行第二个字符 ‘ ’。
4,字符串和字符串结束标志
C在每个字符串的末尾自动加上一个字符串结束标
志‘ \0?,即在‘ \0?前面的字符的个数为该字符串的有效长
度。在用 printf函数输出字符串时,当遇到‘ \0?时就停止
输出。
字符数组并不要求它的最后一定要加 ‘ \0?。是否加
‘ \0?,完全视需要而定。
5,字符数组的输入输出
字符数组的输入输出有两种方法:
? 用,%c”格式符逐个的输入或输出字符数组的字符。
? 用,%s”格式符将整个字符串一次输入或输出。 如:
static char c[ ]={“China”};
printf(“%s”,c);
?用 scanf(“%s”,c)可以输入一个字符串, 以回车键而
不必以结束符 ‘ \0?结束输入, 系统会自动加上一个结
束符 ‘ \0?。 这里 c为字符数组名, 而不是数组元素名 。
同时字符数组名 c前也不再加地址符 &。
?若用一个 scanf函数输入多个字符串, 则以空格作为
字符串之间的分隔 。
?printf(“%s”,c)中 c是字符数组名, 不是数组元素名 。
输出时并不输出结束符 ‘ \0?。
?如果字符数组的长度大于字符串的实际长度, 也只会
输出到 ‘ \0?为止 。
?如果字符数组中有多个‘ \0?,则遇到第一个‘ \0?时停止
输出。
6,字符串处理函数
C中常用的字符串处理函数有:
1) puts( ) 函数
puts( )函数将一个以‘ \0?结束的字符串输出到终端,
且字符串中可以包含转义字符。 如:
static char str[ ]= {“China\nBeijing”};
puts(str);
输出:
China
Beijing
?字符数组必须足够大,以便容纳被拷贝的字符串。
?字符数组必须以数组名的形式出现,字符串可以是数
组名,也可以是字符串常量。
?拷贝时连同字符串后的 ‘ \0?也一起拷贝到字符数组中。
2) gets( ) 函数
gets( )函数从终端输入一个字符串到字符数组, 且
得到字符数组的起始地址 。
3) strcpy(字符数组,字符串 [,n])
将字符串 [前面的 n个字符 ]拷贝到字符数组中。
static char str1[10],str2[5];
static char str3[ ]={“China”};
strcpy(str1,str3); strcpy(str2,str3,2);
将字符数组 str3的全
部字符 (“China”) 拷
贝到字符数组 str1中
拷贝到字符数组 str2 中
将字符数组 str3 中前面
的 2 个字符 (“Ch”)
注,
?不能用赋值语句将一个字符串常量或字符数组直接
赋给一个字符数组 。 如:
str1={“China”}; str2=str1; 是不合法的 。
4) strcmp(字符串 1,字符串 2)
自左至右按 ASCII值对两个字符串中的相应的字符
进行比较,直到出现不同的字符或遇到 ‘ \0?为止。若全
部字符相同,则认为相等;若出现不相同的字符,则以
第一个不相同的字符的比较结果为准。
?若字符串 1 = 字符串 2,函数值为 0 。
?若字符串 1 > 字符串 2,函数值为一 正 整数。
?若字符串 1 < 字符串 2,函数值为一 负 整数。
例,strcmp(str1,str2);
strcmp(“China”,“Korea”);
strcmp(str1,“Beijing”);
str1和 str2为字符数组名
注,两个字符串进行比较, 不能用 以下形式:
if (str1==str2) printf(“yes”);
而 只能用 if (strcmp(str1,str2)==0) printf(“yes”);
5) strlen( )函数
strlen( )函数测试字符串的实际长度 (不包括 ‘ \0?在内 )。
如,static char str[10]={“China”};
printf(“%d”,strlen(str));
输出:
5
例 6.6 输入一行字符,统计其中有多少个单词。
#include,stdio.h”
main( )
{ char c,string[81];
int i,num=0,word=0;
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 为 1 表示一个单词开始
Word 为 0 表示一个单词结束
运行结果:
I am a boy ?
There are 4 words in the line
例 6.7 用函数调用实现字符串的复制。
void copy_string(from,to)
char from[ ],to[ ];
{ int i = 0 ;
while ( from[i] != ?\0? )
{ to[i] = from[i]; i++ ; }
to[i] = ?\0? ;
}
main( )
{char a[ ] =,I am a teacher.” ;
char b[ ] =,you are a student.” ;
copy_string( a,b);
printf(,string_a = %s\nstring_b = %s\n”,a,b);
}
声明形参 from,to为字符数组
实参以数组名将数组 a,b的起
始地址传递给形参 from 和 to
运行结果:
string_a = I am a teacher.
string_b = I am a teacher.
课外练习, 习题册中 习题七 全部