再上一篇:5.8 编译预处理
上一篇:5.9 程序的多文件组织
主页
下一篇:6.2 字符数组的定义及应用
再下一篇:6.3 字符串处理函数
文章列表

第六章 数组

《VC++程序设计基础》,讲述C++语言的语法和标准库,以及Visual C++ 函数库和MFC类库的使用,并附相关代码示例。

C++除了提供前面已介绍的基本数据类型外,还提供了导出(构造)数据类型,以满足不同应用的需要。导出数据类型包括:数组、结构体、共同体和类。本章中介绍数组的定义及应用,包括一维数组、多维数组和字符数组。其它的导出数据类型,在后面有关的章节中介绍。

6.1数组的定义及应用

把相同类型的若干个元素所组成的有序集合称为数组(Arrays),其中每一个元素称为数组的元素变量,简称为元素(Element)。通常用数组的下标(index)来表示数组元素的位置,即使用数组的下标来引用数组的元素。因此,数组元素也称为下标变量。

数组又分为一维数组和多维数组,我们分别介绍其定义和使用的方法。

6.1.1 一维数组的定义及使用

6.1.1.1一维数组的定义

一维数组的定义格式为:

《存储类型》 <类型> <数组名>[<常量表达式>];

其中存储类型是任选的,它可以是register、static、auto或extern;类型定义了数组中每一个元素的数据类型,它可以是C++预定义的数据类型或者是自定义的导出数据类型;数组名由标识符组成;常量表达式的值为一个正整数,它规定了数组的元素个数,即数组的大小。如变量说明:

int x[20];

static float y[50];

char str[10];

说明数组x有20个元素,每一个元素的数据类型为整数;数组y有50个元素,每一个元素为实数,这50个元素的存储类型为静态的;数组str有10个元素,每一个元素的数据类型为字符。

关于数组定义,说明以下几点:

1、数组必须先定义后使用。这与前面介绍的基本类型变量的规定是一样的。

2、数组定义中只给出一维数组的元素个数,而没有列举说明数组的上界和下界,C++语言规定下界是从0开始的。如上面定义的数组x,它的数组元素分别是:x[0],x[1],x[2],......,x[18],x[19]。

3、在 C++中不提供可变化大小的数组,即数组定义中的常量表达式不能包含变量,但可以使用宏定义标识符常量或用const说明的标识符常量。如:

#define ASD 256

const int SIZE=500;

......

int x1[ASD*2];

float yy[ASD+SIZE];

char cs[’a’];

这说明数组x1的元素个数为512个;数组yy的元素个数为756个;字符数组cs的元素个数为97,这是因为字符常量‘a’的ASCII编码值为97。但如下说明:

int n;

cin>>n;

float t[n];

在定义数组t时,变量n没有确定的值,即在程序执行之前,无法知道数组t的元素个数,所以这种说明是不允许的。

4、数组的元素个数一定是一个正整数,即在定义数组时,规定数组元素个数的常量表达式的值必须是一个大于或等于0的正整数。如:

#define PI 3.14

......

int a1[PI*3];

float a2[ int (PI*3)] ;

数组a1的定义是错误的,因PI*3的值是一个实数,而不是一个正整数;数组a2的定义是正确的,先求出PI*3的值9.42,再将它转换成整数9,即说明数组a2的大小为9。

5、数组名的作用域与前一章中介绍的变量作用域相同。当把数组定义为局部变量时,其作用域为块作用域;而把数组定义为全局变量时,其作用域为文件作用域。

6.1.1.2 一维数组元素的使用

数组必须定义在前,使用在后。C++语言规定只能对数组中的元素进行赋值或引用,不能把整个数组作为一个整体进行赋值或引用。

使用数组中某一个元素的格式为:

数组名[下标表达式]

其中下标表达式可以包含常数或变量,即可为一个一般的表达式。应注意二点:

