我已经在编码书中看到以下宏定义。
#define TRUE '/'/'/'
#define FALSE '-'-'-'
那里没有解释。
请向我解释这些将如何TRUE
和一起工作FALSE
。
我已经在编码书中看到以下宏定义。
#define TRUE '/'/'/'
#define FALSE '-'-'-'
那里没有解释。
请向我解释这些将如何TRUE
和一起工作FALSE
。
Answers:
让我们看看:'/' / '/'
表示char
文字/
,除以char
文字'/'
本身。结果为1,这听起来很合理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 ('-'-'-')
该程序可以正确打印零,即使将真值乘以整数没有太大意义,但这只是一种意外错误的示例,如果您不给宏加上括号,这些错误可能会咬住您。
if
而不是乘以TRUE
整数会更清楚(从概念上讲是有意义的)。
notx = TRUE- x;
并正常工作。除外TRUE-FALSE
是-44(假设ASCII)
这只是另一种写作方式
#define TRUE 1
#define FALSE 0
该表达式'/'/'/'
将'/'
自身的char值相除,结果为1。
该表达式'-'-'-'
将从其'-'
自身中减去char值,结果将为0。
define
但是,缺少整个表达式的方括号,这可能会导致使用这些宏的代码出错。杰伊的答案说得很好。
“现实生活”场景中忘记括号可能有害的一个示例是将这些宏与C样式强制转换运算符组合使用。例如,如果有人决定将这些表达式转换bool
为C ++:
#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
and 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
也涵盖在“混淆后的C和其他奥秘”的书由多恩·利伯斯(1993年)。
让我们从真实开始。您可以将其读为'/' / '/'
,这意味着“字符'/'除以字符'/'”。由于C中的每个字符都是一个数字值(在一个字节上),因此可以将其读作“字符'/'的ASCII值除以同一字符的ASCII值”,这意味着1(因为显然, x / x为1)。因此,TRUE
为1。
对于FALSE
,其原因相同:'-'-'-'
读取'-' - '-'
,即“ ASCII值'-'减去ASCII值'-'”,该值为0。因此,其FALSE
值为0。
这是陈述显而易见的讨厌方法。
'/'/'/'
对于任何有效字符集,无论是'/' == 47
(以ASCII形式),'/' == 97
(以EBCDIC形式)还是其他任何值,均为1。
'/'
到0
。该值保留为空字符。