关于指针的加减 一直以来都觉得对指针的加减是个很恶心的事情。虽然指针是个地址值,但是对指针的加N却不是直接将地址值加N,而是增加N*sizeof(指针类型)……这一点很容易让人疏忽。
一般情况下,对指针进行加减运算的代码是很难读的,但是各路考题却总是乐此不疲。 看到这样的道题目: int main() { int a[5] = {1,2,3,4,5}; int *ptr1 = (int*)(&a + 1); int *ptr2 = (int*)((int)a + 1); printf("%x,%x\n", ptr1[-1], *ptr2); return 0; } printf的输出是什么呢(X86体系结构下)? 5,2000000 int *ptr1 = (int*)(&a + 1); 得到的*ptr1是什么? &a 和 a 和 &a[0],都是同一个值,但是它们类型不同。 &a 的类型是:int (*)[5],指向5个int的指针。所以,&a加1,就等于加了5个int的长度。ptr1 = &a[5]。 printf ptr1[-1]的时候,由于ptr1是int*型的,减去1个int长度,则打印的是a[4]的值。 int *ptr2 = (int*)((int)a + 1); 得到的*ptr2是什么? 同样,(int)a 和 &a 和 a 和 &a[0],都是同一个值,但是它们类型不同。 (int)a的类型是int,是一个整型(注意,不是指针)。所以,加1就是直接加1。于是4个字节的int被截断了。 小端情况下(X86体系结构),a按字节表示是: 0x01,0x00,0x00,0x00,0x02,0x00…… 地址值加1后,得到的int是0x00,0x00,0x00,0x02,连起来就是0x02000000。 |
|