1、下标表达式的值必须是一个正整数,不能是一个实数。例如:

int i,j;

float x[20],y ,z;

......

x[i+j*2] = i+j; 元素引用是合法的

z= x[y*2 ] //元素引用是不允许的

2、下标表达式的值应大于等于0,且小于定义数组时规定的数组大小值。在程序的执行过程中,C++语言对下标表达式的取值范围不作合法性检查。如:

int m, aa[20];

......

aa[m*2+1] = 200; //A

cout<

在A行中应保证m*2+1的值大于等于0,而小于20。B行输出数组aa的第21个元素,下标已经出界,执行这一语句将输出一个不确定的值。因此,保证下标表达式取值的正确性是程序设计者的事,而不是C++编译器的事。

3、数组不能作为一个整体直接输入或输出,当数组中的元素的类型是基本类型时,其元素可以直接输入输出。如:

int aa[5],bb[5];

cin >>aa; //错误的

cout<

4、同类型的数组之间也不能相互赋值。如:

bb=aa; //错误的

例 6.1 输入五个实数,并求出这五个实数的平均值。

#include

void main(void)

{

float x[5],sum=0;

cout<<"输入五个数:\n";

for(int i=0;i<5;i++) cin>>x[i];

for(i=0;i<5;i++) sum += x[i];

cout<<"这五个数的平均值为:"<

}

执行程序时,若输入五个数:4 8 6.5 6 10,则程序输出:

这五个数的平均值为:6.9。

6.1.1.3 一维数组的初始化

在引用数组元素时,所引用到的数组元素必须有确定的值。可以使用例6.1中采用的方法,通过输入语句给数组元素赋值;也可以通过赋值语句给数组的元素赋值。这二种方法,都是在程序执行期间完成数组元素的赋值。另一种方法在变量说明时, 给数组元素指定初值。因这种指定数组元素的取值,是在程序执行之前确定的,称为数组的初始化。在定义数组时完成数组元素的初始化,可有以下几种方法:

1、对数组中的所有元素赋初值。如

int x[10] = { 0,1,2,3,4,5,6,7,8,9};

则指定x[0]、x[1]、 ......、x[9]的值分别为0、1、......、9。这种给数组初始化的方法是将数组元素的初值依次放在一对花括号中,在数与数之间用逗号隔开,数组的元素个数与列举的初值个数相同。

2、对数组中的一部分元素列举初值。如

int y[10] = { 1,2,3,4,5};

则说明数组y有10个元素,前五个元素的初值分别为1,2,3,4,5;C++约定数组中的其余元素的初值为0。注意,对数组中的一部分元素置初值时,必须从第0个元素开始,依次列举出部分元素的值。如

int arr1[20]={0,0,0,4,5,6};

即希望数组arr1[3]=4,arr1[4]=5,arr1[5]=6,而其余元素的初值为0时,必须分别列举出前三个元素值为0。

3、在定义数组时,可以不直接指定数组的大小,由 C++编译器根据初值表中元素的个数来自动确定数组元素的个数。如

int z[] = { 0,1,2,3,4,5,6,7,8};

在花括号中列举了9 个值, 因此C++编译器认定数组z的元素个数为9。显然,若要定义的数组大小比列举数组初值的个数大时,必须说明数组的大小。

4、当把数组定义为全局变量或静态变量时,C++编译器自动地将所有元素的初值置为0。当把数组定义为其它存储类型的局部变量时,数组的元素没有确定的初值,即其值是随机的。

例 6.2 输出数组为全局变量和局部变量时的初值。

#include

int x[5];

void main(void)

{

for (int i=0;i<5;i++)cout<

cout<<'\n';

int y[5];

for(i=0;i<5;i++) cout<

cout<<'\n';

}

执行这程序时,输出的第一行值为五个0,即数组x的各个元素的初值为0;输出第二行的值是随机值,即每次执行这程序时,输出的值可能是不同的,换言之,数组y的各个元素没有确定的初始值。

