reinterpret_cast的本质

本文通过示例详细解析了reinterpret_cast的本质,即忽略数据原本含义,重新赋予新的数据类型含义。通过不同类型的变量转换,展示了reinterpret_cast如何改变数据的解释方式。

reinterpret_cast的本质

先看看下面的代码:

#include<iostream>
usingnamespacestd;

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

floatf=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>
usingnamespacestd;

voidmain()
{
char*p="1234";

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

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

再看一个诡异的。

#include<iostream>
usingnamespacestd;

classCData
{
public:
CData(
inta,intb)
{
val1
=a;
val2
=b;
}

private:
intval1;
intval2;
};

voidmain()
{
CDatadata(
0x32313536,0x37383433);

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

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

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值