#if TRUE vs #if YES vs #if 1 在 Objective-C 中有什么不同?
#if TRUE vs #if YES vs #if 1 are different in Objective-C?
在 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
不同?
嗯......我不是一个真正的objective-c人,我个人更喜欢c++,但无论如何让我试着回答你。
如果 1
最后,编译器就像计算机中的几乎所有东西一样,在 0 和 1 上运行。当你在代码中写一个 "if 1" 语句时,它总是会这样做,就像你可能放在那里的所有其他数字一样——也就是说,除了零。那是因为0在字节中的位表示是“00000000”,代表负值。
正因为如此,为了确保在代码级别和编译器级别中有一个 true,最基本的语句是 if(此处为非零数字)- 它将始终为 true。
如果真
true 是编译器中保存的一个字,最后变成了 1。这就是为什么 if(true) 总是有效的原因;自然地,我假设编译器需要一些时间来解析它——但这几乎是唯一的区别,而且相当小。
如果是
编译器不认识单词"Yes"。因此,它会自动假定它是一个参数,并尝试查找它之前是否声明过。当它发现您之前没有在程序中定义它时,它会将默认值放入 if 语句中 - 即 false;因此,命令没有执行。
希望我能帮到你 :)
如果术语 YES
未定义或定义为 0
,则 #if
永远不会变为真。
如果没有定义标识符,则视为0
。所以预处理器会看到
#if 0
NSLog(@"print YES");
#endif
也不会执行NSLog
命令。
#if
语句中的代码只有在YES
为
时才会执行
- 定义和
- 设为非零值
在 #if
的预处理器表达式中,所有未知标识符的计算结果为 0
。因此,在您的情况下,似乎 TRUE
被定义为非 0
并且 YES
未定义或定义为值 0
.
想想都难以置信,但 C 编程语言直到 1998 年才出现布尔类型。程序员们想出了自己的解决方案,随着时间的推移,使用 0 的 int 类型成为惯例不。当最终添加布尔值时,它是真正的第一个 class 布尔类型。这意味着它只能存储值 0 和 1。read more here
您可以在 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 年要长得多。所以 BOOL 实际上比 bool 更早!
这就是为什么它总是被定义为 char 的原因。它实际上能够存储 -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 中,BOOL 被定义为 bool !
来自 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 中的混乱遗留问题,事实是测试 YES 或 true 并不总是 100% 可靠。相反,我建议您测试 !false 或 !NO。听起来很可笑吧?
heres a little blog about it I found on big nerd ranch
PS 我完全理解您在谈论编译器条件,但您确实将其标记为 objC :)
在 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
不同?
嗯......我不是一个真正的objective-c人,我个人更喜欢c++,但无论如何让我试着回答你。
如果 1
最后,编译器就像计算机中的几乎所有东西一样,在 0 和 1 上运行。当你在代码中写一个 "if 1" 语句时,它总是会这样做,就像你可能放在那里的所有其他数字一样——也就是说,除了零。那是因为0在字节中的位表示是“00000000”,代表负值。 正因为如此,为了确保在代码级别和编译器级别中有一个 true,最基本的语句是 if(此处为非零数字)- 它将始终为 true。
如果真
true 是编译器中保存的一个字,最后变成了 1。这就是为什么 if(true) 总是有效的原因;自然地,我假设编译器需要一些时间来解析它——但这几乎是唯一的区别,而且相当小。
如果是
编译器不认识单词"Yes"。因此,它会自动假定它是一个参数,并尝试查找它之前是否声明过。当它发现您之前没有在程序中定义它时,它会将默认值放入 if 语句中 - 即 false;因此,命令没有执行。
希望我能帮到你 :)
如果术语 YES
未定义或定义为 0
,则 #if
永远不会变为真。
如果没有定义标识符,则视为0
。所以预处理器会看到
#if 0
NSLog(@"print YES");
#endif
也不会执行NSLog
命令。
#if
语句中的代码只有在YES
为
- 定义和
- 设为非零值
在 #if
的预处理器表达式中,所有未知标识符的计算结果为 0
。因此,在您的情况下,似乎 TRUE
被定义为非 0
并且 YES
未定义或定义为值 0
.
想想都难以置信,但 C 编程语言直到 1998 年才出现布尔类型。程序员们想出了自己的解决方案,随着时间的推移,使用 0 的 int 类型成为惯例不。当最终添加布尔值时,它是真正的第一个 class 布尔类型。这意味着它只能存储值 0 和 1。read more here
您可以在 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 年要长得多。所以 BOOL 实际上比 bool 更早! 这就是为什么它总是被定义为 char 的原因。它实际上能够存储 -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 中,BOOL 被定义为 bool !
来自 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 中的混乱遗留问题,事实是测试 YES 或 true 并不总是 100% 可靠。相反,我建议您测试 !false 或 !NO。听起来很可笑吧?
heres a little blog about it I found on big nerd ranch
PS 我完全理解您在谈论编译器条件,但您确实将其标记为 objC :)