一道微软面试题引出的 int与unsigned隐式转换问题

写在前面:

近段遇到这样一个题,据说是微软面试题:

unsigned int a = 0; int b = -10;

问a > b 是否正确,说说为什么

第一反应:肯定 0 > -10。不过转念一想,微软面试不会出这么脑残题吧                                                                    

去IDE上运行了一下,确实别有洞天,发现 b - a 的结果是:4294967286。很诡异的一个数字,想不明白为什么会是这么个奇怪的数字。但是在我发现这数的十六进制数是FFFFFFF6时,我想已经离答案很近了...

正文: 

在C/C++语言中,一些数据类型的自身特性,需要特别注意,比如人尽皆知的 浮点数运算会缺失精度,而在项目编写过程中还有一个问题也是经常被有些开发者忽视,从而引起很难被察觉的BUG,就是数据类型的隐式转换

在总结转换问题之前,先说明一下各种数据类型,下表来自MSDN:

结合上表补充说明一下:

  • 在32位机上,int型和unsigned int型都是32位的(4个字节)。
  • enum会跟据最大值来决定类型,一般来说为int型,如果超出int型所能表示的范围,则用比int型大的最小类型来表示(unsigned int, long 或者unsigned long)
  • 关于类型的大小。一般用所能表示的数据范围来比较类型的大小,如char型<unsigned char型<short型...在表达式中,一般都是由小的类型向大的类型转换(强制类型转换除外)

从而引出数据类型的隐式转换规则:

“ 当不同类型的数据进行操作时,应当首先将其转换成相同的数据类型,然后进行操作,转换规则是由低级向高级转换。”如下图所示:

而C/C++在以下四种情况下会进行隐式转换:

  1.   算术运算式中,低类型能够转换为高类型。
  2.   赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给他。
  3.   函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参。
  4.   函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数。

算术运算式中 相较于常用的 char -> int ,float -> double转换,int与unsigned隐式转换却常常容易被忽略,从而产生了与负数一起参与运算时意想不到的效果。

经过这番总结,前面提出的问题的答案应该就很明显了,微软其实想考察的其实就是隐式转换

在表达式中,a是unsigned int型,b是int型(常量整数的类型同enum),所以算术运算式b必须转换为unsigned int型,即0xFFFFFFF6,十进制的4294967286,然后再与a计算,即  4294967286 - 0,因此结果是0xFFFFFFF6,即4294967286

最后: 当我们进行大量编码协同开发时,有些开发者往往会忽略这样的隐式转化问题,这样是很危险的,特别是在遇到负数的情况下,int与unsigned隐式转换,所以 慎用unsigned,一定要注意隐式转换

 

1份赞许 = 100分的认可,如果感觉还不错,点个赞↗ 支持一下吧 ~

不定期分享 有趣、有料、有营养内容,欢迎 订阅关注 我的博客 ,期待在这里与你相遇 ~

好文推荐:   从B站泄露的源码里发现了B站视频推荐的秘密

                     白嫖来的入门级云服务器有这么几个妙用(附教程)

                     Facebook前身 哈佛“选美”网站Facemash核心算法 --- ELO等级分制度(附源码)


 

发布了112 篇原创文章 · 获赞 975 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/qq_41523096/article/details/104353256