2011-08-26 133 views
1
#include <stdio.h> 

int main(void) 
{ 
int a[5]={1,2,3,4,5}; 
int *ptr=(int*)(&a+1); 
printf("%d %d\n",*(a+1),*(ptr-1)); 
return 0; 
} 

輸出:指針變量的大小被存儲在哪裏?

2 5 

在這裏,在聲明*ptr= (int*)(&a+1) 1不添加到&a。其實它就像&a + sizeof(a)。現在我的問題是存儲指針變量的大小,還是沒有存儲指針變量的大小,然後如何計算。在int, float, char等的情況下,它們的大小是在編譯器中預定義的,所以int *a是不同的情況。是不是真的只有地址存儲在指針變量中沒有其他的東西?關於指針變量的元數據被存儲在哪裏?

+1

重複:http://stackoverflow.com/questions/7194388/using-pointers-in-c – phoxis

回答

1

它沒有被存儲。編譯器在編譯代碼時肯定需要跟蹤它,但在此之後,它基本上只是硬編碼到生成的指令中。

2

由於您的變量聲明int a[5] = ...,編譯器知道a類型爲int [5](因此,sizeof(a)將返回20)。由於編譯器知道a的類型,因此獲取a的地址將產生正確類型的指針。這可能有點令人驚訝:&a不會產生int**,而是產生int (*)[5](指向由5個整數組成的數組的指針)。執行

int *ptr=(int*)(&a+1); 

當你的a地址

所以,添加一個(其中,由於方式的C/C++指針算術工作,通過sizeof(a)字節增加了由指針所引用的地址),然後將結果轉換爲int。因此,在這一點上,ptr指向數組最後一個元素後面(偏移20處)。

然後,您將指針指向int*並使用*(ptr-1),因此您將偏移量爲16的int值取消引用 - 這恰好是最後一個數組元素所在的位置。

0

&一個IS int (*)[5]類型,即,一個&是一個指針數組,不是指針爲int。編譯器知道(明顯)數組的大小,並將其用於指針運算。

0

指針具有「雙重類型」。一方面,它是一個具有自己大小的指針(假設某些系統上的每個指針有4個字節)。另一方面,它是指向具有大小的指針(除了void *之外)。

類型通常不能直接在C中訪問。您不能問「變量的類型是什麼」。

但大小總是可以通過sizeof訪問。因此int *本身可能使用4個字節,但編譯器知道它指向一個整數,並且它知道整數的大小。 對於struct xyz *,指針本身可能再次是4個字節,但編譯器知道它指向一個結構,並知道結構的大小。重要的是指針的類型超出了「指針」的範圍。

所以,如果你定義了struct xyz *ptr,你總是可以通過檢查sizeof(*ptr)找出指針指向的大小。即使ptr未初始化,也可以這樣做。

您唯一不能做的事情是在ptr定義爲void *時檢查sizeof(*ptr)

就「元數據」而言,它都是指針的類型。

0

指針只是一個內存地址,沒有元數據。將N添加到類型T *的指針會導致將N * sizeof(T)添加到地址值。編譯器在編譯期間知道每種類型的大小,不存儲任何內容。

  • a+1指向一個第二int,因爲它把a作爲int*即指針的第一個元素,即的sizeof(int)的被添加到存儲器地址
  • &a+1點於「第二INT [5]數組「,即sizeof(int [5])被添加到內存地址
  • ptr-1指向在」第二個數組「的第一個元素之前的int,即a的最後一個元素。