關(guān)于指針的加減 一直以來都覺得對指針的加減是個很惡心的事情。雖然指針是個地址值,但是對指針的加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體系結(jié)構(gòu)下)? 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個字節(jié)的int被截斷了。 小端情況下(X86體系結(jié)構(gòu)),a按字節(jié)表示是: 0x01,0x00,0x00,0x00,0x02,0x00…… 地址值加1后,得到的int是0x00,0x00,0x00,0x02,連起來就是0x02000000。 |
|