我们知道,一维空间是一条线,数学中用一条数轴来表达;二维空间是一个平面,数学中用平面坐标系来表达。那么二维数组又是什么样的呢?

线与面

我们用一个下标来描述一维数组中的某个元素,就好像在用数描述一条线上的点。而所有的数据都是存储在一条线上。如果我们采用两个下标,就能形成一个平面,犹如一张表格,有行有列,所有的数据就能够存放到表格里。

我们把二维数组的两个下标分别称为行下标和列下标,在前面的是行下标,在后面的是列下标。

那么什么时候要用二维数组呢?一般有两种情况,一种是描述一个二维的事物。比如用1表示墙,用0表示通路,我们可以用二维数组来描述一个迷宫地图;用1表示有通路,0表示没有通路,我们可以用二维数组来描述几个城市之间的交通情况。还有一种是描述多个具有多项属性的事物。比如有多个学生,每个学生有语文、数学和英语三门成绩,我们就可以用二维数组来描述。

对于第二种情况,我们要注意各项属性应该是同一种数据类型,比如三种学科的成绩都是整数。如果出现了姓名(字符串属性),就不能将他们组合到一个二维数组里去。所以不要企图将不同数据类型的属性整合到一个二维数组中去。

二维数组的声明和初始化

二维数组的声明和一维数组是类似的,不同之处只是多了一个下标:
    数据类型数组名[行数][列数];

要注意,二维数组的下标也都是从0开始的。

二维数组的初始化分为两种,一种是顺序初始化,一种是按行初始化,我们来看一段程序,就能够对它们有所了解了:(程序7.4.1)
#include "iostream.h"
#include "iomanip.h"
int main()
{
   int array1[3][2]={4,2,5,6};//顺序初始化
   int array2[3][2]={{4,2},{5},{6}};//按行初始化
   cout <<"array1" <<endl;
   for (int i=0;i<3;i++)//输出数组array1
   {
      for (int j=0;j<2;j++)
     {
         cout <<setw(2) <<array1[i][j];
      }
      cout <<endl;
   }
   cout <<"array2" <<endl;
   for (int k=0;k<3;k++)//输出数组array2
   {
      for (int l=0;l<2;l++)
      {
         cout <<setw(2) <<array2[k][l];
      }
      cout <<endl;
   }
   return 0;
}

运行结果:
array1
4 2
5 6
13 4
array2
4 2
5 8
6 8

我们可以看出,所谓按顺序初始化就是先从左向右再由上而下地初始化,即第一行所有元素都初始化好以后再对第二行初始化。而按行初始化则是用一对大括号来表示每一行,跳过前一行没有初始化的元素,在行内从左向右地进行初始化。对于没有初始化的元素,则都是一个不确定的值。

省略第一维的大小

我们在第一节学到,一维数组的大小可以省略。可是二维数组的元素个数是行数和列数的乘积,如果我们只告诉电脑元素个数,电脑无法知道究竟这个数组是几行几列。所以,C++规定,在声明和初始化一个二维数组时,只有第一维(行数)可以省略。比如:
    int array[][3]={1,2,3,4,5,6};
相当于:
    int array[2][3]={1,2,3,4,5,6};

二维数组在内存中的存储情况

先前已经说明,内存是依靠地址来确定内存中的唯一一个存储单元的,即只有一个参数。所以在内存中,所有的数据都是像一维数组那样顺序存储的。那么具有两个下标的二维数组是怎样存放到内存中的呢?

在内存中,先将二维数组的第一行按顺序存储,接着就是第二行的数据,然后是第三行的数据……右图(图7.4)所示的就是一个二维数组在内存中的存储情况。

向函数传递二维数组

我们知道,数组作为参数传递给函数的是数组首元素的地址。对于二维数组来说亦是如此。不过有两个问题,一个是我们必须让函数知道行数和列数,这就像我们要让函数知道一维数组的大小一样,防止发生越界访问。另一个就是我们必须让电脑知道这个二维数组是怎样的一个表格,即必须告知数组的列数。这和只能省略二维数组的行数道理是一样的。下面我们就来看一个向函数传递二维数组的程序:
#include "iostream.h"
#include "iomanip.h"
void disp(int a[][2],int r,int c);//告知数组的列数
int main()
{
   int array[3][2]={4,2,5,6,3,1};
   cout <<"array" <<endl;
   disp(array,3,2);
   return 0;
}
void disp(int a[][2],int r,int c)
{
   for (int i=0;i<r;i++)
   {
      for (int j=0;j<c;j++)
      {
         cout <<setw(2) <<a[i][j];
      }
      cout <<endl;
   }
}

运行结果:
array
4 2
5 6
3 1

二维数组转化成一维数组

有些时候,我们觉得用二维数组来描述一样事物很方便。比如我们用二维数组来画一个迷宫地图,行下标和列下标就如同直角坐标系一样。可是在某些情况下,不能使用二维数组,或者难以制造一个二维数组。二维数组在内存中的存储情况和一维数组是相同的,所以我们只好用一个一维数组来代替它了。

于是,我们不难总结出一个结果,一个二维数组元素a[x][y]在一维数组b中,是:
    a[x][y]=b[x*列数+y]

 
 
 
 
 
 
 
 

