【背景】
unsigned long 类似数据的比较问题,先上一段代码,如下图所示:
就是图中框出的部分,眨眼一看,应该没啥问题,而且我也在本地的编译器vs2019上编译了,确实也没有报错,所以就修改上了项目的库,但是库上却编译报错,如下:
明显提示的意思大概就是:无符号类型数据和0比较了,所以报错,那么为什么呢?还有,同样是unsigned long类型的数据变量,为什么if(gtxpack>0 && grxpack>0)这个语句不报错呢?
【分析与验证】
验证1:unsigned long < 0 (行不通,大坑)
如下图,我们进行比较,在本地编译后,发现其实if语句也是没有进去的,虽然没有编译报错,
但是也没有干事情,这就属于比较隐晦的bug了哦,所以这种比较是最坑的!!!切记:不可用unsigned类型的数据进行<0的比较,因为在编译器看来,unsigned类型的数据,肯定不可能小于0的,因为unsigned long类型的数据范围是0-4294967295;可以这么说,任何unsigned类型的数据,最小值都是0起步的,所以你再运算,编译系统都认为unsigned类型的数据是不可能小于0的,所以不能这样搞!
验证2:unsinged long != 0
可以看出,同样的数据,只是改了判断条件,就符合预期了,所以可以这样搞
验证3:unsigned long之间比较
可以看出,这样也是可以行的通的
验证4:取绝对值比较
这中比较方式也是可以的
我们再来说说,为啥f(gtxpack>0 && grxpack>0)这个语句不报错呢?
首先,gtxpack和grxpack都是unsigned long类型的变量,在编译器认为,肯定是>=0的,所以你判断>0,编译器认为:合理!那么请注意:我们gtxpack和grxpack是差值,那么一旦差值<0呢?首先这个在代码里是不存在的,我们已经杜绝了这个情况的产生,其次,可以这么说,这两个变量最小的值也就是0了,所以编译器没报错,那么我们假设,如果他们小于0呢,会怎么样呢?
验证5:差值(-10) > 0(行不通,大坑)
可以看出,gtxpack > 0也就是-10 > 0竟然成立了!是不是又是一个大坑?!为什么会这样呢?还是刚说的那样:编译器认为一个unsigned long类型的数据,是不可能小于0的,所以只要不是0,编译器就认为都比0大,所以这个条件成立了!但是实际确实是错的,所以,如果你要用这个条件的话,一定要切记:前提是减数一定要大于被减数,这样差值gtxpack才不会出现下面这个样的bug!但是个人建议最好还是用去取绝对值的方式去判断,但是根据语境自己选择吧,就是记住这两个大坑就行了
【总结】
通过以上验证,我们可以总结出两个大坑:
1: unsigned long < 0 (行不通,大坑)
2: 差值(-10) > 0(行不通,大坑)
所以对于以上unsigned类型数据在做判断条件的时候,一定要注意<0 或者 >0的时候,这个一定要好好的分析思考和验证下,再做出判断哦!