一、类型转换
有些表达式的操作数在求值的过程中需要先转换成其他类型再进行运算,这一操作称为数据类型转换。
有些人会问,为什么char类型也可以进行算数运算?
一方面char也是根据ascii表的对应数据存储的,
另一方面使用char类型运算时,char会被升级为int类型。
二、隐式类型转换
在C语言中,许多类型转换都是自动进行的,当char、shot类型出现在表达式里或作为函数的参数时(函数原型除外),都会被升级为int类型。
通常在语句和类型表达式中应使用类型相同的变量或常量,但是 如果使用的混合类型这种非我们本意的异常情况时,C程序并不会死掉或卡在那里,会根据规则进行自动类型转换(隐式),这是它的一个优点,但是这样也可能会导致程序容易出现非预料中的结果。
C的整形算数运算以至少是整形类型的精度来进行,(如果数据本身为更高精度,则以更高的精度来进行),为了获得这个精度,表达式中的字符型和短整形会被转换为普通类型,
这种转换称为 “整形提升” 或 “升级” 。
当在表达式中进行类型转换时,signed,unsigned,char,short int,都会被自动转换成int类型。
举例:
char a,b,c;
a = b+c;
分析:
b 和 c 将先被提升为普通整形,然后进行加法运算,加法运算的结果截取低8位,然后放到a中。假如,a = 250,b =180,最后 a 的结果为174。
解释:a+b结果为430,转换为16进制为1AE,截取8位AE,转换成十进制极为174。
举例:
a = (~a^b<<1)>>1;
由于存在求补和左移操作,8位的精度不够,也需要隐式类型转换。
三、算术转换
如果某个操作符的几个操作数属于不同的类型, 两个值会分别被转换成各自的更高级别,比如int 就会转换为long int。
然后再根据寻常 算术转换 的优先级,将一个操作数的类型转换为另一种操作数的类型。
这里会存在两次转换,一是隐式类型转换,二是算数转换。
寻常算术转换的优先级:
①long double
②double
③float
④unsigned long int
⑤long int
⑥unsigned int
⑦int
优先级转换的顺序为① -> ⑦ ,转换优先级从高到低。如果某个操作数的类型的优先级排名较低,它将被首先转换成另一个操作数的类型,然后执行计算。
四、降级
在赋值表达式语句中,计算结果会被转换成被赋值变量的类型,这一过程中可能会导致数据降级(即被部分截取)或升级。
在函数传参时,函数原型会自动升级,char,short int,都会被自动转换成int,float会被自动转换成double。
“降级”容易出现问题:低级的数据类型存放不下表达式的值。
举例:
如果在8位机上
int a,b;
short int c;
a = 25;
b = 30;
c = b+a;
c的结果为238,我们期望的结果为750。
思考 a+b之后的值,但是又没有赋值给c时存放在哪里,以什么类型存储?
五、强制类型转换
在写代码时应该尽量避免数据类型转换,如果需要进行精确的类型转换或者在程序中表明类型转换的意图,这时候就要用到强制类型转换。
强制类型转换:在某个变量前面放一个使用圆括号括起来的类型名。该类型是需要转换的目标类型。圆括号和它括起来的类型名构成了强制转换类型符。
定义为:
(type)
举例:
int data = 0;
data = 1.6+1.7;
data = (int)1.6 +(int)1.7;
第二行没有进行强制类型转换,第三行进行了强制类型装换,得到data的结果是不一样的
一个是3,一个是2。