数据转换
C语言中的数据转换指的是当不同类型的数据作为操作数时,某些运算符的操作会导致这些操作数的值从一种类型转换为另一种类型。请注意这仅仅是数据的值的类型转换,而不是数据的类型的转换。即: unsigned char Test = 256; 此时 Test的类型为unsigned char 类型,此类型最大值为255, 因此此时Test的值的类型会转换为int 类型。而Test的类型仍然为unsigned char类型。
数据的值的转换按照转换方式可以大致分为隐式(自动)转换和显式(强制)转换。两种转换的结果都一样,区别在于是否有目的的转换(尤其对于指针转换而言)。【本文将不特别区别自动转换和强制转换】
按照转换“方向”可以大致分为“升级”和“降级”。 升级即有较低级别的类型转换为较高级别的类型;降级则相反。
数据转换的目的就是让不同类型的操作数的类型转换为同一类型。一般来说,自动转换会把“较窄”的操作数转换为“较宽”的操作数,进行的是“升级”操作,目的为不丢失数据信息。
一般情况下,自动转换是“保险”的,但有些时候也不得不对自动转换有些“提防”。
例如:
char Test = -1;
这里Test的值就一定是你看到的-1么? 这可不一定! 对于赋值操作来说也是要进行自动转换的! 这里还要涉及到的是对于char这种类型来说倒底是signed char 还是unsigned char 是和编译器的实现相关,也就是说 Test的值有可能是-1 (signed char);也有可能是255 ( unsigned char)。
还有对于函数的返回值的自动转换:
int fun(void)
{
......
return (int)value;
}
对上面的函数的返回值进行保存的时候,如果数据类型不同,也会发生数据转换,也会出现“意想不到”的情况。
下面描述一下一般情况下的算术类型转换(由上至下)
1,如果任何一个操作数为long double类型,则将另一个操作数转换为long double类型;
2,如果任何一个操作数为double类型,则将另一个操作数转换为double类型;
3,如果任何一个操作数为float类型,则将另一个操作数转换为float类型;
4, 对于整型首先对两个操作数进行整形提升;
5,如果任何一个操作数为 unsigned long int 类型,则将另一个操作数转换为 unsigned long int 类型;
6,如果任何一个操作数为 long int 类型,另一个操作数为unsigned int类型。则要看编译器对于int类型,和long int类型哪个更宽,转换为其中更宽的那个。
7,如果任何一个操作数为 long int 类型,则将另一个操作数转换为 long int 类型;
8,如果任何一个操作数为 unsigned int 类型,则将另一个操作数转换为 unsigned int 类型;
9,其余都转换为int 类型;
还有一种情况就是指针的转换,这种转换为函数的实现提供了极大便利: 函数实现无需关心具体数据的类型。函数仅仅需要将调用者传入的指针都作为(void *)类型,转换为自己处理的类型。这个强转指针保证数据类型的任务交给函数的调用者。 这就给程序的调用和实现者都提出了很高的要求,就是对于指针所指对象的对齐提出很高要求,否则会很容易出现由于强转指针导致地址异常的情况。
参考:
1,《C程序设计语言》K&R 第二版
2,http://hi.baidu.com/supersu30/blog/item/862cae97cee97a6855fb967b.html 作者:风急云却静
- 无匹配