类型转换_C++中的int&

本文探讨了C++中(int&)类型转换在浮点数上的表现,解释了(int&)a为何输出为10 6535 3216,涉及浮点数的内存表示、地址转换以及栈的原理。通过不同类型的强制转换展示了可能的结果和精度损失。

类型转换_C++中的int&

看到面试题中有道有趣的,这里mark

...
float a = 1.0f;
cout << (int)a << endl;
cout << &a << endl;
cout << (int&)a << endl;
...

这里的(int&)a的输出竟然为10 6535 3216,相当于16进制的3f80 0000。这是为什么?(天真地以为引用转换==!)那要先了解浮点数在内存中的表示。


浮点数

1.为了便于软件移植,按照IEEE754标准: 32位浮点数符号位为1位,阶码为8位,尾数为23位;64位浮点数符号位为1位,阶码为11位,尾数为52
2.阶码采用移码方法正负指数,即浮点数的指数加上偏移值(32位为127,,64位为1023)。
3.尾数值不为0时,尾数域最高有效位为1,即为浮点数的规格化表示。

所以,1.0f=1.0*2^0,符号位为0,阶码为127,尾数为0(0 0111 1111 000 0000 0000 0000 0000 0000),相当于0011 1111 1000 0000 0000 0000 0000 0000,即0x3f80 0000
详细的话,可以看How to represent FLOAT number in memory in CHow are NaN and Infinity of a float or double stored in memory?

回到原题,得出a的内存值为0x3f80 0000,那(int&)a又是什么?*


(int&)

在C++中,&a代表这变量a的地址,也能代表对a的引用。这里的话,我更倾向于地址。
(int&)a是将a这个浮点数地址开始的sizeof(int)个字节的内容当成int型输出,sizeof(int)等于4字节(32位),一般内存地址都是以地址块的最低字节的至代表地址块的,a按从低到高的地址值4字节的内容则是0x000x000x800x3f,算下来就是0x3f80 0000,而a强制类型转换后会将内存值当成int型输出,结果就为10 6535 3216(10进制的0x3f80 0000,int默认为10进制)。


更多尝试

...
float a = 1.0f;
cout<< (double&)a << endl;  //输出为4.86234e-270
cout<< (float&)a << endl;   //输出为1
double b = 1.0f;
cout<< (double&)b << endl;  //输出为1
cout<< (float&)b << endl;   //输出为0
cout<< (int&)b << endl;     //输出为0
...

(double&)b和(float&)a都是转为原类型,所以值不变。
(float&)b强制转换后,相当于将0x3f80 0000截断为0x0000,所以为0,这应该算是精度丢失。
(int&)b同(float&)一样。
最神奇的数第一个,输出为4.86234e-270,这是因为(double&)a强制转换后,相当于扩展多一半的sizeof(double)个字节(精度扩充?),这就要看运气了,有时这部分的值是不可知的,要了解栈的结构了才行。

栈又称堆栈, 由编译器自动分配释放,存放函数的参数的值,用户存放程序临时创建的局部变量的值等。
简单点,以下面代码为例(非main函数内的局部变量)

float a=1.0f;
float b=1.0f;
float c=1.0f;
cout<<(double&)a<<endl<<(double&)b<<endl<<(double&)c<<endl;

输出为

0.0078125 (相当于0x3f80 0000)
0.0078125
-1.07991e-41

一般说来栈是从高地址往低地址生长的,但查看下它们的地址,发现竟然是反着来!谁能解释一下?
难道与处理器有关,我的g++版本是+ (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4,处理器是i686。所以栈的方向是从低地址到高地址生长的?
也有可能是c、b、a依次入栈,这样就是从高地址往低地址生长了?

`cout<<&a<

...
float a = 1.0f;
cout<< (char&)a << endl;
...

这次的输出为空,或者说是不可见。这倒好理解,a强制类型转换后(sizeof(char)==1)为0x00,在转换为char型输出,但是0x00是非可打印字符,不像字符’0’-‘9’等可以直接输出(打印),可以说基本类型里,除void外,变量强制转换为(char&),最多也只是得到0x000x010x100x11

从(int&)可以看出C++真是博大精深:)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值