2013-01-05 195 views
23

我曾嘗試推行sizeof操作符。我這樣做了..執行sizeof操作符的

#define my_sizeof(x) ((&x + 1) - &x) 

但它總是在給結果爲「1」,結束了對任一數據類型..

我有那麼GOOGLE了它這個..我發現代碼類型強制轉換

#define my_size(x) ((char *)(&x + 1) - (char *)&x) 

而且代碼工作,如果它是類型強制轉換.. I D ONT明白爲什麼..此代碼也填充結構完美..

它還工作

#define my_sizeof(x) (unsigned int)(&x + 1) - (unsigned int)(&x) 

任何人都可以請解釋它是如何工作的,如果類型強制轉換,如果沒有類型強制轉換?

在此先感謝..

+3

投射到'unsigned int'是一個壞主意。 'uintptr_t'更好,但仍然涉及一個惱人但不可避免的隱式轉換。 –

回答

26

指針減法的結果是元素而不是以字節爲單位。因此,第一個表達式按照定義評估爲1

這一邊,你真的應該在宏中使用括號:

#define my_sizeof(x) ((&x + 1) - &x) 
#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x) 

否則試圖使用my_sizeof()在表達式中可能會導致錯誤。

+0

我已經把括號..但它也工作,如果我dint .. :) –

+12

宏是無望的,作爲替代'sizeof'的手段。他們評估論證(也是兩次)......想想'my_sizeof(x ++)'。 – Mat

+0

@Mat:是的..我知道了.. :) –

5

但它總是結束了在給出的結果爲「1」,無論是數據類型

是的,這是怎麼指針運算。它以指向類型的單位工作。所以鑄造到char *作品單位char,這是你想要的。

5

sizeof運算符是C(和C++)語言規範的一部分,在編譯器(前端)中實現。沒有辦法使用其他C結構來實現它(除非使用GCC擴展,如typeof),因爲它可以接受任何類型或表達式作爲操作數,而不會產生任何副作用(例如,i==0將不會崩潰,但i==0但您的宏my_sizeof將由零分割)。另請參閱C coding guidelineswikipedia。您應該瞭解C pointer arithmetic。見例如this question。指針差異以元素而非字節表示。

-2

#定義my_sizeof(X)((& X + 1) - & X)

& X提供了你的變量與一個(& X + 1)的地址和遞增它,將會給地址,另一個類型爲x的變量可以被存儲。((& x + 1) - & x),那麼它會告訴在((& x + 1) - & x)中可以存儲類型x的地址範圍1變量。現在,如果我們使用(char *)[因爲char的大小是1個字節並且增加一個char *只會移動一個字節]來對這些內存進行類型轉換,那麼我們將得到字節數x is消費

5
#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x) 

my_sizeof()宏將不會在下列情況下工作:

  1. sizeof 1 - 4字節(與平臺4字節int
    my_sizeof(1) - 根本不會編譯。

  2. sizeof (int) - 4字節(與4字節int平臺)
    my_sizeof(int) - 不會編譯代碼在所有。

它只適用於變量。它將爲數據類型,例如intfloatchar等一樣23.4'A'等不能正常工作,對於文字,也不是右值表達式像a+bfoo()

+1

這將會是一個很棒的評論,因爲它沒有回答問題,但它是[「建設性批評,指導作者改進帖子」]( HTTP://計算器。com/help/privileges/comment)... – Sebivor

+0

我們如何解決它? –

5
#define my_sizeof(x) ((&x + 1) - &x) 

&x給出變量的地址(可以說雙x)將程序中聲明,並用1遞增它給其中類型x的下一個變量可被存儲(在此addr_of(x) + 8的地址,大小的雙倍是8Byte)。

這個差異給出的結果是,多少個變量的類型x可以存儲在這個數量的內存中,對於類型x來說顯然是1(用1遞增它,並且差別就是我們所做的)。

#define my_size(x) ((char *)(&x + 1) - (char *)&x) 

類型轉換成char*,並採取差異會告訴我們如何char類型的多個變量可以存儲在給定存儲空間(差)。由於每個char只需要1個字節的內存,因此(內存量)/ 1將給出傳遞給該宏的變量類型的兩個連續內存位置之間的字節數,因此該類型變量的內存量爲x需要。

但是你不能將任何文字傳遞給這個宏並知道它們的大小。