标签:
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 类型不一致 可以得到数据 但是不一定正确
标签:
原文地址:http://www.cnblogs.com/JohnABC/p/4466113.html