记C++中发现的隐式转换问题
1 #include <iostream> 2 #include <string> 3 using std::cin; 4 using std::cout; 5 using std::endl; 6 using std::string; 7 int main() 8 { 9 unsigned int a; 10 int b = -1; 11 while (cin >> a) 12 { 13 if (a > b) 14 { 15 cout << "a > b" << endl; 16 } 17 else if (a < b) 18 { 19 cout << "a < b" << endl; 20 } 21 else 22 { 23 cout << "a == b" << endl; 24 } 25 26 } 27 return 0; 28 }
解释:
如果算术运算或关系运算的运算对象有多种类型,需要转换成同一种类型。
这个涉及到无符号类型的运算对象:
如果某个运算符的运算对象不一致,这些运算对象将转换成同一种类型。但是如果某个运算对象的类型是无符号类型,那么转换的结果就要依赖机器中各个整数类型中各个整数类型的相对大小了。
像往常一样,首先执行整型提升。如果结果的类型匹配,无需进行进一步的转换。如果两个(提升后的)运算对象的类型要么都是带符号的、要么都是无符号的,则小类型的运算对象转换成较大的类型。
如果一个运算对象是无符号类型、另外一个运算对象是带符号类型,而且其中的无符号类型不小于带符号类型,那么带符号的运算对象转换成无符号的。如上面的程序中的unsigned int和int,则int类型的运算对象转换成unsigned int类型。如果int型的值恰好为负值,则转换为unsigned int的数值总数去模后的余数。也就造成了a < b的奇怪情况。
例如,8比特大小的unsigned char可以表示0至255区间内的值,如果我们赋了一个区间以外的值,则实际的结果是该值对256取模后所得的余数。因此把-1赋给8比特大小的unsigned char所得的结果是255。
剩下的一种情况是带符号类型大于无符号类型,此时转换的结果依赖于机器,如果无符号类型的所有值都能存在在该带符号类型中,则无符号类型的运算对象转换成带符号类型。如果不能,那么带符号类型的运算对象转换成无符号类型。