2010-03-31 106 views
28

任何人都有专业知识来解释何时使用NSUInteger以及何时使用NSInteger?NSUInteger vs NSInteger,int vs unsigned以及类似的情况

我看到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 

回答

30

与NSUInteger处理与NSInteger的时候你也应该知道的整数变换法则:

例如下面的片段返回0(假),但你希望它打印1(真):

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

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

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

+0

这是新的链接https://www.securecoding.cert.org/confluence/display/c/INT02-C.+Understand+integer+conversion+rules – 2016-09-16 19:03:14

7

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

+1

对于更大的数字,请使用NSDecimalNumber获取38个基数为10的精度。 – codewarrior 2010-03-31 23:42:38

+0

+1,@codewarrior,只有当你可以传递类时,尽管如此。 – 2010-03-31 23:46:19

+7

我走另一条路:除了当我需要负数时,我总是使用NSUInteger。另外,你的意思是对象,而不是类;几乎没有理由传递类,更没有特别通过NSDecimalNumber类的理由。 – 2010-04-03 02:26:49

5

我不知道可可专门,但通常唯一的缺点是有符号整数是他们通常有一半的最大值作为无符号整数。如32位系统的约20亿而不是40亿。一般来说,这不是一个很大的差别,因为如果你处理的价值接近20亿,你可能会同样担心在同一个案例中最大40亿,因为它仍然非常接近溢出,只有一个乘以2或3.

带符号的整数通常是首选,因为在几乎所有场景中都可以使用带符号整数的附加灵活性和事实,无符号整数可以加上所需的所有附加场景。

如果要强制使用正值,则可能会首选无符号值。

+0

我添加了NSInteger和NSUInteger的定义。 – 2010-03-31 23:47:52

+4

有时使用带符号整数,即使在正常范围为正值的情况下,如果您希望能够将变量初始化为“无效”值(例如-1),也可以使用。 – progrmr 2010-04-01 00:01:49

+3

有趣的是,替代Objective C的Swift表示,在可能的情况下总是使用带符号的数字。 *来自文档*: 仅当您特别需要与平台的本机字大小相同的无符号整数类型时才使用UInt。如果不是这种情况,即使要存储的值已知为非负数,Int也是首选。 Int一致地使用整数值有助于代码互操作性,避免了在不同数字类型之间进行转换的需要,并匹配整数类型推断,如类型安全和类型推断中所述。 – Skotch 2014-07-03 16:14:44

17

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

+0

好的答案和什么我需要知道:) – mAc 2017-05-08 18:24:55

+0

如果我想存储-4,294,967,295怎么办?我不能使用NSInteger呢? – Nil 2017-05-16 08:03:56

+0

@Nil long long int:-9,223,372,036,854,775,807 to 9,223,372,036,854,775,807 unsigned long long int:0至18,446,744,073,709,551,615。在您的账户中有相当大的数额:D – 2017-10-27 14:45:10