我曾在一本编码书中看到以下宏定义。
#define TRUE '/'/'/'
#define FALSE '-'-'-'
没有任何解释。
请向我解释这些是如何作为真和假。
我曾在一本编码书中看到以下宏定义。
#define TRUE '/'/'/'
#define FALSE '-'-'-'
没有任何解释。
请向我解释这些是如何作为真和假。
当前回答
Jay已经回答了为什么这些表达式的值是0和1。
出于历史原因,这些表达式'/'/'/'和'-'-'-'来自1984年第一届国际混淆C代码大赛的参赛作品之一:
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);}
(链接到这里的程序,在上面的IOCCC页面中有这个程序做什么的提示。)
如果我没记错的话,这些表示TRUE和FALSE的模糊宏的表达式也在Don Libes(1993)的《模糊C和其他谜团》一书中提到过。
其他回答
这是为True和False编写宏的一种有趣的方式。
正如许多解释所提供的/意味着一个1字节的数字(根据ASCII),当除以本身时,它会给你1,这将被视为True,同样地-又是一个字节数,当减去相同的值时,它会给你0,这将被解释为false
#define TRUE '/'/'/'
#define FALSE '-'-'-'
因此,我们可以用我们喜欢的任何字符替换/或-,例如:
#define TRUE '!'/'!'
#define FALSE 'o'-'o'
将保持与原表达式相同的含义。
让我们从“真”开始。你可以把它读成“/”/“/”,意思是“字符/”除以字符“/”。因为在C语言中,每个字符都是一个数值(在一个字节上),它可以被读取为“字符'/'的ASCII值除以相同字符的ASCII值”,这意味着1(因为,显然,x/x是1)。因此,TRUE为1。
对于FALSE,同样的推理:'-'-'-'读取'-'-'-',即" '-'的ASCII值减去'-'的ASCII值",即0。因此,FALSE为0。
这是对显而易见的事实的一种粗暴的表述。
这只是另一种写法
#define TRUE 1
#define FALSE 0
表达式'/'/'/'将'/'的char值除以自身,结果为1。
表达式'-'-'-'将从表达式本身减去'-'的char值,结果为0。
但是,整个define表达式周围没有括号,这可能导致使用这些宏的代码出现错误。杰伊的回答很好地解决了这个问题。
忘记括号可能有害的“现实”场景的一个例子是将这些宏与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。
Jay已经回答了为什么这些表达式的值是0和1。
出于历史原因,这些表达式'/'/'/'和'-'-'-'来自1984年第一届国际混淆C代码大赛的参赛作品之一:
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);}
(链接到这里的程序,在上面的IOCCC页面中有这个程序做什么的提示。)
如果我没记错的话,这些表示TRUE和FALSE的模糊宏的表达式也在Don Libes(1993)的《模糊C和其他谜团》一书中提到过。
它相当于写作
#define TRUE 1
#define FALSE 0
表达式'/'/'/'实际上做的是将字符/(不管它的数值是什么)除以它自己,所以它变成了1。
类似地,表达式'-'-'-'从自身减去字符-并求值为0。
最好还是写下来
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
避免与其他高优先级操作符一起使用时意外更改值。