主要內容:編譯類型ANSI C和K&R C類型判斷,c編譯器bug的細節
#includeint main() { // 例子1 :編譯器類型判斷 /* * K&R采用無符號保留原則,即當一個無符號類型與ing 或更小的整型混合使用時,結果類型為無符號 * ANSI C采用值保留原則, 即當把幾個整數操作數像下面這樣混合使用時,結果類型可能為有符號也可能為無符號 * ,結果取決於操作數的類型的相對大小 */ if(-1 < (unsigned char)1) // 我使用編譯器是ANSI C, 當寫成if(-1 < (unsigned int)1)時,-1就被轉換成巨大的正數, //而當前表達式卻不轉換,印證了ANSI C值保留原則 printf("-1 is less than (unsigned char)1 : ANSI semantics\n"); else printf("-1 NOT less than (unsigned char)1: K&R semantics\n"); /**************************************************** * 例子2 :錯誤例子說明 * ****************************************************/ int array[] = {1,2,3,4,5,6,7}; #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) /*使用array[0]而不是array[int],可以不改變#define語句的情況下改變array數組的類型(如把int變成char)*/ int d = -1, x; /*(d = -1) <= (7-2 =5) 按理是要打印下面語句 *但是 TOTAL_ELEMENTS返回的是unsigned int類型(因為sizeof()返回 *的類型是無符號數),if語句在signed int和unsigned int之間測試相等性時, *把d的類型提升為unsigned int類型,-1轉換為unsigned int 為很大的正整數, *這個bug在ANSI C中存在,在K&R C中sizeof也是返回無符號,要修正這個問題,只要對 TOTAL_ELEMENTS進行強制類型轉換即可 *加上if (d <= (int)TOTAL_ELEMENTS-2) */ if(d <= TOTAL_ELEMENTS-2) { x = array[d+1]; printf("x = %d\n",x); } /* 小啟發: 1、盡量不要在你的代碼中使用無符號類型,尤其是,不要僅僅因為無符號數不存在負值(如年齡、國債)而用它表示數量 2、盡量使用像int那樣的有符號類型,這樣在涉及升級混合類型的復雜細節時,不必擔心便捷情況(如-1轉換成了非常大的正數) 3、只有在使用位段和二進制掩碼時,才可以用無符號數。應該在表達式中使用強制類型轉換,使操作數均為無符號或有符號, 這樣就不必有編譯器來選擇結果的類型,在第一個例子說明了 */ return 0; }