記錄一次詭異的BUG--C 隱式類型轉換

  代碼以下:ui

vector<int> nums = { 1 };
	int i;
	for (i = 0; i < nums.size() - 2; i++){

	}
	cout << i;
複製代碼

  請問上述代碼執行後輸出結果是什麼?答案是-1。   不少人應該和我同樣,第一反應是0,由於nums的長度是1,循環體根本沒有被執行。實際上這是錯誤的,緣由在於nums.size()方法的返回類型爲size_t,size_t的定義爲:spa

typedef _W64 unsigned int   size_t;
複製代碼

也就是說,size_t是無符號整數類型,當計算nums.size()-2時,因爲結果是-1,將發生溢出,溢出後的結果爲2^32-1。所以循環體將會被執行,那麼將會執行多少次呢?因爲i是int類型,nums.size()-2是size_t類型,在對兩者進行比較大小的時候將會發生隱式類型轉換。《C++ Primer》中這樣解釋:當無符號類型與有符號類型進行計算時,有符號類型將會被隱式轉換爲無符號類型,所以i將會被轉換爲size_t類型。但因爲i是int類型,最後輸出結果時,仍是輸出int類型,也就是將無符號整形值2^32-1轉換爲有符號整形,結果爲-1。上述過程發生了比較複雜的類型轉換,因爲C++中的類型轉換規則比較複雜,所以在實際使用中能夠儘可能避免。例如將上述代碼修改成:code

vector<int> nums = { 1 };
	int i;
	for (i = 0; i < (int)nums.size() - 2; i++){

	}
	cout << i;
複製代碼

這樣,輸出結果就是0。class

相關文章
相關標籤/搜索