关于引用和强制类型转换的问题请教。

idleguy 2004-05-14 03:42:21
如下的代码:
#include <iostream>

using namespace std;

void main()
{
double dval=123.4;
int &rval=(int&)dval;

rval=5;
cout<<&rval<<" "<<&dval<<endl;
cout<<rval<<" "<<dval<<endl;
}

输出:

0012FF70 0012FF70
50000000 123.4

(编译环境:vc++6的cl)
也就是说,dval和rval的地址是一样的。但是为什么输出的值不同呢?


谢谢。
...全文
149 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
idleguy 2004-06-17
  • 打赏
  • 举报
回复
谢谢angelo23的解释,现在明白了~~

我记得这个贴子结过一次了……-_-b..

再结。
angelo23 2004-06-08
  • 打赏
  • 举报
回复
需要补充一点的是:
cngdzhang()说到的“编译器生成一个临时变量”和这里的情况是不一样的

int & dval = (int&)rval: 这个是强制类型转换的格式,实际的作用是让dval引用rval的低四位内存空间,并且把这4个字节按照int来解释。
angelo23 2004-06-08
  • 打赏
  • 举报
回复
Before
Byte 1 : 01011001
Byte 2 : 10011001
Byte 3 : 10011001
Byte 4 : 10011001
Byte 5 : 10011001
Byte 6 : 10011011
Byte 7 : 01111010
Byte 8 : 00000010
-------
Byte 1 : 01011001
Byte 2 : 10011001
Byte 3 : 10011001
Byte 4 : 10011001
Byte 5 : 10011001
Byte 6 : 10011011
Byte 7 : 01111010
Byte 8 : 00000010

dval = 123.4

After
Byte 1 : 10100000
Byte 2 : 00000000
Byte 3 : 00000000
Byte 4 : 00000000
Byte 5 : 10011001
Byte 6 : 10011011
Byte 7 : 01111010
Byte 8 : 00000010
-------
Byte 1 : 10100000
Byte 2 : 00000000
Byte 3 : 00000000
Byte 4 : 00000000
Byte 5 : 10011001
Byte 6 : 10011011
Byte 7 : 01111010
Byte 8 : 00000010

dval = 123.3999633789063
angelo23 2004-06-08
  • 打赏
  • 举报
回复
嗯,写了个东西,搞清楚了

#include <iostream>
#include <iomanip>
using namespace std;

void showbits(const void *address, int size) {
const char *p = reinterpret_cast<const char*>(address);
for(int i = 0; i < size; i++, p++) {
cout << "Byte " << i + 1 << " : ";
for(int j = 0; j < 8; j++)
cout << ( (*p >> j) & 1 );
cout << endl;
}
}

int main()
{
double dval=123.4;
int &rval=(int&)dval;
cout << "Before\n";
showbits(&dval, sizeof(double));
cout << "-------\n";
showbits(&rval, sizeof(double));
cout << "\ndval = " << setprecision(16) << dval << endl;

rval=5;
cout << "\nAfter\n";
showbits(&dval, sizeof(double));
cout << "-------\n";
showbits(&rval, sizeof(double));
cout << "\ndval = " << setprecision(16) << dval << endl;
}

之所以前后两次输出dval的结果一样,并不是因为dval的8个字节的内容都没有改变,只是因为显示精度问题,所以看上去似乎是没变。
btw,上面那个程序众showbits是从低位到高位显示bits内容的。
qwertasdfg123 2004-06-08
  • 打赏
  • 举报
回复
搞了一下。
应该根double和int的数据储存形式有关。
查下。。。。。。
bluejugar 2004-06-08
  • 打赏
  • 举报
回复
严重关注中...............
cngdzhang 2004-05-14
  • 打赏
  • 举报
回复
C++ Primer中3.6

解释:

double dval=1024;
const int &ri=val;

实际上是:

编译器生成一个临时变量

int temp=dval;
const int &ri=temp;
idleguy 2004-05-14
  • 打赏
  • 举报
回复
cngdzhang() 兄,是啊,我奇怪的地方就是在这里。为什么会有这种情况。改变了地址中的内容但是原来的值没有改变。

现在看起来好像是一个地址对应两个值。

我现在的猜测:因为我的int所改变的地址是double没有用到的地方,因为double是8bytes的。

可是问题又出现了,double怎么会有没用到的地方?-_-b...
cngdzhang 2004-05-14
  • 打赏
  • 举报
回复
浮点数是 结构一般是

尾数的符号位 尾数 阶数符号位 阶数
( 补码 )( 移码 )


整形数是

符号位 值
( 补码 )


但是,我刚才实验了一下,引用挺奇怪的
rval=50000000;
rval的改变好象没有改变dval的值

:(

我还在查资料.....
idleguy 2004-05-14
  • 打赏
  • 举报
回复
lj197912(从零开始):
二进制序列相同,二进制序列解释怎么不同的?能让5变成123.4

我现在还不是完全清楚,但是我知道这个和double与long的长度有关系。

sizeof(double)=8
sizeof(long)=4

期望有朋友能详细解释一下。
idleguy 2004-05-14
  • 打赏
  • 举报
回复
02051223(chenlei) ,不能编译是因为你的这行:
long rval=&dval;//can't convert double* to long.

另外,我的转换:
int &rval=(int&)dval;
这是个引用的强制类型转换,如果写成
int &rval=dval;
这C++不允许的,参见C++ Primer
02051223 2004-05-14
  • 打赏
  • 举报
回复
哦!

你说的有道理啊。


不过我把这个程序改到 tc里面怎么就不能通过编译呢?
#include<stdio.h>


void main()
{
double dval=123.4;
long rval;
rval=&dval;

rval=50000000;
printf("\n%ld\t%ld",&rval,&dval);
printf("\n%ld\t%ld",rval,dval);

}
  • 打赏
  • 举报
回复
楼主:

正确!

只要把类型统一起来,就都改变了
lj197912 2004-05-14
  • 打赏
  • 举报
回复
二进制序列相同,二进制序列解释怎么不同的?能让5变成123.4
idleguy 2004-05-14
  • 打赏
  • 举报
回复
ok...就这样了,再回去好好看看书……-_-b...
谢谢cngdzhang,虽然你说的内容我知道。结贴。
idleguy 2004-05-14
  • 打赏
  • 举报
回复
我大概知道怎么回事了。double是8bytes的。long是4bytes的。我修改的地方没有影响到double的出始值。如果把double改成float,就能看出改变了。
idleguy 2004-05-14
  • 打赏
  • 举报
回复

楼上cngdzhang() 兄的意思是,rval是整形引用,dval是浮点数。
cout在输出的时候是按照他们的类型输出的。对吧?

但是,我改变了rval的值,也就是说,我改变了地址0012FF70中的内容,但是为什么dval的值没有改变。这是我想知道的。

cngdzhang 2004-05-14
  • 打赏
  • 举报
回复
因为:
rval和dval指向的是相同的地址,所以输出

0012FF70 0012FF70

这个地址里面存的内容,也就是二进制序列虽然是相同的,

但是
int &rval是整形引用
double dval是浮点数

所以,当用cout输出时,对二进制序列的解释就不一样了
idleguy 2004-05-14
  • 打赏
  • 举报
回复
呃?错了,应该是rval=50000000;

64,681

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