第10章 数组和指针(2 多维数组)

发布于 2021-08-31  420 次阅读


10.2 多维数组

当要存储的数据量巨大时,可以使用数组的数组。
主数组(master array)有5个元素(每个元素表示一年),每个元素是内含12个元素的数组(每个元素表示一个月)。
数组声明:
float rain[5][12];  //内含5个数组元素的数组,每个数组元素内含12个float类型的元素

file

该二维图帮助读者理解二维数组下标。
在计算机内部,这样的数组是按顺序存储的,从第一个内含12个元素的数组开始,然后是第二个内含12个元素的数组。
我们要在气象分析程序中用到这个二维数组。
该程序的目标是,计算每年的总降水量、年平均降水量和月平均降水量
//rain      --多维数组在气象局的应用
#include<stdio.h>
#define YEAR 5
#define MONTHS 12
int main(void) 
{
    const float rain[YEAR][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}
    };
    float sum_month_rain=0,year_rain=0,sum_rain=0;
    int i,j;
    for(i=0;i<YEAR;i++)
        for(j=0;j<MONTHS;j++)
        {
            sum_rain = sum_rain+rain[i][j];
        }
    printf("sum_rain = %.2f\n",sum_rain);
    printf("year_rain = %.2f\n",year_rain = sum_rain/5.0);
    for(j=0;j<MONTHS;j++)
    {
            for(i=0;i<YEAR;i++)
            {
            sum_month_rain = sum_month_rain+rain[i][j];
            }
    printf("%dmonth_rain = %.2f\n",j+1,sum_month_rain/5.0);
    }
    return 0;

}

file

程序使用了两个嵌套的for循环。第1个嵌套for循环的内层循环,在year不变的情况下,遍历month计算某年的总降水量;而外层循环,改变year的值,重复遍历month,计算5年的总降水量。这种嵌套循环结构常用于处理二维数组,一个循环处理数组的第一个下标,另一个循环处理数组的第二个下标:
for(year = 0,total - 0;year<YEAR;year++)
{//处理每一年的数据
    for(month = 0,subtal = 0;month<MONTHS;month++)
    ..//处理每月的数据
    ..//处理每年的数据
}
第二个嵌套for循环和第一个结构相同,但内层循环遍历year,外层循环遍历month。每执行
一次外层循环,就完整遍历一次内层循环。因此再改变月份之前先遍历完年。
for(month=0;month<MONTHS;month++)
{//处理每月的数据
    for(year=0,subtot=0;year<YEAR;YEAR++)
    ...//处理每年的数据
    。。//处理每月的数据
}

10.2.1 初始化二维数组

初始化二维数组是建立再初始化一维数组的基础上。
一维数组的初始化:
sometype arl[5] = {val1,val2,val3,val4,val5};
这里,val1.。等表示sometype类型的值。
二维数组的初始化如上代码所示
const float rain[YEAR][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}
    };
这个初始化使用了5个数值列表,每个数值列表都用花括号括起来。第一个列表的数据用于初始化数组的第一行,第2个列表的数据用于初始化数组的第2行,以此类推。
前面讨论的数据个数和数组大小不匹配的问题同样适用于这里的每一行。也就是,如果第1个列表中只有10个数,则只会初始化数组的第1行的前十个元素,而最后两个元素将被默认初始化为0.
如果某列表中的数值个数超出了数组每行的元素个数,则会出错,但是这并不会影响其他行的初始化。
初始化也可省略内部的花括号,只保留最外面的一堆花括号。只要保证初始化的数值个数正确,初始化的效果与上面相同。
但是!如果初始化数值不够。则按照现后顺序逐行进行初始化,直到用完所有的值。后面没有值初始化的元素被统一初始化为0.

file

因为存储在数组rain中的数据不可修改,所以使用了const关键字声明该数组。

10.2.2 其他多为数组

前面讨论的二维数组的相关内容都适用于三维数组或者更多维数组
int box[10][20][30];
可以把一维数组想象成一行数据,把二维数组想象成数据表,把三维数组想象成一叠数据表。
例如:上述三维数组可以想象成10个二维数组(每个都是20行30列)堆叠起来的。
还有一种理解box方法:把box看作数组的数组,也就是说,box含有10个元素,每个元素是含20个元素的数组,这20个数组元素中的每个元素是内含30个元素的数组。
处理三维数组要使用3重嵌套循环,处理四维数组要使用4重嵌套循环。以此类推。

擦肩而过的概率