我本仁慈,奈何苍天不许
分类: LINUX
2014-01-15 13:17:49
#include
typedef char ARR[5];
int main()
{
char a[] = {1,2,3,4,5,6,7,8,9};
char *p = a;
printf ("%#x\n", *((int *)(p+3)) );
printf ("%#x\n", *((int *)p + 3) );
printf ("%d\n", (int *)&a[5] - (int *)a );
printf ("%d\n", (int)( (ARR*)a + 1) - (int)a );
return 0;
}
分析:
printf ("%#x\n", *((int *)(p+3)) ); 这句话先执行的是p+3,所以指向a[3],然后强转成int *,所以(p+3)所代表的地址空间是从a[3]开始的连续四个字节,所以取内容就是0x7060504;
printf ("%#x\n", *((int *)p + 3) );这句话与上面类似,只是先执行的是(int *)p,即把p强转成int *,故p是从a[0]开始连续的四个字节,然后p+3,因为p是指针,所以p+3实际是加上3个int 个字节,即3*4 = 12个字节,这时就超出了数组a的范围了,所以结果时不确定的;
printf ("%d\n", (int *)&a[5] - (int *)a );这句话的先执行a[5],即取数组的第5个元素,然后对a[5]取地址,最后强转成int *,所以就成了从a[5]开始连续的四个字节,后面的(int *)a就是把数组a强转成int型,这种(int *)型相减,就是看两者之间地址的差值有多少个int型,由于相差5个字节,这只有一个int型,多余的省掉,所以结果为1;
printf ("%d\n", (int)( (ARR*)a + 1) - (int)a ); 这句话的意思与上一句话差不多,只是先把a强转成容量为5个字节的字符数组,然后加1,这就是直接加5个字节,故指向了a[6],最后强转成int型,这时我们就把他当做成整数,后面的(int)a也就是把a强转成int型(a也就是数组a的首地址,是一个整数),最后两者之间的相减,也就是两个整数的相减。
运行结果: