大家好,今天小编来为大家解答代码陷阱类型转换这个问题,很多人还不知道,现在让我们一起来看看吧!
01
提出问题
你写过“比较”代码吗?这是最简单的比较代码:
int main(){ char a=0xff; if(a==0xff) { printf(‘相同’); } else { printf(‘不同’);请告诉我,这个main 函数的最终输出是什么?也许答案并不像你想象的那么简单,让我们实际运行一下,看看真正的输出:
02
代码分析
正如您所看到的,结果是:不同。变量a与0xff不同!第5行的0xff和第6行的0xff有什么区别吗?是的,尽管从源代码来看它们是相同的。但从第6行开始,无论从二进制还是十进制来看,它们都是不同的!
为了实现第6行变量a和0xff的比较,首先需要对它们进行类型统一。一般情况下,char类型的变量a会被转换为int类型:
需要注意的是,虽然变量a的值也等于0xff,但由于是有符号数,根据补码原理,符号位为最高位:1,也就是说变量a为负数数字。因此,它代表的数字是:-1,而不是255。如果转换成int类型,也是:-1(0xffffffff)
第6行右侧的0xff是一个unsigned int:255,转换为int类型后,仍然是255(0x000000ff);显然-1 (0xffffffff) 和255 (0x000000ff) 不相等。
或许,你可能会奇怪:我经常写这样的代码,但为什么不会出错呢?因为在我们的使用习惯中,很少使用负数:
因为无论0x55分配给char a还是unsigned char a,它都代表一个正数:85。所以虽然在第6行,两个比较方的类型仍然不同,但我们仍然可以得到预期的相同结果。
或许正是这种使用习惯让我们逃过一劫,但谁能保证我们永远幸运呢?因此,无论如何,我们都应该积极避免此类问题的发生。
03
解决方案
那么这个问题应该如何解决呢?通过上面的分析我们知道,归根结底是由于第6行代码中比较双方的类型不同造成的,所以我们只需要将双方的数据类型统一一下即可。例如,以下两种方法可以有效解决这种类型歧义:
正如你所看到的,要么0xff 被转换为与变量a 相同的类型;或者变量a 转换为与0xff 相同的类型。只要类型相同,它们之间的比较结果是预期的、可控的。
04
总结
1. 由于补码,负数对应的二进制数既可以解释为正数,也可以解释为负数。例如,0xff 可能是unsigned char、short 或int 类型的正数:255;它也可能是char 类型的负数:-1。
2.由于负数的二义性,编译器发现我们正在执行不同类型的比较时,常常会输出警告;然而,由于我们经常使用正数进行比较,因此可以有效避免歧义的风险。因此,这也使得编译器的警告显得毫无意义。但我们必须充分认识到它可能带来的风险。解决这些警告将使我们的代码更加可靠和健壮。
05
如果你需要系统学习这些编程知识,可以考虑购买Abu写的、很多微软大佬推荐的《CPU眼里的C/C++》。
原创文章,作者:小su,如若转载,请注明出处:https://www.sudun.com/ask/200589.html
用户评论
ˉ夨落旳尐孩。
我以前也踩过很多这样的坑!尤其是从字符串转换为数字的时候,不小心忘记判断是否为空或者格式有没有错导致程序直接崩溃,这次分享真是帮了我大忙!
有8位网友表示赞同!
生命一旅程
其实这种类型的转换问题大部分是来自对基础数据类型理解不够深刻。仔细研究一下数据的特性,写一些测试案例,就能避免很多这类错误。
有7位网友表示赞同!
你瞒我瞒
讲得真清楚,我还在用 printf 直接输出调试信息找 bug ,从这篇文章学会了使用断点调试技巧,感觉以后能更高效地解决程序问题!
有13位网友表示赞同!
花开丶若相惜
确实啊,很多时候把不同类型的数据直接塞进去都会出问题。特别是大型项目,数据传递复杂就更容易出现这类小意外.
有11位网友表示赞同!
万象皆为过客
代码陷阱太多了!这篇文章只讲了部分,比如指针的错误使用也是很大的坑!希望以后能继续分享一些更深入的内容。
有15位网友表示赞同!
减肥伤身#
这种错误感觉很常见吧,有时候不小心忽略细节就会导致意想不到的结果,还是要提醒自己仔细检查每个地方。
有18位网友表示赞同!
你tm的滚
写代码的时候注意力高度集中才能避免这类小错误,放松一下反而更容易犯错!
有15位网友表示赞同!
轨迹!
这篇文章让我明白了数据类型的转换并非简单粗暴的代入,还需要考虑数据的范围、精度等等。以后编程要更加谨慎!
有20位网友表示赞同!
╯念抹浅笑
我觉得这些陷阱确实很 insidious ,容易让人防不胜防,有时候会花很长时间去debug 才发现是类型转换的问题!
有11位网友表示赞同!
﹎℡默默的爱
文章说的太对了,没有遇到这类问题我可真是太幸运了!学习到很多经验,下次要更加小心谨慎地进行类型转换。
有15位网友表示赞同!
娇眉恨
我一直觉得数据类型的转换应该是程序员基本功中的基础,需要不断练习和积累经验才能够熟练掌握
有12位网友表示赞同!
心悸╰つ
代码陷阱确实令人头疼,尤其是新手更容易犯错!希望以后能看到更多的文章分享解决这些问题的技巧和思路。
有6位网友表示赞同!
铁树不曾开花
类型转换问题虽然细小,可是如果处理不当的话后果非常严重。这次学习到很多有用的知识,感谢作者的分享!
有10位网友表示赞同!
一样剩余
代码陷阱是每个程序员都会经历的磨练过程,但也要提醒大家要保持足够的耐心和逻辑思维能力,才能逐渐克服这些挑战!
有13位网友表示赞同!
一别经年
对于初学者来说,这篇关于代码陷阱的文章太抽象了,缺乏具体的案例和解决方案,希望能有更直观的教程来帮助入门
有9位网友表示赞同!
ok绷遮不住我颓废的伤あ
我一直觉得程序开发是一个不断完善的过程,需要我们始终保持思考和学习。阅读此文后,我对类型转换的认识更加深入,也提醒我要保持警惕,避免掉入陷阱!
有20位网友表示赞同!