C++程序设计 湖南大学 杜四春、银红霞
第 5章 数组
5.1 一维数组
5.2 二维数组
5.3 多维数组
5.4 数组与函数
5.5 数组的应用
C++程序设计 湖南大学 杜四春、银红霞
数组类型是一种构造型(组合型)的数据
类型。
数组是由一组具有相同数据类型的元素组
成的集合。数组的类型就是这组元素的数据类
型。构成数组的这组元素在内存中占用一组连
续的存储单元。可以用一个统一的数组名标识
这一组数据,而用下标来指明数组中各元素的
序号。
根据数组的维数,分为一维数组、二维数
组和多维数组,常用的是一维和二维数组。
C++程序设计 湖南大学 杜四春、银红霞
5.1 一维数组
5.1.1 一维数组的定义
定义一维数组的语法格式为:
类型 数组名 [常量表达式 ];
其中,类型是数组类型,即数组中各元素的数据
类型,可以是整型、浮点型、字符型等基本类型。数
组名是一个标识符,代表着数组元素在内存中的起始
地址,它的命名规则与变量名的命名一样。常量表达
式又称下标表达式,表示一维数组中元素的个数,即
数组长度(也称为数组大小),用一对方括号,[ ]”括
起来。方括号,[ ]”的个数代表数组的维数,一个方括
号表示一维数组。
C++程序设计 湖南大学 杜四春、银红霞
例如:下面分别定义了一个具有 5个元素的字符型
数组 a和一个具有 10个元素的整型数组 b:
char a[5];
int b[10];
对上面定义的数组 b,也可以采用下面这种定义方
法:
const int size=10;
int b[size];
注意:在定义数组时, 不能用变量来描述数组定
义中的元素个数 。 例如, 下面的定义方式是不合法的:
int b[n];
C++程序设计 湖南大学 杜四春、银红霞
下标指明了数组中每个元素的序号, 下标值为整
数, 用数组名加下标值就可以访问数组中对应的某个
元素 。 下标值从 0开始, 因此对于一个具有 n个元素的
一维数组来说, 它的下标值是 0~ n-1。 例如, 对上例
中定义的数组 b来说, b[0]是数组中的第一个元素,
b[1]是数组中的第二个元素, …, b[9]是数组中的最后
一个元素, 而不包含 b[10]。
数组元素在内存中是顺序存储的 。 对于一维数组,
就是简单地按下标顺序存储 。
例如, 对上面定义的整型数组 b,在内存中的存放
顺序如图 5-1所示:
图 5-1 一维数组的存储
b[0] b[1] b[2] b[3] b[4]
C++程序设计 湖南大学 杜四春、银红霞
5.1.2 一维数组的初始化
在定义数组时对其中的全部或部分指定初始值, 这
称为数组的初始化 。 只有存储类别为静态的或外部的数
组才可以进行初始化 。 初始化的语法格式为:
类型 数组名 [ 数组范围 ]={值 1,值 2,…, 值 n}
例如:对在 5.5.1小节中定义的数组 a进行初始化 。
char a[5]={’a’,’b’,’c’,’d’,’e’};
或:
char a[ ]={’a’,’b’,’c’,’d’,’e’};
C++程序设计 湖南大学 杜四春、银红霞
在对数组初始化时,也可以只对数组中的部分元
素指定初始值。也即,初始化值的个数可以少于或等
于数组定义的元素的个数,但不可以多于数组元素的
个数,否则会引起编译错误。
当初始化值的个数少于数组元素个数时,前面的
元素按顺序初始化相应的值,后面不足的部分由系统
自动初始化为零(对数值数组)或空字符‘ \0’(对字
符数组)。
C++程序设计 湖南大学 杜四春、银红霞
例如:
int c[5]={1,2};
定义整型数组 c有 5个元素, 但只初始化前两个元
素,c[0]=1,c[1]=2。 对于后面的三个元素没有定义
初始值, 此时由系统自动给它们赋 0。
当数组长度与初始化元素的个数不相等时, 数组
长度不能省去不写, 如上例不能写为:
int c[ ]={1,2};
否则编译器会认为数组 c只有 2个元素而不是 5个元
素。
C++程序设计 湖南大学 杜四春、银红霞
对于字符型数组的初始化, 除了上面介绍的将数
组中的元素一个一个赋值为字符的方式外, 还可以有
另外一种方式, 即将整个字符型数组一次性赋值为一
个字符串, 此时花括号可以省略 。 例如, 下面三种初
始化赋值方式是等价的:
char d[6]={ ’h’,’e’,’l’,’l’,’o’,’\0’ };
char d[6]={”hello”};
char d[6]=”hello”;
后两种方法比较符合用户的习惯。
C++程序设计 湖南大学 杜四春、银红霞
要注意的是:单个字符用单括号括起来, 而字符
串用双括号括起来, 组成字符串的字符除显示给出的
外, 还包括结尾处标识字符串结束的符号 ‘ \0’。 所以
上例中的字符串, hello”实际上包含 6个字符,‘ h’,
‘ e’,‘ l’,‘ l’,‘ o’,‘ \0’ 。 如果将上例定义成
如下形式就错了:
char d[5]=”hello”;