6.1.1.4 一维数组的应用举例

例 6.3 求出3至100之间的所有素数(质数),并要求每行输出五个素数。

求素数的方法有多种,其中的一种方法是:对于大于3的素数一定是奇数,为此先说明一个数组prim[49],各个元素的初值分别为:3,5,7,9,11,13,......,97,99。从第0个元素开始,其后的各个元素若是第0个元素的倍数,则该数不是素数,将其值置为0。再从第一个元素开始,其后的各个元素若是第1个元素的倍数,则将其值置为0。依次类推,直至从第47个元素开始,其后元素若是第47个元素的倍数,则将其值置为0。这时,数组prim中不为0的元素为素数。#include

void main(void)

{

int prime[49],j=3;

for (int i=0;i<49;i++){ //A

prime[i]=j;j+=2;

}

for (i=0;i<48;i++)

if (prime[i] ) //B

for (j=i+1;j<49;j++)

if ( prime[j] && prime[j] % prime[i] == 0 ) prime[j]=0; //C

j=0;

for(i=0;i<49;i++)

if(prime[i] ) { //D

cout<

j++;

if(j%5==0) cout<<'\n';

}

cout<<'\n';

cout<<"素数的个数为:"<

}

程序中的A行完成数组的赋初值。C行判断prime[j] 除以prime[i]的余数是否为0,若余数为0,表明prime[j]不是素数,则将prime[j]置为0。B行的判断是必要的,一方面,当prime[i]的值为0时,直接可以跳过内层的循环,从下一个元素开始判断;另一方面,若不作这样的判断,则在C行做求余运算时,会出现除数为0的情况。一旦出现除数为0,则中止程序的执行。D行中,若prime[i]不等于0,表明prime[i]是一个素数。

例 6.4 用选择排序的方法对输入的十个整数进行排序(从小到大)。

分析:排序分为升序和降序二种。升序是指排序后的数据按从小到大顺序的存放,而降序是指排序后的数据按从大到小的顺序存放。选择排序的思想是:首先找出最小的数放到第0个元素的位置。只要将第0个元素与第1个元素进行比较,若第0个元素大于第1个元素,则二个数进行交换;否则不要交换。再把第0个元素与第2个元素进行比较,若第0个元素大于第2个元素,则二数交换。依次类推,直到第0个元素与最后一个元素进行比较,若大于最后一个元素,则二数交换。这时,已使数组中最小的数放到第0个元素的位置。再从第1个元素开始,用同样的方法,找出次小的数放到第1个元素的位置。依此类推,直到把次大的数放入第8个元素位置。这时第9个元素(最后一个元素)已是最大数。排序到此结束。首先输入十个整数,对这十个整数进行排序,输出排序后的结果。程序为:

#include

void main (void )

{

int f[10],i,j,k ;

//输入十个整数

cout << "\nPlease input 10 data:\n";

for ( i = 0; i < 10 ; i++)

cin >> f[i];

//按升序排序

for ( i=0; i < 9 ; i++){

for ( j = i ; j < 10 ; j++) {

if ( f[i] > f[j] ) { //实现二个整数的交换

k = f[i]; f[i] = f[j]; f[j] = k;

}

}

}

cout << "\n";

//输出排序后数组的各个元素值

for ( i=0 ; i<10 ; i++)

cout << f[i] << " ";

}

6.1.2 多维数组

具有二个或二个以上下标的数组称为多维数组。下面以二维数组为例说明多维数组的定义及使用方法。

6.1.2.1 二维数组的定义

定义二维数组的一般格式为:

《存储类型》 <类型> <数组名>[<常量表达式1>][<常量表达式2>];其中存储类型、类型和数组名的含义与一维数组相同;常量表达式1的值定义了二维数组的行数,而常量表达式2的值定义了每一行中的列数。例如

int x[3][4];

float y[20][40];

