c++ - 类型转换问题
天蓬老师
天蓬老师 2017-04-17 11:51:24
[C++讨论组]
unsigned u=10;
int i=-42;
cout<<i+i<<endl;
cout<<u+i<<endl;

不理解,
结果居然是
-84 4294967264

2的32次方是4294967296.

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回复(4)
巴扎黑
cout << i + i << endl;  // -84

以32位机器为例,int能表示的最大值为2^32 - 1,最小值为-2^32。超过这个区间的int会溢出。这里,i=-42,显然不会溢出。两个int相加,结果还是int,所以得到-84是理所当然。

cout << u + i << endl;  //4294967264

这里是unsigned int和int相加,两种不同的类型相加,编译器会做隐式类型转换。怎样转换?把有符号的转为无符号的!所以,这行代码相当于:

cout << u + (unsigned) i << endl;

关键问题是,怎样把int转为unsigned int?

计算机用补码表示负数,以整形i=-42为例,它在32位计算机中的补码表示为:11111111111111111111111111010110(如果按照16进制,则表示为:FFFFFFD6)

所谓某个变量是int还是unsigned int,在计算机看来都是一回事。关键在于编译器怎样“看待”这个变量。现在编译器不把这个FFFFFFD6当int看了,而是要把它当unsigned int看待。于是,FFFFFFD6的含义就变成了:

FFFFFFD6 = 2^31 + 2^30 + ... + 2^7 + 2^6 + 2^4 + 2^2 + 2^1 = 4294967254

也就是说,(int)-42与(unsigned int)4294967254其实是一回事,只不过编译器对它们的解释不同而已。

结果已经很明了:4294967254 + 10 = 4294967264,这就是你得到的输出!

PHPz

C++支持类型扩展,也就是说当一个能表示大范围的类型和一个能表示小范围类型做运算时,小范围类型会自动强转为大范围类型,在C++的规定中,unsigned int 比int的范围大,所以做运算u+i时,i被强制转换为unsigned int类型,-42被强转为unsigned类型后为4294967254u,加上10u就是4294967264u

天蓬老师

unsigned与int的本质区别是,unsigned用原码表示0~2^32-1,int用补码表示-2^31~2^31-1
int与unsigned相加时,是作为unsigned处理的,返回结果也作为unsigned处理
int i=-42是用补码表示的,把它当做原码的话就是2^32-42
跟10相加,结果是2^32-32=4294967264

ringa_lee

1、i+i是int类型相加,无类型转换,故为-42+(-42)=-84
2、u+i是unsigned int和int类型相加,隐式转换成unsigned int,(int) i =-42 = (unsigned int) i = 2^32 - 42 = 4294967254,则u+i=4294967254+10=4294967264

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号