1. 程式人生 > >2_有符號與無符號

2_有符號與無符號

計算機中的符號位

- 最高位1, 表明這個數為負數
- 最高位0, 標識這個數為正數

int sign = 0;

char i = -5;
short j = 5;
int k = -1;

sign = (i & 0x80);        // sign 不等於0
sign = (j & 0x8000);      // sign 等於0
sign = (k & 0x80000000);  // sign 不等於0

程式設計實驗:有符號數的符號位

Test_1.c
#include <stdio.h>

int main()
{
    char c = -5;
    short s = 6;
    int i = -7;
    
    printf("%d\n", ((c & 0x80) != 0));
    printf("%d\n", ((s & 0x8000) != 0));
    printf("%d\n", ((i & 0x80000000) != 0));
}

輸出:
1
0
1

有符號的表示法

在計算機內部使用補碼錶示有符號數
    - 正數的補碼為正數本身
    - 負數的補碼為負數的絕對值各位取反後加 1

圖片描述

無符號數的表示法

在計算機內部用原碼錶示無符號數
    - 無符號數預設為正數
    - 無符號數沒有符號位

對於固定長度的無符號數
    - MAX_VALUE + 1 => MIN_VAL
    - MIN_VALUE - 1 => MAX_VAL
    

signed 和 unsigned

- C語言中變數預設為有符號的型別
- unsigned 關鍵字宣告變數為無符號型別

#include <stdio.h>
int main()
{
    int i;            // 預設為帶符號整形
    signed int j;     // 顯示宣告為帶符號整形
    unsigned int k;   // 宣告變數為無符號整形
}

*C語言中只有整數型別能夠宣告 unsigned 變數*

例項分析:當無符號數遇見有符號數

Test_2.c

#include <stdio.h>

int main()
{
     unsigned int i = 5;
     int j = -10;
     
     if( (i + j) > 0 )
     {
         printf("i + j > 0\n");
     }
     else
     {
         printf("i + j <= 0\n");
     }
     
     return 0;
}

輸出:
i + j > 0

分析:這不是我們的期望, (-10 + 5) 應該是大於 0 的,為什麼是這樣的輸出呢?
    *當無符號數與有符號數混合計算時,會將有符號數轉換為無符號數後進行計算,結果為無符號數。*
    

小結

有符號數用補碼錶示
    - 正數的符號位為0
    
    - 負數的符號位為1
    
無符號數用原碼錶示
    - 無符號數沒有符號位
    - 無符號數只能用於表示正數
    
unsigned 只能修飾整數型別的變數