2017-09-24 128 views
2
#include <stdio.h> 

int main() 
{ 
    int a[]={11,12,13},*p; 
    printf("%x\n",a); 

    for(int i=0;i<3;i++) 
     printf("%x ",(a+i)); 

    p=(&a)+1; //LINE1 
    printf("this is this %x\n",p); //LINE2 
    printf("%d ",*p); 
    printf("%d\n",*(p-1)); 
    return 0; 
} 

在LINE1上進行指針運算後,爲什麼LINE2打印的地址不等於a [1]?相反,還有4個字節的差異。int * p = somearray但(p + 1)不等於somearray的地址[1]。爲什麼?

+1

請您分享該程序的輸出。這很難理解,至少對我來說 –

+0

'printf''%x'接受一個'unsigned int',而不是'int *'。 – melpomene

+3

'a'的類型爲int(*)[3]'。表達式'(&a)+ 1'偏移指針'sizeof(int(*)[3])'。取出'&'。 –

回答

4

當你寫

&a 

您正在獲取數組a的地址。由於數組a的類型爲int [3],因此該指針的類型爲int (*) [3],這是一個指向三個整數數組的指針。

當你再寫入

&a + 1 

你說「去了一個對象,在過去的a一個指向。」請記住,a的類型爲int (*) [3],因此C解釋爲指向「指向三個int的數組,後面跟着a指向的三個int的數組。因此,您將指向3 × sizeof(int)個字節,超出了陣列的底部,而不是您會找到元素a[1]的位置。

你大概應該從線得到一個編譯器警告

p = (&a) + 1 

,因爲類型是錯誤的。指針pint *,右側的表達式的類型爲int (*) [3]。使用高警告設置進行編譯可能會提醒您某些事情是錯誤的,這可能會導致您錯誤地發現某些事情並不完全正確。我建議今後進行高級警告設置編譯,因爲這些天編譯器報告的許多警告是合法的問題。

有幾件事你可以做,以解決這個問題。之一將是寫

&a[0] + 1 

表達&a[0]裝置「的指針的a第一元件」和具有類型int *,因此當添加一個到它,C將此解釋爲表示「點到下一個inta[0]後,這是在a[1]生命。

由於陣列到指針衰減,也可以寫

a + 1 

因爲C解釋表達式a作爲指向a(即&a[0])的第一個元素的指針。

總結:

  • 指針運算依賴於底層類型的大小。
  • 寫入&a爲您提供指向元素數組的指針,而不是指向數組的第一個元素的指針。地址相同,但類型不同。
0

你需要在數組中的元素使用指針運算: 一個已經INT *,所以你有兩個選擇:

p=(&a[0])+1; //LINE1 

p=a+1; //LINE1 
+0

正確。或只是'p = a + 1;' – Soonts

+0

加上它,thks – Gabriel

1

對於指針算術,您應該知道指針的類型。 現在這裏是一個指向3個元素的整數數組的指針。 即a的數據類型是int(*)[3]。

每當你給a加1時,它會指向3個整數後的下一個存儲單元。 和指針類型&(a [0])是int *。

希望這會解決您的問題。

相關問題