zoukankan      html  css  js  c++  java
  • c/c++编程排坑(1)-- 数据类型的“安静”转换

    这里主要介绍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之类。而对有符号无符号则相对没那么注意。接下来举个例子,请先看代码,猜猜输出是什么?

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

    输出是:
    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

  • 相关阅读:
    通过输入方式在Android上进行微博OAuth登录
    Android应用集成支付宝接口的简化
    Tomcat启动时报 java.lang.OutOfMemoryError: Java heap space
    Myeclipse中 Exploded location overlaps an existing deployment解决办法
    SVN提交项目时版本冲突解决方案
    Jsp过滤器Filter配置过滤类型汇总
    myeclipse修改jsp文件的名称之后,再也打不开的解决方案
    文件上传之 commons-fileupload(二)
    文件上传之 commons-fileupload(一)
    常见池化技术
  • 原文地址:https://www.cnblogs.com/dnhua/p/10088442.html
Copyright © 2011-2022 走看看