设为首页 加入收藏

TOP

4.11.1 算术转换
2013-10-07 16:28:55 来源: 作者: 【 】 浏览:111
Tags:4.11.1 算术 转换

4.11.1  算术转换

算术转换(arithmetic conversion)的含义是把一种算术类型转换成另外一种算术类型,这一点在2.1.2节(第35页)中已有介绍。算术转换的规则定义了一套类型转换的层次,其中运算符的运算对象将转换成最宽的类型。例如,如果一个运算对象的类型是long double,那么不论另外一个运算对象的类型是什么都会转换成long double。还有一种更普遍的情况,当表达式中既有浮点类型也有整数类型时,整数值将转换成相应的浮点类型。

整型提升

整型提升(integral promotion)负责把小整数类型转换成较大的整数类型。对于bool、char、signed char、unsigned char、short和unsigned short等类型来说,只要它们所有可能的值都能存在int里,它们就会提升成int类型;否则,提升成unsigned int类型。就如我们所熟知的,布尔值false提升成0、true提升成1。

较大的char类型(wchar_t、char16_t、char32_t)提升成int、unsigned int、long、unsigned long、long long和unsigned long long中最小的一种类型,前提是转换后的类型要能容纳原类型所有可能的值。

无符号类型的运算对象

如果某个运算符的运算对象类型不一致,这些运算对象将转换成同一种类型。但是如果某个运算对象的类型是无符号类型,那么转换的结果就要依赖于机器中各个整数类型的相对大小了。

像往常一样,首先执行整型提升。如果结果的类型匹配,无须进行进一步的转换。如果两个(提升后的)运算对象的类型要么都是带符号的、要么都是无符号的,则小类型的运算对象转换成较大的类型。

如果一个运算对象是无符号类型、另外一个运算对象是带符号类型,而且其中的无符号类型不小于带符号类型,那么带符号的运算对象转换成无符号的。例如,假设两个类型分别是unsigned int和int,则int类型的运算对象转换成unsigned int类型。需要注意的是,如果int型的值恰好为负值,其结果将以2.1.2节(第35页)介绍的方法转换,并带来该节描述的所有副作用。

剩下的一种情况是带符号类型大于无符号类型,此时转换的结果依赖于机器。如果无符号类型的所有值都能存在该带符号类型中,则无符号类型的运算对象转换成带符号类型。如果不能,那么带符号类型的运算对象转换成无符号类型。例如,如果两个运算对象的类型分别是long和unsigned int,并且int和long的大小相同,则long类型的运算对象转换成unsigned int类型;如果long类型占用的空间比int更多,则unsigned int类型的运算对象转换成long类型。

理解算术转换

要想理解算术转换,办法之一就是研究大量的例子:

  1. bool        flag;       char                cval;  
  2. short       sval;       unsignedshort       usval;  
  3. int             ival;       unsigned int            uival;  
  4. long        lval;       unsigned long       ulval;  
  5. float       fval;       double          dval;  
  6. 3.14159L + ’a’;         // ’a’提升成int,然后该int值转换成long double  
  7. dval + ival;        // ival转换成double  
  8. dval + fval;        // fval转换成double  
  9. ival = dval;        // dval转换成(切除小数部分后)int  
  10. flag = dval;        // 如果dval是0,则flag是false,否则flag是true  
  11. cval + fval;        // cval提升成int,然后该int值转换成float  
  12. sval + cval;        // sval和cval都提升成int  
  13. cval + lval;        // cval转换成long  
  14. ival + ulval;       // ival转换成unsigned long  
  15. usval + ival;       // 根据unsigned short和int所占空间的大小进行提升  
  16. uival + lval;       // 根据unsigned int和long所占空间的大小进行转换  

在第一个加法运算中,小写字母'a'是char型的字符常量,它其实能表示一个数字值(参见2.1.1节,第32页)。到底这个数字值是多少完全依赖于机器上的字符集,在我们的环境中,'a'对应的数字值是97。当把'a'和一个long double类型的数相加时,char类型的值首先提升成int类型,然后int类型的值再转换成long double类型。最终我们把这个转换后的值与那个字面值相加。最后的两个含有无符号类型值的表达式也比较有趣,它们的结果依赖于机器。

4.11.1节练习

练习4.34:根据本节给出的变量定义,说明在下面的表达式中将发生什么样的类型转换:

(a) if (fval) (b) dval = fval + ival; (c) dval + ival * cval;

需要注意每种运算符遵循的是左结合律还是右结合律。

练习4.35:假设有如下的定义,

  1. char cval;      int ival;       unsigned int ui;  
  2.  float fval;    double dval;  

请回答在下面的表达式中发生了隐式类型转换吗?如果有,指出来。

(a) cval = 'a' + 3;   (b) fval = ui - ival * 1.0;

(c) dval = ui * fval;  (d) cval = ival + fval + dval;
 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇4.11 类型转换 下一篇4.11.2 其他隐式类型转换

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: