2012-12-06 79 views
8

我寫越來越多的C應用程序,現在我想知道一些關於演員。在C++中,動態強制轉換是非常昂貴的操作(例如向下轉換),但我甚至不知道它是靜態的。C演員真的做了什麼?

在C,我不得不寫類似的東西:

assert (p); /* p is void* */ 
int v = *(int*)p; 

它是一個«C動態投»?它與C++的static_cast<int*>(p)相同嗎?它要多少錢?

在此先感謝。

+2

...有關「非常」的適當定義... – DevSolar

+0

[C/C++編譯器如何處理具有不同值範圍的類型之間的類型轉換?](https://stackoverflow.com/questions/340413/how-do-cc-compilers-handle-type-casting-between-types-with-different-value-ra) – jww

回答

7

C中的強制轉換隻在編譯時有意義,因爲它告訴編譯器如何處理一段數據。它不會更改數據的實際值。例如,(int*)p告訴編譯器將p視爲一個整數的內存地址。然而,這在運行時不需要花費任何代價,處理器只是按照給它的方式處理原始數據。

+8

這對所有演員都不正確。 '(float)0.3'改變IEEE754系統上的值。它不再等於'0.3'。 –

+0

的確如此,謝謝。 – jazzbassrob

8

指針的C類更像C++ reinterpret_cast。它指示編譯器將變量視爲不同類型,並且在運行時不需要花費任何費用。

+1

它是從一個指針類型投射到另一個,但在這種情況下,'reinterpret_cast'與static_cast'做同樣的事情。比如說,將一個double轉換爲一個整數可以起到真正的作用,並且不像'reinterpret_cast'。對我來說,與'static_cast'的比較似乎比'dynamic_cast'更合適。 – sepp2k

+0

@ sepp2k我已經更新了我的答案,以包含關於指針類型轉換的觀點。我不確定我是否同意你關於static指針和reinterpret轉換的指針類型相同 - 編譯器是否不檢查靜態轉換是否在兼容類型之間? (雖然這可能正好相反,但我確實同意並注意到了你的主要觀點) – simonc

+0

你說得對,'static_cast'只與編譯時的'reinterpret_cast' **相同​​。 – sepp2k

2

指針是指針 - 鑄造指針是一個noop。

之前是內存地址,之後是內存地址。

它基本上是一個聲明「讓我們假設這是一個指向類型x的指針,用於將來的類型檢查」。因爲它不會執行額外的編譯時間類型檢查,例如,你可能會把它稱爲reinterpret_cast在C++方面,因爲它不會執行額外的編譯時間類型檢查,例如, dynamic_caststatic_cast

我不認爲C等於dynamic_cast(「insert runtime type check here」)或static_cast(「在此處執行額外的編譯時類型檢查」)。

請注意,對於非指針事情的行爲會略有不同。

int b = 1; 
double a = (double) b; 

與其說是一個演員,而是一個明確的類型轉換

+0

好吧。所以它比其他任何東西更像是一個_compiler_ **提示**。 – phaazon

+0

對編譯器來說不是一個「暗示」:它不會幫助編譯器優化任何東西。但它是一個*程序員*的東西。我不讓編譯器*猜測*這是正確的,但我*明確指出*這應該被強制轉換,而不是拼寫錯誤;它只是告訴編譯器,這不是一個錯誤,而是指這種方式。「 –

5

C演員陣容更像是所有C++風格演員陣容除了dynamic_cast組合。所以當你將一個int轉換爲另一個整數類型時,它是static_cast。當您將指針指向其他指針類型或整型時,或者相反,它是reinterpret_cast。如果你丟棄const,它是const_cast

C沒有類似於dynamic_cast的東西,因爲它具有對象類型的概念,並且不會像C++那樣使用它們(沒有虛函數...)。關於解釋一個對象的位的類型只有在與指向對象的表達式結合時纔會變得很重要,這些對象本身沒有類型。