今天在测试一段小程序的时候发现了一个很诡异()的现象,是关于数组的。
下面让我举例来说明这个诡异的小插曲:
实例程序一:
int main(int argc, char *argv[])
{
#if 1
/*I have many big questions in this case!!!*/
int a[5]={1,2,3,4,5};
int *ptr1=(int *)(&a+1);
printf(" &a = %d\n",&a);
printf("*ptr1 = %d\n",*ptr1);//2293564
printf(" ptr1 = %d\n", ptr1);//2293564
#endif
return 0;
}这段程序是测试 &a+1 的结果值,终端输出如下:

由上面显示结果可知,&a+1的意思是数组首地址偏移一个数组内存长度之后的值,也就是2293544+20=2293564< http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+ue7S7LXEz9bP87K7ysfV4rj2o6y087zS16LS4rW9o6wqcHRyMb65yLu6zXB0cjHP4LXIo6HO0rWxyrHB6MLSwcuho7jQvvWyu7vh1NmwrsHLoaPV4sqyw7S4+sqyw7SwoaOhPC9wPgo8cD5wdHLKx9K7uPZpbnTA4NDNtcTWuNXro6zG5Na4z/IoJmFtcDthJiM0MzsxKdXiuPa12Na3o6zK5LP2cHRytcTS4su819TIu77NysfK5LP2o6gmYW1wO2EmIzQzOzGjqdXiuPa1xCYjMjA1NDA7o6zSsr7NyscyMjkzNTY0PC9wPgo8cD62+CpwdHKjv9OmuMPKx3B0cta41evWuM/ytcS12Na3tcTE2sjdo6zTycnPw+a1xLPM0PK/ydaqo6zV4rbOtdjWt7KizrSxu7izJiMyMDU0MDujrMv8tcTE2sjdvrnIu8rHy/y1xLXY1rcmIzIwNTQwO6OhPC9wPgo8cD48YnI+CjwvcD4KPGgyPtTZwLS/tL+00ru49sq1wP2jujwvaDI+CjxwPtDeuMS12tK7uPazzNDyyOfPwsv5yr6jujxicj4KPC9wPgo8cD48L3A+CjxwcmUgY2xhc3M9"brush:java;"> #if 1 /*I have many big questions in this case!!!*/ int a[5]={1,2,3,4,5}; int *ptr1=(int *)(&a+1); int iTmp=3; int *piTmp = &iTmp; printf(" &a = %d\n",&a); printf("*ptr1 = %d\n",*ptr1);//2293564 printf(" ptr1 = %d\n", ptr1);//2293564 #endif
输出结果:

有规则的巧合往往预示着什么!
将数组元素地址以及数组后面的一个地址及其地方值打印出来! #if 1
/*I have many big questions in this case!!!*/
int a[5]={1,2,3,4,5};
int *ptr1=(int *)(&a+1);
//int iTmp=3;
//int *piTmp = &iTmp;
int *ptr2=(int *)((int)a+1);
printf(" &a = %d\n",&a);
printf(" &a[0]= %d\n",&a[0]);
printf(" &a[1]= %d\n",&a[1]);
printf(" &a[2]= %d\n",&a[2]);
printf(" &a[3]= %d\n",&a[3]);
printf(" &a[4]= %d\n",&a[4]);
printf(" a[5]= %d\n",a[5]);
printf("*ptr1 = %d\n",*ptr1);
printf(" ptr1 = %d\n", ptr1);
printf("*ptr2 = %d\n",*ptr2);
#endif
可以发现a[5]=2293541 = *ptr1!
证明上述表述是正确的!再定义iTmp变量
#if 1
/*I have many big questions in this case!!!*/
int a[5]={1,2,3,4,5};
int *ptr1=(int *)(&a+1);
int iTmp=3;
int *piTmp = &iTmp;
int *ptr2=(int *)((int)a+1);
printf(" &a = %d\n",&a);
printf(" &a[0]= %d\n",&a[0]);
printf(" &a[1]= %d\n",&a[1]);
printf(" &a[2]= %d\n",&a[2]);
printf(" &a[3]= %d\n",&a[3]);
printf(" &a[4]= %d\n",&a[4]);
printf(" a[5]= %d\n",a[5]);
printf("*ptr1 = %d\n",*ptr1);
printf(" ptr1 = %d\n", ptr1);
printf("*ptr2 = %d\n",*ptr2);
#endif
可以注意到: a[5]=2293537=*ptr1 理论和事实都是这样的,他两相等! 到现在,还是没发现什么。是CPU地址分配的问题 ?还是编译器?
在上面的第二个程序中显示结果我们可以发现:

*ptr1=2293536等于数组第一个元素之前的一个int单元!
从2293540到2293560这些地址,除了2293560为被初始化,其余均被数组初始化了!
所以就将2293560上的内容默认设置为最前面那个未被初始化单元的地址值?
为了证实猜想:
测试程序如下:
#if 1
/*I have many big questions in this case!!!*/
int a[5]={1,2,3,4,5};
int *ptr1=(int *)(&a+1);
int iTmp=3;
int *piTmp = &iTmp;
int *ptr2=(int *)((int)a+1);
printf(" &a = %d\n",&a);
printf(" &a[0]= %d\n",&a[0]);
printf(" &a[1]= %d\n",&a[1]);
printf(" &a[2]= %d\n",&a[2]);
printf(" &a[3]= %d\n",&a[3]);
printf(" &a[4]= %d\n",&a[4]);
printf(" a[5]= %d\n",a[5]);
printf(" a[6]= %d\n",a[6]);
printf("*ptr1 = %d\n",*ptr1);
printf(" ptr1 = %d\n", ptr1);
printf("*ptr2 = %d\n",*ptr2);
#endif
可以发现a[6]的值真的也是前面未被初始化单元(int)的地址值!
发现有些忘记问题是什么的感觉。
有谁能告诉我为什么?
这会又凌乱了。。。。
