2011-05-10 52 views
0

好吧我知道這個問題可能有些不可思議,但我仍然想讓它神祕化。關於C整數類型和printf()說明符的奇怪問題

1)一個int類型在C可在-2147483648範圍存儲號碼爲2147483647

2.)如果我們追加一個unsigned它前面的它的範圍內,將成爲0到2147483647

3.)事情是,爲什麼我們甚至懶得使用關鍵字unsigned時,下面的代碼可以實際工作。


驗證碼:

#include <stdio.h> 

int main(void) 
{ 
    int num = 2147483650; 

    printf("%u\n" , num); 

    return 0; 
} 


4)如你所見,我仍然可以打印出整數unsigned型,如果我用%u符和它會打印我的價值2147483650

5)即使我創建另一個整數類型與價值50num概括起來講,雖然它的溢出,但我卻仍然可以通過使用%u specifier.So打印出正確的和值爲什麼unsigned關鍵詞仍然是一個必要性??

感謝您花時間閱讀我的問題。

+0

除了未定義的行爲之外,打印對於('unsigned')整數的唯一有意義的操作還遠遠不夠。 – 2011-05-10 16:30:25

回答

2

只考慮Q3, 「爲什麼我們懶得使用unsigned」,考慮這個程序片段:

int main(void) { 

    int num = MAX_INT; 
    num += 50; 

    printf("%u\n", num); /* Yes, this *might* print what you want */ 

    /* But this "if" almost certainly won't do what you want. */ 
    if(num > 0) { 
    printf("Big numbers are big\n"); 
    } else { 
    printf("Big numbers are small\n"); 
    } 
} 

我們使用 「簽名」,因爲從unsigned int行爲int不同。除printf的工作方式外,還有更多有趣的行爲。

+0

無符號整數的一個常見用法是用位。當被移位或旋轉比無符號整數多個位時,帶符號整數的行爲會有所不同。 – 2011-05-10 19:12:49

5
  1. 沒有,這是真實的,只有在某些平臺上(其中一個int爲32位,二進制補碼)。

  2. 否,在這種情況下,範圍將是0到4294967295

  3. 該代碼呈現未定義行爲

  4. 請參閱第3

  5. 請參閱第2和3

0
  1. 錯誤。範圍是INT_MIN(在2個補充系統中通常是-INT_MAX + 1)到INT_MAX; INT_MAX和INT_MIN取決於編譯器,體系結構等。

  2. 錯誤。範圍是0到UINT_MAX,通常是INT_MAX * 2 + 1

  3. 無符號整數在溢出和語義方面有不同的行爲。在2補碼中,有一個未定義爲有符號整數的值(即只設置了最高位,其餘爲零),這有點雙重含義。無符號整數可以使用全部位模式。下面是一個練習:在32位機器上比較printf的輸出(「%d%u」,0xffffffff,0xffffffff);

  4. 由於無符號整數的行爲與有符號整數的行爲不同。

+0

請注意,應該是'INT_MAX * 2 + 1'... – 2011-05-10 16:38:31

+0

@Oli:對,你又是了。 – datenwolf 2011-05-10 16:47:17

+0

@pmg:澄清它。 – datenwolf 2011-05-11 08:31:55

0

那麼,首先,分配超出範圍的數字的結果是實現定義的 - 它不必爲使用%u格式說明符打印時提供「有效」的值。但要真正回答你的問題,認爲這是修改代碼:

#include <stdio.h> 

int main(void) 
{ 
    int num = 2147483650; 
    unsigned num2 = 2147483650; 

    num /= 2; 
    num2 /= 2; 

    printf("%u, %u\n" , num, num2); 

    return 0; 
} 

(如果2147483650超出的int你的平臺上的範圍,但unsigned的範圍之內,那麼你只會得到的正確答案1073741825使用unsigned類型)。