今天写一个程序的时候,用到多维数组,但是有些数据会出错。
很奇怪,就写了个测试程序,发现原来数组的引用出了问题。所以输出不对。
测试程序如下。
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
int main()
{
char size[3][12]={
{'6','6','6','6','7','7','7','7','7','7','7','7'}, //首先声明一个测试数组,二维数组。
{'1','5','3','7',' ','1','1','3','1','5','3','7'},
{'2','8','4','8',' ','8','4','8','2','8','4','8'},
};
printf("size[0][0]=%c\n",size[0][0]);
printf("size[0][11]=%c\n",size[0][11]);
printf("size[0][12]=%c\n",size[0][12]); //输出1,会被当成第一行,第13个元素,因为第一行只有12个,所有从第二行第一个被输出。
printf("size[0][13]=%c\n",size[0][13]); //输出5。被当成第二行,第二个
printf("size[1][12]=%c\n",size[1][12]); //输出2。。被当成第三行第一个
printf("size[2][12]=%c\n",size[2][12]);
}
测试结果如下图
由此可知,对于一个行有12的数组,下标是从0-11的。但是即使引用数组的下标超过数组行数,编译器并没有检查出错误。仍然编译完成。。
size[0][0]到size[0][11]正常输出。
size[0][12]会被当成下一行来输出。
而最后一行size[2][12]由于没有声明,所以为空。什么也没有输出。
其实为什么会这样呢?
我们知道内存中数据的分配根据数据声明顺序,类型,是依次排列的。在内存中并没有行列之分,所以当编译器没有检查出错误的时候,会按照排列输出。
我再做一个测试。
声明两个变量,类型为char.
一个初始化为NULL ,一个无初始化。
char size3=NULL;
char size4;
printf("size3=%c\n",size3);
printf("size4=%c\n",size4);
输出都为空。
为什么会这样呢?
我们知道数组在内存的地址分配是依次排列的,所以在我们概念里的行,列,在内存中是不存在的。
所以编译器没有检查出错的时候,数组的值会依次输出。这是我的猜测。
我们可以做个测试,取地址,取出size[1][0]的地址,与size[0][12]的地址,看看是不是一样,就可以知道了。
说干就干。
例程如下。
printf("size[0][12]的地址是:%p \n",&size[0][12]);
printf("size[1][0]的地址是:%p \n",&size[1][0]);
测试结果如下
由此可见,地址完全一样。可以验证我的猜想。
所以编译器检查不出错误,我们在使用数组的时候一定要小心谨慎下标。不然容易出错。