char d[5]={”hello”};
此时,最后一个字符‘ \0’未能放入 d数组中,而是
存放到 d数组之后的存储单元中。这种错误编译器检查
不出来,但由于改写了数组空间以外的内存单元,就
可能会破坏其他数据区或程序本身。在用户编写程序
时,一定要注意避免这样的情况发生。
C++程序设计 湖南大学 杜四春、银红霞
5.1.3 数组的赋值
1,用, =”赋值
与数组元素的初始化不同, 在给数组元素进行赋
值时, 必须逐一赋值 。
例如:对于下述的数组初始化:
int a[3]={1,2,3};
其等价的赋值形式如下:
int a[3];
a[0]=1;
a[1]=2;
a[2]=3;
C++程序设计 湖南大学 杜四春、银红霞
若要在数组之间进行赋值, 也只能一个一个元素
地赋值 。
例如:将上述数组 a的值赋给另一个同样大小的数
组 b,可以利用下面的循环完成赋值操作:
for (i=0;i<3;i++) b[i]=a[i];
C++程序设计 湖南大学 杜四春、银红霞
2,用流命令赋值
其语法格式为:
cin>>数组名;

cin>>数组名 [下标 ];
例如:对一个大小为 5的字符型数组 a赋值, 可以
用下列两种方式:
char a[5];
cin>>a;
或 char a[5];
int i;
for (i=0;i<5,i++) cin>>a[I];
C++程序设计 湖南大学 杜四春、银红霞
3,用 scanf( ) 函数
其语法格式为:
scanf(, 类型标识,, 数组名 ) ;

