当一个算数表达式中既有无符号数又有int值的时候,那个int值就会转换成无符号数。把int转换成无符号数的过程和把int直接赋值给无符号变量一样。
unsigned u = 10;
int i = -42;
std::cout<<i + u <<std::endl;//输出-84
std::cout<< u + i <<std::endl;//如果int占32位,输出4294967264
在第一个输出表达式里,两个(负)整数相加并得到了期望的结果。在第二个输出表达式里,相加前首先把整数-42转换成无符号数。把负数转换成无符号数类似于直接给无符号数赋一个负值,结果等于负数加上无符号数的模。
当从无符号数中减去一个值时,不管这个值是不是无符号数,我们多必须确保结果不能是一个负值。
unsigned u1 = 42,u2 = 10;
std::cout<< u1 - u2 <<std::endl;//正确:输出32
std::cout<<u2 - u1 <<std::endl;//正确:不过,结果是取模后多值
无符号数不会小于0这一事实同样关系到循环的写法。
正确写法:
for (int u = 10; u >= 0; —-i)
std::cout<<i<<std::endl;
错误写法
for(unsigned u = 10;u >= 0; —-u)
std::cout << u<< std::endl;
来看看当u等于0时发生了什么,这次迭代输出0,然后继续执行for语句里的表达式。表达式—u从u当中减去1,得到的结果-1并不满足无符号数的要求,此时像所有表示范围之外的其他数字一样,-1被自动地转换成一个合法的无符号数。假设int类型32位,则当u等于0时,—u的结果将会是4294967295.
一种解决的办法是,用while语句来代替for语句,因为前者让我们能够在输出变量之前(而非之后)先减去1:
unsigned u = 11;
while(u > 0)
{
—u;
std::out<<u<<std::endl;
}