C++中(int&)和(int)的区别
2015-04-13 02:37
351 查看
在说这个问题之前,先说两个需要知道的背景知识:
(1)语言的类型的强制转换不会修改原来的数据,会另外的开辟一个临时的或者程序中指定的空间来存储强制转换后的值。
(2)C++引用的实现是在符号表中动了手脚,把自己的变量符号对应的内存地址写成了它所引用的那个变量的内存地址了。
(3)C++的cout函数的执行,是根据变量的名称找到对应的内存地址,然后根据变量的类型从内存中抓取相应的数据。
有了上面的两个知识点,看下面的程序:
程序执行结果:
View Code
从汇编语言中看到,(int)a是要经过类型强制转换的,并且把转换后的值放在寄存器中输出,(int&)a直接把原来的数据copy到一个寄存器中输出。
重要的说明一下:
符号表是在编译阶段产生的,上面说的temp和temp1这样的临时的变量也是在编译的时候都已经弄到了符号表中,只不过它 的作用域仅仅的就是那句话。不是在执行阶段在往符号表中增加的条目。
最后再说一个知识点:单精度浮点数、双精度浮点数的存储。
单精度和双精度浮点数的存储方式和int类型的存储方式是完全不同的,int的1在内存中的存储方式是00000001h,int的0是00000000h,但是浮点数要用符号位+阶码+尾数的方式存储。
![](http://images.cnblogs.com/cnblogs_com/jillzhang/WindowsLiveWriter/float_A919/clip_image001%5B3%5D_2.gif)
![](http://images.cnblogs.com/cnblogs_com/jillzhang/WindowsLiveWriter/float_A919/clip_image001%5B6%5D_2.gif)
以单精度的float为例:
它的形式是1.M * 2E-127,其中E是指数为的移码形式。所以对于float的1.0,尾数M=0,阶码E=127,符号位是0,所以对应的机器码是:3F800000h。
提示:为什么浮点数阶码部分要用移码?
(1)使用移码方便运算。2的指数部分有正有负,使用了移码之后,2的指数依然有正有负,但是数据的真正的存储位E就完全是正的值了,没有了负值,这样能加快运算。
(2)为了统一浮点数的0和整数的0。整数0的各个二进制位是全0(公认的了),但是如果不用移码,浮点数的全0是1,用了移码之后,这个是就是1.0 * 20-127,由于这个数太小了,这时会发生溢出,也就是0。
(1)语言的类型的强制转换不会修改原来的数据,会另外的开辟一个临时的或者程序中指定的空间来存储强制转换后的值。
(2)C++引用的实现是在符号表中动了手脚,把自己的变量符号对应的内存地址写成了它所引用的那个变量的内存地址了。
(3)C++的cout函数的执行,是根据变量的名称找到对应的内存地址,然后根据变量的类型从内存中抓取相应的数据。
有了上面的两个知识点,看下面的程序:
#include <iostream> using namespace std; int main() { float a = 1.0f; cout << (int)a << endl; cout << (int &)a << endl; cout << endl; float b = 0.0f; cout << (int)b << endl; cout << (int &)b << endl; return 0; }
程序执行结果:
--- C:\Program Files\Microsoft Visual Studio\MyProjects\TestThread\testThread.cpp ----------------------------------------------------------------- 1: #include <iostream> 2: using namespace std; 3: 4: int main() 5: { 00401780 push ebp 00401781 mov ebp,esp 00401783 sub esp,48h 00401786 push ebx 00401787 push esi 00401788 push edi 00401789 lea edi,[ebp-48h] 0040178C mov ecx,12h 00401791 mov eax,0CCCCCCCCh 00401796 rep stos dword ptr [edi] 6: float a = 1.0f; 00401798 mov dword ptr [ebp-4],3F800000h//这里看到,1.0在内存中的存储方式,是单精度浮点数的存储方式 7: cout << (int)a << endl; 0040179F push offset @ILT+195(std::endl) (004010c8) 004017A4 fld dword ptr [ebp-4]//把这个内存单元中的数据以浮点数方式加载到浮点寄存器中 004017A7 call __ftol (0042133c)//这个函数就把浮点数寄存器中的数据转换成了int类型,并把结果放在了eax寄存器中。转换完之后的结果00000001h 004017AC push eax//输出eax中的数据 004017AD mov ecx,offset std::cout (0047ff88) 004017B2 call @ILT+245(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004010fa)//ILT是Debug模式下函数的入口表,Release下就直接调用函数了,245是int类型数据的输出函数序号 004017B7 mov ecx,eax 004017B9 call @ILT+470(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011db) 8: cout << (int &)a << endl; 004017BE push offset @ILT+195(std::endl) (004010c8) 004017C3 mov eax,dword ptr [ebp-4]//直接把a的值原封不动的copy到eax寄存去中 004017C6 push eax//输出eax中的数据 004017C7 mov ecx,offset std::cout (0047ff88) 004017CC call @ILT+245(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004010fa) 004017D1 mov ecx,eax 004017D3 call @ILT+470(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011db) 9: cout << a << endl; 004017D8 push offset @ILT+195(std::endl) (004010c8) 004017DD mov ecx,dword ptr [ebp-4] 004017E0 push ecx 004017E1 mov ecx,offset std::cout (0047ff88) 004017E6 call @ILT+285(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401122)//285是float类型数据的输出函数序号 004017EB mov ecx,eax 004017ED call @ILT+470(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011db) 10: 11: cout << endl << endl; 004017F2 push offset @ILT+195(std::endl) (004010c8) 004017F7 push offset @ILT+195(std::endl) (004010c8) 004017FC mov ecx,offset std::cout (0047ff88) 00401801 call @ILT+470(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011db) 00401806 mov ecx,eax 00401808 call @ILT+470(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011db) 12: 13: float b = 0.0f; 0040180D mov dword ptr [ebp-8],0 14: cout << (int)b << endl; 00401814 push offset @ILT+195(std::endl) (004010c8) 00401819 fld dword ptr [ebp-8] 0040181C call __ftol (0042133c) 00401821 push eax 00401822 mov ecx,offset std::cout (0047ff88) 00401827 call @ILT+245(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004010fa) 0040182C mov ecx,eax 0040182E call @ILT+470(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011db) 15: cout << (int &)b << endl; 00401833 push offset @ILT+195(std::endl) (004010c8) 00401838 mov edx,dword ptr [ebp-8] 0040183B push edx 0040183C mov ecx,offset std::cout (0047ff88) 00401841 call @ILT+245(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004010fa) 00401846 mov ecx,eax 00401848 call @ILT+470(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011db) 16: 17: return 0; 0040184D xor eax,eax 18: }
View Code
从汇编语言中看到,(int)a是要经过类型强制转换的,并且把转换后的值放在寄存器中输出,(int&)a直接把原来的数据copy到一个寄存器中输出。
重要的说明一下:
符号表是在编译阶段产生的,上面说的temp和temp1这样的临时的变量也是在编译的时候都已经弄到了符号表中,只不过它 的作用域仅仅的就是那句话。不是在执行阶段在往符号表中增加的条目。
最后再说一个知识点:单精度浮点数、双精度浮点数的存储。
单精度和双精度浮点数的存储方式和int类型的存储方式是完全不同的,int的1在内存中的存储方式是00000001h,int的0是00000000h,但是浮点数要用符号位+阶码+尾数的方式存储。
![](http://images.cnblogs.com/cnblogs_com/jillzhang/WindowsLiveWriter/float_A919/clip_image001%5B3%5D_2.gif)
![](http://images.cnblogs.com/cnblogs_com/jillzhang/WindowsLiveWriter/float_A919/clip_image001%5B6%5D_2.gif)
以单精度的float为例:
它的形式是1.M * 2E-127,其中E是指数为的移码形式。所以对于float的1.0,尾数M=0,阶码E=127,符号位是0,所以对应的机器码是:3F800000h。
提示:为什么浮点数阶码部分要用移码?
(1)使用移码方便运算。2的指数部分有正有负,使用了移码之后,2的指数依然有正有负,但是数据的真正的存储位E就完全是正的值了,没有了负值,这样能加快运算。
(2)为了统一浮点数的0和整数的0。整数0的各个二进制位是全0(公认的了),但是如果不用移码,浮点数的全0是1,用了移码之后,这个是就是1.0 * 20-127,由于这个数太小了,这时会发生溢出,也就是0。
相关文章推荐
- [c/c++语言知识点1]int a, (int) &a, (int &)a区别
- C++中static_cast、const_cast、reinterpret_cast的用法举例,附带举例说明强制类型转换时int和int&的区别
- C++ 常引用 const int &a 的作用和区别
- [C/C++](int)a,&a,(int)&a,(int&)a区别小结
- c++中vector<int>和vector<int*>的用法区别
- C++中static_cast、const_cast、reinterpret_cast的用法举例,附带举例说明强制类型转换时int和int&的区别
- C++中int、int&、int*和int**的区别与联系、用途
- C++中引用&与取地址&的区别分析
- c和c++中&的用法及区别
- C++ int & *p; //不能建立指向引用的指针;int *a; int * & p=a; //正确,指针变量的引用
- C/C++ STACK &HEAP 区别
- const int & 和 int 的区别
- int *pa(指针)和int *&pa(指针的引用)的区别
- 有关(int&)和(int)的区别
- C/C++/VC MFC----char & int---study
- c/c++中#include 与#include " "区别
- C++ 输入函数 cin>>、cin.getline()和cin.get()区别
- (int)a、&a、(int)&a、(int&)a的区别,很偏僻的题
- [C++基础]019_指针和引用(int*、int&、int*&、int&*、int**)
- C++中 引用&与取地址&的区别