谭浩强C语言-07
7 数组
7.1 一维数组的定义和引用
7.1.1 一维数组的定义方式
在C语言中使用数组必须先进行定义。
一维数组的定义方式为:
其中:
类型说明符是任一种基本数据类型或构造数据类型。
数组名是用户定义的数组标识符。
方括号中的常量表达式表示数据元素的个数,也称为数组的长度。
例如:
对于数组类型说明应注意以下几点:
1)
2)
3)
例如:
是错误的。
4)
5)
例如:
是合法的。
但是下述说明方式是错误的。
6)
例如:
7.1.2 一维数组元素的引用
数组元素是组成数组的基本单元。数组元素也是一种变量, 其标识方法为数组名后跟一个下标。下标表示了元素在数组中的顺序号。
数组元素的一般形式为:
其中下标只能为整型常量或整型表达式。如为小数时,
例如:
都是合法的数组元素。
数组元素通常也称为下标变量。必须先定义数组,才能使用下标变量。在C语言中只能逐个地使用下标变量,而不能一次引用整个数组。
例如,输出有
而不能用一个语句输出整个数组。
下面的写法是错误的:
printf("%d",a);
【例7.1】
main()
{
int i,a[10];
for(i=0;i<=9;i++)
for(i=9;i>=0;i--)
}
【例7.2】
main()
{
int i,a[10];
for(i=0;i<10;)
for(i=9;i>=0;i--)
【例7.3】
main()
{
int i,a[10];
for(i=0;i<10;)
for(i=0;i<=9;i++)
printf("%d",a[i]);
printf("\n%d %d\n",a[5.2],a[5.8]);
}
7.1.3 一维数组的初始化
给数组赋值的方法除了用赋值语句对数组元素逐个赋值外, 还可采用初始化赋值和动态赋值的方法。
数组初始化赋值是指在数组定义时给数组元素赋予初值。数组初始化是在编译阶段进行的。这样将减少运行时间,提高效率。
初始化赋值的一般形式为:
其中在{ }中的各数据值即为各元素的初值,各值之间用逗号间隔。
例如:
相当于a[0]=0;a[1]=1...a[9]=9;
C语言对数组的初始化赋值还有以下几点规定:
1)
当
例如:
表示只给
2)
例如给十个元素全部赋
而不能写为:
3)
例如:
可写为:
7.1.4 一维数组程序举例
可以在程序执行过程中,对数组作动态赋值。这时可用循环语句配合
【例7.4】
main()
{
int i,max,a[10];
printf("input 10 numbers:\n");
for(i=0;i<10;i++)
max=a[0];
for(i=1;i<10;i++)
printf("maxmum=%d\n",max);
}
【例7.5】
main()
{
int i,j,p,q,s,a[10];
printf("\n input 10 numbers:\n");
for(i=0;i<10;i++)
for(i=0;i<10;i++){
}
}
本例程序中用了两个并列的
7.2 二维数组的定义和引用
7.2.1 二维数组的定义
前面介绍的数组只有一个下标,称为一维数组,其数组元素也称为单下标变量。在实际问题中有很多量是二维的或多维的,因此C语言允许构造多维数组。多维数组元素有多个下标,以标识它在数组中的位置,所以也称为多下标变量。本小节只介绍二维数组,多维数组可由二维数组类推而得到。
二维数组定义的一般形式是:
其中常量表达式
例如:
说明了一个三行四列的数组,数组名为
二维数组在概念上是二维的,即是说其下标在两个方向上变化,下标变量在数组中的位置也处于一个平面之中,而不是象一维数组只是一个向量。但是,实际的硬件存储器却是连续编址的,也就是说存储器单元是按一维线性排列的。如何在一维存储器中存放二维数组,可有两种方式:一种是按行排列, 即放完一行之后顺次放入第二行。另一种是按列排列, 即放完一列之后再顺次放入第二列。在C语言中,二维数组是按行排列的。
即:
先存放a[0]行,再存放
7.2.2 二维数组元素的引用
二维数组的元素也称为双下标变量,其表示的形式为:
其中下标应为整型常量或整型表达式。
例如:
表示
下标变量和数组说明在形式中有些相似,但这两者具有完全不同的含义。数组说明的方括号中给出的是某一维的长度,即可取下标的最大值;而数组元素中的下标是该元素在数组中的位置标识。前者只能是常量,后者可以是常量,变量或表达式。
【例7.6】一个学习小组有5个人,每个人有三门课的考试成绩。求全组分科的平均成绩和各科总平均成绩。
| 张 | 王 | 李 | 赵 | 周 |
Math | 80 | 61 | 59 | 85 | 76 |
C | 75 | 65 | 63 | 87 | 77 |
Foxpro | 92 | 71 | 70 | 90 | 85 |
可设一个二维数组a[5][3]存放五个人三门课的成绩。再设一个一维数组
main()
{
int i,j,s=0,average,v[3],a[5][3];
printf("input score\n");
for(i=0;i<3;i++)
average =(v[0]+v[1]+v[2])/3;
printf("math:%d\nc languag:%d\ndbase:%d\n",v[0],v[1],v[2]);
printf("total:%d\n", average );
}
程序中首先用了一个双重循环。在内循环中依次读入某一门课程的各个学生的成绩,并把这些成绩累加起来,退出内循环后再把该累加成绩除以
7.2.3 二维数组的初始化
二维数组初始化也是在类型说明时给各下标变量赋以初值。二维数组可按行分段赋值,也可按行连续赋值。
例如对数组
1)
2)
【例7.7】
main()
{
int i,j,s=0, average,v[3];
int a[5][3]={{80,75,92},{61,65,71},{59,63,70},{85,87,90},{76,77,85}};
for(i=0;i<3;i++)
printf("math:%d\nc languag:%d\ndFoxpro:%d\n",v[0],v[1],v[2]);
printf("total:%d\n", average);
对于二维数组初始化赋值还有以下说明:
1)
赋值后的元素值为
2)
可以写为:
inta[][3]={1,2,3,4,5,6,7,8,9};
3)
如二维数组a[3][4],可分解为三个一维数组,其数组名分别为:
a[0]
a[1]
a[2]
对这三个一维数组不需另作说明即可使用。这三个一维数组都有
必须强调的是,
7.2.4 二维数组程序举例
7.3 字符数组
用来存放字符量的数组称为字符数组。
7.3.1 字符数组的定义
形式与前面介绍的数值数组相同。
例如:
由于字符型和整型通用,也可以定义为
字符数组也可以是二维或多维数组。
例如:
即为二维字符数组。
7.3.2 字符数组的初始化
字符数组也允许在定义时作初始化赋值。
例如:
赋值后各元素的值为:
其中c[9]未赋值,由的值为
当对全体元素赋初值时也可以省去长度说明。
例如:
这时C数组的长度自动定为
7.3.3 字符数组的引用
【例7.8
main()
{
int i,j;
char a[][5]={{'B','A','S','I','C',},{'d','B','A','S','E'}};
for(i=0;i<=1;i++)
}
本例的二维字符数组由于在初始化时全部元素都赋以初值,因此一维下标的长度可以不加以说明。
7.3.4 字符串和字符串结束标志
在C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。前面介绍字符串常量时,已说明字符串总是以
C语言允许用字符串的方式对数组作初始化赋值。
例如:
可写为:
用字符串方式赋值比用字符逐个赋值要多占一个字节, 用于存放字符串结束标志
C | | p | r | o | g | r | a | m | \0 |
7.3.5 字符数组的输入输出
在采用字符串方式后,字符数组的输入输出将变得简单方便。
除了上述用字符串赋初值的办法外,还可用
【例7.9】
main()
{
char c[]="BASIC\ndBASE";
printf("%s\n",c);
}
注意在本例的
【例7.10】
main()
{
char st[15];
printf("input string:\n");
scanf("%s",st);
printf("%s\n",st);
}
本例中由于定义数组长度为
例如当输入的字符串中含有空格时,运行情况为:
输出为:
从输出结果可以看出空格以后的字符都未能输出。为了避免这种情况,可多设几个字符数组分段存放含空格的串。
程序可改写如下:
【例7.11】
main()
{
char st1[6],st2[6],st3[6],st4[6];
printf("input string:\n");
scanf("%s%s%s%s",st1,st2,st3,st4);
printf("%s %s %s %s\n",st1,st2,st3,st4);
}
在前面介绍过,scanf的各输入项必须以地址方式出现,如
这是由于在C语言中规定,数组名就代表了该数组的首地址。整个数组是以首地址开头的一块连续的内存单元。
如有字符数组charc[10],在内存可表示如图。
C[0] | C[1] | C[2] | C[3] | C[4] | C[5] | C[6] | C[7] | C[8] | C[9] |
设数组c的首地址为
7.3.6 字符串处理函数
C语言提供了丰富的字符串处理函数,大致可分为字符串的输入、输出、合并、修改、比较、转换、复制、搜索几类。 使用这些函数可大大减轻编程的负担。用于输入输出的字符串函数,在使用前应包含头文件
下面介绍几个最常用的字符串函数。
1.
【例7.12】
#include"stdio.h"
main()
{
char c[]="BASIC\ndBASE";
puts(c);
}
2.
【例7.13】
#include"stdio.h"
main()
{
char st[15];
printf("input string:\n");
gets(st);
puts(st);
}
3.
【例7.14】
#include"string.h"
main()
{
static char st1[30]="My name is ";
int st2[10];
printf("input your name:\n");
gets(st2);
strcat(st1,st2);
puts(st1);
}
4.
【例7.15】
#include"string.h"
main()
{
char st1[15],st2[]="C Language";
strcpy(st1,st2);
puts(st1);printf("\n");
}
本函数要求字符数组
贝的字符串。
5.
本函数也可用于比较两个字符串常量,或比较数组和字符串常量。
【例7.16】
#include"string.h"
main()
{ int k;
static char st1[15],st2[]="C Language";
printf("input a string:\n");
gets(st1);
k=strcmp(st1,st2);
if(k==0) printf("st1=st2\n");
if(k>0) printf("st1>st2\n");
if(k<0) printf("st1<st2\n");
}
本程序中把输入的字符串和数组
6.
【例7.17】
#include"string.h"
main()
{ int k;
static char st[]="C language";
k=strlen(st);
printf("The lenth of the string is %d\n",k);
}
7.4 程序举例
【例7.18】把一个整数按大小顺序插入已排好序的数组中。
为了把一个数按大小插入已排好序的数组中,应首先确定排序是从大到小还是从小到大进行的。设排序是从大到小进序的,则可把欲插入的数与数组中各数逐个比较,当找到第一个比插入数小的元素
main()
{
int i,j,p,q,s,n,a[11]={127,3,6,28,54,68,87,105,162,18};
for(i=0;i<10;i++)
for(j=i+1;j<10;j++)
if(q<a[j]){p=j;q=a[j];}
if(p!=i)
{
}
printf("%d",a[i]);
}
本程序首先对数组
【例7.19】在二维数组a中选出各行最大的元素组成一个一维数组
a=( 3
b=(87 108 37)
本题的编程思路是,在数组
main()
{
for(j=1;j<=3;j++)
if(a[i][j]>l)l=a[i][j];
b[i]=l;}
printf("%5d",a[i][j]);
printf("\n");}
}
程序中第一个
【例7.20】输入五个国家的名称按字母顺序排列输出。
编程如下:
main()
{
for(j=i+1;j<5;j++)
strcpy(st,cs[i]);
strcpy(cs[i],cs[p]);
strcpy(cs[p],st);
}
本程序的第一个
7.5 本章小结
1.数组是程序设计中最常用的数据结构。数组可分为数值数组
2.数组可以是一维的,二维的或多维的。
3.数组类型说明由类型说明符、数组名、数组长度
4.对数组的赋值可以用数组初始化赋值,输入函数动态赋值和赋值语句赋值三种方法实现。对数值数组不能用赋值语句整体赋值、输入或输出,而必须用循环语句逐个对数组元素进行操作。
文章来自 : 谭浩强C语言-07