例子:
int32 Temp;
Temp= (Temp & 0xFFFF);
我怎么知道是0xFFFF已簽名而不是未簽名。通常我們在十六進制數上加一個“u”0xFFFFu然后進行運算。但是當我們需要一個簽名的結果時會發生什么呢?
uj5u.com熱心網友回復:
我怎么知道 0xFFFF 是有符號的而不是無符號的。
您需要知道int給定系統上的大小:
- 如果是 16 位,則
0xFFFF型別為unsigned int. - 如果它是 32 位,
0xFFFF則為 (signed) 型別int。
有關詳細資訊,請參見 C17 6.4.4.1 §5 中的表格。如您所知,這既不便攜也不可靠,這就是為什么我們應該始終u在十六進制常量上使用后綴。(請參閱Why is 0 < -0x80000000?了解由此引起的細微錯誤的示例。)
在進行按位運算時確實需要有符號數的罕見情況下,請使用顯式強制轉換。例如,用于屏蔽有符號整數的某些部分的 MISRA-C 兼容代碼將是:
int32_t Temp;
Temp = (int32_t) ((uint32_t)Temp & 0xFFFFu);
這u使得0xFFFFu“基本上沒有簽名”。我們不允許在可能存在隱式提升的情況下混合基本上有符號和無符號運算元,因此強制Temp轉換為無符號型別。當一切都完成后,我們必須顯式地轉換回有符號型別,因為在賦值期間也不允許隱式地從無符號變為有符號。
uj5u.com熱心網友回復:
如何將十六進制表示為有符號并執行操作?
當int大于 16 位時,0xFFFF已簽名且無需更改。
int32 Temp;
Temp= (Temp & 0xFFFF);
要處理任意int位寬,請使用強制轉換來消除該警告。
Temp = Temp & (int32)0xFFFF;
或者,使用有符號常量作為十進制常量,因為 C99 始終是有符號的。
Temp = Temp & 65535; // 0xFFFF
另一種想法違背了“將十六進制表示為有符號”,但好的代碼避免了裸幻數,因此十六進制常量的使用不太相關,因為掩碼的概念應該在其名稱中攜帶。
#define IMASK16 65535
...
Temp = Temp & IMASK16;
uj5u.com熱心網友回復:
在 C 中,大多數事物的默認狀態是有符號整數……否則您必須采取措施使其成為可能
用非常簡單的話來說:
#define UNSIGNED_MAGIC_INT 0x7FFFu // u denotes unsigned
#define SIGNED_MAGIC_INT 0x7FFF // no u denotes signed
#define UNSIGNED_MAGIC_LONG 0x7FFFul // l = long, u denotes unsigned
#define SIGNED_MAGIC_LONG 0x7FFFl // l = long, no u denotes signed
等等
整數提升也可能會發揮作用,具體取決于用途,但這本身就是另一個主題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/434835.html
