NSUInteger vs NSInteger,int vs unsigned,以及类似的情况

时间:2010-03-31 23:31:42

标签: c objective-c cocoa types

任何人都有专业知识来解释何时使用NSUInteger以及何时使用NSInteger?

我已经看到Cocoa方法返回NSInteger,即使返回的值总是无符号的。

根本原因是什么?如果我们想要表示负值,NSInteger或int是否严格限制?

来自NSObjCRuntime.h:

#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif

4 个答案:

答案 0 :(得分:31)

在处理NSUInteger与NSInteger时,您还应该了解整数转换规则:

以下片段例如返回0(false),尽管您希望它打印1(true):

NSInteger si = -1;
NSUInteger ui = 1;
printf("%d\n", si < ui);

原因是[si]变量被隐式转换为unsigned int!

请参阅CERT's Secure Coding site,深入讨论这些“问题”以及如何解决这些问题。

答案 1 :(得分:17)

默认情况下,假定整数已签名。换句话说,编译器假定将调用整数变量来存储负数或正数。这限制了范围可以在任一方向上达到的程度。例如,32位int的范围为4,294,967,295。在实践中,因为该值可以是正的或负的,所以范围实际上是-2,147,483,648到+2,147,483,647。如果我们知道永远不会调用变量来存储负值,我们可以将其声明为无符号,从而将(正)范围扩展为0到+4,294,967,295。所以我想说,当你知道你有一个受限制的输出范围时,可以使用NSInteger。我个人使用NSUInteger,如果我需要返回真正大的正面数字

答案 2 :(得分:7)

如果您的方法具有适当限制的输出范围,您也可以使用NSInteger,因为它更容易输入。如你所说,如果你需要返回负数,NSInteger是镇上唯一的游戏;如果我出于某种原因需要返回真正的大数字,我只会使用NSUInteger

答案 3 :(得分:5)

我并不特别了解cocoa,但通常签名整数的唯一缺点是它们的最大值通常是unsigned int的一半。比如大约20亿而不是40亿的32位系统。一般情况下这并不是一个很大的区别,因为如果你处理接近20亿的价值,你可能会同样担心同样情况下最多40亿,因为它仍然非常接近溢出乘以2或3.

有符号整数通常是首选,因为额外的灵活性和几乎在所有场景中都可以使用有符号整数的事实,无符号整数可以加上所有其他场景,而不需要负数。

如果您想强制执行仅正值,则可能首选无符号。