有關於變量類型的隱含問題

在C編程的時候,經常遇到類型轉換(強制類型轉換和隱式類型轉換)問題,比如無符號整型到短整型轉換(位截斷),無符號短整型到有符號整型的轉換(位擴展)。如果不瞭解類型轉換的內在原理,寫好的代碼可能會出現意想不到的問題。類型轉換如果從變量的字節數量上來看,可以分爲2類,位擴展和位截斷:

1)位擴展

位擴展,通俗點表達就是字節少的變量轉換爲字節多的變量,比如short到int的轉換。方法如下:

(1)有/無符號的待擴展變量到有/無符號目的變量轉換

如果待擴展變量是有符號的,則用符號位進行填充,使得待擴展變量的字節長度與目標變量字節長度一致。然後,進行符號變換(如果待擴展變量與目的變量都是有符號,則不需要轉換)。

如果待擴展變量是無符號的,則用符號“0”進行填充,使得待擴展變量的字節長度與目標變量字節長度一致。然後,進行符號變換(如果待擴展變量與目的變量都是無符號,則不需轉換)。

short    x = -12345;
unsigned ux = x;// ux = ?

unsigned short y = 12345;
int     sy = y; // sy = ?

有符號變量x是待擴展變量,無符號變量ux爲目的變量。無符號變量y爲待擴展變量,有符號變量sy爲目的變量。

16位的x首先進行位擴展,擴展到32位後的16進製表示:0xffffcfc7。然後進行符號位變換,那麼此時ux表示的值是無符號的(4294967296 - 12345 = 4294954951)

16位的y首先進行位擴展,擴展到32位後的16進製表示:0x00003039。然後進行符號位變換,那麼此時sy表示的值是有符號的(12345 - 4294967296 = -4294954951)

2)位截斷

(1)有/無符號的待截斷變量到有/無符號目的變量的轉換

將待截斷變量先進行無符號變換(有符號的截斷變量需要符號變換,而無符號變量則不需要)。如果目的變量的bit位數是k,而待截斷變量的bit位數是w,則將無符號變換得到的無符號數對2^k取模運算,並將得到的無符號結果進行符號變換(如果目的變量是無符號的則不需要)。

int    x = -12345;
short sx = (short)x; // sx = ?

在此例中,x的16進製表示爲:0xffffcfc7,經過無符號變換後表示的數據爲4294954951,該數據經過截斷後表示的數據爲0xcfc7,0xcfc7經過符號變換後得到數據-12345。看另外一個例子

int    x = 53191;
short sx = (short)x; // sx = ?

x轉換爲4294967296+53191的無符號整數,取模2^16,得到53191的無符號的整數,進行有符號變換,得到52191-65536= -12345的有符號數。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章