程序如下:
#include<iostream>
int main()
{
unsigned u=10;
long long i=-42;
std::cout<<u+i<<std::endl;
return 0;
}
输出结果是-32
#include<iostream>
int main()
{
unsigned u=10;
int i=-42;
std::cout<<u+i<<std::endl;
return 0;
}
输出结果是4294967264
导致结果不同的原因在哪
这是默认的类型提升引起的问题。
第一个例子里的表达式u+i里,long long的类型比unsigned 的类型大,所以这里u会被转换成long long,u+i的结果就如输出
第二个例子的表达式里u+i里,u的类型比int大,所以i=-42会转换成unsigned。-42转换成无符号就是一个很大的值(4294967254),u+i就是输出结果了。
以下是默认类型提升的规则
同一句语句或表达式如果使用了多种类型的变量和常量(类型混用),C 会自动把它们转换成同一种类型。以下是自动类型转换的基本规则:
1. 在表达式中,char 和 short 类型的值,无论有符号还是无符号,都会自动转换成 int 或者 unsigned int(如果 short 的大小和 int 一样,unsigned short 的表示范围就大于 int,在这种情况下,unsigned short 被转换成 unsigned int)。因为它们被转换成表示范围更大的类型,故而把这种转换称为“升级(promotion)”。
2. 按照从高到低的顺序给各种数据类型分等级,依次为:long double, double, float, unsigned long long, long long, unsigned long, long, unsigned int 和 int。这里有一个小小的例外,如果 long 和 int 大小相同,则 unsigned int 的等级应位于 long 之上。char 和 short 并没有出现于这个等级列表,是因为它们应该已经被升级成了 int 或者 unsigned int。
3. 在任何涉及两种数据类型的操作中,它们之间等级较低的类型会被转换成等级较高的类型。
4. 在赋值语句中,= 右边的值在赋予 = 左边的变量之前,首先要将右边的值的数据类型转换成左边变量的类型。也就是说,左边变量是什么数据类型,右边的值就要转换成什么数据类型的值。这个过程可 能导致右边的值的类型升级,也可能导致其类型降级(demotion)。所谓“降级”,是指等级较高的类型被转换成等级较低的类型。
第一个例子里的表达式u+i里,long long的类型比unsigned 的类型大,所以这里u会被转换成long long,u+i的结果就如输出
第二个例子的表达式里u+i里,u的类型比int大,所以i=-42会转换成unsigned。-42转换成无符号就是一个很大的值(4294967254),u+i就是输出结果了。
以下是默认类型提升的规则
同一句语句或表达式如果使用了多种类型的变量和常量(类型混用),C 会自动把它们转换成同一种类型。以下是自动类型转换的基本规则:
1. 在表达式中,char 和 short 类型的值,无论有符号还是无符号,都会自动转换成 int 或者 unsigned int(如果 short 的大小和 int 一样,unsigned short 的表示范围就大于 int,在这种情况下,unsigned short 被转换成 unsigned int)。因为它们被转换成表示范围更大的类型,故而把这种转换称为“升级(promotion)”。
2. 按照从高到低的顺序给各种数据类型分等级,依次为:long double, double, float, unsigned long long, long long, unsigned long, long, unsigned int 和 int。这里有一个小小的例外,如果 long 和 int 大小相同,则 unsigned int 的等级应位于 long 之上。char 和 short 并没有出现于这个等级列表,是因为它们应该已经被升级成了 int 或者 unsigned int。
3. 在任何涉及两种数据类型的操作中,它们之间等级较低的类型会被转换成等级较高的类型。
4. 在赋值语句中,= 右边的值在赋予 = 左边的变量之前,首先要将右边的值的数据类型转换成左边变量的类型。也就是说,左边变量是什么数据类型,右边的值就要转换成什么数据类型的值。这个过程可 能导致右边的值的类型升级,也可能导致其类型降级(demotion)。所谓“降级”,是指等级较高的类型被转换成等级较低的类型。
温馨提示:答案为网友推荐,仅供参考
第1个回答 2014-08-11
这个涉及数值类型的隐式转换问题,参考下图,希望能够解决你的问题
本回答被提问者采纳第2个回答 2014-08-11
原因是: 第一题中, 输出时, u+i 的结果会隐式的转换为 long long 类型, 所以结果正确
第二题中, 输出时, 会隐式转换为 unsigned int 类型, 由于结果为负数, 最高位为1, 那么变为无符号数的时候结果就变得非常大了。。。追问
第二题中, 输出时, 会隐式转换为 unsigned int 类型, 由于结果为负数, 最高位为1, 那么变为无符号数的时候结果就变得非常大了。。。追问
无符号数和int、long、long long这些整型互相运算时,结果没有固定的隐式转换成整型或者无符号数吗,还是说有什么规律可循
追答有规律的, 有double 结果 double 否则,有long 结果为 long , 否则有int 结果为int
有无符号数, 结果为无符号数
总结来说就是小范围的自动匹配到大范围的。。。
第3个回答 2014-08-11
unsigned是一个无符号的,这里没有写什么数据类型,默认为int; unsingned int的是8个byte,int占有的字节是4byte,编译器计算不出不同字节相加的情况从而得出他们相加是一个乱码;而long long 是8个byte,正好跟unsigned int的范围是一样,故能得出正确答案;望采纳!追问
应该不是乱码,无符号数和int运算的时候会将int值转换成无符号数,导致加上一个负的int数相当于加上一个正数(模)
追答如果负负得正的,话那就是负数,实际上显示的是一个正数,说明超过了那个负数的最大范围,就变成正数了