[英]Does c standard guarantee bit pattern interpretation for signed and unsigned?
C標准是否規定應如何解釋位表示? 換句話說,如果條件始終為真,則執行以下操作嗎? 假設sizeof(int)= 4且CHAR_BIT = 8
unsigned u = 0xffffffff;
if (u == 4294967295) /* do something */
int i = 0xffffffff;
if (i == -1) /* do something */
unsigned u = (int)0xffffffff;
if (u == 0xffffffff) /* do something */
int i = hex_literal;
unsigned u;
memcpy (&u, &i, sizeof (u));
if (i == u) /* do something */
if ((i & 0x7fffffff) == (u & 0x7fffffff)) /* do something */
int i = hex_literal;
unsigned u = i;
if (i == u) /* do something */
unsigned u = hex_literal;
int i = u;
if (i == u) /* do something */
int i = hex_literal;
unsigned u = hex_literal;
if (i == hex_literal && u == hex_literal) /* do something */
char c = 0xff;
if (c >> 4 == 0xf) /* do something */
signed char c = 0xff;
if (((c >> 4) & 0xff) == 0xf) /* do something */
對於未簽名,是的。 對於帶符號的類型,否; 該標准允許2的補碼,1的補碼或符號幅度表示。 標准(C99)的相關部分是6.2.6.2。
一個單獨的問題是,諸如unsigned u = (int)0xffffffff
調用未定義的行為,因為這會導致整數溢出(第6.3.1.3節)。
另一個問題是該代碼,例如char c = 0xff; c >> 4
char c = 0xff; c >> 4
是實現定義的,這有兩個原因。 首先, char
可以是有signed
也可以是unsigned
。 其次,如果它是帶signed
,則右移負數是實現定義的(第6.5.7節)。
我將做出額外的假設,即所討論的實現中沒有類型具有填充位。 讓我們一次帶他們一個:
unsigned u = 0xffffffff;
if (u == 4294967295) /* do something */
是。
int i = 0xffffffff;
if (i == -1) /* do something */
否。將超出范圍的數字轉換為帶符號的類型將給出實現定義的結果。
unsigned u = (int)0xffffffff;
if (u == 0xffffffff) /* do something */
不,與前面的示例相同。
int i = hex_literal;
unsigned u;
memcpy (&u, &i, sizeof (u));
if (i == u) /* do something */
if ((i & 0x7fffffff) == (u & 0x7fffffff)) /* do something */
是。 該標准保證有符號類型中的每個值位在對應的無符號類型的對象表示中具有相同的值。
int i = hex_literal;
unsigned u = i;
if (i == u) /* do something */
是。 i
從int
到unsigned
的提升是確定性的,並且在對u
的賦值和比較中都產生相同的值。
unsigned u = hex_literal;
int i = u;
if (i == u) /* do something */
是的,但是僅當hex_literal
處於可以由int
表示的(正)值范圍內時,否則實現定義的結果將再次出現。
int i = hex_literal;
unsigned u = hex_literal;
if (i == hex_literal && u == hex_literal) /* do something */
u == hex_literal
將始終評估為true,但是i == hex_literal
僅在hex_literal
處於int
表示的值范圍內i == hex_literal
需要這樣做。
char c = 0xff;
if (c >> 4 == 0xf) /* do something */
char
可以是已簽名或未簽名。 如果未簽名,則測試為true;否則為true。 如果已簽名,則c
和c >> 4
將具有實現定義的值,因此可能不正確。
signed char c = 0xff;
if (((c >> 4) & 0xff) == 0xf) /* do something */
c
將具有實現定義的值,因此測試可能不正確。
請注意,除了memcpy()
以外,您所有的問題僅與值有關,而與表示有關 。
無符號數保證了模2 ^ n的模運算。 簽名者沒有這樣的保證。
關於位模式,什么也沒說。 請注意,0xfffffff不是“位模式”,它是一個數字(其“位模式”對於C ++標准沒有意義),如果x
是您要使用的32位無符號數,則保證滿足x + 1 = 0分配為0xffffffff。
要記住的關鍵項是十六進制文字(例如0x0F
)是指值 (此處為15
),而不是物理上存儲位和字節的順序。
它是依賴於機器這是怎么保存-有些人會首先存儲最低顯著位,其他高位第一次,據我所知在x86它至少顯著字節第一,但高位第一。
但始終是真的, 0x000F
等於15
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.