定义了二个二维数组,数组x有3行,每一行有4个元素;数组y为20行,每一行有40个元素。若要定义数组a为3行且每行2列的实型数组,不能说明为:

float a[3,2];

在C++语言中, 二维数组可以看作是对一维数组的直接扩展,即把二维数组作为一种特殊的一维数组来定义的,它的每一个元素又是一个一维数组。如上面说明的数组x,可把它看作一维数组,它有三个元素x[0]、 x[1] 、x[2],每一个元素 x[i]又包含了四个元素的数组。因计算机存储器是一维的地址空间,二维数组在存储器中是按行从小到大的顺序依次来存放的;即先依次存放第零行中的元素(按列号从小到大的顺序存放),再存放第一行的所有元素,等等。二维数组的行下标和列下标均是从0开始的。在表6.1中给出了数组x的存放方式及行列下标间的对应关系。

表6.1 数组x的各个元素的存放顺序

x[0][0] x[0][1] x[0][2] x[0][3]

x[1][0] x[1][1] x[1][2] x[1][3]

x[2][0] x[2][1] x[2][2] x[2][3]

与定义一维数组一样,在定义二维数组的行数和列数时,只能是一个常量表达式,不能含有变量,并且其值只能是一个正整数。

在C++中,允许定义多维数组,对数组的维数没有限制。并且可由二维数组直接推广到三维、四维和更高维数组。如,定义三维数组:

int b[2][3][4];

在计算机存储器中存放的排列顺序为:最左边的下标变化最慢,而最右边的下标变化最快。三维数组b在计算机内存放顺序为:

b[0][0][0], b[0][0][1], b[0][0][2], b[0][0][3], b[0][1][0], b[0][1][1],b[0][1][2], b[0][1][3], b[0][2][0], b[0][2][1], b[0][2][2], b[0][2][3],b[1][0][0], b[1][0][1], b[1][0][2], b[1][0][3], b[1][1][0], b[1][1][1],b[1][1][2], b[1][1][3], b[1][2][0], b[1][2][1], b[1][2][2], b[1][2][3]6.1.2.2 多维数组的引用

我们以二维数组为例来说明如何引用多维数组中的元素。使用二维数组中的某一元素的一般格式为:

数组名[<下标表达式1>][<下标表达式2>]

其中二个下标表达式均为一般表达式,与一维数组一样可包含变量,但其值只能是一个整数,其值必须在该数组的定义范围之内。如:

x[2][3]=56;

表示将56赋给二维数组x的第二行第三列元素。多维数组的引用方法依此类推。6.1.2.3 多维数组的初始化

以二维数组为例来说明给多维数组元素进行初始化的方法。与一维数组类同,可对所有元素初始化,也可只对部分元素初始化。

1、以数组中的行为单位,依次给数组元素赋初值。如:

int a[3][4] = { { 1,2,3,4}, { 5,6,7,8}, {9,10,11,12}};

这种方法把第一个花括号内数据(1,2,3,4)依次赋给数组a的第零行的元素,即 a[0][0]=1,a[0][1]=2,a[0][2]=3,a[0][3]=4;把第二个花括号内数据依次赋给数组a的第一行的元素;......;将最后一个花括号内数据依次赋给数组a的最后一行的元素。

2、按数组元素的排列顺序,依次列出各个元素的值,并只用一个花括号括起来。如:

int y[3][4] = { 1,2,3,4,5,6,7 ,8,9,10,11,12};

使得 y[0][0]=1,y[0][1]=2,......,y[2][3]=12。尽管这种置初值的效果与第一种方法相同,但当数组比较大时,建议使用第一种方法。因为前一种方法是以行为单位,看起来一目了然。

3、只对部分元素赋初值,可有二种说明方式:一种是以行为单位,依次列出部分元素的值;另一种是以数组元素的排列顺序,依次列出前面部分元素的值。如:

