1< -1评估为TRUE

时间:2014-08-11 12:55:07

标签: ios objective-c

在我的部分代码中,我编写了一个简单的for循环来迭代数组中的元素(所有NSMutableDictionary s),我发现循环已执行,即使条件基本上是1 < -1

所以我编写了以下代码,以测试此问题的有效性:

NSMutableArray* arr = [[NSMutableArray alloc] init];

NSLog(@"COUNT: %d | %i", arr.count, 1 < (arr.count - 1));

输出结果为:

COUNT: 0 | 1

这实质上意味着计数为0,而1则小于-1。

我想也许是因为数组是刚刚初始化的,并且添加和删除对象可能会改变这一点,所以我继续这样做:

NSMutableArray* arr = [[NSMutableArray alloc] init];

[arr addObject:@1];
[arr removeObject:@1];

NSLog(@"COUNT: %d | %i", arr.count, 1 < (arr.count - 1));

结果仍然相同:

COUNT: 0 | 1

我想到的可能原因是:

  • 我还不了解编译器/目标-C的某些内容
  • 我的Mac中的注册被困扰
  • 我失去了理智

我非常怀疑它是最后两个案例中的哪一个,我仍然想知道为什么这种情况。

4 个答案:

答案 0 :(得分:7)

arr.count是无符号整数值(类型NSUInteger)。使用无符号算术时,(0 - 1)会回绕到一个非常大的正数,而不是-1

如果将值转换为有符号整数,您可能会看到预期的结果:

NSLog(@"COUNT: %d | %i", (int)arr.count, 1 < ((int)arr.count - 1));

有关处理此常见错误来源的一些方法,请参阅此主题:Constant bugs from [NSArray count] being unsigned

答案 1 :(得分:4)

发生这种情况的原因是左侧的1被视为无符号。反过来,这是因为arr.count是无符号类型,因此表达式arr.count-1也是无符号的。从无符号零中减去1时,会出现下溢,结果是一个非常大的数。

为了避免这样的问题,在处理unsigned类型的值时要非常小心减法。更喜欢添加到另一方 - 特别是,而不是写

if (a < unsignedB - c)

if (a+c < unsignedB)

答案 2 :(得分:3)

数组的count属性为NSUInteger类型,表示unsigned long。表达式arr.count - 1从无符号整数中减去1,因此结果也是无符号的。而不是-1,因为溢出而得到非常大的正数,而且这个数字大于1。

答案 3 :(得分:2)

[arr count]返回(NSUInteger),这只是typedef unsigned long NSUInteger;

因此NSUInteger不会有任何负数。值从0开始到某个最大值,它将像一个循环,如下所示

... | MAX-2 | MAX-1 | MAX | 0 | 1 | 2 | 3 | 4 | ...
           -1      -1    -1  -1  -1  -1  -1

So, the math is like 2-1 = 1
                     1-1 = 0
                     0-1 = MAX
                     0-2 = MAX-1