淺析無符號整型和有符號整型

整型包括長整型(long),短整形(short),整型(int),字符型(char)。衆所周知,char是字符類型。但其實char也是一個比較古怪的整型,長度爲1字節 (默認是無符號類型)。

然後我們來解釋一下有符號數無符號數,首先我們要明白有符號和無符號都是針對二進制數來講的,並且他們都是以補碼的方式在計算機中存儲的。
有符號數:用最高位最符號位,‘0’代表正數,‘1’代表負數,其餘位用作數字位代表數值位。
無符號數:所有位都爲數值位,無正負之分,亦無符號位。

之後我們在來瞧一瞧補碼^_^
正數:原碼,反碼,補碼都相同
負數:反碼爲除符號位外按位取反,補碼爲反碼+1。

好了接下來我們看一下關於無符號和有符號的一些題

1.

int main()
{
    char a = -1;
    signed char b = -1;
    unsigned char c = -1;
    printf("%d %d %d", a, b, c);//a=-1 b=-1 c=255
    system("pause");
    return 0;
}

這個題中的a和b應該比較好理解,但是c呢我們可以來算一下
1000 0001 -1的原碼
1111 1110 -1的反碼
1111 1111 -1的補碼
當一個無符號1字節的整型%d輸出時這就涉及到整型提升(即表達式中的字符和短整型操作數在使用之前被轉換爲普通整型(32bit))
那-1輸出是個它前應加上它的符號位‘’(若在定義是爲有符號數就要要加‘1’)
即輸出 0000 0000 0000 0000 0000 0000 1111 1111
此時依據整型來說此數應是2^8-1=255

2.

char a = -128;
printf("%u\n", a);//1111 1111 1111 1111 1111 1111 1000 0000

我們依舊來分析一下

首先我們先要知道這個-128在內存中是怎麼存儲的
char類型1個字節8個比特位若表示無符號數字的話是0000 0000~1111 1111 即0~255
但如果表示有符號數的話最高比特位應是符號位即
負數:1000 0000~1111 1111 即-128~-1 (我們規定1000 0000是-128)
正數:0000 0000~0111 1111 即0~127
我們再來看上面的這個題
1000 0000 -128
1111 1111 1111 1111 1111 1111 1000 0000 整型提升之後
按無符號整型十進制輸出即4294967168

3.

char a = 128;
printf("%u\n", a);

上面說道char能表示得有符號數字的範圍是0~127和-128~-1
本題中顯然僅靠char中的8個比特位已經不夠表示128了我們可以借一位表示即
1 1000 0000 (此時最高位依舊錶示符號位)
1111 1111 1111 1111 1111 1111 1000 0000(整型提升增加符號位後)
無符號整型是十進制輸出依舊是4294967168

4.

int i = -20;
unsigned int j = 10;
printf("%d\n", i + j);//輸出10

算一波!!!

1000 0000 0000 0000 0000 0000 0001 0100 -20的原碼
1111 1111 1111 1111 1111 1111 1110 1011 -20的反碼

1111 1111 1111 1111 1111 1111 1110 1100 -20的補碼
0000 0000 0000 0000 0000 0000 0000 1010 10的補碼 +
————————————————————————————
1111 1111 1111 1111 1111 1111 1111 0110 i+j的補碼
1111 1111 1111 1111 1111 1111 1111 0101 i+j的反碼
0000 0000 0000 0000 0000 0000 0000 1010 i+j的原碼=10

5.

unsigned i;
for (i = 9; i >= 0; i--)
{
    printf("%u\n",i);
}

此時我們會發現程序陷入了一個停不下來的情況,那這又是爲什麼嘞
我們一定要清楚i是一個無符號數是不可能爲負數的所以條件是一定成立的所以是一個死循環

6.

char a[1000];
int i;
for (i = 0; i < 1000; i++)
{
    a[i] = -1-i;
}
printf("%d", strlen(a));//255

再來看這個代碼首先a是一個無符號的數組,無符號只能放入的數字範圍是0~255所以在第一個數字-1(1111 1111)存入數組時數組會以爲它是一個無符號數255存入,接下來-2(1111 1110)254,以此類推,在存入‘0’時strlen就找到了‘停止符’此時數組裏存入了255~1,255個數字

7.

unsigned char i = 0;
for (i = 0; i <= 255; i++)
{
    printf("Hello World!\n");
}

這個代碼依舊是一個死循環
首先我們知道i是一個無符號數,範圍是0~255,所以for循環裏的條件是永遠成立的,所以它會一直循環下去

好了花了一下午的時間寫的這個,還是那句話,若是有人看到發現什麼問題,希望你們不吝賜教,咱們一起學習一起進步麼是吧~~^_^

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