int x[3][4] = { { 1,2}, {3}, {4,5,6}};

没有明确列举元素值的元素,其值均为0,即等同于:

int x[3][4] = { { 1,2,0,0}, {3,0,0,0}, {4,5 ,6,0}};又如:

int xx[3][4] = { 1,2,3};

使得xx[0][0] =1,xx[0][1] =2,xx[0][2] =3,其余的各个元素的初值为0。

4、根据给定的初始化的数据,自动确定数组的行数。如:

float b[ ][4] = {{1,2,3},{4,5,6},{10,11,12,14}};这里定义数组b为三行四列的数组。又如:

int aa[ ][3]={1,2,3,4,5};

定义数组aa为二行三列的数组。说明数组b的方式比说明数组aa的方式好,对应的关系清楚。注意,只能省略行数,不能省略列数,理由是明显的,若省略列数,则行列之间的关系不唯一。

与一维数组类同,当说明为静态的多维数组或全局变量的多维数组时,系统自动地将数组的各个元素的初值置为0。同类型的同维数组之间也不能直接相互赋值。要将一个数组赋给另一个数组时,必须逐个元素赋值。如,设数组定义:

int a[5][3],b[5][3];

要将数组a中的各个元素依次赋给数组b时,要用如下形式的循环语句来实现:

for ( int i=0; i< 5;i ++)

for(int j=0;j<3;j++) b[i][j]=a[i][j];

6.1.2.4 二维数组程序举例

例 6.5 输入一个3行4列的二维数组,求出数组元素中的最大值和最小值,以及最大值元素和最小值元素所在的行号和列号。

程序设计思想:首先将数据输入数组a的各个元素中,并把a[0][0]作为最大值max和最小值min,将max依次和数组中各个元素比较,若某个元素值大于max,则将该元素值赋给max。与数组中的所有元素比较完后,max中值是最大值。最小值的求法类同。

#include

void main (void )

{

int i,j,rmax,rmin,cmax,cmin , min, max ;

int a[3][4];

cout<<"输入三行四列的二维数组:";

for(i=0;i<3;i++) //将数据输入数组a中

for(j=0;j<4;j++)

cin>>a[i][j];

min= max = a[0][0]; //将0行0列的元素作为最大和最小值rmax=rmin=cmax=cmin=0; //记录最大和最小值所在的行列号

for ( i = 0 ; i<3; i++)

for ( j = 0 ; j < 4 ; j++) {

if ( a[i][j] > max ) max = a[i][j], rmax = i, cmax = j ; //A

if ( a[i][j] < min ) {min = a[i][j];rmin = i;cmin = j ; } //B

}

cout << "最大值=" << max << '\t'

cout <<" 所在的行号列号为:( " <

cout << "最小值=" << min << '\t'

cout <<" 所在的行号列号为:( " <

}

注意程序中A行与B行之间的不同,A行中三个赋值表达式只构成一个逗号表达式语句,所以不要用花括号括起来;B行是用三个赋值表达式语句来实现的,必须用花括号括起来构成一个复合语句。max和min的初值可以取数组中的任一个元素值,而不能取其它值。

例 6.6 将一个4行4列的二维数组中行和列元素互换(数学上称为矩阵的转置),并存放到另一个数组中。如:

⎡11,12,13,14 ⎤ ⎡11,15,19,23 ⎤

⎢15,16,17,18 ⎥ ⎢12,16,20,24⎥

a = ⎢ ⎥ b= ⎢ ⎥

⎢19,20,21,22⎥ ⎢13,17,21,25⎥

⎢23,24,25,26⎥ ⎢14,18,22,26⎥

⎣ ⎦ ⎣ ⎦

将数组a的行列互换后,存入数组b中。程序为:

#include

void main (void )

