(30)'c++:COMPLETE REFERENCE' 第一部分 第四章(数组和以空字符结束的字符串) 第五节

来源:互联网 发布:clean my mac 破解版 编辑:程序博客网 时间:2024/05/14 19:46

二维数组

      C/C++支持多维数组,其中最简单的多维数组就是二维数组.二维数组本质上是一个由多个一位数组组成的数组.例如,要定义一个整型二维数组,大小为10和20,名字为d,我们应该这样书写:

int d[10][20];

      注意看二维数组的声明,有些其它语言用逗号将两个维格开.C/C++则用两个独立的方括号.类似于一维数组,要访问点1,2上的元素,应该这样写:

d[1][2]

下面的例子把1到12都装入数组:

#include <stdio.h>

int main( void )
{
    int t, i, num[3][4];

    for( t=0; t<3; t++ )
        for( i=0; i<4; i++ )
            num[t][i] = t*4 + i + 1;

    /* now print them out */
    for( t=0; t<3; t++ ){
        for( i=0; i<4; i++ )
            printf( "%d", num[t][i] );
        printf( "/n" );
    }

    return 0;
}

在这个例子中,num[0][0]被赋值为1,num[0][1]为2,依次类推,num[2][3]为12.可以把数组形象的相成这样:

(图略)

      二维数组被存储在一个行列矩阵中,前面的索引表示行号,后面的那个表示列号.也就是意味着当用右边的索引访问数组的元素的时候,地址的位移会比左边的大.下面的公式可以计算二位数组的字节长度:

bytes = size of 1st index * size of 2nd index *sizeof( base type )

      因此,假设整型长度为4个byte,一个10*5的二维数组的内存字节数为: 10*5*4 = 200 bytes.
      当二维数组被做为参数传递给函数的时候,传递的仅仅是二位数组的首个元素的地址.而在定义形式参数的时候,至少右边的索引大小必须定义.

      编译器必须知道数组的行的尺寸,才能正确的索引整个二维数组,其中道理显而易见..例如:

void func1( int x[][10] )
{
    .
    .
    .
}

      编译器之所以要知道二位数组的行的长度,是为了能正确的运行如 x[2][4] 这样的表达式,如果编译器不知道行的长度,那么就无法知道第三行是从什么地址开始.
      下面的程序用二维数组来存储某个老师的3个班级里的每一个学生的年级数.假定老师有三个班级,每个班级最多有30个学生.

/* A simple student grades database. */
#include <srdio.h>
#include <ctype.h>
#include <stdlib.h>

#define CLASSES 3
#define GRADES 30

int grade[CLASSES][GRADES];

void enter_grades( void );
int get_grade( int num );
void disp_grades( int g[][GRADES] );

int main( void )
{
    char ch, str[80];

    for( ; ; ){
        do{
            printf( "(E)nter grades/n" );
            printf( "(R)eport grades/n" );
            printf( "(Q)uit/n" );
            gets( str );
            ch = toupper( *str );
        }while( ch!='E' && ch!='R' && ch!='Q' );

        switch( ch ){
            case 'E':
                enter_grades();
                break;
            case 'R':
                disp_grades();
                break;
            case 'Q':
                exit( 0 );
        }
    }

    return 0;
}

/* Enter the student's grades. */
void enter_grades( void )
{
    int t, i;

    for( t=0; t<CLASSES; t++ ){
        printf( "Class # %d:/n", t+1 );
        for( i=0; i<GRADES; i++ )
            grade[t][i] = get_grade(i);
    }
}

/* Read a grade. */
int get_grade( int num )
{
    char s[80];

    printf( "Enter grade for student # %d:/n", num+1 );
    gets( s );
    return( atoi(s) );
}

/* Display grades. */
void disp_grades( int g[][GRADES] )
{
    int t, i;

    for( t=0; t<CLASSES; t++ ){
        printf( Class # %d:/n", t+1 );
        for( i=0; i<GRADES; i++ )
            printf( "Student # %d is %d/n", i+1, g[t][i] );
    }
}

字符串数组

      在编程中使用字符串数组再平常不过了.例如,再数据库的输入处理程序中经常就需要用一个现成的字符串命令的数组来校验用户输入的命令.用空字符结尾的字符串组成一个二维数组.左边的索引值决定了这种字符串的数量,而右边的索引则确定了字符串的最大长度.下面的例子中声明了一个可以存储30个字符串的二位数组,每个字符串的最大长度是79在加上一个空结束符.

char str_array[30][80];

要访问其中的单个字符串非常容易,只需要指定左边的索引.例如:

gets( str_array[2] );

这个句子访问了字符串数组的第三个字符串.它等价于:

gets( &str_array[2][0] );

当然,第一种写法会比较专业一些.

      为了进一步理解数组的用法,我们来学习下面的程序,这是一个以数组为基础的文本编辑程序:

/* A very simple text editor */
#include <stdio.h>

#define MAX 100
#define LEN 80

char text[MAX][LEN];

int main( void )
{
    register int t, i, j;

    printf( "Enter an empty line to quit./n" );

    for( t=0; t<MAX; t++ ){
        printf( "%d:", t );
        gets( text[t] );
        if( !text[t] ) break;  /* quit on blank line */
    }

    for( i=0; i<t; i++ ){
        for( j=0; text[i][j]; j++ ) putchar( text[i][j] );
        putchar( '/n' );
    }

    return 0;
}

这个程序让用户一行一行的输入字符串,知道用户输入空白行为止.然后一次性将它们都显示出来.