C++二维数组讲解、二维数组的声明和初始化的更多相关文章

  1. [zt]C++二维数组讲解、二维数组的声明和初始化

    定义: int *pia = new int[10]; // array of 10 uninitialized ints 此 new 表达式分配了一个含有 10 个 int 型元素的数组,并返回指向 ...

  2. C语言数组:C语言数组定义、二维数组、动态数组、字符串数组

    1.C语言数组的概念 在<更加优美的C语言输出>一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下: #include <stdio.h> #include &l ...

  3. C语言一维数组、二维数组、结构体的初始化

    C语言数组的初始化表示方法 一.C语言一维数组初始化: (1)在定义数组时对数组元素赋以初值.如: static int a[10]={0,1,2,3,4,5,6,7,8,9}; 经过上面的定义和初始 ...

  4. C#的一维数组和二维数组定义方式:

    一维数组: //一维数组定义与初始化 ,, };//第一种方式 , , }; //第二种方式 int[] one3; //第三种方式 one3=,,}; 二维数组: //二维数组定义与初始化 //不规 ...

  5. 【C语言学习】-05 二维数组、字符串数组、多维数组

    ⼆二维数组.字符串数组.多维数组

  6. homework-02 二维的,好喝的(二维数组的各种子数组)

    1)输入部分 对于输入部分,我定义的输入格式是这样的 前两行为列数和行数 如果文件无法打开,或者输入文件格式不对,均会提示出错并退出 2)二维数组的最大矩形子数组 首先,我使用最最简单的暴力算法,直接 ...

  7. C# 数组、一维数组、二维数组、多维数组、锯齿数组

    C#  数组.一维数组.二维数组.多维数组.锯齿数组 一.数组: 如果需要使用同一类型的对象,就可以使用数组,数组是一种数据结构,它可以包含同一类型的多个元素.它的长度是固定的,如长度未知的情况下,请 ...

  8. c++ 依据输入动态声明数组(一维,二维)

    较早的编译器是不同意这样做的,所以一些书籍比方以Tc解说的书本都说数组的下标不能是变量.在vc6.0下亦是如此. 只是在一些较新的编译器如dev c++已经支持了,例如以下代码不会报错 #includ ...

  9. 《Javascript权威指南》学习笔记之十二:数组、多维数组和符合数组(哈希映射)

    Array(数组)是JavaScript中较为复杂的数据类型,同Java.C#.VB等程序语言的数组相比.Javascript数组中的元素不必为同样的数据类型,能够在数组每一个元素上混合使用数字.日期 ...

随机推荐

  1. Object-C编程基础总结:

    1,nil,NULL,NSNull:nil用来给对象附值,object—c里允许对象为空,空对象也可以接受消息.但是不允许指针为空,NULL是给任何指针附值的.所以NULL只在C或C++里才用.NSN ...

  2. Spring MVC @ModelAttribute 详解

    1.@ModelAttribute注释void返回值的方法 @Controller public class HelloModelController { @ModelAttribute public ...

  3. PHP语言的优势?

    稳定性: 毫无疑问,PHP已经是目前互联网服务端使用最广泛的编程语言之一,目前PHP在互联网应用领域的占有率位居全球第一.试问,如果本身不够成熟和稳定,如何能占有如此大的市场呢? 易用性: 简单实用, ...

  4. ffmpeg参数说明(转载)

    ffmpeg.exe -i F:\闪客之家\闪客之歌.mp3 -ab 56 -ar 22050 -b 500 -r 15 -s 320x240 f:\11.flv ffmpeg -i F:\01.wm ...

  5. 详细记录ASP.NET中的图象处理

    最近做网站时,要求上传能加上水印,就研究了一下相关的功能.推荐一下程序人生的网站,大家也可以写一些开发感悟在上面.在使用ASP的时候,我们时常要借助第三方控件来实现一些图象功能.而现在,ASP.NET ...

  6. android4.0 USB Camera实例(三)UVC

    前面我写了两篇文章说明了zc301的实现 详细请看 http://blog.csdn.net/hclydao/article/details/21235919 以下顺便把通用的USB也写上 前面的ZC ...

  7. ftm时钟源

    FTMx_SC中的 CLKS时钟选择位 00 :无 01: System clock 10:Fixed frequency clock 11 External clock 此处的01:System c ...

  8. .NET-MVC站点部署到windows server2008r2服务器404错误

    iis站点搭建 产生原因: 由于服务器上的.net4.0没有进行注册导致的 解决方法: 注册.net 4.0 打开运行-cmd-输入如下命令: C:\WINDOWS\Microsoft.NET\Fra ...

  9. 一次踩坑记录(使用rpc前后端分离服务总是注册不上)

    问题简述: 项目架构使用了前后端分离,使用rpc进行服务调用与注册,这里没有用dubbo之类的,仅仅用zookeeper,每次在启动项目时总是报错rpcException异常跟NPE异常,后台查看zo ...

  10. PHP快速入门 如何下载和安装

    1 从该网站下载 http://www.appservnetwork.com/ 2 双击安装,注意安装路径和安装组件 按下面的填写,端口不要和IIS冲突,字符编号为UTF-8 安装完成之后,注意安装文 ...