2012-01-28 98 views
1

我寫了這一小段代碼來測試一些:爲什麼比較signed char和unsigned int不能正常工作?

#include <stdio.h> 

int main() 
{ 
    unsigned x = 1; 
    signed char y = -1 ; 
    if (x>y) 
     printf("X > Y"); 
    else 
     printf("X <= Y"); 
    return 0; 
} 

我得到的輸出是「X < = Y」。不是1> -1?

+0

將-1賦值給一個帶符號的變量不會起作用。 – talonmies 2012-01-28 21:38:19

+0

-1當unsigned爲255時 – QuentinUK 2012-01-28 21:38:24

+3

歡迎使用StackOverflow。請使用適當的英語句子,例如「爲什麼我會得到這個輸出?」 「而我會得到這個輸出嗎?」而不是短信。請同時閱讀[常見問題](http://stackoverflow.com/),尤其是[如何在此處提問?](http://stackoverflow.com/faq#howtoask) – 2012-01-28 21:38:34

回答

10

我們:

unsigned x = 1; 
signed char y = -1; 

這個表達式:

x > y 

用作if語句的控制表達式。

經過通常的算術轉換後,右操作數y將轉換爲unsigned int值。負值signed char-1的轉換結果將是一個巨大的值unsigned int(等於UINT_MAX)。

1U > UINT_MAX 

這始終是假(即,評價爲0):

所以表達式x > y將作爲進行評價。

這是簡短的版本。爲了解釋我們如何用C標準規則得出這個結果,我在下面解釋它。

這是怎麼一回事呢:

>關係運算符時,這裏是C對關係運算符說:

關係運算符(C99,6.5.8p3) 「如果兩個操作數都有算術類型,則執行通常的算術轉換。」

好的,在我們的例子中,兩個操作數都是整數類型,整數類型是算術類型。所以通常的算術轉換會完成。通常的算術轉換是什麼? 。

通常的算術轉換(C99,6.3.1.8p1)「,否則,整數優惠是在兩個操作數執行然後以下規則被施加到推動操作數:`

確定,第一個整數促銷是對每個操作數,如何整數宣傳執行?

整數促銷(C99,6.3.1.1p2)「如果int可以代表所有VA原始類型的值,值被轉換爲int;否則,它被轉換爲一個unsigned int。這些被稱爲整數促銷。「

ysigned char型的,它首先被提升爲int整數促銷後xunsigned int類型,並保持一個unsigned int

然後常見的算術轉換會發現兩個操作數之間的常見類型。在我們的例子中,它的意思是:

常見的算術轉換(套)(C99,6.3.1.8p1)「,否則,無論是操作數轉換爲對應於與符號整型操作數的類型的無符號整數類型。」

unsigned int具有相同的轉換秩爲int類型(記住signed char晉升爲int),所以促進了y將從int轉換(以後推廣)至unsigned int。有關信息,整數變換行列在(C99,6.3.1.1p1)中所定義。 正如你可以注意到的,unsigned int在通常的算術轉換中贏得了int,另一種說法是說unsigned粘性

現在是如何的-1int值(其推廣到intsigned char-1)轉換爲unsigned int價值?`。下面是C對整型轉換說,在這種具體情況下:

整數轉換(C99,6.3.1.3p2)「,否則,如果新類型是無符號的,則該值是通過重複地相加或相減轉換的一個比可以在新的類型來表示,直到該值是在新的類型的範圍內的最大值更「。

本段的寫法使得它的含義與簽名的數字表示無關。對於二的補碼錶示,這意味着int-1轉換爲(UINT_MAX + 1) - 1,其等於UINT_MAX。因此,在我們的具體情況,

x > y 

相當於

1U > UINT_MAX 

相當於

0 
7

如果你比較不屬於同一類型的變量,其中一人有比較完成之前被強制成其他的類型。

「較短」類型將被提升爲「較長」類型。

在這種情況下,signed char y將被轉換爲值爲UINT_MAXunsigned int

具體地,假設使用32位ints一個編譯器:

signed char   -1 = 0xff  becomes 
-> signed int   -1 = 0xffffffff becomes 
-> unsigned int 0xffffffff = UINT_MAX 

x < y因此。

+0

實際上是UINT_MAX。 – 2012-01-28 21:40:45

+1

是的,我已經修復了...... [感謝ouah的回答] – Alnitak 2012-01-28 21:41:08

+0

轉換是在'char'側面還是'int'側面完成的?如果它是二進制副本,它不會是'0xFF000000'嗎? – Polynomial 2012-01-28 21:45:06

1

是不是1> -1?

這是,除非你使用unsigned值。在unsigned的世界中,最小值是零和1。其他所有內容都較大,並且該語言明確指出unsigned(-1)最大的無符號值。

+0

我想知道數學是否有一個「最小值」爲'unsigned'?它的算術是模,所以它就像一個圓圈。再少一次('i - '),你最終會在'UINT_MAX'處結束。那麼什麼是「最小」的價值? – 2012-01-28 22:00:06

+1

考慮到'unsigned'' 0 2012-01-28 22:04:09

+0

比較運算符不服從模運算,這很有意義,因爲模運算沒有順序關係。相反,比較運算符在根據升級規則提升其參數後,總是表現正常整數算術*的規律。 – 2012-01-28 22:26:20