我在编码书中看到了以下宏定义。
db.secondCollection.find({"firstCollectionField":{$exists:false}})
那里没有解释。
请向我解释这些内容如何作为#define TRUE '/'/'/'
#define FALSE '-'-'-'
和TRUE
。
答案 0 :(得分:374)
我们看到:'/' / '/'
表示char
文字/
,除以char
文字'/'
本身。结果是一个,TRUE
听起来合理。
'-' - '-'
表示char
文字'-'
,从中减去。这是零(FALSE
)。
这有两个问题:第一,它不可读。使用1
和0
绝对会更好。另外,正如TartanLlama和KerrekSB所指出的那样,如果您打算使用该定义,请在它们周围添加括号,这样您就不会有任何意外:
#include <stdio.h>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
printf ("%d\n", 2 * FALSE);
return 0;
}
这将打印char
文字'-'
的值(我的系统上为45)。
括号:
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
程序正确地打印零,即使将真值乘以整数没有多大意义,但它只是一个例子,如果你没有括起你的宏,可能会咬你的意外错误
答案 1 :(得分:87)
这只是另一种写作方式
#define TRUE 1
#define FALSE 0
表达式'/'/'/'
将'/'
的char值除以其自身,结果为1。
表达式'-'-'-'
将从自身中减去'-'
的char值,结果为0。
虽然缺少整个define
表达式的括号,但这可能导致使用这些宏的代码出错。 Jay's answer很好地说明了这一点。
忘记括号可能有害的“真实”场景的一个例子是将这些宏与C风格的强制转换运算符结合使用。如果有人决定将这些表达式转换为C ++中的bool
:
#include <iostream>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
std::cout << "True: " << (bool) TRUE << std::endl;
std::cout << "False: " << (bool) FALSE << std::endl;
return 0;
}
这是我们得到的:
True: 0
False: -44
因此,(bool) TRUE
实际上会评估为false
,而(bool) FALSE
会评估为true
。
答案 2 :(得分:44)
相当于写作
#define TRUE 1
#define FALSE 0
表达式'/'/'/'
实际上做的是将字符/
(无论其数值是什么)除以它自己,因此它变为1
。
同样,表达式'-'-'-'
从自身中减去字符-
并计算为0
。
最好写
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
以避免在与其他更高优先级的运算符一起使用时意外更改值。
答案 3 :(得分:32)
Jay已经回答了为什么这些表达式的值为0
和1
。
为了历史起见,这些表达式'/'/'/'
和'-'-'-'
来自1st International Obfuscated C Code Contest in 1984的其中一个条目:
int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}
(链接到程序here,这个程序在上面的IOCCC页面中有一些提示。)
此外,如果我没记错,这些表达式作为TRUE
和FALSE
的混淆宏也包含在Don Libes(1993)的"Obfuscated C and Other Mysteries"书中。
答案 4 :(得分:7)
为True
和False
编写宏的热闹方式。
提供了很多解释/
表示一个1字节的数字(按照ASCII),当它除以它时,它会给你1
,它将被视为True
,同样-
1}}再次是一个字节数,减去它给你0
的相同值,它将被解释为false
#define TRUE '/'/'/'
#define FALSE '-'-'-'
因此我们可以用我们喜欢的任何字符替换/
或-
,例如:
#define TRUE '!'/'!'
#define FALSE 'o'-'o'
与原始表达保持相同的含义。
答案 5 :(得分:6)
让我们从真实开始吧。您可以将其读作'/' / '/'
,这意味着“字符'/'除以字符'/'”。由于C中的每个字符都是一个数值(在一个字节上),因此可以将其读作“字符的ASCII值'/'除以相同字符的ASCII值”,这意味着1(因为很明显, x / x是1)。因此,TRUE
为1。
对于FALSE
,其原因相同:'-'-'-'
读取'-' - '-'
,即“ - '的ASCII值减去' - '的ASCII值,即0。因此,FALSE
为0。
这是陈述显而易见的一种令人讨厌的方式。