问题
在判断条件中使用数组的count
属性获取数量会有个坑,先看代码:
NSArray *array = @[@"", @""];
NSInteger left = -1;
NSInteger per = 30;
NSInteger count = array.count;
if (left < per * count) {
NSLog(@"YES");
} else {
NSLog(@"NO");
}
// console: YES
if (left < per * array.count) {
NSLog(@"YES");
} else {
NSLog(@"NO");
}
// console: NO
- 第一个if的判断结果是正确的。
- 第二个if的判断结果是错误的。
目前原因暂未查到,如有大佬知道烦请告知
原因
感谢朋友@DeveloperHZ 提了个醒,原因找到了。
因为比较条件中的array.count
是NSUInteger
类型,所以比较条件右边的表达式per*array.count
的计算结果其实是NSUInteger
类型,NSInteger
类型和NSUInteger
类型做比较时会现将表达式中的类型都转换为NSUInteger
类型。
其本质原因是c语言中有符号类型和无符号类型运算比较的问题,直接说结论:
- 有符号数和无符号数相运算(加减乘除)时,结果的二进制表达式不受何种符号类型影响的,而计算结果的值取决于结果所需呈现的类型
- 当表达式中存在有符号类型和无符号类型时,默认情况下(没有强制转换)表达式的值将转化为无符号类型
解决方法
平时在开发时如要做条件判断,除非确定所有数据的格式类型,否则尽量将表达式两边强制转换为同一类型(避免默认转换为无符号类型,结论第二条)
或者先将两个比较条件赋值局部变量再进行进行比较(计算结果值取决于所需类型,结论第一条)
推荐写法:
NSArray *array = @[@"", @""];
NSInteger left = -1;
NSInteger per = 30;
// 处理方法一
NSInteger sum = per * array.count;
if (left < sum) {
NSLog(@"YES");
} else {
NSLog(@"NO");
}
// 处理方法二
if (left < (NSInteger)(per * array.count)) {
NSLog(@"YES");
} else {
NSLog(@"NO");
}
网友评论