数组
数组的概念
数组(array)是由一系列相同类型的元素构成的复合数据类型
定义一个数组的语法如下:
<存储类型> <数据类型> 数组名[元素个数];
从内存方面看,定义一个数组相当于在内存中申请一段连续的空间,基地址(数组起始地址,又为首地址)为数组名。(代码举例)
#include <stdio.h>
int main(void)
{
int array[10]={0,1,2,3,4,5,6,7,8,9};
printf("数组名元素的地址为:%p\n", array);//数组名即为数组的基地址
printf("数组名首元素为:%d\n", *array);//*array等价于array[0],数组名为数组的基地址,地址指向的值为数组第一个元素的地址,即用*(解引用)得到地址所指向的值
printf("数组的第二个元素的地址为:%p\n", array + 1);//对数组的基地址进行加1,相当于指向了数组的第二个元素
printf("数组的第二个元素为:%d\n", *(array + 1));//*(array + 1)等价于array[1]
return 0;
}
- 解析
在上面的代码中,我们对地址进行了+1操作,那是不是就是在数值上简单的+1呢?显然不是的,实际上我们在定义数组的时候是按照:<存储类型> <数据类型> 数组名[元素个数];这个语法来定义的,那么地址位移规则是按照你所定义的数据类型的字节数来进行。
打个比方说我们执行以下代码:
int array[5] = {0, 1, 2, 3, 4};
printf("基地址为:%p\n", array);//数组名为数组的基地址,打印出数组的基地址
printf("基地址的下一个地址为:%p\n", array + 1);//打印出在基地址基础上加一的地址
得到的结果为:
-
解析
那很明显的可以看出来基地址的下一个地址在基地址的基础上数值增加了4,int的字节数为4,那也就对应了上面那句话:地址位移规则是按照你所定义的数据类型的字节数来进行。 -
一维数组与二维数组
上面的阐述中其实就是一维数组的概念,那二维数组其实就是一维数组的排列,画一个草图来表示二维数组在内存的存储形式。
那也就是说在内存当中并没有二维数组的概念,所谓的多维数组只是一维数组的排列。
那我们不妨用代码来实际演示一遍:
int a[2][2] = {1, 2, 3, 4};//定义一个二维数组
printf("%p\n",a)//打印出二维数组的基地址
printf("%p\n", *a);//打印出二维数组的第一个元素的地址
结果如下:
上面两个printf()打印的结果是一样的,按道理来说,解引用一个地址,应该得到一个地址所指向的一个具体的值,那为什么还是得到一个地址呢,而且还是和二维数组的基地址一样。
- 解析
可以这么理解,从上面的概念我们可以知道,二维数组其实就是一维数组的排列。上面提到一维数组的基地址就是第一个元素的地址,那我们从这个方面去理解二维数组,因为二维数组其实就是一维数组的排列,我们解引用一次相当得到二维数组中的一个一维数组。那自然而然得到的就是一维数组的基地址,也就是得到上面的结果,这时候我们再解引用一次就得到了一个具体的值。
printf("%d\n", **a);//再一次解引用
结果:
- 以上内容都是自己的理解,如有错误,还望指出