码迷,mamicode.com
首页 > 其他好文 > 详细

C-类型转换(陷阱)

时间:2015-04-29 16:44:28      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

1.自动类型转换(运算符两边变量类型不同时)

  1).两个变量类型自动转换成一样的类型(会根据参数类型自动转换, 而不是直接位转换), 且运算结果也是转换后的类型

  2).当较低类型的数据转换为较高类型时, 一般只是形式上有所改变, 而不影响数据的实质内容, 而较高类型的数据转换为较低类型时则可能有些数据丢失

  3).在进行自动类型转换的时候, 如果原来的数是无符号数, 那么在扩展的时候, 高位填充的是0, 如果是有符号数, 那么高位填充的时符号位

#include <stdio.h>

int main() {
    unsigned int a = 8;
    if (a > -1) printf("8>-1\n");
    else printf("8<=-1\n");
    return 0;
}

  输出结果是8<-1, 明明赋值为8的变量i, 结果被程序判定比-1还小, 这是怎么回事?

  问题根源在于变量i定义中的unsigned; 我们都知道, int/short/char等类型分signed和unsigned, C的表达式中signed和unsigned混合运算有三种情况:

    a.操作数全为signed

    b.操作数全为unsigned

    c.操作数混合了signed和unsigned

  前两种情况,相同符号操作没什么问题, 可情形c.涉及不同符号间的混合计算就要注意, 编译器会自动对操作数进行规整化:只要表达式中存在一个无符号数, 所有操作数都被转化为无符号数, 运算按相应无符号操作符进行, 计算结果也是一个无符号数(结论:运算时变量会自动转换, 且计算结果同转换后的类型)

  为防止意外转换, 一方面要显式指定类型, 不要用int, char这种缺少提示的中性表示法, 这种含糊的表示用多了, 会本能地忽略和回避符号问题; 另一方面要谨慎选用unsigned型, 不要仅仅因为无符号数没有负值就用它表示数量, 比如有人喜欢用unsigned int定义for/while循环计数量, 这很不安全, 一不小心在循环内和负数做比较, 就会发生逻辑错误或死循环; 最后, 如果非要让unsigned型参与计算, 可以用强制类型转换保证中间操作数和结果为signed

2.赋值中的类型转换, 当赋值运算符两边的运算对象类型不同时, 将要发生类型转换, 转换的规则是: 把赋值运算符右侧表达式的类型转换为左侧变量的类型, 具体的转换如下:

  1).浮点型与整型 

    将浮点数(单双精度)转换为整数时, 将舍弃浮点数的小数部分, 只保留整数部分

    将整型值赋给浮点型变量, 数值不变, 只将形式改为浮点形式, 即小数点后带若干个0

    注意:赋值时的类型转换实际上是强制的

  2).单、双精度浮点型

    由于C语言中的浮点值总是用双精度表示的, 所以:

    float型数据只是在尾部加0延长为doub1e型数据参加运算, 然后直接赋值

    doub1e型数据转换为float型时, 通过截尾数来实现, 截断前要进行四舍五入操作

  3).char型与int型

    int型数值赋给char型变量时, 只保留其最低8位, 高位部分舍弃

    char型数值赋给int型变量时, 一些编译程序不管其值大小都作正数处理, 而另一些编译程序在转换时, 若char型数据值大于127, 就作为负数处理; 对于使用者来讲, 如果原来char型数据取正值, 转换后仍为正值;如果原来char型值可正可负, 则转换后也仍然保持原值, 只是数据的内部表示形式有所不同

  4)int型与long型

    long型数据赋给int型变量时, 将低16位值送给int型变量, 而将高16 位截断舍弃(这里假定int型占两个字节)

    int型数据送给long型变量时, 其外部值保持不变, 而内部形式有所改变

  5)无符号整数

    将一个unsigned 型数据赋给一个占据同样长度存储单元的整型变量时(如:unsigned→int、unsigned long→long,unsigned short→short), 原值照赋, 内部的存储方式不变, 但外部值却可能改变

    将一个非unsigned整型数据赋给长度相同的unsigned型变量时, 内部存储形式不变, 但外部表示时总是无符号的

    计算机中数据用补码表示, int型量最高位是符号位, 为1时表示负值, 为0时表示正值; 如果一个无符号数的值小于32768则最高位为0, 赋给int型变量后、得到正值; 如果无符号数大于等于32768, 则最高位为1, 赋给整型变量后就得到一个负整数值; 反之, 当一个负整数赋给unsigned 型变量时, 得到的无符号值是一个大于32768的值, (这里假定int型占两个字节)

    C语言这种赋值时的类型转换形式可能会使人感到不精密和不严格, 因为不管表达式的值怎样, 系统都自动将其转为赋值运算符左部变量的类型, 而转变后数据可能有所不同, 在不加注意时就可能带来错误, 这确实是个缺点, 也遭到许多人们批评, 但不应忘记的是:C面言最初是为了替代汇编语言而设计的, 所以类型变换比较随意, 当然, 用强制类型转换是一个好习惯, 这样, 至少从程序上可以看出想干什么

3.强制类型转换

  对于从高到低的强制转换, 实质上就是一个截断的操作, 只把低端需要的部分保留, 其余的部分直接扔掉了

2.printf 就是按照什么类型去打印一串010101010111

3.scanf 类型不一致 可以得到数据 但是不一定正确

 

C-类型转换(陷阱)

标签:

原文地址:http://www.cnblogs.com/JohnABC/p/4466113.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!