struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
假设p的值为0x100000.如下表达式的值为多少:
p+0x1=0x_?
(unsigned long)p+0x1=0x_?
(unsigned int*)p+0x1=0x_?
p+0x1的值为 0x100000+sizof(Test)*0x1。至于此结构体的大小为 20byte,所以 p+0x1的值为:0x100014。
(unsigned long)p + 0x1的值呢?这里涉及到强制转换,将指针变量p保存的值强制转换成无符号的长整型数。任何数值一旦被强制转换,其类型就改变了。所以这个表达式其实就
是一个无符号的长整型数加上另一个整数。所以其值为:0x100001。
(unsigned int*)p + 0x1的值呢?这里的 p被强制转换成一个指向无符号整型的指针。所以其值为:0x100000+sizof(unsigned int)*0x1,等于 0x100004。
上面这个问题似乎还没啥技术含量,下面就来个有技术含量的:
在 x86系统下,其值为多少?
int main()
{
int a[4]={1,2,3,4};
int *ptr1=(int *)(&a+1);
int *ptr2=(int *)((int)a+1);
printf("%x,%x",ptr1[-1],*ptr2);
return 0;
}
ptr1:将&a+1的值强制转换成 int*类型,赋值给 int* 类型的变量 ptr,ptr1肯定指到数组 a 的下一个 int类型数据了。ptr1[-1]被解析成*(ptr1-1),即 ptr1 往后退 4 个 byte。所以其
值为 0x4。
ptr2:按照上面的讲解,(int)a+1的值是元素 a[0]的第二个字节的地址。然后把这个地址强制转换成 int*类型的值赋给 ptr2, 也就是说*ptr2的值应该为元素 a[0]的第二个字节开始的连续 4 个byte的内容。
好,问题就来了,这连续 4 个byte里到底存了什么东西呢?也就是说元素 a[0],a[1]里面的值到底怎么存储的。这就涉及到系统的大小端模式了,如果懂汇编的话,这根本就不是问题。既然不知道当前系统是什么模式,那就得想办法测试。大小端模式与测试的方法在第一章讲解 union关键字时已经详细讨论过了,请翻到彼处参看,这里就不再详述。我们可以用下面这个函数来测试当前系统的模式。
int checkSystem( )
{
union check
{
int i;
char ch;
}c;
c.i = 1;
return (c.ch ==1);
}
如果当前系统为大端模式这个函数返回 0;如果为小端模式,函数返回 1。也就是说如果此函数的返回值为 1的话,*ptr2的值为 0x2000000。如果此函数的返回值为 0的话,*ptr2的值为 0x100。