zoukankan      html  css  js  c++  java
  • C++基础回顾强制类型转换

    直接上代码

    float a = 1.0f;
    cout << (int)a << endl;
    cout << (int&)a << endl;
    cout << boolalpha << ( (int)a == (int&)a ) << endl; // 输出什么?
    float b = 0.0f;
    cout << (int)b << endl;
    cout << (int&)b << endl;
    cout << boolalpha << ( (int)b == (int&)b ) << endl; // 输出什么?
    

    请问输出结果如何?

    1
    1065353216
    false
    0
    0
    true
    

    为什么0.0f和1.0f有这么大的差别呢?让我们反汇编看看代码如何?

    00931620  push        ebp  
    00931621  mov         ebp,esp  
    00931623  sub         esp,0D8h  
    00931629  push        ebx  
    0093162A  push        esi  
    0093162B  push        edi  
    0093162C  lea         edi,[ebp-0D8h]  
    00931632  mov         ecx,36h  
    00931637  mov         eax,0CCCCCCCCh  
    0093163C  rep stos    dword ptr es:[edi]  
    	float a = 1.0f;
    0093163E  fld1  //将1.0f装载到st(0)
    00931640  fstp        dword ptr [a]  
    	cout << (int)a << endl;
    00931643  mov         esi,esp  
    00931645  mov         eax,dword ptr [__imp_std::endl (93D31Ch)]  
    0093164A  push        eax  
    0093164B  fld         dword ptr [a]  //st0 = a
    0093164E  call        @ILT+340(__ftol2_sse) (931159h)  //具体做什么不太清楚好像望城了从float到long类型的转换,得到的值为1
    00931653  mov         edi,esp  
    00931655  push        eax  
    00931656  mov         ecx,dword ptr [__imp_std::cout (93D318h)]  
    0093165C  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D314h)]  
    00931662  cmp         edi,esp  
    00931664  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    00931669  mov         ecx,eax  
    0093166B  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D310h)]  
    00931671  cmp         esi,esp  
    00931673  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    	cout << (int&)a << endl;
    00931678  mov         esi,esp  
    0093167A  mov         eax,dword ptr [__imp_std::endl (93D31Ch)]  
    0093167F  push        eax  
    00931680  mov         edi,esp  
    00931682  mov         ecx,dword ptr [a]  //输出a地址内容(强制将内容转换为int类型),a内存中的内容为3f800000(float的编码方式),强制转换为int类型得到了3f800000的10进制值
    00931685  push        ecx  
    00931686  mov         ecx,dword ptr [__imp_std::cout (93D318h)]  
    0093168C  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D314h)]  
    00931692  cmp         edi,esp  
    00931694  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    00931699  mov         ecx,eax  
    0093169B  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D310h)]  
    009316A1  cmp         esi,esp  
    009316A3  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    	cout << boolalpha << ( (int)a == (int&)a ) << endl; // 输出什么?
    009316A8  mov         esi,esp  
    009316AA  mov         eax,dword ptr [__imp_std::endl (93D31Ch)]  
    009316AF  push        eax  
    009316B0  fld         dword ptr [a] 
    009316B3  call        @ILT+340(__ftol2_sse) (931159h)  
    009316B8  cmp         eax,dword ptr [a]  //(1==0x3f800000)肯定输出false
    009316BB  sete        cl  
    009316BE  mov         edi,esp  
    009316C0  movzx       edx,cl  
    009316C3  push        edx  
    009316C4  mov         ebx,esp  
    009316C6  push        offset std::boolalpha (931113h)  
    009316CB  mov         ecx,dword ptr [__imp_std::cout (93D318h)]  
    009316D1  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D30Ch)]  
    009316D7  cmp         ebx,esp  
    009316D9  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    009316DE  mov         ecx,eax  
    009316E0  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D308h)]  
    009316E6  cmp         edi,esp  
    009316E8  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    009316ED  mov         ecx,eax  
    009316EF  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D310h)]  
    009316F5  cmp         esi,esp  
    009316F7  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    	float b = 0.0f;
    009316FC  fldz  
    009316FE  fstp        dword ptr [b]  
    	cout << (int)b << endl;
    00931701  mov         esi,esp  
    00931703  mov         eax,dword ptr [__imp_std::endl (93D31Ch)]  
    00931708  push        eax  
    00931709  fld         dword ptr [b]  
    0093170C  call        @ILT+340(__ftol2_sse) (931159h)  
    00931711  mov         edi,esp  
    00931713  push        eax  
    00931714  mov         ecx,dword ptr [__imp_std::cout (93D318h)]  
    0093171A  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D314h)]  
    00931720  cmp         edi,esp  
    00931722  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    00931727  mov         ecx,eax  
    00931729  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D310h)]  
    0093172F  cmp         esi,esp  
    00931731  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    	cout << (int&)b << endl;
    00931736  mov         esi,esp  
    00931738  mov         eax,dword ptr [__imp_std::endl (93D31Ch)]  
    0093173D  push        eax  
    0093173E  mov         edi,esp  
    00931740  mov         ecx,dword ptr [b]  
    00931743  push        ecx  
    00931744  mov         ecx,dword ptr [__imp_std::cout (93D318h)]  
    0093174A  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D314h)]  
    00931750  cmp         edi,esp  
    00931752  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    00931757  mov         ecx,eax  
    00931759  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D310h)]  
    0093175F  cmp         esi,esp  
    00931761  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    	cout << boolalpha << ( (int)b == (int&)b ) << endl; // 输出什么?
    00931766  mov         esi,esp  
    00931768  mov         eax,dword ptr [__imp_std::endl (93D31Ch)]  
    0093176D  push        eax  
    0093176E  fld         dword ptr [b]  
    00931771  call        @ILT+340(__ftol2_sse) (931159h)  
    00931776  cmp         eax,dword ptr [b]  //b对应内容为0x00000000,转换之后依然为0所以相等
    00931779  sete        cl  
    0093177C  mov         edi,esp  
    0093177E  movzx       edx,cl  
    00931781  push        edx  
    00931782  mov         ebx,esp  
    00931784  push        offset std::boolalpha (931113h)  
    00931789  mov         ecx,dword ptr [__imp_std::cout (93D318h)]  
    0093178F  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D30Ch)]  
    00931795  cmp         ebx,esp  
    00931797  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    0093179C  mov         ecx,eax  
    0093179E  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D308h)]  
    009317A4  cmp         edi,esp  
    009317A6  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    009317AB  mov         ecx,eax  
    009317AD  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D310h)]  
    009317B3  cmp         esi,esp  
    009317B5  call        @ILT+505(__RTC_CheckEsp) (9311FEh)  
    

    如此就可以推导出结果对应为

    1

    0x3f800000

    false

    0

    0  

    true

  • 相关阅读:
    向现有的磁盘组加入/删除ASM磁盘
    词语相似度计算
    C++ STL algorithm 列表
    ORACLE内核参数
    一款好的UI草图设计软件
    (转)svn检出的时候报 Unable to connect to a repository at URL错误
    HTTP 错误 500.19 – Internal Server Error web.config 文件的 system.webServer/httpErrors 节中不允许绝对物理路径“C:\inetpub\custerr”。
    使用SVN后系统变慢的解决方法
    oracle 11g ORA12541: TNS: 无监听程序 (DBD ERROR: OCIServerAttach)
    [转载]无法删除oci.dll文件的解决办法
  • 原文地址:https://www.cnblogs.com/SkyMouse/p/2485982.html
Copyright © 2011-2022 走看看