精华内容
下载资源
问答
  • 有如下结构体定义:  typedef struct cemsg  {  uchar dl;  uchar mg;  uchar data[10];  }CEMSG;  typedef struct msg{  uchar id;...  void ap_getmsg(MSG *d_OsMsgPtr,CEMSG *d_Ce
  • C#强制类型转换小结

    2020-08-30 02:24:14
    任何一门编程语言均有相关数据类型。C#也不例外,不过转换过程要注意小类型能转换成大类型,但大类型一般不能转换成小类型,下面小编给大家详解C#强制类型转换小结,需要的朋友参考下吧
  • 一说起强制类型转换大家都很熟悉,相信很多学习完C++的朋友还在使用C语言的强制类型的方式 (类型)变量. C++其实也具有自己的一套强制类型转换它们分明是:static_cast reinterpret_cast const_cast dynamic_cast...
  • LabVIEW中TCP通讯需要用到的强制类型转换的使用方法
  • 最近项目中经常需要int与float之间转换,有必要对它们之间转换的原理做个了解。
  • 强制类型转换

    千次阅读 2019-10-29 14:47:13
    详细各种类型转换,看完这篇,能解决大多数需求

    ​这篇会详细介绍各种类型转换,值得一看

    抽象值转换

    先介绍ToString,ToNumber,ToBoolean这三种抽象值转换操作,以便于后面了解具体转换

    ToString

    处理非字符串到字符串的强制类型转换

    对于基本类型值的字符串转换:null转换为"null",undefined转换为"undefined",true转换为"true",false转换为"false",数字转换为字符串也是遵循这种通用规则(对于极大和极小值,会转换为指数形式的字符串)

    var a=1000*1000*1000*1000*1000*1000*100000;console.log(a.toString());//1e+23

    那么对于普通的对象来说,除非这个对象定义了toString()方法,否则toString()(Object.prototype.toString.call())方法返回的就是对象内部的[[class]]属性(参见《类型与值》)

    (将对象强制转换为string是通过ToPrimitive抽象操作完成的,下面会说)

    对于数组,略显不同,就是会添加一个“,”号

    var arr=[1,2,3];console.log(arr.toString());//1,2,3
    

     还有一个JSON字符串化(这个也是蛮重要的)

    JSON.stringify()在将JSON对象字符串化时也用到了ToString

    对于大多数简单值来说,JSON字符串化和ToString的效果基本相同,只是序列化的结果总是字符串

    console.log(JSON.stringify(42));//"42"console.log(JSON.stringify("ab"));//""ab""(含有双引号的字符串)console.log(JSON.stringify(null));//"null"console.log(JSON.stringify(true));//"true"

    所有安全的JSON值都可以使用JSON.stringify()方法进行字符串化,那么什么又是安全的JSON值呢?

    安全的JSON值太多了,来看不安全的JSON值,记住这些就够了

    undefined,function,symbol以及包含循环引用的对象都是不安全的值,无法使用JSON.stringify()方法

    console.log(JSON.stringify(undefined));//undefinedconsole.log(JSON.stringify(function(){}));//undefinedconsole.log(JSON.stringify(Symbol()));//undefined

    JSON.stringify()方法在对象中遇到undefined,function,symbol会自动忽略,在数组遇到则会返回null

    console.log(JSON.stringify([1,undefined,function(){},Symbol(),7]));//[1,null,null,null,7]console.log(JSON.stringify({  a:2,  b(){},  c:undefined}));//{"a":2}

    在包含循环引用的对象中使用JSON.stringify()方法会抛出错误

    如果对象中包含了toJSON()方法,那么当使用JSON.stringify()方法时会调用对象中的toJSON()方法,然后用这个方法的返回值进行字符串化

    var a={};var b={  q:"1",  w(){},  e:undefined,  r:a}a.t=b;console.log(JSON.stringify(b));//报错

    但是,当对象中添加这个方法就不会报错了

    b.toJSON=function(){  return { q:this.q }}console.log(JSON.stringify(b));//{"q":"1"}
    

    再来仔细看看这个JSON.stringify()方法,实际上有三个参数可使用

    JSON.stringify(value[, replacer [, space]])

    第一个参数都知道就不说了,看第二个第三个

    replacer:如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为null或者未提供,则对象所有的属性都会被序列化

    var a={  b:23,  c:"qwer",  d:[1,23]}console.log(JSON.stringify(a,["b","c"]));//{"b":23,"c":"qwer"}console.log(JSON.stringify(a,function(key,value){  if(key !== "c") return value;}));//{"b":23,"d":[1,23]}

    我觉得这个可选参数就类似于toJSON()方法,甚至比之还简单好用

     

    space:指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为10。该值若小于1,则意味着没有空格;如果该参数为字符串(字符串的前十个字母),该字符串将被作为空格;如果该参数没有提供(或者为null)将没有空格

    var a={  b:23,  c:"qwer",  d:[1,23]}console.log(JSON.stringify(a,null,3));//{   "b": 23,   "c": "qwer",   "d": [      1,      23   ]}

     

    ToNumber

    处理非数字到数字的强制类型转换

    对于基本类型值转换:true转换为1,false转换为0,null转换为0,undefined转换为NaN,非纯数字字符串转换为NaN

    console.log(Number(undefined));//NaNconsole.log(Number(true));//1console.log(Number(false));//0console.log(Number(null));//0console.log(Number("2"));//2console.log(Number("a"));//NaNconsole.log(Number("2e"));//NaNconsole.log(Number("undefined"));//NaN

    对于对象而言,首先会被转换为基本类型值,然后判断是否为数字的基本类型,不是,就按照上面的规则进行转换

    至于对象是如何转换为基本类型值的,抽象操作ToPrimitive首先会检查该对象是否有valueOf()方法(参见《原生函数》),有且返回一个基本类型值,就会使用该返回值进行强制类型转换。如果没有则会检查是否有toString()方法,有且有返回值,也是使用该返回值进行强制类型转换。如果还是两个都不返回基本类型值,则会抛出TypeError错误

    解释一下为什么要使用这俩个方法,第一个方法是为了获取封装对象(参见《原生函数》)中的基本类型值,或者复杂对象自定义了该方法(不定义则返回NaN)且返回基本类型值,第二个方法是为了获取复杂对象返回的基本类型值(在复杂对象中也是要自定义,不定义则返回NaN)

    这里还有一个特例,就是由Object.create(null)创建出来的对象,它没有valueOf()和toString()方法,所以无法进行强制类型转换(转换了是报错而不是返回NaN)。如果自定义了这俩个方法则可以强制类型转换

    //valueOf()方法var num=new Number(2);var no_num={  a:2}var new_num={  a:4,  valueOf(){    return this.a;  }}console.log(Number(num));//2console.log(Number(no_num));//NaNconsole.log(Number(new_num));//4//toString()方法var str={  a:"21",  toString(){    return this.a;  }}var no_str={  a:"21"}console.log(Number(str));//21console.log(Number(no_str));//NaN//当两个方法同时存在时var obj={  a:"21",  b:"10",  valueOf(){    return this.b;  },  toString(){    return this.a;  }}console.log(Number(obj));//10//Object.create(null)var obj=Object.create(null);obj.a=2;obj.valueOf=function(){  return this.a}console.log(Number(obj));//2
    

    ToBoolean

    在JavaScript中的值可以分为两类:

    1. 可以被强制类型转换为false的值

    2. 其他值(被强制类型转换为true)

    假值有这些:

    ◦ undefined

    ◦ null

    ◦ +0 -0 NaN

    ◦ false

    ◦ ""

    这些假值转换为布尔值都为false,除此之外都转换为true,就连[]这个空对象也是true

    还有一些长得像假值的对象,比如下面这些,都包装了假值,但是其实这些对象转换为布尔值都为true

    var w=new Boolean(true);//truevar e=new Boolean(false);//truevar r=new Number(0);//truevar t=new String("");//truevar a=Boolean(w && e && r && t);console.log(a);//true
    var a=[];var b={};var c=function(){}var d=Boolean(a && b && c );console.log(d);//true

    只要记住那几个假值就行,除此之外都是真值

     

    显示强制类型转换

    什么是显示强制类型转换呢?就是那种一眼就能看穿的,就叫显示强制类中转换。对我来说,现在啥也看不穿,啥都是显示强制类型转换

     

    先说字符串和数字之间的转换

    对于这两个类型的转换,可以通过String()和Number()函数(参见《原生函数》)进行转换

    var num=234;console.log(String(num));//"234"var str="212";console.log(Number(str));//212

    这两个函数都是分别遵循前面所说的ToString规则和ToNumber规则

    当然还有其他方式进行转换

    var a=42;var s=a.toString();console.log(typeof s);//stringvar b="23";var c= +b;console.log(typeof c);//number

    第一个肯定晓得,第二个呢就是利用 + 这个一元运算符对字符串显示强制类中转换,这个比较常见

    还有~运算符也可以,它会对运算数执行ToNumber操作

    var num="23";var num_2=~num;console.log(num_2);//-24console.log(typeof num_2);//numbervar no_num="23s";var no_num_2=~no_num;console.log(no_num_2);//-1console.log(typeof no_num_2);//number

    可以结合字符串的indexOf方法一起使用

    var a="hello js";function b(){  if(~a.indexOf("el")){    console.log("true")  }  if(!~a.indexOf("ho")){    console.log("false");  }}b();//true false

    indexOf方法在未找到指定字符时返回-1,~-1为0,0为假值,!0为真值

    还有~~运算符,也是可以将字符串转换为数字的。注意,只会截取整数部分

    var a="234.123";var b=~~a;console.log(b);//234console.log(typeof b);//numbervar c="234.123a";var d=~~c;console.log(d);//0console.log(typeof d);//number

     

    可能还会记得这两个函数,parseInt()和parseFloat()。这俩也可以将字符串转换为数字

    但是,也是有区别的,Number()是强制转换,而parseInt()和parseFloat()是半解析字符串半强制。对于字符串中含有非数字字符,Number是会返回NaN的,而parseInt()则会解析字符串中的数字并返回

    parseInt()和parseFloat()中传入的参数如果不是字符串,则会进行强制类型转换,遵循ToString规则

    //第一个例子var str="23a";var str_2="a23";var num_1=Number(str);var num_2=parseInt(str);var num_3=parseInt(str_2);console.log(num_1,num_2);//NaN 23console.log(num_3);//NaN//第二个例子var num=parseInt(new String("23"));console.log(num);//23var obj={  num:24,  toString(){ return this.num }}console.log(parseInt(obj));//24var obj_2={  num:24}console.log(parseInt(obj_2));//NaN

    解析整数使用parseInt(),解析浮点数使用parseFloat()。parseInt()和parseFloat()都是从左往右解析的下

     

     

    现在看看布尔值的转换

    同上,Boolean()也是显示强制类型转换,遵循ToBoolean规则

    var a=[];var c={};var d="0";var e=null;var f;var g=0;var h='';console.log(Boolean(a));//trueconsole.log(Boolean(c));//trueconsole.log(Boolean(d));//trueconsole.log(Boolean(e));//falseconsole.log(Boolean(f));//falseconsole.log(Boolean(g));//falseconsole.log(Boolean(h));//false

    当然不止这一种方法,还有!运算符,估计都没少用。!运算符可以将值强制类型转换为布尔值,但它还将值进行反转了。所以,!!才应该是正确的用法,反转再反转

    console.log(!!a);//trueconsole.log(!!c);//trueconsole.log(!!d);//trueconsole.log(!!e);//falseconsole.log(!!f);//falseconsole.log(!!g);//falseconsole.log(!!h);//false

    这样写是不是简单多了呢,学到了

     

    隐式强制类型转换

    先瞅瞅字符串和数字之间的转换

    +运算符,既能用于数字加法,也能用于字符串拼接。估计都知道,但是如何判别呢?或者说这其中是如何操作的呢?

    var a="20";var b="0";var c=20;var d=10;
    console.log(a+c);//"2020"console.log(a+b);//"200"console.log(c+d);//30

    这个例子确实是很简单,但下面这个例子呢?

    var a=[1,2,3];var b=[4,5,6];var c=20;var d="20";console.log(a+b);//1,2,34,5,6console.log(a+c);//1,2,320console.log(a+d);//1,2,320

    这些运行输出的结果都知道吗?为什么会这样呢?

    简单说就是,在+运算操作中,一个操作数是字符串(或者能通过valueOf()方法以及toString()方法得到字符串),则执行字符串拼接,否则进行数字加法。这么说,才应该是比较合理的

    那么就可以这么解释上面的例子了。数组通过toString()方法得到一个字符串,当进行+运算时,进行字符串拼接

    知道这个+运算符的操作过程之后,应该也能理解下面这个语句的意思了

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

    但是,这里有一个小的细节要注意,如果a是对象且定义的valueOf()和toString()方法的返回值不同,那么当你对这个对象进行隐式和显示强制类型转换时,会发现结果不一样

    var obj={  valueOf(){return 1;},  toString(){return 2;}}console.log(obj+"");//1console.log(String(obj));//2

    出现这种结果,是因为进行隐式时,先执行valueOf(),然后对返回值进行ToString抽象操作返回字符串。但是显示时,则直接调用toString()方法

     

    再来看看布尔值到数字

    var bol=false;var bol_2=true;console.log(Number(bol));//0console.log(Number(bol_2));//1
    function onlyOne(a,b,c){  return !!((a && !b && !c) || (!a && b && !c) || (!a && !b && c))}var bol_1=true;var bol_2=false;console.log(onlyOne(bol_1,bol_2,bol_2));//true

    这个例子就是当且仅当一个参数为true时,这个函数返回true。但是,如果这么写,就会显得比较麻烦了, 比如有很多个参数呢?还要一个一个写出来吗?这时候就可以用到布尔值转换为数字了

    function onlyOne(){  let sum=0;  for (let i = 0; i < arguments.length; i++) {    if(arguments[i]){      sum +=arguments[i];    }  }  return sum==1;}var bol_1=true;var bol_2=false;console.log(onlyOne(bol_1,bol_2,bol_2,bol_2));//trueconsole.log(onlyOne(bol_1,bol_2,bol_2,bol_1));//false

    这里sum +=arguments[i];就将布尔值转换为了数字,简单方便

    这个例子可以用于满足某一条件来控制事件的发生

     

    至于隐式强制类型转换为布尔值,只要记住那几个假值即可

    在下面这些情况中会发生隐式强制类型转换

    (1)if语句

    (2)for(...,...,...)中第二个表达式

    (3)while(){}和do...while(){}表达式

    (4)?:三元表达式

    (5)&& 和 || 逻辑运算符

    前4个感觉都用的非常多,应该不用解释。至于最后一个,反正我不是很了解,这里来说说

    对于&& 和 || 逻辑运算符,其实它们俩的返回值并不是布尔值,而是两个操作数中的一个

    var a=23;var b=0;console.log(a||b);//23console.log(a&&b);//0

    首先,会对&& 和 || 的第一个操作数执行条件判断,如果不是布尔值就先进行ToBoolean强制类型转换,然后再执行条件判断,最后返回其中的一个操作数,就类似于?:这个三元运算符

    var a=23;var b=0;console.log(a?a:b);//23 ===》相当于 ||console.log(a?b:a);//0 ===》相当于 &&

    每次我都会记混了&&和||的返回值,现在联想到三元运算符就好多了

    那么下面这两个例子应该也能理解了

    //第一个function foo(a,b){  a=a||"hello";  b=b||"javascript";  console.log(a+","+b);}foo();//hello,javascriptfoo("l","like you");//l,like you//第二个function foo(){  console.log(a);}var a=42;a && foo();//42

     

    最后看看宽松相等和严格相等(== 和 ===),这里也有隐式强制类型转换

    可能对于这两个的理解是这样的,“==检查值是否相等,===检查值和类型是否相等”,听起来确实不错。然而在这里却是,“==允许在相等比较中进行强制类型转换,===不允许”,至于为什么会这么理解,看完便知

     

    先说字符串和数字之间的相等

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

    如果两个值类型不同,就对其中之一或两者都进行强制类型转换

    那具体怎么转换呢?a从42转换为字符串还是b从“42”转换为数字呢?

    在ES5规范中是这么说的

    (1)如果Type(x)是数字,Type(y)是字符串,则返回 x==ToNumber(y)的结果

    (2)如果Type(x)是字符串,Type(y)是数字,则返回 ToNumber(x)==y的结果

    可以看出都是转换为数字来比较的,数字优先比较

     

    还有就是其他类型和布尔类型之间的相等

    看这样一个例子

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

    仔细看看,先是b为true,然后对比a为false。再是b为false,对比a还是false。是不是有点奇怪?a居然不是真值也不是假值?其实错了,不是这么看的。得先理解在==中其他类型和布尔类型的比较规则才行

    在ES5规范中是这样说的

    (1)如果Type(x)是布尔类型,则返回 ToNumber(x) == y 的结果

    (2)如果Type(y)是布尔类型,则返回 x == ToNumber(y) 的结果

    同样也是数字优先,先将布尔值转换为数字再进行比较

    再回头看看这个例子,b先转换为数字0和1,然后a也转换为数字42,然后进行对比才得出false。并不是a单纯的和布尔值进行比较

     

    怎么能忘了null和undefined呢?

    这两个比较特殊,要谨记

    在ES规范中规定

    (1)如果x为null,y为undefined,则结果为true

    (1)如果x为undefined,y为null,则结果为true

    console.log(null == undefined);//true

    在==中,undefined和null相等(它们也与其自身也相等),除此之外不和任何值相等(注意,这里是直接进行==比较,而不是进行显示强制类型转换后再进行比较的),看下面例子就明白了

    //这是直接进行比较的var a;var b=null;console.log(a == a);//trueconsole.log(a == false);//falseconsole.log(a == 0);//falseconsole.log(a == '');//false      console.log(b == b);//trueconsole.log(b == false);//falseconsole.log(b == 0);//falseconsole.log(b == '');//false//这是进行显示强制类型转换后再比较的var a;var b=null;console.log(Number(a) == a);//falseconsole.log(Number(a) == false);//falseconsole.log(Number(a) == 0);//falseconsole.log(Number(a) == '');//falseconsole.log(Number(b) == b);//falseconsole.log(Number(b) == false);//trueconsole.log(Number(b) == 0);//trueconsole.log(Number(b) == '');//true

    第一个例子中,a和b不会和假值相等,与其自身相等。看第二个例子,这里对a和b进行显示强制类型转换为数字,a是undefined,b是null,显示转换后,a是NaN,b是0,再进行==比较,b能和假值相等了

    再注意看这两行

    console.log(Number(b) == b);//falseconsole.log(Number(b) == 0);//true

    说明在==中,null不会强制转换为其他类型(除非手动),除了undefined之外

    说了这么多,总结一下就是,在==比较中,undefined和null能进行强制类型转换并相等。与其他类型值进行比较时,不会进行强制类型转换,所以不会相等

     

    基本类型值之间的比较都说完了,现在该说对象与基本类型值之间进行比较了

    关于对象(对象 | 函数 | 数组)和基本类型(布尔 | 字符串 | 数字 )之间的比较,在ES5中有如下规定

    (1)如果Type(x)是基本类型值,Type(y)是对象,则返回 x == ToPrimitive(y)的结果

    (2)如果Type(y)是基本类型值,Type(x)是对象,则返回ToPrimitive(x) == y的结果

    如果忘了ToPrimitive是啥,可以往前翻翻,在ToNumber中有介绍,简单说就是查找valeuOf()方法和ToString()方法的返回值

    var a=[123];var b="123";console.log(a==b);//truevar obj={  a:"24",  toString(){    return this.a;  }}var str="24";console.log(obj==str);//true

    再看这个例子

    var a="23";var b=Object(a);console.log(a==b);//true

    这个例子中,先对b进行封装,然后在==中对b对象进行了拆封,拿到了b的基本类型值,也就是a,所以会相等

    但是,这下面几个值就不一样了,也是封装再拆封,但是返回值不一样

    var a=null;var b=Object(null);console.log(a==b);//falsevar c=undefined;var d=Object(undefined);console.log(c==d);//falsevar e=NaN;var f=Object(e);console.log(e==f);//false

    因为undefined和null都没有封装对象,所以不能对它们俩进行封装,Object()返回的是一个常规对象(参见《原生函数》)

    至于NaN,可以被封装,然后拆封之后仍然是NaN,但是NaN不等于自身

     

    好了,到这里已经介绍完了大多数的隐式转换,现在看看一些比较特殊的例子

    先回想一下前面所看的内容,然后再套用在下面的例子中,看看能否都解释出来

    console.log("0" == null);//falseconsole.log("0" == undefined);//falseconsole.log("0" == false);//true console.log("0" == NaN);//falseconsole.log("0" == 0);//trueconsole.log("0" == "");//falseconsole.log("=============");console.log(false == null);//falseconsole.log(false == undefined);//falseconsole.log(false == NaN);//falseconsole.log(false == 0);//true console.log(false == "");//true ====>坑console.log(false == []);//true ====>坑console.log(false == {});//falseconsole.log("=============");console.log("" == null);//falseconsole.log("" == undefined);//falseconsole.log("" == NaN);//falseconsole.log("" == 0);//true ====>坑console.log("" == []);//true ====>坑console.log("" == {});//false console.log("=============");console.log(0 == null);//falseconsole.log(0 == undefined);//falseconsole.log(0 == NaN);//falseconsole.log(0 == []);//true ====>坑console.log(0 == {});//false

    其实解释不出来也没多大关系,毕竟这些还是很少碰到的,尤其是标注了坑的那5个语句

    console.log(false == "");//true ====>坑console.log(false == []);//true ====>坑console.log("" == []);//true ====>坑console.log("" == 0);//true ====>坑console.log(0 == []);//true ====>坑

    这其中包含==false的语句应该避免使用,这样使用其实不是很规范,很容易产生误解,也不易理解

    剩下的3种,这边建议记住哦

    还有一个看起来可能更加难理解的例子

    console.log([] == ![]);//trueconsole.log([]== []);//false

    首先看到![] 应该想到ToBoolean抽象操作,所以此时[] == false,然后false被强制转换为数字0,而[]同样被强制转换为数字0,所以返回true。至于为什么不会等于自身,这两个数组不是同一个对象,不会相等

     

    鉴于上面这些难以理解的语句,在使用==时,应该要注意下面两个原则

    (1)如果等式两边有true或false,不要使用==

    (2)如果等式两边有[],"",或0,也不要使用==

    是不是完美规避了上面那些语句呢?不懂这个,我不用不就行了嘛。当然,你不用不代表别人不用,所以还是记一记比较好

     

    到这里还没结束呢。还有最最最后一种方式也用到了隐式转换

    var a=23;var b="24";console.log(a<b);//true

    虽然很少会这么写,但是确实有

    比较双方首先会调用ToPrimitive抽象操作,如果结果出现非字符串,就根据ToNumber规则将双方强制类型转换为数字进行比较

    var a=[2];var b=["3"];console.log(a<b);//true

    如果结果都是字符串,则按照字母顺序进行比较

    var a=["20"];var b=["012"];console.log(a<b);//falsevar a=[2,3];var b=[0,1,2];console.log(a<b);//false

    第一个例子是比较"20"和"012","0"在字母顺序上小于"2",所以a大于b

    第二个例子是比较"2,3"和"0,1,2","0"在字母顺序上小于"2",所以a大于b

    再来看看对象的比较,这里比较有趣,可能会和你想的不大相同

    var a={b:2};var b={b:3};console.log(a<b);//falseconsole.log(a>b);//falseconsole.log(a==b);//falseconsole.log(a<=b);//trueconsole.log(a>=b);//true

    看完输出结果是不是有点懵?来,慢慢分析

    首先,ab是对象,执行ToPrimitive抽象操作,得到a的字符串[object Object],b同样得到[object Object],所以a>b和a<b都返回false。解释一下为什么a不会等于b,因为ab是两个不同的对象,不会相等。那么问题来了,为什么a<=b和a>=b会输出true呢?

    可能你会把<=和>=理解为“小于或等于”和“大于或等于”。但是,注意,在JavaScript中并没有这种理解,而是把<=理解为“不大于”,>=理解为“不小于”。看起来相同,实则操作不同。“不大于”意味着会将a<b处理为!(a>b),“不小于”则是将a>b处理为!(a<b)。是不是蛮有趣的,和所理解的完全不一样。至于为什么,等我学习了底层知识再来讲讲

    这么一解释,那上面输出的内容就很好理解了

     

    建议多看两遍,哈哈。如果遇到类型转换的,可以参考这篇,我觉得写的还是蛮详细的。当然还有很多没顾及到的,不可能面面俱到,希望可以指出来

    最后的最后,如果你看到这里了,希望能点个赞

    要是觉得不错,还可以关注一下我的公众号,每周更新,篇篇干货

                                                                       

    展开全文
  • 文章目录前言golang强制类型转换类型断言类型转换指针类型转换总结引用 前言 golang是强类型语言,有强制类型转换,但是不同于Java语言所使用的强制类型转换。 golang强制类型转换 golang语言中分为类型转换(type ...
  • 1.1 强制类型转换  大家都知道在C语言里强制类型转换的方法非常简单,只要在要转换的变量前用括号确定要转换的类型即可,如要将一个double型的变量强制转换为int类型,代码如下:  double x = 3.14; int y = ...
  • 众所周知,JS在很多情况下会进行强制类型转换,其中,最常见两种是: 1.使用非严格相等进行比较,对==左边的值进行类型转换 2.在if判断时,括号内的值进行类型转换,转化为布尔值 今天,我就来聊一聊JS在if中的强制...
  • C++强制类型转换

    千次阅读 2021-04-20 18:41:34
    C++ 类型转换(C风格的强制转换): 在C++基本的数据类型中,可以分为四类:整型,浮点型,字符型,布尔型。其中数值型包括 整型与浮点型;字符型即为char。 (1)将浮点型数据赋值给整型变量时,舍弃其小数部分。...

    C++ 类型转换(C风格的强制转换):

    在C++基本的数据类型中,可以分为四类:整型,浮点型,字符型,布尔型。其中数值型包括 整型与浮点型;字符型即为char。

    (1)将浮点型数据赋值给整型变量时,舍弃其小数部分。

    (2)将整型数据赋值给浮点型变量时,数值不变,但是以指数形式存储。

    (3)将double型数据赋值给float型变量时,注意数值范围溢出。

    (4)字符型数据可以赋值给整型变量,此时存入的是字符的ASCII码。

    (5)将一个int,short或long型数据赋值给一个char型变量,只将低8位原封不动的送到char型变量中。 
    (6)将有符号型数据赋值给长度相同的无符号型变量,连同原来的符号位一起传送。

     

    C++强制类型转换:

    在C++语言中新增了四个关键字static_cast、const_cast、reinterpret_cast和dynamic_cast。这四个关键字都是用于强制类型转换的。

    新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强制转换。

    C++中风格是static_cast<type>(content)。C++风格的强制转换其他的好处是,它们能更清晰的表明它们要干什么。程序员只要扫一眼这样的代码,就能立即知道一个强制转换的目的。 

     

    1) static_cast

    在C++语言中static_cast用于数据类型的强制转换,强制将一种数据类型转换为另一种数据类型。例如将整型数据转换为浮点型数据。
    [例1]C语言所采用的类型转换方式:

    int a = 10;
    int b = 3;
    double result = (double)a / (double)b;

    例1中将整型变量a和b转换为双精度浮点型,然后相除。在C++语言中,我们可以采用static_cast关键字来进行强制类型转换,如下所示。
    [例2]static_cast关键字的使用:

    int a = 10;
    int b = 3;
    double result = static_cast<double>(a) / static_cast<double>(b);

    在本例中同样是将整型变量a转换为双精度浮点型。采用static_cast进行强制数据类型转换时,将想要转换成的数据类型放到尖括号中,将待转换的变量或表达式放在元括号中,其格式可以概括为如下形式:    

    用法:static_cast <类型说明符> (变量或表达式)

    它主要有如下几种用法:
        (1)用于类层次结构中基类和派生类之间指针或引用的转换
          进行上行转换(把派生类的指针或引用转换成基类表示)是安全的
          进行下行转换(把基类的指针或引用转换为派生类表示),由于没有动态类型检查,所以是不安全的
        (2)用于基本数据类型之间的转换,如把int转换成char。这种转换的安全也要开发人员来保证
        (3)把空指针转换成目标类型的空指针
        (4)把任何类型的表达式转换为void类型
        注意:static_cast不能转换掉expression的const、volitale或者__unaligned属性。

    static_cast:可以实现C++中内置基本数据类型之间的相互转换。

    如果涉及到类的话,static_cast只能在有相互联系的类型中进行相互转换,不一定包含虚函数。

     

    2) const_cast

    在C语言中,const限定符通常被用来限定变量,用于表示该变量的值不能被修改。

    而const_cast则正是用于强制去掉这种不能被修改的常数特性,但需要特别注意的是const_cast不是用于去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,其去除常量性的对象必须为指针或引用。

    用法:const_cast<type_id> (expression)
        该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。
        常量指针被转化成非常量指针,并且仍然指向原来的对象;
        常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

    [例3]一个错误的例子:

    const int a = 10;
    const int * p = &a;
    *p = 20;                  //compile error
    int b = const_cast<int>(a);  //compile error

    在本例中出现了两个编译错误,第一个编译错误是*p因为具有常量性,其值是不能被修改的;另一处错误是const_cast强制转换对象必须为指针或引用,而例3中为一个变量,这是不允许的!

    [例4]const_cast关键字的使用

    #include<iostream>
    using namespace std;
    
    
    int main()
    {
        const int a = 10;
    
        const int * p = &a;
    
        int *q;
    
        q = const_cast<int *>(p);
    
        *q = 20;    //fine
    
        cout <<a<<" "<<*p<<" "<<*q<<endl;
    
            cout <<&a<<" "<<p<<" "<<q<<endl;
    
        return 0;
    }

    在本例中,我们将变量a声明为常量变量,同时声明了一个const指针指向该变量(此时如果声明一个普通指针指向该常量变量的话是不允许的,Visual Studio 2010编译器会报错)。

     

    之后我们定义了一个普通的指针*q。将p指针通过const_cast去掉其常量性,并赋给q指针。之后我再修改q指针所指地址的值时,这是不会有问题的。

    最后将结果打印出来,运行结果如下:
    10 20 20
    002CFAF4 002CFAF4 002CFAF4

    查看运行结果,问题来了,指针p和指针q都是指向a变量的,指向地址相同,而且经过调试发现002CFAF4地址内的值确实由10被修改成了20,这是怎么一回事呢?为什么a的值打印出来还是10呢?

    其实这是一件好事,我们要庆幸a变量最终的值没有变成20!变量a一开始就被声明为一个常量变量,不管后面的程序怎么处理,它就是一个常量,就是不会变化的。试想一下如果这个变量a最终变成了20会有什么后果呢?对于这些简短的程序而言,如果最后a变成了20,我们会一眼看出是q指针修改了,但是一旦一个项目工程非常庞大的时候,在程序某个地方出现了一个q这样的指针,它可以修改常量a,这是一件很可怕的事情的,可以说是一个程序的漏洞,毕竟将变量a声明为常量就是不希望修改它,如果后面能修改,这就太恐怖了。

    在例4中我们称“*q=20”语句为未定义行为语句,所谓的未定义行为是指在标准的C++规范中并没有明确规定这种语句的具体行为,该语句的具体行为由编译器来自行决定如何处理。对于这种未定义行为的语句我们应该尽量予以避免!

    从例4中我们可以看出我们是不想修改变量a的值的,既然如此,定义一个const_cast关键字强制去掉指针的常量性到底有什么用呢?我们接着来看下面的例子。

    例5:

    #include<iostream>
    using namespace std;
    
    const int * Search(const int * a, int n, int val);
    
    int main()
    
    {
    
        int a[10] = {0,1,2,3,4,5,6,7,8,9};
    
        int val = 5;
    
        int *p;
    
        p = const_cast<int *>(Search(a, 10, val));
    
        if(p == NULL)
    
            cout<<"Not found the val in array a"<<endl;
    
        else
    
            cout<<"hvae found the val in array a and the val = "<<*p<<endl;
    
        return 0;
    
    }
    
    const int * Search(const int * a, int n, int val)
    
    {
    
        int i;
    
        for(i=0; i<n; i++)
    
        {
    
            if(a[i] == val)
    
                return &a[i];
    
        }
    
        return  NULL;
    
    }

    在例5中我们定义了一个函数,用于在a数组中寻找val值,如果找到了就返回该值的地址,如果没有找到则返回NULL。函数Search返回值是const指针,当我们在a数组中找到了val值的时候,我们会返回val的地址,最关键的是a数组在main函数中并不是const,因此即使我们去掉返回值的常量性有可能会造成a数组被修改,但是这也依然是安全的。

    对于引用,我们同样能使用const_cast来强制去掉常量性,如例6所示。

    例6:

    #include<iostream>
    using namespace std;
    const int & Search(const int * a, int n, int val);
    
    int main()
    
    {
    
    int a[10] = {0,1,2,3,4,5,6,7,8,9};
    
    int val = 5;
    
    int &p = const_cast<int &>(Search(a, 10, val));
    
    if(p == NULL)
    
    cout<<"Not found the val in array a"<<endl;
    
    else
    
    cout<<"hvae found the val in array a and the val = "<<p<<endl;
    
    return 0;
    
    }
    
    
    const int & Search(const int * a, int n, int val)
    
    {
    
    int i;
    
    for(i=0; i<n; i++)
    
    {
    
    if(a[i] == val)
    
    return a[i];
    
    }
    
    return NULL;
    
    }

     了解了const_cast的使用场景后,可以知道使用const_cast通常是一种无奈之举,同时也建议大家在今后的C++程序设计过程中一定不要利用const_cast去掉指针或引用的常量性并且去修改原始变量的数值,这是一种非常不好的行为。

     

    3) reinterpret_cast

    在C++语言中,reinterpret_cast主要有三种强制转换用途:改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整型转换为指针或引用类型

    用法:reinterpret_cast<type_id> (expression)
        type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。
        它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。
        在使用reinterpret_cast强制转换过程仅仅只是比特位的拷贝,因此在使用过程中需要特别谨慎!

    例7:

    int *a = new int;
    double *d = reinterpret_cast<double *>(a);

    在例7中,将整型指针通过reinterpret_cast强制转换成了双精度浮点型指针。

    reinterpret_cast可以将指针或引用转换为一个足够长度的整形,此中的足够长度具体长度需要多少则取决于操作系统,如果是32位的操作系统,就需要4个字节及以上的整型,如果是64位的操作系统则需要8个字节及以上的整型。 

     

    4) dynamic_cast

     用法:dynamic_cast<type_id> (expression)

     

    (1)其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。

    (2)不能用于内置的基本数据类型的强制转换。

    (3)dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。

    (4)使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。

            B中需要检测有虚函数的原因:类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意义。

            这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念,详细可见<Inside c++ object model>)中,

            只有定义了虚函数的类才有虚函数表。

     (5)在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

            向上转换,即为子类指针指向父类指针(一般不会出问题);向下转换,即将父类指针转化子类指针。

           向下转换的成功与否还与将要转换的类型有关,即要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。

            在C++中,编译期的类型转换有可能会在运行时出现错误,特别是涉及到类对象的指针或引用操作时,更容易产生错误。Dynamic_cast操作符则可以在运行期对可能产生问题的类型转换进行测试。

     

    例1:

    #include<iostream>
    
    using namespace std;
    
     
    
    class base
    
    {
    
    public :
    
        void m(){cout<<"m"<<endl;}
    
    };
    
    
    class derived : public base
    {
    public:
    
        void f(){cout<<"f"<<endl;}
    
    };
    
    int main()
    
    {
    
        derived * p;
    
        p = new base;
    
        p = static_cast<derived *>(new base);
    
        p->m();
    
        p->f();
    
        return 0;
    
    }

    本例中定义了两个类:base类和derived类,这两个类构成继承关系。在base类中定义了m函数,derived类中定义了f函数。在前面介绍多态时,我们一直是用基类指针指向派生类或基类对象,而本例则不同了。

    本例主函数中定义的是一个派生类指针,当我们将其指向一个基类对象时,这是错误的,会导致编译错误。

    但是通过强制类型转换我们可以将派生类指针指向一个基类对象,p = static_cast<derived *>(new base);语句实现的就是这样一个功能,这样的一种强制类型转换时合乎C++语法规定的,但是是非常不明智的,它会带来一定的危险。

    在程序中p是一个派生类对象,我们将其强制指向一个基类对象,首先通过p指针调用m函数,因为基类中包含有m函数,这一句没有问题,之后通过p指针调用f函数。一般来讲,因为p指针是一个派生类类型的指针,而派生类中拥有f函数,因此p->f();这一语句不会有问题,但是本例中p指针指向的确实基类的对象,而基类中并没有声明f函数,虽然p->f();这一语句虽然仍没有语法错误,但是它却产生了一个运行时的错误。换言之,p指针是派生类指针,这表明程序设计人员可以通过p指针调用派生类的成员函数f,但是在实际的程序设计过程中却误将p指针指向了一个基类对象,这就导致了一个运行期错误。

    产生这种运行期的错误原因在于static_cast强制类型转换时并不具有保证类型安全的功能,而C++提供的dynamic_cast却能解决这一问题,dynamic_cast可以在程序运行时检测类型转换是否类型安全。

    当然dynamic_cast使用起来也是有条件的,它要求所转换的操作数必须包含多态类类型(即至少包含一个虚函数的类)。

    例2:

    #include<iostream>
    using namespace std;
    
    class base
    
    {
    
    public :
    
        void m(){cout<<"m"<<endl;}
    
    };
    
    class derived : public base
    
    {
    public:
    
        void f(){cout<<"f"<<endl;}
    
    };
    
    
    int main()
    {
    
        derived * p;
    
        p = new base;
    
        p = dynamic_cast<derived *>(new base);
    
        p->m();
    
        p->f();
    
        return 0;
    }

    在本例中利用dynamic_cast进行强制类型转换,但是因为base类中并不存在虚函数,因此p = dynamic_cast<derived *>(new base);这一句会编译错误。

    为了解决本例中的语法错误,我们可以将base类中的函数m声明为虚函数,virtual void m(){cout<<"m"<<endl;}。

    dynamic_cast还要求<>内部所描述的目标类型必须为指针或引用。

    例3:

    #include<iostream>
    #include<cstring>
    using namespace std;
     
     
    class A
    {
    public:
       virtual void f()
       {
           cout<<"hello"<<endl;
     
           };
     
    };
     
     
    class B:public A
    {
    public:
     
        void f()
        {
            cout<<"hello2"<<endl;
        } 
    };
     
     
    class C
    {
      void pp()
      {
          return;
      }
     
    };
     
    int fun()
    {
        return 1;
    }
     
    int main()
    {
        A* a1=new B;//a1是A类型的指针指向一个B类型的对象
     
        A* a2=new A;//a2是A类型的指针指向一个A类型的对象
     
        B* b;
     
        C* c;
     
        b=dynamic_cast<B*>(a1);//结果为not null,向下转换成功,a1之前指向的就是B类型的对象,所以可以转换成B类型的指针。
     
        if(b==NULL)
        {
            cout<<"null"<<endl;
        }
        else
        {
     
            cout<<"not null"<<endl;
     
        }
     
        b=dynamic_cast<B*>(a2);//结果为null,向下转换失败
     
        if(b==NULL)
        {
            cout<<"null"<<endl;
     
        }
        else
        {
            cout<<"not null"<<endl;
        }
     
     
        c=dynamic_cast<C*>(a);//结果为null,向下转换失败
     
        if(c==NULL)
     
        {
            cout<<"null"<<endl;
        }
        else
        {
            cout<<"not null"<<endl;
     
        }
     
        delete(a);
        return 0;
    }

     

    展开全文
  • Java 强制类型转换

    千次阅读 2019-01-09 10:25:20
    强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟带转换的变量名。例如: double x = 9.997; int nx = (int)x; 这样,变量nx的值为9。强制类型转换通过截断小数部分将浮点值转换为整型。 ...

    强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟带转换的变量名。例如:

    double x = 9.997;
    int nx = (int)x;

    这样,变量nx的值为9。强制类型转换通过截断小数部分将浮点值转换为整型。

    如果想对浮点数进行舍入运算,以便得到最接近的整数(在很多情况下,这种操作更有用),那就需要使用Math.round方法:

    double x = 9.997;
    int nx = (int)Math.round(x);

    现在,变量nx的值为10.当调用round的时候,任然需要使用强制类型转换(int)。其原因是round方法返回的结果为long类型,由于存在信息丢失的可能性,所以只有使用显示的强制类型转换才能够将long类型转换为int类型。

    警告:如果试图将一个数值从一种类型强制转换为另一种类型,而又超出了目标类型的表示范围,结果就会截断成一个完全不同的值。例如,(byte)300 的实际值为 44。

    展开全文
  • C++ 四种强制类型转换的总结
  • C++ 强制类型转换

    2020-01-07 21:00:07
    强制类型转换 C++语言中提供了static_cast、const_cast、reinterpret_cast和dynamic_cast。这四个关键字都是用于强制类型转换的。 二.static_cast 1.基本数据之间的转换,如int转化为double int a = 1; ...

    一.强制类型转换

    C++语言中提供了static_cast、const_cast、reinterpret_cast和dynamic_cast。这四个关键字都是用于强制类型转换的。 

    二.static_cast

    1.基本数据之间的转换,如int转化为double

    int a = 1;
    double b = static_cast<double>(a);

    2.用于类层次结构中基类和派生类之间指针或引用的转换
    ①进行上行转换(把派生类的指针或引用转换成基类表示)是安全的
    ②进行下行转换(把基类的指针或引用转换为派生类表示),由于没有动态类型检查,所以是不安全的

    //写两个类,假如 Derive类继承Basic
    Basic *b = nullptr;
    Derive *d = new Derive;
    b = static_cast<Basic *> d;

    3.把空指针转换成目标类型的空指针

    int *p;
    void *m = malloc(sizeof(int));
    p = static_cast<int *>m;

    4.把任何类型的表达式转换为void类型 

    三.const_cast

    cost_cast即用于强制转换指针或者引用的const或volatile限制,特别注意的是,const_cast不是用于去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,其去除常量性的对象必须为指针或引用。

    //错误例子
    const int a = 2;
    int b = const_cast<int>a;        //错误,const_cast强制转换的对象必须是指针或引用
    
    //正确例子
    int c = 2;
    const int *d = &c;
    int *e = const_cast<int *>d;

    四.reinterpret_cast 

    reinterpret_cast运算符用于处理无关类型之间的转换,他会产生一个新的值,这个值会有与原始参数(原数据类型)有完全相同的比特位。

    1.从指针类型到一个足够大的整数类型

    2.从整数类型或者枚举类型到指针类型

    3.从一个指向函数的指针到另一个不同类型的指向函数的指针

    4.从一个指向对象的指针到另一个不同类型的指向对象的指针

    5.从一个指向类函数成员的指针到另一个指向不同类型的函数成员的指针

    6.从一个指向类数据成员的指针到另一个指向不同类型的数据成员的指针

    五.dynamic_cast

    1.前面三种都是编译时完成的强制转换,dynamic_cast是运行时处理的。

    2.不能用于内置的基本数据类型的强制转换。

    3.dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。

    4.使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。

    5.在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

    使用dynamic_cast进行向下强制类型转换。使用此关键字有以下几个条件:

    ①.必须有虚函数

    ②.必须打开编译器的RTTI开关

    ③.必须有继承关系 

    展开全文
  • C语言强制类型转换

    万次阅读 多人点赞 2018-10-12 00:18:44
    强制类型转换是通过类型转换运算来实现的。其一般形式为: (类型说明符) (表达式) 其功能是把表达式的运算结果强制转换成类型说明符所表示的类型。例如: (float) a 把a转换为实型(int)(x+y) 把x+y的结果转换为整型...
  • 深入理解C++中五种强制类型转换的使用场景

    千次阅读 多人点赞 2021-07-02 22:15:48
    C++中五种强制类型转换解析1、C风格的强制类型转换2、C++风格的强制类型转换2.1、static_cast2.1.1、类实例转换场景使用static_cast2.1.2、没有多态的场景下使用static_cast2.1.3、具有多态的场景下使用static_cast...
  • Python 强制类型转换

    万次阅读 2019-10-16 16:39:25
    学习过程中遇到了强转问题,这里整理一下。...本篇主要介绍Python的强制类型转换。 软件环境 系统 UbuntuKylin 14.04 软件 Python 2.7.3 IPython 4.0.0 Python数据类型的显式转换 数据类型的显示转换,...
  • js的强制类型转换

    千次阅读 2020-11-19 09:41:19
    js的强制类型转换 方法主要有三种 转换函数、强制类型转换、利用js变量弱类型转换。 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数。前者把值转换成整数,后者把值转换成浮点数。只有对String...
  • 【C++】四种强制类型转换

    万次阅读 多人点赞 2019-02-28 21:05:08
    C++ 四种强制类型转换   C语言中的强制类型转换(Type Cast)有显式和隐式两种,显式一般就是直接用小括号强制转换,TYPE b = (TYPE)a; 隐式就是直接 float b = 0.5; int a = b; 这样隐式截断(by the way 这样...
  • C++ 四种强制类型转换

    千次阅读 2019-08-28 22:07:37
    C++ 类型转换(C风格的强制转换): 在C++基本的数据类型中,可以分为四类:整型,浮点型,字符型,布尔型。其中数值型包括 整型与浮点型;字符型即为char。 (1)将浮点型数据赋值给整型变量时,舍弃其小数部分。...
  • C++的四种强制类型转换,所以C++不是类型安全的。分别为:static_cast , dynamic_cast , const_cast , reinterpret_cast为什么使用C风格的强制转换可以把想要的任何东西转换成合乎心意的类型。那为什么还需要一个新...
  • 主要介绍了C#中的自动类型转换和强制类型转换,非常不错,具有一定的参考借鉴价值 ,需要的朋友可以参考下
  • 强制类型转换 强制类型转换是把变量从一种类型转换为另一种数据类型。例如,如果你想存储一个long类型的值到一个简单的整型中,需要把long类型强制转换为int类型。可以使用强制类型转换运算符来把值显示地从一种类型...
  • C++四种强制类型转换运算符

    千次阅读 2020-02-29 12:03:13
    C/C++中的类型转换分为两种:隐式类型转换和显式类型转换。 而对于隐式类型转换,在很多时候,不经意间就发生了,比如int类型...//C style,强制类型的转换. C++对C兼容,所以上述方式的类型转换是可以的,但是有时...
  • C强制类型转换总结

    千次阅读 多人点赞 2017-11-08 09:52:11
    C强制类型转换阅读目录: 一、强制类型转换目的、基本格式 二、C中变量的本质含义 三、普通变量强制类型转换 四、指针变量类型转换
  • 学习隐式类型转换和强制类型转换的基本概念. 本意或非本意下使用类型转换时可能会出现的问题. 在C语言是可以进行类型之间的转换且其中存在两种类型转换的方式 强制类型转换 隐式类型转换 强制类型转换 强制类型...
  • Java之强制类型转换

    万次阅读 多人点赞 2019-01-04 18:58:24
    在之前的文章中介绍过,将一个类型强制转换为另一个数据类型的过程称为强制类型转换。本文即将介绍的是继承过程中发生的引用类型转换。  引用类型转换是指对象引用的强制类型转换,在了解对象引用的强制类型转换...
  • java 中的强制类型转换

    万次阅读 多人点赞 2019-06-13 00:25:24
    1) 整数 int 转换成字串 String , 有三种方法 : String s = String.valueOf(i); String s = Integer.toString(i); String s = "" + i; 2 )String 转 int int i = Integer.parseInt([String]); i = Integer....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 465,461
精华内容 186,184
关键字:

强制类型转换