程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 程序猿之---C語言細節16(看了絕對值,編譯類型ANSI C和K&R C類型判斷,c編譯器類型轉換bug的細節)

程序猿之---C語言細節16(看了絕對值,編譯類型ANSI C和K&R C類型判斷,c編譯器類型轉換bug的細節)

編輯:關於C語言

程序猿之---C語言細節16(看了絕對值,編譯類型ANSI C和K&R C類型判斷,c編譯器類型轉換bug的細節)


主要內容:編譯類型ANSI C和K&R C類型判斷,c編譯器bug的細節

#include 

int 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;
}

輸出:



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved