1. 程式人生 > >C之有符號與無符號(二)

C之有符號與無符號(二)

C語言 有符號數 無符號數

我們在 C 語言中經常會見到 unsigned 關鍵字,那麽這是什麽意思呢?在計算機內,數據類型分為有符號和無符號兩種類型。它的最高位用於標識數據的符號:如果最高位為 1,表明這個數為負數;如果是0的則表明這個數為正數。那麽我們就來做個試驗驗證下,代碼如下所示:

#include <stdio.h>

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

c 為負數最高位為1,理論上 & 之後應該不等於0,所以打印的會是1;s 為正數最高位為0,,理論上 & 之後應該等於0,打印的會是0;i 位負數,會打印1。下來我們在 Linux 環境中用 gcc 編譯下,看看結果是否和我們分析的一致,結果如下:

技術分享圖片

我們打印的結果也從側面證實了我們的分析是對的。那麽在計算機內部是怎樣表示有符號數的呢?答案用補碼來表示,正數的補碼為正數本身,負數的補碼為負數的絕對值各位取反後加1。我們來分析下 -7 的補碼是多少?

-7 ==> |-7| + (末位+1)==> 111 + 1==> 0000 0111 + 1 ==> 1111 1000 + 1 ==> 1111 1001

這是我們分析的結果,那麽我們用計算器轉換下看看,是否和我們分析的一致呢?

技術分享圖片技術分享圖片

我們看到結果和我們分析的是一致的。在計算機內部用原碼表示無符號數,無符號數默認為正數,無符號數沒有符號位。對於固定長度的無符號數,MAX_VALUE + 1 ==> MIN_VALUE,MIN_VALUE - 1 ==> MAX_VALUE。

在 C 語言中變量默認為有符號的類型,unsigned 關鍵字聲明變量為無符號類型。註意:C 語言中只有整數類型能夠聲明 unsigned 變量。下來我們再做個試驗,代碼如下:

#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,可事實是這樣嗎?我們來編譯下,得到結果如下:

技術分享圖片

結果和我們想的不一樣,那麽這是怎麽回事呢?原來在計算機內部,當有符號數和無符號數混合運算時,計算機將自動的將有符號數轉換為無符號數後再進行計算,結果為無符號數。那麽這個程序輸出的結果當然是大於0的啦。

我們在這塊要註意一個陷阱,那就是錯誤的使用了 unsigned 。我們來看這樣一個例子,代碼如下:

#include <stdio.h>

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

在我們的認為中,這個程序會輸出 0-9 就完了,那麽真是這樣嗎?我們編譯下,看看結果

技術分享圖片

結果就是如上圖所示,那麽這些這麽的大的數字是在哪打印出來的呢?程序在不停輸出,不得已中斷程序的運行。仔細的看看我們的示例代碼,我們定義的是 unsigned int 類型的,無符號類型的。因而它是一直大於0的,在減到0的時候,再次減1就是 2^32 - 1 了。為什麽是32呢?因為在 Linux 中,int 型數據是 4 個字節,每個字節占 8 bit,所以一共占 32 bit位。

那麽我們本節學習了有符號數與無符號數。有符號數用補碼表示:正數的符號位為0,負數的符號位為1。無符號數用原碼表示:無符號數沒有符號位,無符號數只用於表示正數。unsigned 只能修飾整數類型的變量,當有符號數和無符號數混合運算時,計算機將自動的將有符號數轉換為無符號數後再進行計算,結果為無符號數。後面我們會繼續學習 C 語言的相關知識。


有興趣的可以加我一起學習 C 語言,QQ:243343083


C之有符號與無符號(二)