C語言中的整數除了可以使用十進制,還可以使用二進制、八進制和十六進制。
一個數字預設就是十進制的,表示一個十進制數位不需要任何特殊的格式。但是,表示一個二進制、八進制或者十六進制數位就不一樣了,爲了和十進制數位區分開來,必須採用某種特殊的寫法,具體來說,就是在數位前面加上特定的字元,也就是加字首。
二進制由 0 和 1 兩個數位組成,使用時必須以 0b
或 0B
(不區分大小寫)開頭,例如:
//合法的二進制
int a = 0b101; //換算成十進制爲 5
int b = -0b110010; //換算成十進制爲 -50
int c = 0B100001; //換算成十進制爲 33
//非法的二進制
int m = 101010; //無字首 0B,相當於十進制
int n = 0B410; //4不是有效的二進制數位
請注意,標準的C語言並不支援上面的二進制寫法,只是有些編譯器自己進行了擴充套件,才支援二進制數位。換句話說,並不是所有的編譯器都支援二進制數位,只有一部分編譯器支援,並且跟編譯器的版本有關係。
八進制由 0~7 八個數位組成,使用時必須以 0
開頭(注意是數位 0,不是字母 o),例如:
//合法的八進制數
int a = 015; //換算成十進制爲 13
int b = -0101; //換算成十進制爲 -65
int c = 0177777; //換算成十進制爲 65535
//非法的八進制
int m = 256; //無字首 0,相當於十進制
int n = 03A2; //A不是有效的八進制數位
十六進制由數位 0~9、字母 A~F 或 a~f(不區分大小寫)組成,使用時必須以 0x
或 0X
(不區分大小寫)開頭,例如:
//合法的十六進制
int a = 0X2A; //換算成十進制爲 42
int b = -0XA0; //換算成十進制爲 -160
int c = 0xffff; //換算成十進制爲 65535
//非法的十六進制
int m = 5A; //沒有字首 0X,是一個無效數位
int n = 0X3H; //H不是有效的十六進制數位
十進制由 0~9 十個數位組成,沒有任何字首,和平時的書寫格式一樣。
C語言中常用的整數有 short、int 和 long 三種類型,通過 printf 函數,可以將它們以八進制、十進制和十六進制的形式輸出。下表列出了不同類型的整數、以不同進制的形式輸出時對應的格式控制符:
short | int | long | |
---|---|---|---|
八進制 | %ho | %o | %lo |
十進制 | %hd | %d | %ld |
十六進制 | %hx 或者 %hX | %x 或者 %X | %lx 或者 %lX |
十六進制數位的表示用到了英文字母,有大小寫之分,要在格式控制符中體現出來:
x
小寫,表明以小寫字母的形式輸出十六進制數;X
大寫,表明以大寫字母的形式輸出十六進制數。八進制數位和十進制數位不區分大小寫,所以格式控制符都用小寫形式。如果想使用大寫形式,那麼行爲是未定義的:
注意,雖然部分編譯器支援二進制數位的表示,但是卻不能使用 printf 函數輸出二進制,這一點比較遺憾。當然,通過轉換函數可以將其它進位制數位轉換成二進制數位,並以字串的形式儲存,然後在 printf 函數中使用%s
輸出即可。
#include <stdio.h>
int main()
{
short a = 0b1010110; //二進制數位
int b = 02713; //八進制數位
long c = 0X1DAB83; //十六進制數位
printf("a=%ho, b=%o, c=%lo\n", a, b, c); //以八進制形式輸出
printf("a=%hd, b=%d, c=%ld\n", a, b, c); //以十進制形式輸出
printf("a=%hx, b=%x, c=%lx\n", a, b, c); //以十六進制形式輸出(字母小寫)
printf("a=%hX, b=%X, c=%lX\n", a, b, c); //以十六進制形式輸出(字母大寫)
return 0;
}
執行結果:
a=126, b=2713, c=7325603
a=86, b=1483, c=1944451
a=56, b=5cb, c=1dab83
a=56, b=5CB, c=1DAB83
可以發現,一個數字不管以何種進位制來表示,都能夠以任意進位制的形式輸出。數位在記憶體中始終以二進制的形式儲存,其它進位制的數位在儲存前都必須轉換爲二進制形式;同理,一個數字在輸出時要進行逆向的轉換,也就是從二進制轉換爲其他進位制。
注意觀察上面的例子,會發現有一點不完美,如果只看輸出結果:
區分不同進制數位的一個簡單辦法就是,在輸出時帶上特定的字首。在格式控制符中加上 #
即可輸出字首,例如 %#x、%#o、%#lX、%#ho 等,請看下面 下麪的程式碼:
#include <stdio.h>
int main()
{
short a = 0b1010110; //二進制數位
int b = 02713; //八進制數位
long c = 0X1DAB83; //十六進制數位
printf("a=%#ho, b=%#o, c=%#lo\n", a, b, c); //以八進制形似輸出
printf("a=%hd, b=%d, c=%ld\n", a, b, c); //以十進制形式輸出
printf("a=%#hx, b=%#x, c=%#lx\n", a, b, c); //以十六進制形式輸出(字母小寫)
printf("a=%#hX, b=%#X, c=%#lX\n", a, b, c); //以十六進制形式輸出(字母大寫)
return 0;
}
執行結果:
a=0126, b=02713, c=07325603
a=86, b=1483, c=1944451
a=0x56, b=0x5cb, c=0x1dab83
a=0X56, b=0X5CB, c=0X1DAB83
十進制數位沒有字首,所以不用加 #
。如果你加上了,那麼它的行爲是未定義的,有的編譯器支援十進制加 #
,只不過輸出結果和沒有加#
一樣,有的編譯器不支援加#
,可能會報錯,也可能會導致奇怪的輸出;但是,大部分編譯器都能正常輸出,不至於當成一種錯誤。