{

int a[4][4]={{11,12,13,14},{15,16,17,18},{19,20,21,22},

{23,24,25,26}};

int b[4][4],i,j;

cout<<"数组a:\n";

for( i=0;i<4;i++){

for( j=0;j<4;j++) cout<

cout<<'\n';

}

for( i=0;i<4;i++)

for(j=0;j<4;j++) b[j][i]=a[i][j];

cout<<"b数组:\n";

for(i=0;i<4;i++){

for(j=0;j<4;j++)cout<

cout<<'\n';

}

}

执行程序后的输出为:

数组a:

11 12 13 14

15 16 17 18

19 20 21 22

23 24 25 26

b数组:

11 15 19 23

12 16 20 24

13 17 21 25

14 18 22 26

若直接将数组a中的行列互换,显然只要将主对角线上的上、下三角形的行列元素互换即可,程序为:

#include

void main (void )

{

int a[4][4]={{11,12,13,14},{15,16,17,18},{19,20,21,22},

{23,24,25,26}};

int t,i,j;

cout<<"数组a:\n";

for( i=0;i<4;i++){

for( j=0;j<4;j++) cout<

cout<<'\n';

}

for( i=0;i<4;i++)

for(j=i;j<4;j++) { //A

t= a[i][j]; a[i][j]=a[j][i];a[j][i]=t;

}

cout<<"转置后数组a:\n";

for(i=0;i<4;i++){

for(j=0;j<4;j++)cout<

cout<<'\n';

}

}

因只要把主对角线上的上、下三角形元素进行交换,A行中j的初值不是0,而是i。

6.1.3 数组与函数

在定义函数时,形参可以是数组。在函数调用时,可以把数组的一个元素作为函数的实参,也可以把整个数组作为函数的实参。

1、数组元素作为函数的参数

因实参数可以是表达式,所以,数组元素当然可以作为函数的实参,并将该元素的值传递给函数。

2、数组名作为函数的实参

当形式参数定义为数组时,对应的实参可以是数组名。数组名作为实参时,可以将数组所有元素的值传递给函数,也可以将数组元素的值带回来。换言之,整个数组可作为输入参数,也可作为输出参数。

例6.7 输入一个数组,按升序排序后输出。要求用一个函数实现数组的排序。采用例6.4中介绍的选择排序的方法进行排序。程序为:

#include

void sort(int a[10]) //说明形参a为包含10个元素的数组

{

int t,i,j;

for(i=0;i<9;i++)

for(j=i+1;j<10;j++)

if(a[i]>a[j]){ //实现二数交换

t=a[i];a[i]=a[j];a[j]=t;

}

}

void main (void )

{

int b[10],i;

cout<<"输入10个整数:\n";

for( i=0;i<10;i++) cin>>b[i];

sort(b); //A

cout<<"排序后的结果为:\n";

for( i=0;i<10;i++) cout<

cout<<'\n';

}

本例中,形参中定义的数组与实参中给出的数组是相同大小的,这二个数组的大小也可以不一致,为保证程序能正确执行,要求形参数组的大小应小于或等于实参数组的大小。否则,程序能执行,但结果可能不正确。

数组作为函数参数的另一种方法是,在定义函数时,仅指明形参是数组,但不指定数组的大小。再用一个形参说明数组的大小。在函数调用时,一个实参为数组名,另一个实参指明数组的实际大小。如上例中的排序函数 sort()可改写为:

void sort(int a[ ],int n) //说明形参a为数组,n为数组的大小{

int t,i,j;

