C++ 类型转换,切勿混用无符号数和有符号数

类型转换

基本内置类型转换的原则

类型所能表示的值的范围决定了转换的过程:

  • 当我们把一个非布尔类型的算数值赋给布尔类型时,初始值为 0 则结果为 false,否则结果为 true

    例1:
    bool b = 42;            // b 为 true
    
    例2:
    int i = 42;
    if(i) {                 // if 条件的值将为 true 
        i = 0;
    }
    

    当在程序的某处使用了一种算术类型的值而其实所需的是另一种类型的值时,编译器同样会执行类型转换,如上面例 2 中:如果 i 的值为 0,则条件的值为 falsei 的其他所有取值(非 0)都将使条件为 true

    以此类推,如果我们把一个布尔值用在算术表达式里,则它的取值非 0 即 1,所以一般不宜在算术表达式里使用布尔值

  • 当我们把一个布尔值赋给非布尔类型时,初始值为 false 则结果为 0,初始值为 true 则结果为 1

    bool b = 42;            // b 为 true
    int i = b;              // i 的值为 1
    
  • 当我们把一个浮点数赋给整数类型时,进行了近似处理。结果值将仅保留浮点数中小数点之前的部分

    int i = 3.14            // i 的值为 3
    
  • 当我们把一个整数值赋给浮点类型时,小数部分记为 0;。如果该整数所占的空间超过了浮点类型的容量,精度可能有损失

    int i = 3.14            // i 的值为 3
    double pi = i           // pi 的值为 3.0
    
  • 当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。例如,8 比特大小的 unsigned char 可以表示 0 至 255 区间内的值,如果我们赋了一个区间以外的值,则实际的结果是该值对 256 取模后所得的余数。

    例1:
    unsigned char c = -1;   // 假设 char 占 8 字节,c 的值为 255
    
    例2:
    unsigned u1 = 42, u2 = 10;
    cout << u1 - u2 << endl;    // 正确,输出 32
    cout << u2 - u1 << endl;    // 正确,不过结果是取模后的值,
                                // 假设 int 占 4字节,那么结果是 4294967264
    
    例3:
    for(unsigned u = 10; u >= 0; --u) { // u 永远也不会小于 0,循环条件一直成立
        cout << u << endl;
    }
    

    上面例 3 中,假设 int 类型占 32 位,则当 u 等于 0 时,--u 的结果将会是 4294967295.

  • 当我们赋给带符号类型一个超出它表示范围的值时,结果是未定义的(undefined)。此时,程序可能继续工作,可能崩溃,也可能生成垃圾数据。

    signed char c2 = 256;   // 假设 char 占 8 字节,c2的值是未定义的
    

含有无符号类型的表达式

尽管我们不会故意给无符号对象赋一个负值,却可能(特别容易)写出这么做的代码。

当一个算术表达式既有无符号数又有无符号数又有 int 值时,那个 int 值就会转换成无符号数。

若有符号数和无符号数进行运算或比较,会先将有符号数转换为无符号数,然后再进行运算或比较。

unsigned u = 10;
int i = -42;
cout << u + i << endl;      // 如果 int 占 32 位,输出4294967264

切勿混用带符号类型和无符号类型,如果表达式里既有带符号类型又有无符号类型,当带符号类型取值为负时会出现异常结果,这是因为带符号数会自动地转换成无符号数,例如在 a*b 式中,如果 a=-1,b=1,而且 ab 都是 int,则表达式的值显然是 -1。然而如果 aintbunsigned,则结果必须视在当前机器上 int 所占位数而定。在我们的环境里,结果是 4294967295。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值