! vs ==在objective-c中为零

时间:2011-07-21 20:16:47

标签: iphone objective-c c

如果你有像NSString * someString这样的对象,那么

之间有什么区别?
if (!someString)

VS

if (someString == nil)

谢谢!

6 个答案:

答案 0 :(得分:23)

您使用的第一种语法:

 if (!someString)

利用C的一种“模糊性”,这是因为C的原始标准缺乏适当的布尔类型。因此,任何等于0的整数值被解释为“假”,并且任何不同于“0”的整数值被视为“真”。因此!的含义是基于此约定定义的,C标准的当前版本保留了原始的兼容性定义。

在您的特定情况下,someString是指针,因此首先将其转换为整数,然后! someStringtrue时被解释为someString的布尔值在0x000000位置指向,否则它会变为“真实”。

这在大多数情况下都很好(我会说永远),但理论上,NULL/nil could be different from 0x000000在某些编译器下,所以(在非常理论上)最好使用第二种语法,这更明确:

 if (someString == nil)

无论如何它更具可读性,因为someString不是整数(而是指针),IMO,一般来说是更好的练习。

编辑:关于NULL的定义......

C标准是否将NULL定义为0对我来说是一个有趣的话题......

根据C99 standard,第7.17节“共同定义”:

  

NULL [which]扩展为实现定义的空指针常量;

因此,在stddef.h中将NULL定义为实现定义的空指针常量 ... 第47页的同一文件指出:

  

值为0的整型常量表达式,或者类型为void *的表达式,称为空指针常量.55)如果将空指针常量转换为指针类型,则生成的指针称为null指针,保证比较不等于指向任何对象或函数的指针。

因此,空指针常量((void*)0)可以转换到空指针,并且保证比较不等于指向任何对象或函数的指针。

所以,我认为这基本上取决于实现是否决定将空指针常量转换为空指针的结果产生一个转换回指针的指针整数给出0.不清楚空指针被解释为整数等于0.

我会说标准真的尝试并强制将空指针设为0,但是将门打开systems where the null pointer was not 0

答案 1 :(得分:8)

对于大多数指针而言,它们是等效的,尽管我知道的大多数编码器都更喜欢前者,因为它更简洁。

对于弱链接符号,前者解析符号(如果丢失则会导致崩溃),而与nilNULL的显式比较则不会。

答案 2 :(得分:3)

C中的爆炸,感叹,!前缀运算符是逻辑不。至少,它是它的一个版本。如果你看一个典型的逻辑非真值表,你会看到类似这样的东西:

Input       Result
  1            0
  0            1

然而,在C中,逻辑非运算符更像是这样:

Input       Result
non-zero      0
   0          1

因此,当您认为Objective-C中的NULL和nil都计算为0时,您知道应用于它们的逻辑非运算符将导致1。

现在,考虑 equality ==运算符。它比较两个项的值,如果它们相等则返回1,如果不相等则返回0。如果您将其结果映射到真值表,那么它看起来与逻辑非结果完全相同。

在C和Objective-C程序中,条件性实际上由int确定,而不是真正的布尔值。这是因为在C中没有布尔数据类型这样的东西。所以写这样的东西在C中完全正常:

if(5) printf("hello\n"); // prints hello

另外

if(2029) printf("hello\n"); // also prints hello

基本上,任何非零的int都会在C中评估为'true'。你将它与真值表结合起来用于逻辑否定和相等,你很快意识到:

(! someString) and (someString == nil)

对所有意图都相同!

所以下一个合乎逻辑的问题是,为什么更喜欢一种形式呢?从纯粹的C观点来看,它主要是风格点,但大多数(好的)开发人员会选择相等测试,原因有很多:

  1. 它更接近您在代码中尝试表达的内容。您 试图检查someString变量是否为nil。
  2. 它更便携。像Java这样的语言有一个真正的布尔类型。 您不能对其变量或NULL使用爆炸记号 定义。在需要的地方使用相等性可以更容易移植 C以后再用这些语言。
  3. Apple可能会更改nil的定义。好吧,不,他们不会!但它 从不伤害安全!

答案 3 :(得分:2)

在你的情况下,它意味着同样的事情。任何未指向nil的指针都将返回YES(true)。

通常,感叹号运算符会否定BOOL值。

答案 4 :(得分:2)

如果您要测试条件“foo为零”,您应该说:foo == nil

如果你的意思是测试布法值为false,!foo是可以的,但我个人认为一个很小的感叹号很容易错过,所以我更喜欢foo == NO

编写好的代码不仅可以清楚地向编译器传达您的意图,还可以传达给下一个程序员(可能是您的未来)。在这两种情况下,你可以更明确地了解你正在尝试做什么,就越好。

除此之外,!==nil在我能想到的所有情况下都具有相同的效果。

答案 5 :(得分:0)

!是一个否定运算符。如果您的对象未分配,您将从真值表中获得与== nil操作相同的结果。

但是,!通常更多地用于布尔运算。

if(!isFalse) {
     //if isFalse == NO, then this operation evaluates to YES (true)
     [self doStuff];
}

当你对!这样的对象使用!something时,它只是检查指针是否指向nil,如果没有,则返回true,if声明火灾。

相关问题