文档章节

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

idreamo
 idreamo
发布于 2016/07/23 07:25
字数 1722
阅读 36
收藏 0

例如,气象员要分析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重嵌套循环,对于其他多维数组,依此类推。

© 著作权归作者所有

idreamo
粉丝 18
博文 139
码字总数 224743
作品 0
青岛
产品经理
私信 提问
C Primer Plus 第10章 数组和指针 10.7 指针和多维数组

指针和多维数组有什么关系?为什么我们需要知道它们之间的关系?函数是通过指针来处理多维数组的,因此在使用这样的函数之前,您需要更多的了解指针。假设有如下的声明: int zippo[4][2] ; ...

idreamo
2016/08/06
71
0
C++ Primer 学习笔记(第三章:字符串、向量和数组)

C++ Primer 学习笔记(第三章:字符串、向量和数组) [TOC] 3.1 命名空间的声明 声明语句可以一行放多条。 位于头文件的代码,一般来说不应该使用声明。因为其内容会拷贝到每个使用该头文件的...

ShawnLue
2015/08/20
152
0
C Primer Plus 第10章 数组和指针 10.9 复合文字

假设需要向带有一个int参量的函数传递一个值,您可以传递一个Int变量,也可以传递一个int常量,比如5。在C99标准出现之前,数组参数的情况是不同的:可以传递数组,但没有所谓的数组常量可供...

idreamo
2016/08/09
39
0
C Primer Plus (第六版) 中文版 随手笔记(九)

版权声明: https://blog.csdn.net/qq_38351824/article/details/80102638 声明:本篇文章只是个人知识盲区、知识弱点、重点部分的归纳总结,望各位大佬不喜勿喷。梳理顺序是按照书籍的实际顺...

sumjess
2018/04/27
0
0
指针——C语言的灵魂

为什么说C指针是C语言的灵魂? 来自读者对C和指针的解说 他可以直接访问硬件,这是灵活性和效率的体现,程序离硬件越近自然效率越高,当然运用不当也可导致效率低下 难掌握及太危险,如果对指...

生气的散人
2013/03/25
1K
5

没有更多内容

加载失败,请刷新页面

加载更多

Flink Graph生成及Hash生成分析

222

MrPei
7分钟前
1
0
[译]Android Activity 和 Fragment 状态保存与恢复的最佳实践

https://blog.csdn.net/growing_tree/article/details/53759564 https://blog.csdn.net/u013588712/article/details/54691791...

shzwork
7分钟前
1
0
调用第三方快递鸟物流单号查询接口API代码示例

最近进行网站后台开发,需要实现物流的即时查询,发现之前集成的 快递100物流查询 API ——【PHP 快递查询源码资源】 已经不能正常使用了; 为了方便以后的业务需求,经过比较,最后选择使用...

程序的小猿
15分钟前
2
0
java Poi 操作执行excel 文件中函数问题

poi 读取excel 文件,当excel 有函数时,poi直接读取返回的是excel 函数,并不能返回函数计算结果: 解决步骤: sheet.setForceFormulaRecalculation(true); 判断该列格式是否为...

早a
22分钟前
3
0
js模拟实现输入框input事件

直接修改value值是无法触发对应元素的事件的。 通过发送输入框input事件了, 可以触发。 这里简单封装了一个方法. window.inputValue = function (dom, st) { var evt = new InputEvent('i...

開援带碼
23分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部