二维数组
5.2.1 二维数组的一般形式 C语言允许使用多维数组,最简单的多维数组是二维数组。实际上,二维数组是以一维数组为元素构成的数组,要将d说明成大小为(1 0,2 0)的二维整型数组,可以写成: int d[10][20] 请留心上面的说明语句, C不像其它大多数计算机语言那样使用逗号区分下标,而是用方 括号将各维下标括起,并且,数组的二维下标均从0计算。 与此相似,要存取数组d中下标为( 3,5)的元素可以写成: d [ 3 ] [ 5 ] 在例5 - 3中,整数1到1 2被装入一个二维数组。 [例5 - 3 ] main ( ) { int t,i,n u m [ 3 ] [ 4 ] for (t=0; t<3; ++t) for (i=0;i<4;++i) n u m [ t ] [ i ] = ( t * 4 ) + i + 1 ; } 在此例中, n u m [ 0 ] [ 0 ]的值为1,n u m [ 0 ] [ 2 ]的值为3, . . . . . .,n u m [ 2 ] [ 3 ]的值为1 2。可以将 该数组想象为如下表格: 二维数组以行―列矩阵的形式存储。第一个下标代表行,第二个下标代表列,这意味着 按照在内存中的实际存储顺序访问数组元素时,右边的下标比左边的下标的变化快一些。图 5 - 2是一个二维数组在内存中的情形,实际上,第一下标可以认为是行的指针。 记住,一旦数组被证明,所有的数组元素都将分配相应的存储空间。对于二维数组可用 下列公式计算所需的内存字节数: 行数×列数×类型字节数=总字节数 因而,假定为双字节整型,大小为( 1 0,5)的整型数组将需要:1 0×5×2=100 字节 当二维数组用作函数的参数时,实际上传递的是第一个元素(如[ 0 ] [ 0 ])的指针。不过该 函数至少得定义第二维的长度,这是因为C编译程序若要使得对数组的检索正确无误,就需要 知道每一行的长度。例如,将要接收大小为( 1 0,1 0)的二维数组的函数,可以说明如下: func1 (x) int x[ ][10] { . . . } 第一维的长度也可指明,但没有必要。 C编译程序对函数中的如下语句: X [ 2 ] [ 4 ] 处理时,需要知道二维的长度。若行长度没定义,那么它就不可能知道第三行从哪儿开 始。 [例5-4] 用一个二维数组存放某一教师任教的各班学生的分数。假定教师有三个班,每班 最多有三十名学生。注意各函数存取数组的方法。 #define classes 3 #define grades 30 #include <stdio.h> main( ) { void enter_grades(); void disp_grades( ); int get_grade( ); int a[classes] [grades];定/*义二维数组,每行存放一个班学生成绩*/ char ch; for( ; ;) { do { /*菜单显示* / printf("(E)nter grades/n"); printf("(R)eport grades/n"); p r i n t f ( " ( Q ) u i t / n " ) ; ch=toupper(getchar()); /将*键盘输入字符转换为大写*/ } while(ch!='E' && ch!='R' && ch!='Q'); switch(ch) { case 'E': enter_grades( ); b r e a k ; case 'R': d i s p _ g r a d e s ( g r a d e ) ; b r e a k ; case 'Q': e x i t ( 0 ) ; } } } void enter_grades(a) int a[][grades]; { int t, i; for (t=0;t<classes;t++) { printf (" class #%d:/n",t+1); for (i=0; i<grades; i++) a [ t ] [ i ] = g e t _ g r a d e ( i ) ; } } int get_grades(num) int num; { char s[80]; printf("enter grade for student # %d:,/nn"u m + 1 ) ; g e t s ( s ) ;/ *输入成绩* / r e t u r n ( a t o i ( s ) ) ; } void disp_grades(g) /*显示学生成绩* / int g[ ][grades]; { int t,i ; for(t=0; t<classes; ++t) { printf("class # %d:/n,"t+ 1 ) ; f o r ( i = 0 ; i < g r a d e s ; + + i ) printf("grade for student #%d is %d/,ni"+ 1 ,g[ t ] [ i ] ) ; } } 我们将实际问题简化为共有2个班,每班两个学生,即将程序中的常量定义修改如下: #define classes 2 #define grades 2 运行程序: R U N (E)nter grades (R)eport grades ( Q ) u i t : e class #1: enter grade for student #17:8 enter grade for student #289: ¿ class #2 enter grade for student #19:8 ¿ enter grade for student #29:0 ¿ (E)nter grades (R)eport grades ( Q ) u i t : r¿ class #1 grade for student #1 is 78 grade for student #2 is 89 class #2 grade for student #1 is 98 grade for student #2 is 90 (E)nter grades (R)eport grades (Q)uit :q 运行程序,我们首先看到一个菜单,选择“ e”输入成绩,选择“ r”显示成绩,选择“q” 退出。a t o i ( )函数用于将实参字符串转换为整型。 5.2.2 字符串数组 程序设计中经常要用到字符串数组。例如,数据库的输入处理程序就要将用户输入的命 令与存在字符串数组中的有效命令相比较,检验其有效性。可用二维字符数组的形式建立字 符串数组,左下标决定字符串的个数,右下标说明串的最大长度。例如,下面的语句定义了 一个字符串数组,它可存放3 0个字符串,串的最大长度为8 0个字符: char str_array[30][80]; 要访问单独的字符串是很容易的,只需标明左下标就可以了。例如,下面的语句以数组 s t r _ a r r a y中的第三个字符串为参数调用函数gets( )。 g e t s ( s t r _ a r r a y [ 2 ] ) ; 该语句在功能上等价于: g e t s ( & s t r _ a r r a y [ 2 ] [ 0 ] ) ; 但第一种形式在专业程序员编制的C语言程序中更为常见。 为帮助理解字符串数组的用法,研究例5 - 5。它以一个字符串数组为基础做简单的文本编辑。 [例5 - 5 ] #include <s t d i o . h > #define MAX 100 #define LEN 80 char text [MAX][LEN] /* 一个非常简单的文本编辑器* / main( ) { register int t,i,j ; for(t=0;t<MAX; t++) /*逐行输入字符串* / { p r i n t f ( " % d : " ,t ) ; g e t s ( t e x t [ t ] ) ; if(! text[t][0]) break; /* 空行退出*/ } f o r ( i = 0 ; i < t ,i++) /*按行,逐个字符输出字符串* / { for(j=0; text [i][j];j++) putchar(text [i][j]); putchar( '/n'); } } 该程序输入文本行直至遇到一个空行为止,而后每次一个字符地重新显示各行。
|