正在查看旧版本。 查看 当前版本.

与当前比较 查看页面历史记录

版本 1 下一个 »

二维数组

数组里面存储的元素是数组的话得到的就是二维数组,采用如下方式定义:

int a[2][3] = { {1, 2, 3}, {4, 5, 6} };

该数组里面有两个元素,每个元素是一个含有三个int型成员的数组。以下是二维数组的内存图: 

还有一种虚拟的二维数组内存图,它将二维数组理解成二维矩阵,通过行与列的方式,有助于对二维数组的记忆,如下:

数组或许该这么定义

如果我们换一种方式来思考一维数组这种数据类型的话,那么对于二维数组的理解将会非常简单。以整型一维数组举例,我们通过int a[3]定义了一个一维数组a,它有三个int类型的成员。而我们知道,数组也是一种数据类型,那么,它到底是什么类型呢,也就是说,我们的数组a到底是什么类型? 答案是,每一个一维数组都是一种单独的数据类型,以a为例,它的类型可以理解为int[3],表示的是含有3个整型元素的数组类型。同理,int b[5],b表示的类型是int[5],表示的是含有5个整型元素的数组类型。那么我们的数组或许可以这么定义:

int[3] a; //通过int[3]这种数据类型定义一个变量a,它有三个int型元素 int[3] a[2]; //通过int[3]这种数据类型定义一个数组a,它的每个元素都是//int[3]类型

通过这种理解方式,二维数组本质上还是一维数组,可以将二维数组甚至是多维数组拆解成一层一层的一维数组,按照一维数组的性质进行分析(所有关于一维数组地址运算法则都适用,比如地址偏移计算,取地址,解地址)。

关于数组名

在二维数组中,关于数组名与数组首地址的讨论将更加复杂一些,我们来看一下: int a[2][3]; 

注:&a, a, a[0]的关系就好比浙江省省政府,杭州市市政府,滨江区区政府,虽然这三个政府都在杭州,但是代表的身份完全不一样。

二维数组初始化

  1. 分行初始化 int a[3][3] = { {1,2,3}, {4,5,6}, {7,8,9} };
  2. 顺序初始化 int a[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  3. 省略行长度 int a[][3] = {1, 2, 3, 4, 5, 6, 7 , 8 , 9 }; 建议不要采用省略行长度的做法
  4. 分行部分元素初始化 int a[3][3] = { {2}, {5, 6}, {7, 8, 9} };

二级指针

指针变量也有地址,它的地址可以用一个二级指针来存放,如下: int a = 3; int* p = &a; //一级指针 int** pp = &p; //二级指针

二级指针内存图:

通过二级指针访问变量: *pp ==> p **pp ==> a

数组指针

数组指针本质上还是一个指针,只不过它指向的是整个数组。按照我们刚才对数组的理解,那么,要定义一个指向整个数组的指针,或许可以这么定义:

int[3] a; int[3]* p = &a; //定义一个指针p,它指向a这个变量的地址

但实际上,道理可以这么去理解,形式上还是要遵从C语言的语法规定,C语言中,定义数组指针的方式如下: int a[3]; int *p; //定义一个数组指针p,它希望存储一个含有三成员的整型数组地址 p = &a; //让p指向数组a

以下是数组指针的内存图: 

既然p指向的是含有三个元素的整型数组类型(int[3]类型),那么,就不可以把除此之外的类型赋值给它,哪怕同样是整型,类似下面的写法是错误(Warning)的: int a[5]; int *p = &a; //类型不匹配,报Warning错误,由编译器进行强制类型转换

既然p指向了整个数组,那么,对p的算术运算将以整个数组大小为单位进行偏移。 

通过数组指针获取指向的数组成员方法: p ==> &a p[0] ==> a p[0][0] ==> a[0]

数组指针与二维数组

可以通过数组指针保存二维数组的数组名,因为二维数组的数组名代表的就是一个数组的地址,如下: int a[2][3]; int *p = a; //数组指针p指向二维数组首地址 那么,在往后要使用a的地方都可以用p来代替: p[1] ==> a + 1 p[1][0] ==> a[1][0]

数组指针与指针数组

注意落脚点,数组指针的本质是一个指针,在32位系统下永远占用4个字节,而指针数组本质是一个数组,代表的是一串连续的内存空间,只不过由于它是一个指针数组,所以它里面存储的是地址值。它们的定义如下,注意区分有括号和没括号: int a[3]; //指针数组,整体占用12字节,存储了三个整型地址* *int (a)[3]; //数组指针,占用4个字节,希望存储一个int[3]类型的地址

  • 无标签