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

  • 相关阅读:
    sql语句之group_concat函数
    Yii2 PHPExcel在linux环境下导出报500错误
    使用 PuTTY 时遇到错误:“expected key exchange group packet from server”
    Yii2 执行Save()方法失败,却没有错误信息
    js
    导航切换到当前页的时候,会触发这个方法
    Yii2 场景scenario的应用
    Yii2 hasMany 关联后加条件
    设置Yii2发生错误返回json
    Exception 'ReflectionException' with message 'Class require does not exist'
  • 原文地址:https://www.cnblogs.com/dnhua/p/10088442.html
Copyright © 2011-2022 走看看