#if TRUE vs #if YES与 #if 1在Objective-C中是不同的



In Xcode 6.1.1 (Obj-C)

#if 1
    NSLog(@"print 1");
#endif
#if TRUE
    NSLog(@"print TRUE");
#endif
#if YES
    NSLog(@"print YES");
#endif

结果是:

print 1
print TRUE

可以向我解释结果吗?为什么#if TRUE vs #if YES vs #if 1不同?

嗯...我不是一个真正的客观c人,我个人更喜欢c ++,但无论如何让我试着回答你。

如果 1

最后,编译器就像计算机中的几乎所有东西一样,在零和一上运行。当你在代码中编写"if 1"语句时,它总是会这样做,就像你可能放在那里的所有其他数字一样 - 也就是说,除了零。这是因为 0 的位表示形式(以字节为单位)是"00000000",它重新发送负值。正因为如此,为了确保在代码级别和编译器级别中有一个 true,您可以做出的最基本的语句是 if(此处为非零数) - 它将永远为真。

如果为真

true 是编译器中保存的单词,最终变为 1。这就是为什么 if(true) 总是有效;当然,我认为编译器需要一些时间来解析它 - 但这几乎是唯一的区别,而且相当小。

如果是

编译器不知道单词"是"。因此,它会自动假定它是一个参数,并尝试查找它之前是否被声明过。当它发现你之前没有在你的程序中定义它时,它会将默认值放在 if 语句中 - 即 false;因此,不会执行该命令。

希望我帮助:)

#if的预处理器表达式中,所有未知的构思器的计算结果都0。因此,在您的情况下,似乎TRUE被定义为非0的东西,而YES要么未定义,要么用值0定义。

如果术语YES没有被定义或定义为0,那么#if永远不会成为真的。

如果未定义标识符,则将其视为0 。所以预处理器会看到

#if 0
    NSLog(@"print YES");
#endif

这也不会执行NSLog命令。

#if语句中的代码仅在 YES

  1. 定义
  2. 设置为非零值

当你想到它时很难相信,但 C 编程语言直到 1998 年才有布尔类型。 程序员提出了自己的解决方案,随着时间的推移,使用带有 0 表示 no 的 int 类型成为惯例。 当布尔值最终被添加时,它是真正的一类布尔类型。 这意味着它只能存储值 0 和 1。在此处阅读更多内容

您可以使用这样的东西在 objC 中自己测试这一点。

bool foo = 55;
NSLog ((foo) ?  (@"foo, it is true") :(@"no, foo is false") ); //will log true..
NSLog (@"foo's int value", (int)foo ); // will log 1 

现在 bool 确实使用了完整的 8 位,它只是(我认为)只有第一个(或最后一个,取决于您的架构/字节序)被写入/读取。

现在ObjectiveC已经存在了比1998年长得多的时间。 所以布尔实际上比布尔更古老!这就是为什么它总是被定义为字符。它实际上能够存储 -127 到 128 之间的值。 同样,您可以在Xcode中对此进行测试

    BOOL bar = 55;
    NSLog ((bar) ?  (@"bar, it is true too!") :(@"no, bar neither") ); 
//will again log true..
    NSLog (@"bar's int value", (int)bar ); 
// will log 55 on 32bit builds but 1 on 64bit builds 

是的,但并非总是如您所见。 在 64 位 objC 中,布尔值被定义为布尔值!

从 objc.h

 #if !defined(OBJC_HIDE_64) && TARGET_OS_IPHONE && __LP64__
    typedef bool BOOL;
    #else
    typedef signed char BOOL; 
    // BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
    // even if -funsigned-char is used.
    #endif

由于 bool 和 bool 在 C 和 objC 中的混乱遗产,真相是测试是或 true 并不总是 100% 可靠。 相反,我建议您测试 !false 或 !NO 。 听起来很荒谬吧?

这是我在大书牧场找到的关于它的小博客

PS 我完全理解您在谈论编译器条件,但您确实将其标记为 objC :)

最新更新