C 语言中类型转换遵循下面原则:
1. 若参与运算量的类型不同,则先转换成同一类型,然后进行运算
2. 转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算
a、若两种类型的字节数不同,转换成字节数高的类型
b、若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型
#includeint main() { long i = -1; unsigned long j = 1; if(i > j) printf("-1L > 1ULn"); else printf("1UL > -1Ln"); return 0; }
上述代码的输出结果是 :
-1L > 1UL
之所以出现上述结果是由于在比较时候,带符号类型long自动转换成了unsigned类型
可见不同数据类型作比较或运算也许得不到预期的结果,程序中应避免这种情况。
另外看下面程序
#includeint main() { int i = -2; unsigned int j = 10; printf("%dn", i*j); printf("%dn", i*j/10); return 0; }
用gcc编译的运行结果为:
-20 429496727
当用%d打印i*j的运算结果时,首先会把i转换成unsigned int类型,由于负数是以补码的形式表示,所以-2的补码是0xFFFFFFFE,i*j之后的值为0x9FFFFFFEC,在%d打印时会把其进行舍位 *** 作,舍位之后为0xFFFFFFEC,最高位代表符号位,所以这个值为-20.
i*j/10计算过程是:先计算i*j,然后舍位后为0xFFFFFFEC,然后以unsigned int形式除以10, 由于是整数除法,会舍弃小数部分,所以实际计算过程为4294967276/10 = 429496727.
3. 所有的浮点运算都是以双精度进行的,即使是两个float单精度量运算的表达式,也要先转换成double型,再作运算.(书中说两个float型运算时并不会转换成double型)
4. char型和short型参与运算时,都先转换成int型
5. 在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。
如果右边量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度,舍入方向根据机器不同而不同。
详细的数据类型转换规则见如下链接:
http://akaedu.github.io/book/ch15s03.html
编码时要注意:
1. 避免不同类型的数据参与运算(比较),如确实需要参与运算,一定要转换成同一类型进行。
例如上述代码,写成 printf("%dn", i*(int)j/10); 时才能得到正确的结果。
2. 强制类型转换不会改变原变量的数据属性
如下面代码:
#includeint main() { float i = 2.3; printf("%fn", (unsigned int)i); printf("%fn", i); return 0; }
运行结果为:
0.000000 2.300000
打印时强制转换i,并没有影响i本身的值。
注:float转int没有任何意义,因为两者的数据表示方法不同。(用floor或ceil函数)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)