2009-02-01 51 views
2

可能重複:
A riddle (in C)爲什麼這兩個程序在ANSI C中表現不同?

1.

main() 
{ 

if(-1<(unsigned char)1) 
    printf("-1 is less than (unsigned char)1:ANSI semantics"); 
else 
    printf("-1 NOT less than (unsigned char)1:K&R semantics"); 
} 

2.

int array[] = {23,41,12,24,52,11}; 
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0])) 
main() 
{ 
    int d = -1,x; 
    if(d<=TOTAL_ELEMENTS -2) 
     x = array[d+1]; 
} 

第一轉換無符號字符1到的標誌ed變量,而第二個程序將d轉換爲一個無符號整型,這使得在ANSI C中 條件表達式返回false。 爲什麼它們的行爲有所不同?

+0

在你的第二個代碼示例中,你的意思是「數組」而不是「arrary」嗎? – mweiss 2009-02-01 09:56:53

回答

4

對於第一個右邊是一個無符號字符,並且所有無符號字符值都適合一個帶符號整數,所以它被轉換爲帶符號整數。

對於第二個,右側是一個無符號整型,所以左側從signed int轉換爲unsigned int。請參閱this CERT document on integer conversions

1

starblue解釋了你的問題的第一部分。我會參加第二部分。因爲TOTAL_ELEMENTSsize_t,它是無符號的,所以int被轉換爲無符號類型。你的size_t是這樣int不能代表它的所有值,所以發生intsize_t的轉換,而不是size_tint

完美定義負數轉換爲無符號:值包裝。如果您將-1轉換爲unsigned int,則結果爲UINT_MAX。無論您是否使用二進制補碼來表示負數,情況都是如此。

rationale for C文件有更多關於保值轉換的信息。

0

這是我記得的方式轉換是如何自動應用:

  • 如果操作數的大小不同,則轉換適用於較小的操作,使其成爲同類型較大的操作數(帶符號延伸如果較小操作數被簽名)

  • 如果操作數的大小相同,但一個是帶符號和無符號等,則符號操作數轉換爲無

雖然上述可能不適用於所有實現,但我相信對於所有二進制補充實現都是正確的。

相關問題