例:
[cpp] view plain copyunsigned int n = 1024; unsigned int m = 0XFF; 其中1024和oxff這兩個常量都是有符號數(shù),這就意味著每個賦值操作包含了一個隱式的由有符號數(shù)到無符號數(shù)的類型轉(zhuǎn)換。而1024u和0xffu則視為無符號數(shù)。例:
[cpp] view plain copyunsigned char a = 178; unsigned short b = a;a的二進制表示為1011,0010,b的二進制表示為0000,0000,1011,0010,這就是零擴展。零擴展對于應(yīng)匯編(ia32)指令movz。
有符號數(shù)一般使用補碼表示,有符號數(shù)的由短變長的轉(zhuǎn)換使用符號擴展,即較短的數(shù)的二進制表示的最高位是0則用零擴展,同無符號數(shù)的零擴展,而如果是1,則用1來補充缺少的位。例:
[cpp] view plain copychar a = -78; short b = a; a的二進制表示為1011,0010,b的二進制表示為1111,1111,1011,0010。當(dāng)然,此時b的大小仍是-78。而由長變短則更簡單,直接截斷即可,高位的字節(jié)直接丟掉,低位的字節(jié)保持不變。當(dāng)發(fā)生有符號數(shù)和無符號數(shù)之間的強制類型轉(zhuǎn)換時,如果他們的長度是相同(比如int和unsigned一般都是4個字節(jié),short和unsigned short都是兩個字節(jié)),那么在位一級的表示上并沒有變化,即如果都轉(zhuǎn)化為二進制的形式來看,都是一樣的。雖然從二進制01組成的角度來看是一樣的,但我們要知道有符號數(shù)和無符號數(shù)的區(qū)別是最高位的權(quán)值發(fā)生了變化,有符號整數(shù)用補碼表示,最高位的權(quán)值是-2^(w-1),w為位寬,如int類型w大小為32,而無符號整數(shù)的最高為的權(quán)值為2^(w-1)。而如果兩個數(shù)長度不同,則先進行前面提到的2中長度的轉(zhuǎn)換,再進行類型轉(zhuǎn)換。
4. 有符號數(shù)和無符號數(shù)在一起進行運算時,要首先將有符號數(shù)轉(zhuǎn)換為無符號數(shù),再進行運算。
例:
[cpp] view plain copyshort n = -1; unsigned short m = 1; if(m > n) PRintf("m > n"); else printf("m < n");這樣可以得到什么結(jié)果呢?
首先n轉(zhuǎn)化為無符號數(shù),大小為65535,所以輸出是m<n。
5. 整型常量
在1中我們說,如果一個常數(shù)沒有后綴,那么默認的是int類型,如果后綴是u,則默認為unsigned int。但這樣的說法并不完整。
首先,我們默認了常數(shù)的格式是十進制,但是十六進制的也很常用。
然后,還可能出現(xiàn)這樣的情況:給出的常數(shù)的值已經(jīng)超越了int或是unsigned int的范圍。這種情況又該如何處理?
可能目前為止都沒有遇到過這種情況,但是如果發(fā)生該如何理解呢?別急,C標準對這些情形都給出了明確的說明,了解之后你就會知道為啥不知道耶沒有發(fā)生錯誤。
看完下面這張表你也許悟到了點啥,莫名其妙也沒關(guān)系,讓我們來細說一例:
“十進制常數(shù)”和“none”后綴的對應(yīng)的格子里的內(nèi)容是:
int
long int
long long int
這三行的意思是對于沒有后綴的十進制常數(shù),如1024和3147483647,首先用int類型來匹配,int類型值得范圍是-2147483648~2147483647,1024在此范圍之內(nèi),那么這個常數(shù)的類型就是int了,但3147483647不在此范圍之內(nèi),即int類型罩不住,那么看第二行,long int類型,其范圍還依賴于機器的字長,一般32位機上為-2147483648~2147483647,還是罩不住,再看第三行,long long int,其范圍是-9223372036854775808到9223372036854775807,所以3147483647最終匹配的類型是long long int。
對于八進制或十六進制的常數(shù),如果沒有后綴,會先匹配有符號數(shù),再匹配無符號數(shù),畢竟從取值的絕對值的范圍的角度上看無符號數(shù)更廣。
如果一個常數(shù)大的表中沒有任何類型能夠表示,那么就要看有沒有擴展類型能夠表示它,如果沒有,那么這個常數(shù)沒有類型。
| Suffix 后綴 | Decimal Constant 十進制常數(shù) | Octal or Hexadecimal Constant 八或十六進制常數(shù) |
| none | intlong intlong long int | intunsigned intlong intunsigned long intlong long intunsigned long long int |
| u or U | unsigned intunsigned long intunsigned long long int | unsigned intunsigned long intunsigned long long int |
| l or L | long intlong long int | long intunsigned long intlong long intunsigned long long int |
| Both u or Uand l or L | unsigned long intunsigned long long int | unsigned long intunsigned long long int |
| ll or LL | long long int | long long intunsigned long long int |
| Both u or Uand ll or LL | unsigned long long int | unsigned long long int |
參考CSAPP和C99
新聞熱點
疑難解答