2012-03-01 100 views
1

可能重複:
Unsigned and signed comparison
A riddle (in C)比較操作

#include<stdio.h> 
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0])) 
int array[] = {23,34,12,17,204,99,16}; 
int main() 
{ 
    int d = -1; 
    if (d < TOTAL_ELEMENTS) 
     printf("of course -1 is less than %d",TOTAL_ELEMENTS); 
    else 
     printf("how on earth"); 
    return 0; 
} 

答案是:::上述程序的輸出是:如何在地球上

+1

你的問題是什麼? – 2012-03-01 15:56:19

+0

另請參閱:http://stackoverflow.com/questions/950051/confused-about-c-macro-expansion-and-integer-arithmetic – Mat 2012-07-01 17:16:40

回答

3

當你執行混合有符號與無符號比較(其中s無符號的類型不大於無符號的類型),則在無符號的域中執行比較,即將有符號的操作數隱式轉換爲無符號類型。

在你的情況下,TOTAL_ELEMENTSsize_t,它是無符號的。這意味着您的d也被隱式轉換爲size_t類型。所以,你的d < TOTAL_ELEMENTS實際上被解釋爲(size_t) d < TOTAL_ELEMENTS(size_t) -1 < TOTAL_ELEMENTS

(size_t) -1是一個非常大的正值。它實際上是size_t類型的最大可能值。因此你得到的結果。

在你的情況下,你顯然想要一個簽名的比較。爲此,您必須將無符號值顯式轉換爲帶符號類型(密切注意不要導致溢出)。例如,這將工作「預期」

if (d < (int) TOTAL_ELEMENTS) 
    ... 
2

這是因爲sizeof_t映射到無符號長類型,所以-1成爲0xFFFFFFFFFFFFFFFF,一個相當大的整數。試試這個:

#include<stdio.h> 
#define TOTAL_ELEMENTS(a) ((int)(sizeof((a))/sizeof(*(a)))) 
int array[] = {23,34,12,17,204,99,16}; 
int main() { 
    int d = -1; 
    if (d < TOTAL_ELEMENTS(array)) { 
     printf("of course -1 is less than %d",TOTAL_ELEMENTS(array)); 
    } else { 
     printf("how on earth"); 
    } 
    return 0; 
} 

注意我如何重新寫你的宏引用array作爲它的參數,並添加了強制轉換爲int,確保比較-1會帶來預期的結果。