C Primer Plus 第10章 数组和指针 10.2 多维数组

例如,气象员要分析5年中每月的降水量数据,首先需要解决的问题是如何表示这些数据。可以使用60个变量。或者使用一个60个元素的数组,或者使用5个数组,每个数组12个元素。这些方法都比较笨拙,而且如果要处理的数据是50年,这些方法就很不合适。我们需要找到一种更好的方法。

更好的处理方法是使用一个数组的数组,即:主数组包含5个元素,每个元素代表一年。代表一年的元素是包含12个元素的数组。这种数组的数组,我们称之为二维数组。下面是这种数组的声明方法:

float rain [5][12];  //5个由12个浮点数组成 的数组 的数组

理解这个声明的一种方法是首先查看位于中间的那部分:

float rain[5][12];  //rain是一个包含5个元素的数组

这部分说明rain是一个包含5个元素的数组。至于每个元素的情况,需要查看声明的其余部分。

float rain[5][12];  //12个浮点数的数组

这说明每个元素的类型是float [12];也就是说,rain具有5个元素,并且每一个元素都是包含12个float数值的数组。

按此类推,rain的首元素rain[0]是一个包含12个float数值的数组。rain[1],rain[2]等待也是如此。rain[0]是数组,那么它的首元素是rain[0][0],第二个元素是rain[0][1],依此类推其他元素。简单地说,rain是一个包含5个元素(每个元素又是包含12个float数的数组)的数组,rain[0]是一个包含12个float数的数组,rain[0][0]是一个float数。

也可以把rain数组看作是一个二维数组,它包含5行,每行12个列。改变第二个下标,可以沿着一行移动,每移动一个单位代表一个月份。改变第一个下标,可以沿着一列垂直移动,每移动一个单位代表一年。

用二维视图表示数组便于我们直观地想象具有两个索引的数组。实际上,数组是顺序存储的,前12个元素之后,跟着就是第二个包含12个元素的数组,依次类推

我们将在气象分析程序中使用这个二维数组,程序的目的是计算年降水总量,年降水平均量和月降水平均量。

程序清单10.7  rain.c程序

/*rain.c --针对若干年的降水量数据,计算年降水问题、年降水平均量、以及月降水平均量*/

#include <stdio.h>
#define MONTHS 12
#define YEARS 5
int main (void)
{
    //把数组初始化为2000年到2004年的降水量数据
    const float rain[YEARS][MONTHS] = {
        {4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},
        {8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3},
        {9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4},
        {7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2},
        {7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2}
        };
    int year,month;
    float subtot,total;

    printf(" YEAR  RAINFALL (inches) \n");
    for (year = 0,total = 0;year<YEARS;year++)
    {                  //对于每一年各月的总降水量
        for(month=0,subtot=0;month<MONTHS;month++)
            subtot+=rain[year][month];
        printf("%5d %15.lf\n",2000+year,subtot);
        total+=subtot;  //所有年度的总降水量
    }
    printf("\nThe yearly average is %.1f inches.\n\n",total/YEARS);
    printf("MONTHLY AVERAGES: \n\n");
    printf("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec\n");

    for (month=0;month<MONTHS;month++)
    {        //对于每个月,各年该月份的总降水量
        for(year=0,subtot=0;year<YEARS;year++)
            subtot+=rain[year][month];
        printf("%4.1f",subtot/YEARS);
        }
    printf("\n");
    return 0;

}

研究此程序时,请注意数组的初始化方法和计算方案。而数组的初始化是其中较复杂 的部分,我们先来研究相对简单的部分(计算)。

要计算某年度的降水总量,则保持year为常量,让month遍历整个范围,这正是程序的第一部分的内部for循环的作用。程序第一部分外部循环的目的则是让变量year在值域(5年)内遍历。像这样的嵌套循环结构在处理二维数组时是比较方便的。利用一个循环处理第一个下标,利用另一个循环处理第二个下标。

程序第二部分的结构和第一部分相同,但year被改变为内部循环,而month被改变为外部循环。注意,外部循环每执行一次,内部循环完整遍历一次。因此,在月份改变之前,年度先遍历。先得到的是5年中一月份的降水平均量,然后依次类推。

10.2.1  初始化二维数组

对二维数组的初始化是建立在对一维数组的初始化之上的。

前面讨论的数据个数和数组大小不匹配的问题同样适用二维数组。也就是说,如果第一个列表 中有10个数值,则第一行只有前10个元素得到赋值,最后两个元素被默认初始化为0。如果列表中的数值多于12个,则报告错误;而且这些数值不会影响到下一行的赋值。

初始化的时候可以省略内部的花括号,只保留一对外部的花括号。只要保证数值的个数正确,初始的效果就是一样的。如果数值的个数不够,那么在数组初始化的时候,按照先后顺序来逐行赋值,因此前面的元素首先得到赋值,直到没有数值为止。后面没有赋值的元素被初始化为0。

10.2.2  更多维数的数组

前面关于二维数组的讨论对于三维乃至更多维数组同样适用。可以用下面的方式声明三维数组:

int box[10][20][30];

可以这样直观地理解,一维数组是排成一行的数据,二维数组是放在一个平面上的数据,三维数组是把平面数据一层一层垒起来。例如,可以把上面定义的数组 box直观想象为数据构成的方块:由10个二维数组(每个二维数组都是20行30列)堆放起来构成的立方体。

另一种理解box的方法认为它是数组的数组的数组。即box是包含10个元素的数组,其中每个元素又是包含20个元素的数组,这20个元素中的每一个又是包含30个元素的数组。或者可以简单地按照所需的索引数目去理解数组。

通常处理三维数组需要3重嵌套循环,处理四维数组需要4重嵌套循环,对于其他多维数组,依此类推。

转载于:https://my.oschina.net/idreamo/blog/716539

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值