隐式类型转换_c++隐式类型转换 - CSDN
精华内容
参与话题
  • 隐式类型转换

    2016-05-09 21:20:11
    1、算术运算符中,低类型转换为高类型。 2、赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值。 3、函数调用传递参数时,系统将实参转换为形参的类型后,赋给形参。 4、函数有返回值是,系统将...

    C语言中有以下四种情况会进行隐式转换:
    1、算术运算符中,低类型转换为高类型。
    2、赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值。
    3、函数调用传递参数时,系统将实参转换为形参的类型后,赋给形参。
    4、函数有返回值是,系统将表达值类型转换为返回值类型。

    1、算术转换

    进行算术运算时,不同类型的数必须转换成同一类型的数据才能进行运算,在转换时依照低级类型向高级类型转换,其转换类型高低级如图所示:
    这里写图片描述
    在运算的时候,以表达式中最长类型为主,其他类型均往该类型转换,如:
    (1)如果运算中有double或者float型的,则其他的类型均转换成double类型进行运算;
    (2)如果运算中最长类型为int,那么char也将转换为int进行运算。
    PS:算术转换是在运算过程中自动完成的;

    包含long与unsigned int,在32位环境中都是4字节,所以均转换为unsigned long。
    包含signed int和unsigned int,signed会转换为unsigned,如果int恰好为负数,那么在运算时通过取补码相加的方式运算,结果可能就是一个很大的数了,现在我们通过以下两个代码来给大家讲一下:

    1.1 当转换类型所占字节小于原类型

    (1)如果int为正数,与无符号进行运算,直接取所需位数的原码即可。例如:

    #include<stdio.h>
    #include<stdlib.h>
    
    int main(){
        int a = 300;
        int b = -1;
        unsigned char c = a;
        printf("%d\n", c);
        c = b;
        printf("%d\n", c);
    
        return 0;
    }

    该程序的运行结果为44、255,说到这里,可能就觉得有些迷惑了,这是为什么?那么我们用两个图来大家说明一下:
    这里写图片描述
    从图上可以看出,int占位比char多,所以取后8位(因为char占8位),输出来就是44,其实就是a(300)对256取模后的值。
    (2)如果int为负数,则先取int的补码,再进行上述计算,例如上面代码中的b,如图所示:
    这里写图片描述
    如图所示,取-1的补码,然后和(1)中一样,所以输出值为255

    1.2 当转换类型所占字节大于等于当前类型

    很明显,当大于或等于时,无需截取某一段,直接进行运算就可以,但是同样的,对负数来说,也是要先取补码,再运算,比如下面代码:

    #include<stdio.h>
    
    int main(){
        int a = -3;
        unsigned int b = 2;
        long c = a + b;
        printf("%ld\n", c);
    
        return 0;
    }

    这段代码在32位环境中运行结果为-1,64位环境中运行结果为4294967295
    至于说为什么,也是和上面的一样,-3是一个很小的值,但是当与unsigned类型进行运算的时候,-3先取补码,我们就可以发现,其补码为1111….11100,就成为了一个很大的数,再与2运算,结果就是2^32-1,是一个很大的数,超出了long的最大范围,所以显示为-1,至于4294967295,就是这个真正的值了。
    说到这里,就要将将,我们怎么解决这个问题呢?因为我们知道虽然int、long、unsigned int都是4字节大小,但是int和long真正的存储数据的只有31位,第一位是符号位,导致其范围为2^31-1,而unsigned int没有符号位。
    第一种方法:printf(“%lu\n”, a + b);即可输出正常的值;
    第二种方法:定义c为long long,用%lld输出也可以,因为long long占8个字节,完全可以放得下。

    PS:即使操作数中只有char、short,也是先转换为int进行计算

    2、赋值转换

    在赋值时,赋值运算符右边的类型必须转换为左边的类型,如果右边的类型长度大于左边,则要进行截取的操作。
    以以下例子做说明:

    int main(){
        char a = 2;
        int i = 257;
        a = i;
        printf("%d\n", a);
    
        return 0;
    }

    因为char的范围为0-255,且 i 的长度是大于char的,所以在赋值后,会对 i 进行截取,所以最后输出结果就是1,也很容易计算,当 i>255,则对256取模就是最后的结果。

    3、输出转换

    在使用printf按制定格式输出的时候,当输出的类型和输出格式不符合的时候,就会进行类型转换。例如:用long输出%d,则相当于将long转换为int输出;将int用%c输出,相当于将int转换为char再输出。用以下两个例子说明:

    int main(){
        int a = 65;
        int b = 321;
        printf("%c\n", a);
        printf("%c\n", b);
    
        return 0;
    }

    根据前文解释,此处输出应为两个‘A’;
    我们再看下一个例子:

    int main(){
        long a = 80000;
        long b = 32769;
        printf("%hd\n", a);
        printf("%hd\n", b);
        //1000 0000 0000 0001     32769的原码
        //1 0011 1000 1000 0000     80000的原码
        //11 1000 1000 0000   14464的原码
        return 0;
    }

    答案是14464 -32767,为什么和上一个直接取模不一样呢?那是因为char是无符号的,而%hd(short)是有符号的,所以:
    在取80000时,看注释,取后面16位,首位为0,是正数,直接就是结果:14464;
    而取32769的时候,首位为1,是负数,所以取其补码,结果就是-32767。
    其实我们也可以从取模的角度来思考,当超过32767,由于short的取值范围是 -32767—32767,所以,又从负数开始取到正数,再如此循环,因此我们会看到当long的值不断增大,输出结果呈现的是正负不断交替的。

    4、函数返回值隐式转换

    相信看了前面的,大家肯定也明白了这是怎么一回事,这里就不再赘述了,直接通过这段代码来展示一下:

    int fun(double n){
        return n;
    }
    
    int main(){
        double a = 5.69;
        printf("%d\n", fun(a));
        return 0;
    }

    结果当然就是5啦,其他的比如int到short,负数的结果什么的,就交给大家自己去实验了,只要明白了他的原理,无论何时都够很轻易地分析出来的。最后,给一张汇总图了断,哈哈哈哈哈
    这里写图片描述

    展开全文
  • js隐式强制类型转换

    2019-04-29 10:01:14
    隐式强制类型转换:通过一些操作导致的,如:运算操作、判断语句、循环语句。 显式类型转换:通过一些操作符,如:Number()、String()、toString()、Boolean()等一些很显而易见、目的明确的方式去进行的类型转换。 ...

    隐式强制类型转换:通过一些操作导致的,如:运算操作、判断语句、循环语句。

    显式类型转换:通过一些操作符,如:Number()、String()、toString()、Boolean()等一些很显而易见、目的明确的方式去进行的类型转换。

    关于显式和隐式的类型转换,也是比较偏向主观的,如果你一眼就能看到某行代码执行的时候,发生了什么事情,那么这应该也能看成是显式的类型转换。或者说你不知道String()是干嘛用的,那么你看到一行代码调用该方法时,这也可以当成主观上的隐式类型转换。本文将着重讲解隐式强制类型转换。

    先看一个例子:demo1

    var a = [1, 2];
    var b = [3, 4];
    console.log(a + b);		// 1,23,4

    例子中的a和b都不是字符串类型,那为什么会输出 1,23,4这个结果呢?原因是它们都被强制转换了字符串类型然后进行了拼接。

    在+运算操作符中,如果有其中一个操作数能够通过valueOf或者toString方法转换为字符串,那么最后都会进行字符串的拼接。在上面的例子中,a和b在进行+运算时,最开始都是调用了vlaueOf的方法来获取原始数据,但是数组的valueOf方法无法获得基本数据类型,于是转为调用toString方法,数组调用toString方法的话是可以返回值的字符串类型的。实际上执行的是这样的代码:

    console.log(a.toString() + b.toString());

    demo2:

    var a = 12;
    var b = a + "";
    console.log(typeof b, b);    // string 12

    demo2的例子中,主要是数字加字符串,变成了字符串拼接,返回字符串类型的12也比较好理解。这种隐式强制类型转换也是比较常见的一种。这里说一下String(a)的类型转换和本例子中的类型转换的区别,当调用String方法时,如果值有toString方法,则使用该方法并返回结果。而本例中的转换过程详细来说应该是:a先调用valueOf方法,然后再通过toString方法将返回值转换为字符串。如果本例中的a要使用String来转换为字符串的话,是直接调用了toString方法的。


    demo3:

    var a = {
    	valueOf: function() {return 42},
    	toString: function() {return "4"}
    }
    
    console.log(a + "");            // "42"
    console.log(String(a));         // "4"

    本例子重写了对象的原型方法valueOf和toString,很好的验证了demo2中的说法,当a+“”的时候,确实是先调用了valueOf方法,而使用String方法则是直接调用了toString方法,因为对象是有toString方法的。


    demo4:

    var a = "5";
    var b = 2;
    console.log(a - b);    // 3

    减法运算,字符串a会被强制类型转换为数字。


    demo5:

    var a = [10];
    var b = [3];
    console.log(a - b);    // 7

    a和b都是数组,所以最开始都会被调用toString方法,之后调用Number方法转换为数字。因为 - 运算符只适用于数字,* 和 / 的运算同样也可以将字符串转为数字,只是大多数情况下不会这样做。


    demo6:

    var a = true;
    var b = false;
    var c = undefined;
    var d = null;
    var e = NaN;
    
    console.log(1 + a);    // 2    等同于1 + 1
    console.log(1 + b);    // 1    等同于1 + 0
    
    console.log(c + a);    // NaN  undefined + true或者false 都会返回NaN,不能相加。
    console.log(c + b);    // NaN
    
    console.log(d + a);    // 1    null + true或者false,null会被强制转换为0
    console.log(d + b);    // 0
    
    console.log(e + a);    // NaN  NaN加任何值都会返回NaN
    console.log(e + b);    // NaN
    
    console.log(Number(null));    // 0

    true和false进行 + 运算时,会被隐式强制类型转换为数字 1 和 0 。所以:

    undefined + true或者false 都会返回NaN,不能相加。

    null + true或者false,null会被强制转换为0。因为当数字和字符串以外的原始数据类型进行加法运算时,都会将该值进行数字的转换,而null调用Number时又是返回0。前面说了true和false在加运算时会被转为数字,所以null + true/false 时,等同于null + 1/0,然后等同于0 + 1/0)

    NaN加任何值都会返回NaN


    demo7:

    var a = 20;
    var b = "aaa";
    var c;
    var d = null;
    if (a) {
        console.log("代码执行到这里");
    }
    
    while (c) {
        console.log("代码不会执行到这里");
    }
    
    c = d ? a : b;
    console.log(c);     // "aaa"
    
    if ((a && b) || c) {
        console.log("代码执行到这里");
    }

    在if、循环、三目运算、逻辑运算等操作都会隐式地将表达式的值强制转为布尔值


    demo8:

    var a = 5;
    var b = "5";
    console.log(a == b);		// true
    console.log(a === b);		// false

    本例子中使用了宽松相等 == 和 严格相等 === 来对 a 和 b 进行判断,在宽松相等中a和b是相等的,但是在严格相等中a和b是不相等的。这是为什么呢?答案是这里面也存在隐式强制类型转换。一直以来,大家可能都觉得宽松相等(==)主要是判断值是否相等;严格相等(===)主要是判断值和类型是否相等。也没错,确实是这样。但是从原理上来说,也可以说是宽松相等会进行隐式强制类型转换,而严格相等却不允许。

    那么从这个例子上来看,虽然知道了会发生类型转换,但是a从数字转为字符串?还是b从字符串转为数字呢?根据ES5的规范,如果Type(a)是数字,Type(b)是字符串,那么返回a == Number(b)。如果Type(a)是字符串,type(b)是数字,那么返回Number(a) == b。按这个规范来看,个人觉得最后都是字符串会转为数字来进行比较的。所以本例中的比较实际上是这样的:

    console.log(a == Number(b));		// true    允许隐式强制类型转换
    console.log(a === b);		        // false   不允许隐式强制类型转换
    
    

    关于== 和 ===的性能,有人会觉得, == 的性能会比 === 的性能要慢。没错,== 确实是要比 === 多花一点时间,但是这只是微秒级的差别,也就是万分之一秒左右,对于程序来说可忽略不计。但是无论 == 还是 === 都会检测类型,只是检测出来之后各自的操作不一样。


    demo9:

    var a = '666';
    var b = true;
    console.log(a == b);	// false

    这是一个既简单又复杂的问题,可能很多人会觉得这会返回true,原因是忽略了一个隐式类型转换。首先来看一下a,它的值为字符串666,如果把它转为布尔类型,那绝对是返回true的。所以很多人到这里看到a为true,b也为true,所以是相等的。但实际上,在a == b(’666‘ == true)这里并没有发生布尔值的比较,字符串666也没有被转换为true。而最先被隐式强制类型转换的是b,b被转换为了1,也就是变成:’666‘ == 1。前面说过,宽松相等是会发生隐式强制类型转换的,所以字符串666变成了数字类型666。也就是:666 == 1,很显然是不相等的,所以最后返回了false。如果a是等于字符串1的话,结果就会返回true。

    ECMA规定:

    如果Type(a)是布尔值,则返回Number(a) == b;

    如果Type(b)是布尔值,则返回a == Number(b);


    demo10:

    var a = 10;
    var b = [10];
    console.log(a == b);

    基本类型(字符串、数字、布尔)和对象(对象、数组、函数)之间的相等判断,ECMA也是做了规定的:

    如果Type(a)是基本类型,Type(b)是对象,那么返回a == ToPrimitive(b);

    如果Type(a)是对象,Type(b)是基本类型,那么返回ToPrimitive(a) == b;

    在本例当中,b会调用ToPrimitive抽象操作,返回了字符串10,即:10 == ’10‘,接着变成:10 == 10,所以就返回了true。

    关于ToPrimitive抽象操作的原理,在这里可以先理解为调用了内部默认的方法,如:toString()、valueOf()、Number()之类的操作。


    demo11:

    [] + {};
    {} + [];

    第一行代码,由于隐式强制类型转换,空数组会被转换为空字符串 "",而 {} 在加运算符中是解析为空对象的。也就是说第一行代码等同于:"" + [object Object],这里会发生字符串拼接,所以返回字符串的 [object Object]。

    第二行代码,由于js引擎词法解析原因,花括号 {} 会被解析为一个空的代码块,也就是说什么事都没有发生。而后面的空数组和加运算符在一起,最开始空字符串调用valueof()方法,但是无法返回基本数据类型值,于是它转而调用toString()方法。此时返回一个空的字符串,但前面有一个加运算符(+ ""),空字符串会调用Number()返回,是返回0的。

    所以第一行代码是返回 "[object Object]",第二行代码是返回 0。但是这不能使用console.log()或者alert()的方法取运行,这样得到的结果都会是[object Object]。


    暂时先介绍到这里,如文中有不切当的地方欢迎各位大神指点。

    展开全文
  • js面试题大坑——隐式类型转换

    万次阅读 多人点赞 2018-09-28 17:50:17
    · 1.4 坑二:关系运算符:会把其他数据类型转换成number之后再比较关系 · 1.5 坑三:复杂数据类型在隐式转换时会先转成String,然后再转成Number运算 · 1.6-坑四:逻辑非隐式转换与关系运算符隐式转换搞混淆 ...

    · 1.1 隐式转换介绍

    · 1.2 隐式转换规则

    · 1.3 坑一:字符串连接符与算术运算符隐式转换规则混淆

    · 1.4 坑二:关系运算符:会把其他数据类型转换成number之后再比较关系

    · 1.5 坑三:复杂数据类型在隐式转换时会先转成String,然后再转成Number运算

    · 1.6-坑四:逻辑非隐式转换与关系运算符隐式转换搞混淆

    1.1-隐式转换介绍

    · 在js中,当运算符在运算时,如果两边数据不统一,CPU就无法计算,这时我们编译器会自动将运算符两边的数据做一个数据类型转换,转成一样的数据类型再计算

    o 这种无需程序员手动转换,而由编译器自动转换的方式就称为隐式转换

    · 例如1 > "0"这行代码在js中并不会报错,编译器在运算符时会先把右边的"0"转成数字0`然后在比较大小

    1.2-隐式转换规则

    1. 转成string类型: +(字符串连接符) 2..转成number类型:++/--(自增自减运算符) + - * / %(算术运算符) > < >= <= == != === !=== (关系运算符)

    2. 转成boolean类型:!(逻辑非运算符)

    1.3-坑一:字符串连接符与算术运算符隐式转换规则混淆

    · 常见面试题如下

    js面试题大坑——隐式类型转换

     

    · 原理分析

    js面试题大坑——隐式类型转换

     

    1.4-坑二:关系运算符:会把其他数据类型转换成number之后再比较关系

    常见面试题如下

    js面试题大坑——隐式类型转换

     

    · 原理分析

    js面试题大坑——隐式类型转换

     

    1.5-坑三:复杂数据类型在隐式转换时会先转成String,然后再转成Number运算

    js面试题大坑——隐式类型转换

     

    js面试题大坑——隐式类型转换

     

    · 原理分析

    js面试题大坑——隐式类型转换

     

    1.6-坑四:逻辑非隐式转换与关系运算符隐式转换搞混淆

    · 前方高能,请注意~

    o 空数组的toString()方法会得到空字符串,而空对象的toString()方法会得到字符串`[object Object]` (注意第一个小写o,第二个大写O哟)

    · 常见面试题

    js面试题大坑——隐式类型转换

     

    · 原理分析

    js面试题大坑——隐式类型转换

     

    js面试题大坑——隐式类型转换

     

    js面试题大坑——隐式类型转换

     

    js面试题大坑——隐式类型转换

     

    js面试题大坑——隐式类型转换

     

    展开全文
  • C语言中隐式数据类型转换

    千次阅读 2018-09-13 17:58:21
    1. 隐式转换  C在以下四种类型中会进行隐式转换:  1. 算术运算符中,低类型转换为高类型 ... 函数有返回值,系统隐式返回表达式类型转换为返回值类型  2. 算术运算符隐式转换  C语言中算术运算符隐式...

    1. 隐式转换

     C在以下四种类型中会进行隐式转换:

          1. 算术运算符中,低类型转换为高类型

          2. 赋值表达式中,右边的值自动隐式转换为左边变量的类型,并赋值

          3. 函数调用参数传递,系统隐式将实参转换为形参的值

          4. 函数有返回值,系统隐式返回表达式类型转换为返回值类型

      2. 算术运算符隐式转换

          C语言中算术运算符隐式转换:

                低类型要转换为高类型计算!

                (1)有符号的和无符号的计算,会优先转换为无符号类型:

             例如:

                 unsigned  int i=3;

                 cout << i*(-1);

            答案是: -1转换为 unsigned  int   2^32 +(-1)   = 4294967295 

                           4294967295  * 3  = 12884901885 出现溢出 转换为16 进制  0x2FFFFFFFD,由于unsigned int只能表示32位,因此结果是0xfffffffd,即4294967293。

                 (2)其他转换规则如下:

                  

                char  ,  unsigned char  ,  short  , unsigned short  ,  int    ,   unsigned int  ,  long , unsigned long  ,   double 

                 低级                                                                                                                                                              高级

                float  一律 要转换为 double类型

     

    C++有符号类型和无符号类型转换规则:

    1.   当我们给一个无符号类型赋一个超过其表示范围的负值时,其最后的结果是该负值与该无符号类型所能表示的数的总个数的和,如果所得结果还是一个不在此类型表示范围的负数,则将所得结果重复以上相加的过程,直到最后得到一个在其表示范围的数,此即为最后的结果

            例如:  unsigned char m = -258;

                        int n = m;

                    n的结果为 :-258 + 256 = -2;

                                       -2 + 256 =254;  所以  n =254;

    2. 当我们赋给一个无符号类型一个超出它表示范围的 正值 时,结果是将我们所赋的这个值对此无符号类型所能表示的数的总个数取模后的余数

             例如:  unsigned char j =258;

                           int k = j;

                      k的结果为  258%256 = 2

    补:

     1.  short = signed short  等等

    参考 : 1. https://blog.csdn.net/abnerwang2014/article/details/20656423

                 2. https://blog.csdn.net/qq_24373811/article/details/52922272

    展开全文
  • C语言隐式类型转换

    万次阅读 2015-07-26 18:00:01
    隐式类型转换分三种,即算术转换、赋值转换和输出转换。 1.算术转换  进行算术运算(加、减、乘、除、取余以及符号运算)时,不同类型数招必须转换成同 一类型的数据才能运算,算术转换原则为:  整型提升:...
  • js中隐式类型转换

    千次阅读 2018-04-07 17:09:23
    值类型之间的数据类型转换: (1)数字和字符串使用+运算符: 数字和字符串如果使用+运算符进行操作,那么会将数字先转换为字符串,然后进行字符串连接操作: var antzone = "antzone"; var num = 8; ...
  • JS隐式类型转换详解

    千次阅读 2019-03-07 16:21:01
    本文依据犀牛书,以及一些文章(参考链接在末尾给出...转换为字符串 转换为数字 转换为布尔值 转换为对象 undefined “undefined” NaN false throw TypeError null “null” 0 false throw TypeError true ...
  • 在使用EF开发时候,遇到 using 语句中使用的类型必须可隐式转换为“System.IDisposable“ 这个问题。 原因就是 这个程序集中没有引用EntityFramework。可以使用Nuget 安装EntityFramewok。
  • Scala之隐式转换

    万次阅读 多人点赞 2020-06-19 14:31:33
    概述简单说,隐式转换就是:当Scala编译器进行类型匹配时,如果找不到合适的候选,那么隐式转化提供了另外一种途径来告诉编译器如何将当前的类型转换成预期类型。隐式转换有四种常见的使用场景: 将某一类型转换成...
  • 数据库里面的数据类型错了,应该是varchar,而我选了varbinary。
  • [Scala隐式转换示例]

    万次阅读 2018-06-02 19:20:56
    一、隐式转换 Scala编程语言中引入了一种叫做隐式类的新特性。隐式类指的是用implicit关键字修饰的类。在对应的作用域内,带有这个关键字的类的主构造函数可用于隐式转换隐式转换是一项强大的程序语言功能,它...
  • 直接奖泛型转为T是不能转换的 要先转Object 例: public static T GetValue(string inValue) { if (typeof(T) == typeof(Bitmap)) { return (T)(Object)new Bitmap(inValue);
  • 前言: 相信很多小伙伴在刚入门的时候遇到的问题最多的就是此类问题了...赋值时两边的值不是同一类型转换类型错误 &lt;三&gt;窗体中某个控件的名称与赋值的名称重复   解决方法: 下面附上各种类型...
  • Oracle DB 隐式和显示数据类型转换

    千次阅读 2013-10-17 09:22:44
    但是,Oracle Server 会在内部将这些数据类型转换为Oracle 数据类型。 在某些情况下,Oracle Server 会收到数据类型与预期的数据类型不同的数据。发生这种情况时,Oracle Server 可自动将该数据转
  • 隐式转换:说白了就是在转换时不给系统提示具体的显示模型,让其自动转换,但是要记住一条编译器一般只支持自下而上的类型转换,例如int 转 float int a =4; float b= 5.56; b =a; //这个就是隐式转换,默认的把...
  • 关于无法将类型“object”隐式转换为“string” 原码: void SubmitBtn_Click(Object sender, EventArgs e) { Session["username"]=""; OleDbConnection objConnection; OleDbCommand objCommand; OleDbDataReader ...
  • Java基础——隐式转换vs强制转换

    万次阅读 2015-02-21 16:13:04
    在定义变量时,有许多要注意的问题,一不小心就会出现损失精度或者不兼容类型等问题。 例如:  1.定义长整型数据时,必须加后缀l或L  long l =123456789012345L  2.定义单精度类型时(7-8位有效数字),必须加...
  • 原文:C# 泛型 无法将类型xx隐式转换为“T”直接奖泛型转为T是不能转换的 要先转Object例: public static T GetValue&lt;T&gt;(string inValue) { if (typeof(T) == typeof(Bitmap)) { return (T)...
  • 出现这个问题是因为把控件DataGridView的Name属性写成了Name 无法将类型“string”隐式转换为"System.Windows.Forms.XXX"的错误,可以想想是不是XXX控件的Name属性写成Name了  ...
  • 【前言】 ...”隐式转换为“int”。存在一个显式转换(是否缺少强制转换?)” 今天就来说说这个令人头疼的bug! 【正文】 一、bug描述: 1、When——何时出现的? 此问题是出现在我写lin...
1 2 3 4 5 ... 20
收藏数 155,472
精华内容 62,188
关键字:

隐式类型转换