scanf(“类型标识”,数组元素地址);
C++程序设计 湖南大学 杜四春、银红霞
4,用 C++库函数中的 strcpy( ) 函数 ( 字符串拷贝函
数 )
其常见语法格式为:
strcpy( 数组名, 字符串 ) ;
//将一个字符串赋值到一个字符数组中
例如:
char str1[10];
strcpy(str1,”hello”);
注意, 此例不能写为:
str1=”hello”; //不合法
C++程序设计 湖南大学 杜四春、银红霞
另一种常见的语法格式为:
strcpy( 数组名 1,数组名 2) ;
//将数组 2中的字符串赋值到数组 1中
例如:
strcyp(str1,str2);
注意, 上例不能写为:
str1=str2; //不合法
C++程序设计 湖南大学 杜四春、银红霞
5.1.4 数组元素的引用
数组在定义后即可引用 。 其引用形式为:
数组名 [下标 ]
指明了引用数组名的数组中下标所标识的元素。
下标可以是整常数或整型表达式。例如 a[2+1],a[i+j]
等( i和 j为整型变量)。例如:
a[2]=10; //将 10赋给数组中的 a[2]元素 。
a[5]=a[2]; //将 a[2]元素的值赋给 a[5]元素
cout<<a[5]; //打印 a[5]元素的值
注意区分定义与引用形式上的相似与含义上的区
分, 定义时是指数组的大小空间;引用时是指引用下
标标识的元素 。
C++程序设计 湖南大学 杜四春、银红霞
5.1.5 数组越界
在给数组元素赋值或对数组元素进行引用时, 一
定要注意下标的值不要超过数组的范围, 否则会产生
数组越界问题 。 因为当数组下标越界时, 编译器并不
认为它是一个错误, 但这往往会带来非常严重的后果 。
例如:定义了一个整型数组 a:
int a[10];
数组 a的合法下标为 0~9。如果程序要求给 a[10]赋
值,将可能导致程序出错,甚至系统崩溃。
C++程序设计 湖南大学 杜四春、银红霞
常用下面的式子确定数组的大小,预防数组越界
情况的发生 。
假定对于一个整型数组 a,它的大小为:
sizeof( a) /sizeof( int)
sizeof( a)表示求数组 a在内存中所占字节数,
sizeof( int)表示求整型数据在内存中所占字节数。使
用上面这个式子,可以使数组大小计算在 16位机器和
32位机器之间移植。
C++程序设计 湖南大学 杜四春、银红霞
5.2 二维数组
5.2.1 二维数组的定义
二维数组也称为矩阵, 需要两个下标才能标识某
个元素的位置, 通常称第一个下标为行下标, 称第二
个下标为列下标 。 定义二维数组的语法格式为:
类型 数组名 [常量表达式 1][常量表达式 2];
定义二维数组的格式与定义一维数组的格式相同,
只是必须指定两个常量表达式,第一个常量表达式标
识数组的行数,第二个常量表达式标识数组的列数。
C++程序设计 湖南大学 杜四春、银红霞
例如,int a[2][3];
上面定义了一个 a数组, 它在逻辑上的空间形式为
2行 3列, 每一个数组元素都是整型数据, 因此 a数组的
各元素如下:
a[0][0] a[0][1] a[0][2]
a[1][0] a[1][1] a[1][2]
//每一维的下标都是从 0开始
可见, 二维数组中每个元素都是用下列方式标识:
数组名 [行下标 ][列下标 ]
C++程序设计 湖南大学 杜四春、银红霞
二维数组在内存中的排列顺序是, 先行后列,,
即在内存中先存第一行的元素, 然后再存第二行的元
素 。 从数组下标变化来看, 先变第二个下标, 第一个
下标先不变化 ( 即 i[0][0],i[0][1],i[0][2]), 待第二
个下标变到最大值时, 才改变第一个下标, 第二个下
标又从 0开始变化 。 比如上面定义的 2行 3列的二维数组
a,在内存中的存放顺序如图 5-6所示 。
对于二维数组,可以把它看成是由多个一维数组
构成的。例如上例,int a[2][3];就可以看成是由两个
形如 int a[3];的一维数组构成的。
C++程序设计 湖南大学 杜四春、银红霞
由于二维数组在内存中是线性排列的, 引用一维
数组和引用二维数组都是引用相应存储地址的内容,
因此可以计算出一个二维数组元素在对应一维数组中
的顺序号, 从而将对二维数组元素的引用转变为对一
维数组元素的引用, 这个过程称为, 降维处理, ( 经
常在向函数传递数组时用到 ) 。
举例来说, 假设有一个 m x n的二维数组 a,其中
第 i行第 j列元素 a[i][j]在数组中的位置公式为:
i*n+j+1
C++程序设计 湖南大学 杜四春、银红霞
例如有一个 3*4的矩阵 a:
a00 a01 a02 a03
a= a10 a11 a12 a13
a20 a21 a22 a23
a21元素在数组中的位置是 2*4+1+1=10。 即它在
数组中是第 10个元素 。 对一个 aij元素 ( 在 C++语言中
表示为 a[i][j]), 在它前面有 i行 ( 对 a21来说它前面有
两个整行 ), 这 i行共有 i*n个元素 。 在 aij所在行中, aij
前面还有 j个元素, 因此在数组 a中 aij前面共有 ( i*n+j)
个元素 。 那么 aij就是第 ( i*n+j) +1个元素 。 如果顺序
号从 0算起, 那么 aij在 a数组中的顺序号计算公式为
i*n+j。 a21的顺序号为 2*4+1=9。 即按从 0算起的话,
它的顺序号为 9,或者说它前面有 9个元素 。
C++程序设计 湖南大学 杜四春、银红霞
5.2.2 二维数组初始化
和一维数组一样, 二维数组也能在定义时被初始
化, 只是要注意必须按照前面所讲的存储顺序列出数
组元素的值 。 常见有如下一些初始化方式:
( 1) 分别对各元素赋值, 每一行的初始值用一对
花括号括起来 。 例如:
int a[2][3]={{1,2,3},{4,5,6}};
将第一对花括号内的三个初始值分别赋给 a数组第
一行三个元素, 第二对花括号内的三个初始值赋给第
二行元素 。 数组中各元素为:
1 2 3
4 5 6
C++程序设计 湖南大学 杜四春、银红霞
( 2) 将各初始值全部连续地写在一个花括号内,
在程序编译时会按内存中排列的顺序将各初始值分别
赋给数组元素 。 例如
int a[2][3]={1,2,3,4,5,6};
数组中各元素为:
1 2 3
4 5 6
( 3) 只对数组的部分元素赋值 。 例如:
int a[2][3]={1,2,3,4};
数组共有 6个元素, 但只对前面 4个元素赋初值,
后面两个未赋初值, 其值为 0。 数组中各元素为:
1 2 3
4 0 0
C++程序设计 湖南大学 杜四春、银红霞
( 4) 可以在分行赋初值时, 只对该行中一部分元
素赋初值, 例如:
static int a[2][3]={{1,2},{1}};
对第一行中的第一, 二列元素赋初值, 而第三个
元素未赋初值 。 第二行中只有第一列元素赋初值 。 数
组中各元素为:
1 2 0
1 0 0
C++程序设计 湖南大学 杜四春、银红霞
5.2.3 省略第一维大小
若在定义数组时给出了全部数组元素的初值, 则
数组的第一维下标可以省略, 但第二维下标不能省略 。
例如:下面两种定义方式等价:
static int a[2][3]={1,2,3,4,5,6};
static int a[ ][3]={1,2,3,4,5,6};
编译器会根据元素的总个数分配空间, 每行 3列,
共 6个元素, 故该数组行数为 6/3=2行 。
但上例不能写成:
static int a[2][ ]={1,2,3,4,5,6};
C++程序设计 湖南大学 杜四春、银红霞
在分行定义时, 也可以只对部分元素赋初值而省
略第一维的下标 。 例如:
int a[ ][4]={{1,2},{},{3,4,5}}
该数组表示 3行 4列的整型数组, 等价于下面的定
义:
int a[3][4]={{1,2,0,0},{0,0,0,0},{3,4,5,0}}
C++程序设计 湖南大学 杜四春、银红霞
5.3 多维数组
5.3.1 多维数组的定义
类型 数组名 [常量表达式 1][常量表达式 2]… [常量表达式
n];
由于大于三维的数组基本上不常用, 所以在此以
三维数组为例介绍多维数组 。
例如:定义一个整型三维数组:
int a[2][3][4];
数组有 24个元素,它们在内存中排列顺序跟二维
数组类似:先变化第三个下标,然后变化第二个下标,
最后变化第一个下标。
对于三维数组,可以把它看成是由多个二维数组
构成的。依此类推,一个 n维数组可以看成是由多个 n-
1维数组构成的。
C++程序设计 湖南大学 杜四春、银红霞
5.3.2 多维数组初始化
以三维数组初始化为例:
int a[2][3][4]={{{1,2,3,4},{5,6,7,8},{9,10,11,12}},
{{13,14,15,16},{17,18,19,20},{21,22,23,24}}};
由于第一维的大小为 2,可以认为 a数组有两个二
维数组组成, 每个二维数组为 3行 4列 。 因此初始化时,
按每个二维数组按行给初值的方法, 分别用花括号把
各行元素值括起来, 并且将三行的初值再用花括号括
起来 。
例如,{{1,2,3,4},{5,6,7,8},{9,10,11,12}}是第一个
二维数组的初值;
同样, {{13,14,15,16},{17,18,19,20},{21,22,23,24}}
是第二个二维数组的初值 。
C++程序设计 湖南大学 杜四春、银红霞
当然也可以不必用这么多的花括号, 而把三维数
组中全部元素连续写在一个花括号内, 按元素在内存
中排列顺序依次赋初值 。 例如:
static int a[2][3][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
17,18,19,20,21,22,23,24};
C++程序设计 湖南大学 杜四春、银红霞
5.3.3 省略第一维大小
多维数组也可以省写第一维的大小, 以上面定义
的三维数组 a为例, 定义也可改写为:
int a[ ][3][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
17,18,19,20,21,22,23,24};
系统会根据初值个数, 算出第一维的大小为:
24/( 3*4) =2。
在分行定义时, 也可以只对部分元素赋初值而省
略第一维的下标 。 例如:
int a[ ][3][2]={{{1,2},{3},{5}},{{0,7},{8},{10}}};
显然这是一个三维数组,大小为 2*3*2。等价于下
面的定义:
int a[2][3][2]={{{1,2},{3,0},{5,0}},{{0,7},{8,0},{10,0}}};
C++程序设计 湖南大学 杜四春、银红霞
5.4 数组与函数
数组也可以作为函数参数, 将数组中数据传送到
另一个函数中 。 传递可以采用两种方法:
1,数组元素作为函数的参数
当把数组元素作为函数的实参时,它的用法与普
通变量作参数相同。将数组元素的值传送给形参进行
函数体调用,函数调用完返回后,数组元素的值不变。
这种传送方式是“值传送”方式,即只能从实参传送
给形参,而不能从形参传送给实参。
应当注意,实参与形参的类型要相同。
C++程序设计 湖南大学 杜四春、银红霞
2,数组名作为函数的参数
当用数组名作为函数的实参和形参时,传递的是
数组的地址。这时实参数组和形参数组应该分别在它
们所在的函数中定义。此时采取的不是“值传送”方
式,而是“地址传送”方式,即把实参数组的起始地
址传送给形参数组,这样形参数组就和实参数组共占
同一段内存单元,当形参值发生变化时,实参值也发
生变化。
C++程序设计 湖南大学 杜四春、银红霞
此时应该注意:
( 1)实参数组与形参数组类型要一致。
( 2)形参数组的长度不要超过实参数组的长度。
实参数组必须定义为具有确定长度的数组,而形参数
组可以不定义长度,只在数组名后跟一个空的方括号,
同时在被调用的函数中另设一个参数用来传递元素的
个数。
( 3)可以在被调用函数中采用降维处理,即用单
重循环来遍历二维数组中的所有元素。此时调用函数
中的数组不要用数组名表示,而要用第一个元素的地
址表示。
C++程序设计 湖南大学 杜四春、银红霞
5.5 数组的应用
例 5-2:输入 10个学生的成绩, 求平均成绩, 并将低于平
均成绩的分数打印出来 。
#include <iostream.h>
#include <iomanip.h>
void readdata(float score[10])
{cout<<"Please input 10 student's score:"<<endl;
for(int i=0;i<10;i++)
cin>>score[i];
return;
}
C++程序设计 湖南大学 杜四春、银红霞
float aver(float score[10])
{float sum=0; int i;
for(i=0;i<10;i++)
sum+=score[i];
return(sum/10); }
void print(float score[10],float ave)
{int i;
cout<<"the scores which are below the average:";
for(i=0;i<10;i++)
if(score[i]<ave)
cout<<score[i]<<" ";
return; }
C++程序设计 湖南大学 杜四春、银红霞
void main()
{void readdata(float score[10]);
float aver(float score[10]);
void print(float score[10],float ave);
float ave,score[10];
readdata(score);
ave=aver(score);
cout<<"average="<<ave<<endl;
print(score,ave);
}
C++程序设计 湖南大学 杜四春、银红霞
此程序的运行结果为:
Please input 10 student's score:
10 20 30 40 50 60 70 80 90 100
average=55
the scores which are below the average:10 20 30 40 50