经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
c/c++编程排坑(1)-- 数据类型的“安静”转换
来源:cnblogs  作者:dnhua  时间:2018/12/10 9:46:37  对本文有异议

这里主要介绍ANSI C的特性:当执行算术运算时,操作数的类型如果不同,就会发生转换。数据类型一般朝着精度更高、长度更长的方向转换,整型数如果转换为signed不会丢失信息,就转换为signed,否则转换为unsigned。

一、算术转换(K&R C)

首先:

  • 任何类型为char或short的操作数会被转换为int。
  • 任何类型为float的操作数会被转换成double。

其次:

  • 如果其中一个操作数的类型时double,那么另外一个操作数会被转换成double,计算结果也是double。
  • 如果其中一个操作数的类型时long,那么另外一个操作数会被转换成long,计算结果也是long。
  • 如果其中一个操作数的类型时unsigned,那么另外一个操作数会被转换成unsigned,计算结果也是unsigned。

如果不符合上面几种情况,那么两个操作数的类型都作为int,计算结果也是int。

二、ANSI C的做法

字符和整型(整型升级)

char,short int或者int型位段(bit-field),包括他们的有符号和无符号变型,以及枚举类型,可以使用在需要int或unsigned int的表达式中。如果int可以完整表示源类型的所有值,那么该源类型的值就转换为int,否则转换为unsigned int。这称之为整型升级。

寻常算术转换

许多操作数类型为算数类型的双目运算符会引发类型转换,并以类似的方式产生结果类型。它的目的是产生一个普通类型,同时也是运算结果的类型。这个模式称之为寻常算术转换。

具体解释起来较为费篇幅,简单而言(不严谨的说)就是开篇提到的那段话:

当执行算术运算时,操作数的类型如果不同,就会发生转换。数据类型一般朝着精度更高、长度更长的方向转换,整型数如果转换为signed不会丢失信息,就转换为signed,否则转换为unsigned。

一个类型转换bug

往往我们对算术转换都相对敏感,比如float转double之类。而对有符号无符号则相对没那么注意。接下来举个例子,请先看代码,猜猜输出是什么?

  1. #include <iostream>
  2. #define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0]))
  3. using namespace std;
  4. int array[] = {1,2,3,4,5,6,7,8,9};
  5. int main()
  6. {
  7. int d = -1;
  8. if(d < TOTAL_ELEMENTS)
  9. cout << "-1 小于 TOTAL_ELEMENTS" << endl;
  10. else
  11. cout << "-1 大于 TOTAL_ELEMENTS" << endl;
  12. }

输出是:
TOTAL_ELEMENTS = 9
-1 大于 TOTAL_ELEMENTS

你答对了吗?
结论竟然是:-1<9。这是因为if在signed int和unsigned之间测试相等性,d被升级为unsigned int类型,-1被转换成unsigned int将是一个非常大的数!!!

See you next time. Happy Coding!!!
我的github

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号