2012-02-20 32 views
3

我現在正在linux機器上用GCC中的sizeof()來玩弄我,我發現了一些令人驚訝的東西。C爲什麼指針會大於整數

printf ("\nsize of int = %lu\n", sizeof(int)); 
printf ("\nsize of int* = %lu\n", sizeof(int *)); 

產量

size of int = 4 
size of int* = 8 

我認爲一個指向整數的尺寸會比實際的整數本身小得多!

我現在正在研究嵌入式軟件,我的理解是,通過引用比通過價值更有效(在功耗方面)。

有人請澄清如果指針的大小大於實際值,爲什麼通過引用傳遞比通過值更有效。

謝謝!

+3

您是否在64位操作系統上運行? – 2012-02-20 18:24:23

+0

不要比較對象(或類型)的大小。根據需要使用它們。 – pmg 2012-02-20 18:31:07

+0

太棒了!我在一臺64位機器上,但爲什麼通過引用比按值更有效? – icedTea 2012-02-20 18:31:29

回答

9

Integer可以是編譯器編寫者喜歡的任何大小,唯一的規則(在標準C中)是:a)int不小於一個長或大於一個長,並且b)至少有16位。

在64位平臺上保持int爲32位兼容性並不罕見。

+0

「你」是某人實現C,如果這不明顯。 – 2012-02-20 18:29:23

+0

@JerryCoffin - 謝謝,雖然這是'新'在C99 – 2012-02-20 19:13:01

+0

@JerryCoffin - 抱歉我掃描該數字爲32位。我確定它在早期的Windows上曾經是16位 - 當然是這樣。 – 2012-02-20 19:21:06

2

在C中,一個指針,任何指針,只是一個內存地址。您使用的是64位機器,而在硬件級別上,內存地址是以64位值來引用的。這就是爲什麼64位機器可以使用比32位機器更多的內存。

+0

某個CPU的nn位代表它可以在一條指令中處理多大塊數據,也稱爲「數據總線」。這與計算機上的大型地址無關。實際上地址總線通​​常與數據總線寬度不同。在32/64位(數據總線)PC計算機上,爲了方便起見,地址總線恰好與數據總線一樣大。 – Lundin 2012-02-21 13:38:40

0

http://developers.sun.com/solaris/articles/ILP32toLP64Issues.html

當轉換32位程序到64位程序,僅長類型從32個比特的大小 和指針類型更改爲64個比特; int類型的整數 保留32位大小。

在64位可執行文件中,指針是64位的。長整數也是64位,但整數只有32位。

在32位可執行文件中,指針,int和長整型都是32位。 32位可執行文件也支持64位「long long」整數。

+0

不是普遍適用的,也許在一個編譯器或編譯器生成的例子中(例如gcc 4.x)。 – 2012-02-20 18:32:19

+0

正如dwelch所示,不同的編譯器使用不同的內存模型。微軟使用IL32P64(32位長和64位指針),大多數Unices(顯然包括Mac OS X)使用I32LP64(64位長和64位指針)。我不確定有關Windows的GCC。 – 2012-02-20 23:36:55

0

指針必須能夠引用所有內存。如果(虛擬)存儲器大於4吉字節左右,則指針必須大於32位。

5

當要傳遞的值大於參考大小時,按引用傳遞比傳遞值更有效。如果你傳遞的是一個大的struct/object,那麼通過引用傳遞就很有意義。如果您想持續修改您的價值,傳遞參考也是有意義的。

1

有一件事與另一件事無關。一個是一個地址,一個指向某個東西的指針,如果它是一個char或者short或者int或者結構,它是無關緊要的。另一種是一種特定於語言的東西,稱爲int,該系統的編譯器以及該版本的編譯器和命令行選項恰好定義爲某種大小。

看起來好像您正在64位系統上運行,所以您的指針/地址將會是64位。他們指出的是一個單獨的討論,多頭可能也會是64位,有時整數,短褲可能仍然是16位,但不是硬/快速規則,並希望8位,但也不是硬/快速規則。

在這種情況下可能會變得更糟糕的是交叉編譯,而在使用llvm-gcc之前,clang與現在一樣穩定。對於64位主機,字節碼全部是基於64位主機生成的,所以64位整數,64位指針等等,然後當你爲arm目標執行後端時,它必須使用編譯器庫調用來完成所有這些64位工作。這些變量幾乎不需要縮短整數,但是是整數。由於主機不是最終目標,-m32開關被打破,你仍然有64位整數。 gcc直接不會出現這個問題,並且clang + llvm目前也不存在這個問題。

簡短的回答是語言定義了一些數據類型char,short,int,long等,並且這些數據類型具有編譯器實現定義的大小。而地址只是另一種實現定義的數據類型。這就像是問爲什麼短的字節長度不一樣?因爲它們是不同的數據類型,所以一個是短的,一個是長的。一個是地址另一個是變量,兩個不同的東西。

3

通過引用傳遞更有效,因爲不需要複製數據(除指針外)。這意味着在傳遞具有許多字段或結構的類或任何其他大於所用系統上的指針的數據時,這樣做效率更高。

在你提到的情況下,由於實際值小於指向它的指針(至少在你正在使用的機器上),所以不使用指針確實可以更高效。 請注意,在32位機器上,指針有4個字節(4 * 8 = 32位),而在64位機器上,您顯然使用的指針有8個字節(8 * 8 = 64位)。

在更老的16臺機器的指針也只需要2個字節,也許有一些嵌入式系統仍然採用這種架構,但我不知道這...

2

一個指向整數可以點在一個整數,但同一個指針也可以指向十,二十,一百萬或一百萬整數。

很明顯,傳遞單個8字節指針代替單個4字節整數不是一個勝利;但傳遞一個8字節的指針來代替一百萬個4字節的整數肯定是。

相關問題