各位小夥伴咱們先從乙個簡單的例子demo1.c
入手:
#include int main()
else
return 0;
}
不言而喻,這個程式的執行結果為:因為程式上來就是乙個
aaa
if
判斷語句,如果0
>−1
0 > -1
0>−1
為真,則列印輸出aaa
,反之,則列印輸出bbb
。故輸出了aaa
。
那我們繼續再看,如果在0的後面加上乙個u
,demo2.c
結果會如何?嗯哼?
#include int main()
else
return 0;
}
程式執行結果為:
bbb
下面咱們來簡單**一下,大家都知道
demo1.c
的0與10與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的最大值42949672954294967295
429496
7295
。所以程式中的條件判斷語句
0u > -1
等價於0u > 4294967295
。所以才會得出這個程式執行結果。當然我們也可以驗證一下的:
#include int main()
else
return 0;
}
程式執行結果:
aaa
-1
4294967295
等價於
demo1.c
#include int main()
else
return 0;
}
程式執行結果:c語言允許在各種不同的數字資料型別之間做強制型別轉換。例如,假設變數x宣告為
bbb
-1
4294967295
等價於
demo2.c
這裡再次驗證了結論,就是數值可能會改變,但是位模式不變。
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,...