我已经在编码书中看到以下宏定义。
#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已经回答了为什么这些表达式的值是0and 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。该值保留为空字符。