C/C++中指針加 1 的問題

  先用貝爾的一道筆試題簡要的說明一下吧: 【題】說明以下程序。 #include int main(void) { unsigned int a[3] = {0x01020304, 0x05060708, 0x090a0b0c}; unsigned int *p = (unsigned int *)((int)a +1);① printf("%x/n", *p); return 0; } 【題目解析】 這段程序的輸出結果應該是 8010203(即0x08010203)。 內存存儲結構如(圖1)所示(在 big-endian 的系統中)。在①處的語句中,首先把數組 a 的首地址轉化爲整型,然後再加 1 ,再強制轉化爲 (unsigned int *) ,這個時候 p 值應該是 0x1235,所以取的是從 0x1235 到 0x1238 四個字節組成的新的整數,所以就是 0x08010203。 給出公式的話就是 (a[0]>>8 | a[1]<<24)。 圖 1 內存結構示意圖 【補充說明】 看一下這條語句輸出是什麼呢? p = a; printf("%d %08x %d %d %d", (p+1)-p, *(p+1), &a[1]-&a[0],(int)(p+1)-(int)p, (char *)(p+1)-(char *)p ); 結果是: 1 05060708 1 4 4 第一個輸出大家可能理解爲理所當然了,我們先看後面的結果。 第二個輸出值是數組 a 的 a[1] 元素的值,也就是說 (p+1) 指向的地址是 0x1238,而不是0x1235。爲什麼呢?因爲指針加 1 的時候,實際上是加上了他所指向數據類型的寬度,這樣指針就可以指向下一個元素而不是一個元素的一半了。彙編代碼如下: 0040106A mov ecx,dword ptr [ebp-10h] 0040106D add ecx,4 ;注意這裏,實際加的是 4,而不是1 00401070 sub ecx,dword ptr [ebp-10h] 00401073 sar ecx,2 00401076 push ecx 第三個輸出按理來說應該是 0x1238-0x1234 = 4,但是爲什麼是 1 呢?因爲返回的是這種元素的個數,而不是真正的地址差值,也就是把差值再除以元素寬度。下面是 VC 的彙編代碼,參數 &a[1]-&a[0] 的壓棧過程。 00401043 lea ecx,[ebp-8] ; 取 a[1] 的地址值 00401046 lea edx,[ebp-0Ch] ; 取 a[0] 的地址值 00401049 sub ecx,edx ; 計算地址值之差,並放入 ecx 中 (值爲4) 0040104B sar ecx,2 ; 將 ecx 中的數值右移兩位,也就是除以 4 (值爲1) 0040104E push ecx ; 參數壓棧,供函數 printf() 使用 第四個輸出是 4,因爲int類型的相減就是實際數字的相減,不需考慮其它因素,彙編代碼如下: 00401063 mov edx,dword ptr [ebp-10h] 00401066 mov eax,dword ptr [edx+4] 00401069 push eax ; 注意!壓棧之前沒有右移操作 第五個輸出,講到這裏 我想大家應該都明白了爲什麼是4了,我只給出彙編代碼: 0040104F mov eax,dword ptr [ebp-10h] 00401052 add eax,4 00401055 sub eax,dword ptr [ebp-10h] 00401058 push eax 現在在回頭看一下第一個輸出結果的彙編代碼。在執行 p+1 的時候實際上是加了 4 (int類型的寬度),只是在減的時候將結果除了個 4,所以結果仍然是 1。 ;(p+1)-p 0040106A mov ecx,dword ptr [ebp-10h] 0040106D add ecx,4 00401070 sub ecx,dword ptr [ebp-10h] 00401073 sar ecx,2 00401076 push ecx 【後記】 這些以前都有點印象,但是不是十分確定,昨天就試驗了一下,找出了一下規律。其實這些 C99 上應該都有的,我同學正在幫我找,找到了將鏈接貼到這裏。 When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements. (結果是兩個數組元素的下標之差) From:http://blog.csdn.net/evers/articles/193603.aspx
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章