我们常常将不同类型的数据相互转换,但也常常发生错误。当然可以由编译器来帮忙检查。但是,我们认为的一些数据类型转换的错误在C++里有可能完全合法。从而编译器没法检查出来。下面看这样一段代码:
#include<iostream>
using namespace std;
int main()
{
bool b = 42; //b为真
int i = b; //i的值为1
i = 3.14; //i的值为3
double pi = i; //pi的值为3.0
unsigned char c = -1; //书上说是255
signed char c2 = 256; //未定义
cout << b << endl;
system("pause");
return 0;
}
你会发现编译器全通过了,让我们看看具体是怎么转换的:
- 当我们把一个非bool类型赋给bool时,0代表false,其余结果为true。
- 当我们把一个bool赋给非bool时,false对应的结果为0,true对应的结果为1;
- 当我们把一个非int类型赋值给int时,结果保留整数部分。
- 当我们把非doudle类型赋值给doudle类型时,小数部分为0。
- 当我们赋给无符号类型一个超过它范围的值时。结果为对无符号类型范围取模后的余数。
- 当赋给带符号类型一个超过它表示范围的值时,结果为未定义。很可能让程序崩溃。
含有无符号类型和有符号类型同时运算
当一个算数表达式既有无符号又有int值时,int将先转换为无符号类型。然后在进行运算。
#include <iostream>
using namespace std;
int main()
{
int i = -42;
unsigned u = 10;
cout << i + i << endl; //输出 -84
cout << i + u << endl; //输出 4294967264
system("pause");
return 0;
}
你会发现i+u变成了一个很可怕的数。让我们看看具体怎么得到这个可怕的数:
- int为32位,范围为2^32=4294967296。
- 根据取模的定义(-42+4294967296)%4294967296=4294967254。
- 4294967254+10=4294967264。
结论
当赋给无符号负数时就进行取模运算。
参考:C++primer 第五版
网友评论