在X86系统下,以下程序输出的值为多少?
1 #include <stdio.h> 2 #include <stdlib.h> 3 int main(void) 4 { 5 int a[5]={1,2,3,4,5}; 6 int *ptr1=(int *)(&a+1); 7 int *ptr2=(int *)((int)a+1); 8 printf("%x,%x,%x ",*(a+1),ptr1[-1],*ptr2); 9 system("pause"); 10 return 0; 11 }
执行以上代码,运行结果为:
分析:
&a+1:取数组a的首地址,该地址的值加上 sizeof(a) 的值,即:&a + 5 * sizeof(int),也就是下一个数组的首地址,显然当前指针已经越过了数组的界限。
*(a+1):a 和&a的值是一样的,但是意思不一样,a是数组首元素的首地址,(元素类型为int型,占四个字节,X86下为小端模式,因此首地址存放的是低字节数据) 即a[0]的首地址。
a+1 是数组下一个元素的首地址,即a[1]的首地址。所以 *(a+1) 输出 2。
&a是数组的首地址。 &a+1是下一个数组的首地址。
ptr1[-1]:因为ptr指向 a[5],ptr[-1]被解析为*(ptr-1),即ptr1往后退4字节,指向a[4],输出 5。
(int)a+1:将a[0]的首地址强制转换为 int 型,再加1,即两个 int 型数据相加,其值为a[0]第二个字节的地址。即(int)a + 1 指向图中的地址1,由于*ptr2是int类型,所以*ptr2代表从a[0]的第二个字节到a[1]的第一个字节的数据,
即下图中内存地址1到地址4的数据。由于X86下是小端模式,所以输出是2000000。
ps.以下为大小端模式测试程序
1 int checkSystem() 2 { 3 union check 4 { 5 int i; 6 char ch; 7 }c; 8 c.i = 1; 9 return(c.ch==1); //小端模式返回1,大端模式返回0 10 }