【二维数组】仅此一篇 让你深刻理解二维数组

作者:MiTu_-_

本帖内容著作权归作者所有,转载请务必保留本文链接

二维数组

二维数组其实是一维数组的扩展。(这句话要记住哟!)

  • 比如我们这样定义一个一维数组:
    int a[ 2 ];
    那么数组a就有两个个元素;如果此时再在每个元素里面定义5个数组,这样一个一维数组就扩展成了一个二行五列的二维数组了。
  • 比如我们这样定义一个二维数组:
    int a[ 2][ 5 ];
    这就是一个2* 5的二维数组了。

可以这样理解:

  • 一维数组 int a[ 2 ];
    a 表示数组的首地址,即a[ 0 ]的地址,
  • 那么扩展到二维数组 int a[ 2 ][ 5 ];
    其实就是往一维数组a[ 0 ]里面再装进去5个元素,那二维数组的a就表示整个一维数组的 a[ 0 ] 的首地址地址,也就是含有5个元素的数组的首地址,如果你理解数组指针的话(如果不理解的小伙伴可以先看看我的上一篇【数组指针】),那么a[ 0 ] 其实就是一个数组指针,即 int (*p)[0];

一定要把二维数组的一行看成是一个整体!!!
(因为它的实质是:在一维数组里的元素里再次进行扩展)

我就用一个代码来演示:

#include <stdio.h>

int main()
{
/* 1) */	int a[2][5] = { {1, 2, 3, 4, 5}, {6, 7, 8, 9, 10} };
			int (*p)[5] = a;
	
/* 2) */	printf("*(a+1): %p\n", *(a + 1));
/* 3) */	printf("a[1]: %p\n", a[1]);
/* 4) */	printf("&a[1][0]: %p\n\n", &a[1][0]);
/* 5) */	printf("*a[1]: %d\n", *a[1]);
/* 6) */	printf("a[1][0]: %d\n", a[1][0]);
/* 7) */	printf("**(a+1): %d\n\n", **(a + 1));
	
/* 8) */	printf("*p + 1: %p\n", (*p + 1));
/* 9) */	printf("*(*p + 1): %d\n", *(*p + 1));
/* 10) */	printf("*p[1]: %d\n\n", (*p)[1]);
	
/* 11) */	printf("*(p + 1) + 1: %p\n", *(p + 1) + 1);
/* 12) */	printf("**(p + 1) + 1: %d\n", *(*(p + 1) + 1));
/* 13) */	printf("*p[1]: %d\n", *(p[1] + 1));

	return 0;
 } 

剖析代码

1)第一行先定义了一个2 * 5的二维数组,第一行的值为1,2,3,4,5;第二行的值为6,7,8, 9,10。


2)接着打印*(a+1),结果是地址,我们该怎么理解里面的a + 1 和 * 呢?
根据前面所说的:

  • a 是二维数组第一行数组的首地址(其实就是一维数组的首地址,即一维数组的 a[ 0 ] )。
  • a + 1 是二维数组第二行数组的首地址(其实就是一维数组的第二个元素的地址,即一维数组的 a[ 1 ] )。
  • *(a + 1) 是二维数组的第二行数组的第一个元素的地址(和数组指针相同)。

可以把上面的步骤理解为:
① 找到一维数组。取数组的首地址。
② 到一维数组里的第二个元素去。取数组的第二个元素的地址。
③ 到一维数组里的第二个元素里的第一个元素去。取数组的第二个元素里第一个元素的地址。


3)打印a[ 1 ] ,结果是地址。
a[ 1 ] 就表示第二行数组的首地址(相当于一维数组里第二个元素的地址)。


4)打印 &a[ 1 ][ 0 ],结果是地址。
a[ 1 ][ 0 ] 就表示第二行数组第一个元素的内容了,再用取址运算符&就得到地址了(相当于取出一维数组里第二个元素里第一个元素的地址)。


5)打印*a[ 1 ],结果是6.
由上知 a[ 1 ]是第二行数组第一个元素的地址,再用取值运算符 * 就得到里面的内容了。


6)打印a[ 1 ][ 0 ]同上。


7)打印**(a + 1),结果是6.
由上知 *(a + 1)表示二维数组第二行首元素的地址,再用 取值运算符 * 就得到里面的内容了。


8)到了这你应该会对二维数组有深刻的理解了吧。其实二维数组和数组指针是有关系的。比如:
int a[ 2 ][ 5 ];
int (*p)[ 5 ] = a;

那么 p 就相当于 a[ 0 ] 了。都是指向二维数组第一行数组的首地址。
*p 则为第一行数值首元素的地址。

printf("*p + 1 : %p\n", *p + 1);
  • p为二维数组a,即 a[ 0 ],也就是第一行数组的首地址。
  • *p 是指二维数组a[ 0 ][ 0 ],也就是第一行数组首元素的地址。
  • 再加1,就是二维数组a[ 0 ][ 1 ],也就是第一行数组的第二个元素的地址。

9) *( * p + 1) ,
10) (*p)[ 1 ];   结果为2.
由8)知可知,要打印的就是第一行数组第二个元素的地址。
如果看了我的上一篇【数组指针】的同心可能就会发现,这里和那里的代码是几乎相同的。

	for(i = 0; i < 5; i++)
	{
		printf("%d\n", *(*p + i));
		printf("%d\n", (*p)[i]) ;
	 } 

11)打印 *(p + 1) + 1,结果为地址。

  • p是第一行数组的首地址。
  • p + 1 是第二行数组的首地址。
  • *(p + 1) 是第二行数组首元素的地址。
  • 再加1,就是第二行数组第二个元素的地址。

12)打印*(*(p + 1) + 1) ,结果是7。
由11)知,再加上取值运算符就是取第二行第二个元素的内容了。


13)打印*(p[1] + 1) ,结果是7。
这里其实用到的是指针数组的知识(不懂的小伙伴可以先看看我的上一篇【指针数组】)

  • 在上面我定义的二维数组中,可以把它看成一个一维数组,里面有两个指针,分别指向了含有5个元素的数组首元素的地址。
  • 那么p[ 1 ] 则表示指针指向了第二个数组首元素的地址。
  • 再加1,表示指向了第二个数组第二个元素的地址。
  • 外面再加上取值运算符 * 就得到第二行第二个元素地址里的内容了。

二维数组的内容就到这里了。

不知道大家是这样呢
晕

还是
酷



赠人玫瑰,手有余香!!!还望大家随手点个赞哟(^U^)ノ~YO

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值