型別轉換運算子
來自 cppreference.com
執行顯式型別轉換
目錄 |
[編輯] 語法
( 型別名 ) 表示式 |
|||||||||
其中
型別名稱 | - | 型別 void 或任何標量型別 |
表示式 | - | 任何標量型別的表示式(除非型別名是 void,在這種情況下可以是任何型別) |
[編輯] 解釋
如果型別名是void,則評估表示式的副作用,並丟棄其返回值,這與表示式作為表示式語句單獨使用時相同。
否則,如果型別名與表示式的型別完全相同,則不執行任何操作(除了如果表示式具有浮點型別並且以比其型別指示的更大範圍和精度表示——見下文)
否則,表示式的值將轉換為型別名指定的型別,如下所示
允許所有隱式轉換,如同透過賦值一樣。
除了隱式轉換,還允許以下轉換
- 任何整數都可以轉換為任何指標型別。除了空指標常量,如NULL(不需要轉換),結果是實現定義的,可能未正確對齊,可能不指向引用型別的物件,並且可能是陷阱表示。
- 任何指標型別都可以轉換為任何整數型別。結果是實現定義的,即使對於空指標值(它們不一定產生零值)。如果結果不能在目標型別中表示,則行為是未定義的(無符號整數在從指標轉換時不實現模運算)
- 任何物件指標都可以轉換為任何其他物件指標。如果值未針對目標型別正確對齊,則行為是未定義的。否則,如果值轉換回原始型別,則與原始值相等。如果物件指標轉換為任何字元型別的指標,則結果指向物件的最低位元組,並且可以遞增到目標型別的大小(換句話說,可以用於檢查物件表示或透過memcpy或memmove進行復制)。
- 任何函式指標都可以轉換為指向任何其他函式型別的指標。如果結果指標轉換回原始型別,則與原始值相等。如果使用轉換後的指標進行函式呼叫,則行為是未定義的(除非函式型別是相容的)
- 在指標之間進行轉換時(無論是物件還是函式),如果原始值是其型別的空指標值,則結果是目標型別的正確空指標值。
在任何情況下(無論是執行隱式轉換還是同類型轉換),如果表示式和型別名都是浮點型別,並且表示式以比其型別指示的更大範圍和精度表示(參見FLT_EVAL_METHOD),則剝離範圍和精度以匹配目標型別。
型別轉換表示式的值類別始終是非左值。
[編輯] 注意
由於const
、volatile
、restrict
和_Atomic
限定符僅對左值有效,因此轉換為 cvr-限定或原子型別與轉換為相應的非限定型別完全等效。
轉換為void有時可用於消除關於未使用結果的編譯器警告。
此處未列出的轉換是不允許的。特別是,
- 指標和浮點型別之間沒有轉換
- 函式指標和物件指標(包括void*)之間沒有轉換
如果實現提供intptr_t和/或uintptr_t,則從物件型別指標(包括cv void)到這些型別的轉換始終是明確定義的。然而,對於函式指標不保證這一點。 |
(C99 起) |
請注意,許多編譯器將函式指標和物件指標之間的轉換作為擴充套件接受,並且POSIX dlsym()
函式的一些用法也需要這種轉換。
[編輯] 示例
執行此程式碼
#include <stdio.h> int main(void) { // examining object representation is a legitimate use of cast double d = 3.14; printf("The double %.2f (%a) is: ", d, d); for (size_t n = 0; n < sizeof d; ++n) printf("0x%02x ", ((unsigned char*)&d)[n]); // edge cases struct S { int x; } s; // (struct S)s; // error; not a scalar type // even though casting to the same type does nothing (void)s; // okay to cast any type to void }
可能的輸出
The double 3.14 (0x1.91eb851eb851fp+1) is: 0x1f 0x85 0xeb 0x51 0xb8 0x1e 0x09 0x40
[編輯] 參考
- C23 標準 (ISO/IEC 9899:2024)
- 6.5.4 型別轉換運算子 (p: TBD)
- C17 標準 (ISO/IEC 9899:2018)
- 6.5.4 型別轉換運算子 (p: 65-66)
- C11 標準 (ISO/IEC 9899:2011)
- 6.5.4 型別轉換運算子 (p: 91)
- C99 標準 (ISO/IEC 9899:1999)
- 6.5.4 型別轉換運算子 (p: 81)
- C89/C90 標準 (ISO/IEC 9899:1990)
- 3.3.4 型別轉換運算子
[編輯] 另請參閱
C++ 文件關於顯式型別轉換
|