类型转换_C++中的int&
2016-06-11 23:28
344 查看
类型转换_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 C和How 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字节的内容则是0x00、0x00、0x80、0x3f,算下来就是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&),最多也只是得到0x00、0x01、0x10、0x11。
从(int&)可以看出C++真是博大精深:)。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性