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
- 定义和
- 设置为非零值
当你想到它时很难相信,但 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 :)