reinterpret_cast的本质

先看看下面的代码:

#include  < iostream >  
using   namespace  std;

void  main() 

    
int  i  =   875770417
    cout
<< i << "   " ;
    
char *  p  =  reinterpret_cast < char *> ( & i);
    
for ( int  j = 0 ; j < 4 ; j ++ )
        cout
<< p[j];
    cout
<< endl;

    
float  f  =   0.00000016688933 ;
    cout 
<< f << "   " ;
    p 
=  reinterpret_cast < char *> ( & f);
    
for (j = 0 ; j < 4 ; j ++ )
        cout
<< p[j];
    cout
<< endl;
}

我们看到不管是int型的 i 还是float型的 f ,经过reinterpret_cast<char*>(&addr)的转换后,输出都是"1234"

这是因为整型的875770417和单精度浮点型的0.00000016688933,在内存中的数据表示从低位到高位依次是0x31 0x32 0x33 0x34。

数据的表示是相同,你把它当int型数据来看,他就是875770417;你把它当float型数据来看,它就是0.00000016688933,关键就是看编译器怎么来解释数据,也就是语义表达的问题。

所以reinterpret_cast<char*>的转换就是不理会数据本来的语义,而重新赋予它char*的语义。有了这样的认识有以后,再看看下面的代码就好理解了。

#include  < iostream >  
using   namespace  std;

void  main() 

    
char *  p  =   " 1234 " ;

    
int *  pi  =  reinterpret_cast < int *> (p);
    cout
<<* pi << endl;
}

输出的是875770417(0x34333231,注意高低位),就是上面的逆运算,好理解吧。

再看一个诡异的。

#include  < iostream >  
using   namespace  std;

class  CData
{
public :
    CData(
int  a,  int  b)
    {
        val1 
=  a;
        val2 
=  b;
    }

private :
    
int  val1;
    
int  val2;
};

void  main() 

    CData data(
0x32313536 0x37383433 );

    
int *  pi  =  reinterpret_cast < int *> (( char * ) & data  +   2 );
    cout
<<* pi << endl;
}

pi指向哪里?指向CData类型数据data的内存地址偏移2个字节。也就是说指向CData::val1和CData::val2的中间。这不是乱指嘛!没错,就是乱指,我们仍然看到输出数据显示875770417。

        也就是说只要是个地址,reinterpret_cast都能转,不管原来数据是啥,甚至不是一个数据的开始。所以,请正确的使用它,用你希望的方式。



from:  http://blog.csdn.net/coding_hello/article/details/2211466   谢谢您对知识耐心的总结!很受用!

猜你喜欢

转载自blog.csdn.net/alss1923/article/details/78892832