for(i=0;i

for(j=i+1;j

if(a[i]>a[j]){ //实现二数交换

t=a[i];a[i]=a[j];a[j]=t;

}

}

程序中的A行也要修改为:

sort(b,10);

函数 sort()经这样改写后,成为一个通用的一维数组的排序程序。如说明数组x的大小为100个元素时:

int x[100];

调用函数sort()对数组x排序时,调用形式为:

sort(x,100);

二维数组用作函数的参数时,其用法与一维数组的用法类同,在函数定义时,可以明确指定二维数组的行数和列数,也可以不指定行数,但必须指定二维数组和列数。如函数定义:

void fun1(float a[20][30])

{

...... //函数体

}

调用这函数的时,其实参应该是20行30列的任一数组。如说明:

float x[20][30],y[20][30];

......

fun1(x);

......

fun1(y);

......

*例 6.8 输入一个二维数组(3行4列),排序后输出各个元素,并求出平均值。要求用函数实现数组的排序和求平均值。

程序设计思想:用一个函数input()实现数据的输入;用函数sort()实现数据的排序;用函数ave()求平均值,并返回平均值。

#include

void input(float a[3][4])

{

int i,j;

cout<<"输入3行4 列的二维数组:\n";

for(i=0;i<3;i++)

for(j=0;j<4;j++) cin>>a[i][j];

}

void sort(float b[ ][4],int n)

{

int i,j,k,m, col,row, flag;

float temp;

for(i=0;i

for(j=0;j<4;j++){

row=i; col= j; flag=j+1; //A

for(k=i;k

for(m=flag;m<4;m++) //B

if(b[row][col] > b[k][m]) row=k,col=m; //C

flag=0; //D

}

temp=b[i][j]; //E

b[i][j]=b[row][col]; //F

b[row][col]=temp; //G

}

}

float ave(float c[][4],int num)

{

float sum=0;

for(int i=0;i

for(int j=0;j<4;j++) sum+=c[i][j];

sum /= num * 4;

return sum;

}

void main (void )

{

float x[3][4];

input(x);

sort(x,3); //H

cout<<"排序后的结果为:\n";

for( int i=0;i<3;i++) {

for(int j=0;j<4;j++) cout<

cout<<'\n';

}

cout<<"平均值为:"<

}

执行程序时,输入的数据为:

23 45 67 89

2 34 66 100

1 65 33 21

输出排序后的数据为:

1 2 21 23

33 34 45 65

66 67 89 100

平均值为:45.5

函数input()和ave()比较简单,不再作说明,下面对函数sort()作进一步的说明。二维数组的排序要比一维数组的排序复杂一些,程序中的A行记住b[i][j]的下标值。当b[i][j]与其后的各个元素比较时,要分二种情况:第一种情况是与第i行上的元素比较时,可以从第j+1个元素开始,为此把j+1赋给flag,并作为内层循环变量m的初值;第二种情况是与第i+1或i+2行上的元素比较时,必须从第i+1或i+2行上的第0列元素开始,即要将内层循环变量m的初值置为0,因此在第一次由m控制的循环结束时,将0赋给flag(参见D行)。B行保证在k的值与i的值相同时,m的初值置为j+1;而当k取其它值时,m的初值置为0。C行的作用是记住自b[i][j]后,最小值的下标。E、F、G行自b[i][j]后的最小值与b[i][j]交换。

由于二维数组中的元素是按行的顺序依次存放的,所以,可以把二维数组作为一维数组来排序。也可用以下的函数sort1()来代替例中的函数sort():void sort1(float a[],int m)

{

int i,j;

float t;

for(i=0;i

for(j=i+1;j

if(a[i] > a[j]){

t=a[i]; a[i]=a[j];

a[j]=t;

}

}

主函数中的H行用下面的行来代替:

sort1((float *)x,3*4);

其中对x作的强制类型转换是必要的,其含义到指针这一章中说明,第二个参数为二维数组的元素个数。比较这二个排序函数,显然,后一排序函数比前一函数要简单得多。当然也可把多维数组转换为一维数组来排序。

类同地,三维或更多维数组作为函数的形参数时,仅允许最高维不说明其大小,其余维必须指定其大小。如三维数组作为函数的参数:

void aaa(float x[][15][20],int num)

{

...... //函数体定义

}

三维数组x的第一维的大小由参数num指定,第二维的大小为15,第三维的大小为20。