1. 程式人生 > >為什麼INT_MIN不是直接寫成-2147483648

為什麼INT_MIN不是直接寫成-2147483648

轉載自https://www.cnblogs.com/helloWaston/p/4624543.html

最近在程式設計中遇到一個問題:

 

#include <iostream>

using namespace std;

int main()
{	
	int n = -2147483648;
	//cout << (1 > -2147483648) << endl;
	
	return 0;
}

 

使用VS2012編譯提示:error C4146: 一元負運算子應用於無符號型別,結果仍為無符號型別

使用g++編譯提示:

 

test.c:7:2: warning: this decimal constant is unsigned only in ISO C90 [enabled
by default]

在網上搜索,發現VS之前的版本提示的是warning,而到了VS2012版本就直接提示為error,加強了嚴重性。

 

 

實際上,當程式設計師嘗試表達最小整數值 -2147483648 時,會發生此問題。 該值不能寫為 -2147483648,因為表示式處理分兩個步驟:

1. 計算數字 2147483648。 因 2147483648 大於最大整數值 2147483647,所以其型別不是 int,而是 unsigned int。

2. 將一元負應用於該值,得到無符號結果(即還是無符號數),該結果碰巧是 2147483648。

而這種隱含轉換的無符號型別的結果可能導致意外行為,所以編譯器會提示waring甚至在VS2012中直接提示error。

 

關於導致的意外行為,參看上述程式碼註釋行: cout << (1 > -2147483648) << endl;

因為-2147483648會被轉換為unsigned即2147483648,同時在比較中1也會被提升為unsigned,從而得到結果0,而這行程式碼我原意是比較兩個int數,結果預計為1。

 

如何避免出現編譯器提示waring甚至是error?

1. 使用limits.h中巨集定義的INT_MIN。那為什麼使用了該巨集定義就不提示了呢?具體看其定義:

#define INT_MIN     (-2147483647 - 1) /* minimum (signed) int value */

不是直接給出-2147483648的常量來避免;

2. 根據上述提示,因而給int變數賦最小int值時,也可以使用 n = -2147483647 - 1 或者你想特立獨行的搞個 n = -2147483646 - 2,只要不直接出現-2147483648就不會出現unsiged的轉換。