為什麼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的轉換。