2011-11-28 95 views
1
#include <stdio.h> 
int arr[] = {1, 2,3,4,5}; 
#define TOT (sizeof(arr)/sizeof(arr[0])) 

int main() 
{ 
    int d = -1, x = 0; 
    if(d<= TOT){ 
     x = arr[4]; 
     printf("%d", TOT); 
    } 
    printf("%d", TOT); 
} 

TOT的值爲5,但if條件失敗......爲什麼?使用sizeof(數組)的宏沒有給出預期的輸出

+0

你有[UB](HTTP ://c2.com/cgi/wiki?UndefinedBehavior)在'printf's中:你說你會傳遞一個'int',但'TOT'的類型不匹配。 – pmg

+0

@pmg實際上C編譯器是否支持%zd語法?看起來甚至沒有GCC做到這一點,我試着用-std = c99 -pedantic並打印出「zd」。 – Lundin

+0

@pmg我想我有一個太過舊版本的GCC ... – Lundin

回答

5

因爲在if的工作中存在「通常的算術轉換」。

運算符sizeof返回無符號類型...並且d轉換爲無符號使其大於arr中的元素數。

嘗試

#define TOT (int)(sizeof(arr)/sizeof(arr[0])) 

if(d<= (int)TOT){ 
+0

挑剔的是,這裏發生的隱式升級是「通常的算術轉換」(又名平衡)。 「整數升級」通常指的是何時將一個小整數類型隱式轉換爲「int」。除非size_t小於int,但我不認爲C標準允許這樣做。 – Lundin

+0

已更改。謝謝@Lundin – pmg

2

這是因爲sizeof返回一個無符號數,而d簽署。當d隱式轉換爲單數號碼,然後它比TOT大得多。

您應該收到關於比較編譯器的無符號比較的警告。

1

您的TOT表達式是unsigned值,因爲操作者sizeof()總是返回無符號(正)值。

當你比較signed可變d有了它,d被自動轉換爲一個非常大的unsigned值,並因此變得更大TOT。的sizeof

0

返回類型爲無符號整數....這就是爲什麼如果失敗......因爲「d」由編譯器作爲簽署了被視爲比TOT更大