先看一端具体代码
struct S{
240 int a;
241 int b;
242 int c;
243 };
244
245 struct S s;
246
247 int *p1, *p2;
248 int diff;
249 p1 = (int*)&s;
250 p2 = &(s.c);
251 diff = p2 - p1;
252 printf("p1=0x%x\n", (unsigned int)p1);
253 printf("p2=0x%x\n", (unsigned int)p2);
254 printf("diff=%d \n", diff);
在win32 32bit平台 用GCC编译运行出来的结果为
p1=0xbf8f8678
p2=0xbf8f8680
diff=2
可能有人会问 明明p2-p1=0xbf8f8680 - 0xbf8f8678 = 8, 那为什么diff运行后值为2呢? 这要从指针间加减的原理说起,就是地址相加减得乘以或除以其所指向数据类型长度。
所以diff = (p2_addr - p1_addr) / sizeof(int) = 2。 反汇编后就能印证
diff = p2 - p1;
804a789: 8b 54 24 28 mov 0x28(%esp),%edx
804a78d: 8b 44 24 24 mov 0x24(%esp),%eax
804a791: 89 d1 mov %edx,%ecx
804a793: 29 c1 sub %eax,%ecx
804a795: 89 c8 mov %ecx,%eax
<strong><span style="background-color: rgb(255, 0, 0);"> 804a797: c1 f8 02 sar $0x2,%eax</span></strong>
有兴趣的可以自己验证下面这些打印值为多少?
255 printf("diff2=%d\n", (int *)p2 - (int *)p1);
256 printf("diff2=%d\n", (char *)p2 - (char *)p1);
下面这个式子把指针类型强制转换为普通变量,diff值就为8了。
<pre class="html" name="code">257 printf("diff2=%d\n", (int)p2 - (int)p1);