有符號數和無符號數之間的轉換 2020 C

2021-10-08 12:16:17 字數 3754 閱讀 4485

各位小夥伴咱們先從乙個簡單的例子demo1.c入手:

#include int main()

else

return 0;

}

不言而喻,這個程式的執行結果為:

aaa

因為程式上來就是乙個if判斷語句,如果0

>−1

0 > -1

0>−1

為真,則列印輸出aaa,反之,則列印輸出bbb。故輸出了aaa

那我們繼續再看,如果在0的後面加上乙個udemo2.c結果會如何?嗯哼?

#include int main()

else

return 0;

}

程式執行結果為:

bbb

下面咱們來簡單**一下,大家都知道demo1.c的0與1

0與10與

1都是預設int型別。對於64位機器上int為4bytes,即32bit有符號,再加上絕大多數的機器內部是以補碼的形式儲存的;所以我們把int型的0、1的32位形式補碼表示出來:

0 ->[0000 0000 0000 0000 0000 0000 0000 0000]

-1->[1111 1111 1111 1111 1111 1111 1111 1111]

對於demo2.c的程式是在demo1.c的基礎之上在0後面加上乙個u。故把0隱式轉換為unsigned int,這是無符號int版本。那到底為什麼結果就輸出了bbb呢?這個又有什麼影響呢?

原來c語言是這樣規定的:對於大多數c語言的實現,處理同樣的字長的有符號數和無符號數之間相互轉換的一般規則是:數值可能會改變,但是位模式不變。大概意思就是,現在的demo2.c的條件判斷0u > -1就是unsigned int 0 > [signed] int -1。所以需要乙個型別向另外乙個型別進行隱式轉換。對於同樣字長的有符號數和無符號數之間的隱式轉換是:有符號轉向無符號數,當然,內部位上不會轉變,只是改變讀取位上的方式。所以把原先按照int型別讀取-1的方式,改變為用unsigned int 的方式來讀取其位上的0、1字串序列:因為-1的位模式為[1111 1111 1111 1111 1111 1111 1111 1111],所以其轉換為無符號的十進位制表示即為:unsigned int的最大值4294967295

4294967295

429496

7295

。所以程式中的條件判斷語句0u > -1等價於0u > 4294967295。所以才會得出這個程式執行結果。當然我們也可以驗證一下的:

#include int main()

else

return 0;

}

程式執行結果:

aaa

-1

4294967295

等價於demo1.c

#include int main()

else

return 0;

}

程式執行結果:

bbb

-1

4294967295

等價於demo2.c

這裡再次驗證了結論,就是數值可能會改變,但是位模式不變。

c語言允許在各種不同的數字資料型別之間做強制型別轉換。例如,假設變數x宣告為int,u宣告為unsigned。表示式(unsigned)x會將x的值轉換成乙個無符號數值,而(int)u將u的值轉換成乙個有符號整數。將有符號數強制型別轉換成無符號數,或者反過來,會得到什麼結果?從數學的角度來說,可以想象到幾種不同的規則。很明顯,對於在兩種形式中都能表示的值,我們是想要保持不變的。另外乙個方面,將負數轉換成無符號數可能會得到0.如果轉換的無符號數太大以至於超過了補碼能夠表示的範圍,可能會得到該範圍的最大值。不過,對於c語言的實現來說,對這個問題的回答都是從位級角度來看,而不是從數的角度。

比如說,考慮下面的**:

short int v = -12345;

unsigned short uv = (unsigned short)v;

printf("v = %d, uv = %u\n",v,uv);

在一台採用補碼的機器來說,上述**會產生如下輸出:

v = -12345, uv = 53191

原因如下:

首先對於有符號整型v來說,-12345在採用補碼的機器上面儲存的位模式為[1100 1111 1100 0111]

其次對於無符號整型uv來說,53191在採用補碼的機器上面儲存的位模式位[1100 1111 1100 0111]

還可以反過來檢驗:

/**十六進製制表示寫作0xcfc7的16位位模式既是-12345的補碼表示,又是53191的無符號表示。同時注意:12345+53191 = 65536 = 2^16這個屬性可以推廣到給定位模式的兩個數值(補碼和無符號數)之間的關係。*/

#include int main()

程式輸出示例:

53191

-12345

綜上,***強制型別轉換的結果保持位值不變,只是改變了解釋這些位的方式***。因為由上圖可知,-12345的16位補碼表示與53191的16位無符號表示是完全一致的。將short強制型別轉換為unsigned short改變量值[解釋這些位的方式],但是不改變位表示本身

對於大多數c語言的實現,處理同樣的字長的有符號數和無符號數之間相互轉換的一般規則是:數值可能會改變,但是位模式不變。

有符號數和無符號數

有符號和無符號整數 1.通常情況下,大多數字預設的是有符號數,比如 4,5 要想寫乙個無符號數必須在後面加u 比如 4u,5u 2.在計算機中有符號數是用補碼的形式來表示的,最高位是符號位。無符號數就是正數唄 正數的補碼和原碼相同。比如 1 在計算機中表示為 11111111 11111111 11...

無符號數和有符號數

人有十個手指頭,習慣了逢十進一,於是十進位製成了生活中的標準。程式的世界只有高低電平兩種狀態,更適合用二進位制來表示,於是二進位製成了程式世界的標準。對與無符號數來說,我們更喜歡談他們之間的轉化,十進位制是我們最習慣的進製,於是十進位制轉為r進製,r進製轉為十進位制變尤為重要。十進位制 r進製 整數...

有符號數和無符號數

刷題刷到了有符號數的問題,回顧一下知識點 有符號數 signed 可以區分正負數 最高位表示數值的正負 0表示正數,1表示負數 無符號數 unsigned 不區分正負數 只有整數型別 雖然無符號數所能表示的最大數值大於有符號數,但兩者所能表示的數值範圍相同。eg.short int 128,0 0,...