首先大家要记住两个要点:
1.数组名单独放在括号里面表示的是数组的地址
2.对数组名进行取地址取出来的是数组的地址
对于一维数组大家应该都很好理解!
比如:a[3] = { 1,2,3 };
这个一维数组a他里面有三个元素,数组名表示的是数组的地址,特殊的是数组的地址,和1
这个数组元素的地址是一样的但是意义却不一样。
有什么不一样呢?
对于数组的地址加1的话跳过去的是整个数组
而对第一个元素加1的话跳过去的是一个数组元素
就对a这个数组,假设a的地址为0x1000
&a + 1(数组的地址加1) 0x1012
a + 1 (首元素的地址加1) 0x1004
sizeof(a)(a单独放在括号内部,表示整个数组的地址) 求出来所占内存大小为12
sizeof (a + 1)(表示第二个元素的地址(即2的地址)) 求出来大小为4
这就是数组的地址和首元素的地址的区别
对于一维数组传参的话,传过去的是数组名,也就是首元素的地址,需要用一个一级指针来进行接收,或者采用一维数组来接收也可以,但是要记住数组传参传的是数组首元素的地址,是一个地址即使你采用一维数组来进行接收,也只是数组的地址赋给这个一维数组,而不是将整个数组传过来。
这是为什么?数组传参传的的是地址,而不是整个数组
原因很简单:数组在进行传参是,是开辟临时栈来接收的如果传的是整个数组的话,那么需要压栈的元素太多,字节太大有可能导致,栈溢出,所以一般传参传的都是数组首元素的地址。
接下来说一下二维数组:
对于二维数组在内存中存储的时候是采用行主序来进行存储的。所以二维数组存储下来不像是自己脑海中想象的几行几列,实际上也是一行而已。
例:a[3][4] = { { 1,2,3,4 }, { 5,6,7,8 }, { 9,10,11,12 }}
这个数组在内存中存储是这样的:
是一行来进行存储的。地址空间是连续的(4和5的地址,8和9的地址都是连续的)。
可以看到这个存储就像是三个一位数组来进行存储。
实际上二维数组就相当于是三个数据元素,只不过这三个数据元素又都是一维数组而已。
所以二维数组的数组名就相当于是一个一维数组指针。
因为数组名数组首元素的地址,而二维数组的首元素是一个一维数组,则这个首元素的地址就是一维数组的地址。也就是一个数组指针。
对于这个指针进行解引用得到的就是一个一维数组。此时这个指针就是这个一维数组的数组名了。
所以对于二维数组传参的时候传的是数组名,接受的时候要用一个数组指针来进行接收这个参数,因为传过来的是数组首元素的地址,而二维数组的首元素就是一个一维数组。