TRUE和FALSE宏的奇怪定义

本文探讨了TRUE和FALSE宏的不寻常定义,这些定义在某些编程书籍中出现。这些宏通过字符除以自身或从自身减去字符来实现布尔值1和0。虽然这种做法可能导致代码错误,尤其是在与其他高优先级运算符结合使用时,但它们源自1984年的国际混淆C代码竞赛。建议使用更清晰的TRUE和FALSE表示法,以提高代码可读性和避免潜在问题。
摘要由CSDN通过智能技术生成

本文翻译自:Strange definitions of TRUE and FALSE macros

I have seen the following macro definitions in a coding book. 我在编码书中看到了以下宏定义。

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

There was no explanation there. 那里没有解释。

Please explain to me how these will work as TRUE and FALSE . 请向我解释这些将如何工作为TRUEFALSE


#1楼

参考:https://stackoom.com/question/2IvEh/TRUE和FALSE宏的奇怪定义


#2楼

It's just another way of writing 这只是另一种写作方式

#define TRUE 1
#define FALSE 0

The expression '/'/'/' will divide the char value of '/' by itself, which will give 1 as a result. 表达式'/'/'/'将自己的char值除以'/' ,这将得到1作为结果。

The expression '-'-'-' will substract the char value of '-' from itself, which will give 0 as a result. 表达式'-'-'-' '-'将从自身中减去'-'的char值,结果将得0。

Brackets around the whole define expressions are missing though, which can lead to errors in the code using these macros. 虽然缺少整个define表达式的括号,但这可能导致使用这些宏的代码出错。 Jay's answer adresses that pretty well. 杰伊的回答很好地说明了这一点。

An example of "real-life" scenario where forgetting the brackets can be harmful is the combined use of these macros with a C-style cast operator. 忘记括号可能有害的“现实”场景的一个例子是将这些宏与C风格的强制转换操作符结合使用。 If someone decides to cast these expressions to bool in C++ for instance: 如果有人决定在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;
}

Here's what we get: 这是我们得到的:

True: 0
False: -44

So (bool) TRUE would actually evaluate to false , and (bool) FALSE would evaluate to true . 所以(bool) TRUE实际上会评估为false ,而(bool) FALSE会评估为true


#3楼

It is equivalent to writing 它相当于写作

#define TRUE 1
#define FALSE 0

What the expression '/'/'/' actually does is dividing the character / (whatever its numeric value is) by itself, so it becomes 1 . 表达式'/'/'/'实际上是将字符/ (无论其数值是什么)除以它自己,因此它变为1

Similarly, the expression '-'-'-' subtracts the character - from itself and evaluates to 0 . 类似地,表达式'-'-'-' - '-'-'-'减去字符-从它自身开始并计算为0

It would be better to write 写作会更好

#define TRUE ('/'/'/')
#define FALSE ('-'-'-')

to avoid accidental change of values when used with other higher-precedence operators. 与其他更高优先级的运算符一起使用时,避免意外更改值。


#4楼

Let's see: '/' / '/' means the char literal / , divided by the char literal '/' itself. 让我们看看: '/' / '/'表示char literal / ,除以char literal '/'本身。 The result is one, which sounds reasonable for TRUE . 其结果是,这对于听起来很有道理TRUE

And '-' - '-' means the char literal '-' , subtracted from itself. '-' - '-'char常量'-' ,从自身减去。 This is zero ( FALSE ). 这是零( FALSE )。

There are two problems with this: first, it's not readable. 这有两个问题:首先,它不可读。 Using 1 and 0 is absolutely better. 使用10绝对更好。 Also, as TartanLlama and KerrekSB have pointed out, if you are ever going to use that definition, please do add parentheses around them so you won't have any surprises: 另外,正如TartanLlama和KerrekSB所指出的那样,如果您打算使用该定义,请在它们周围添加括号,这样您就不会有任何意外:

#include <stdio.h>

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

int main() {
        printf ("%d\n", 2 * FALSE);
        return 0;
}

This will print the value of the char literal '-' (45 on my system). 这将打印char literal '-' (在我的系统上为45)。

With parentheses: 括号:

#define TRUE  ('/'/'/')
#define FALSE ('-'-'-')

the program correctly prints zero, even though it doesn't make much sense to multiply a truth value by an integer, but it's just an example of the kind of unexpected bugs that could bite you if you don't parenthesize your macros. 程序正确地打印为零,即使将真值乘以整数没有多大意义,但它只是一个例子,如果你没有用括号表示你的宏可能会咬你。


#5楼

Let's start with true. 让我们从真实开始吧。 You can read it as '/' / '/' , which means "character '/' divided by character '/'". 您可以将其读作'/' / '/' ,表示“字符'/'除以字符'/'”。 Since each character, in C, is a numeric value (on one byte), it can be read as "the ASCII value of character '/' divided by the ASCII value of that same character", which means 1 (because, obviously, x/x is 1). 由于C中的每个字符都是一个数值(在一个字节上),因此可以将其读作“字符的ASCII值'/'除以相同字符的ASCII值”,这意味着1(因为很明显, x / x是1)。 Hence, TRUE is 1. 因此, TRUE是1。

For FALSE , its the same reasoning: '-'-'-' reads '-' - '-' , ie "the ASCII value of '-' minus the ASCII value of '-'", which is 0. Hence, FALSE is 0. 对于FALSE ,它的理由相同: '-'-'-' '-' - '-' '-'-'-''-' - '-' ,即' - '的ASCII值减去' - '的ASCII值,即0。因此, FALSE是0。

This is a nasty way to state the obvious. 这是一个令人讨厌的方式来说明显而易见的。


#6楼

Jay already answered why the values of these expressions are 0 and 1 . Jay已经回答了为什么这些表达式的01

For history sake, these expressions '/'/'/' and '-'-'-' come from one of the entries of 1st International Obfuscated C Code Contest in 1984 : 为了历史起见,这些表达式'/'/'/''-'-'-'来自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);}

(Link to the program here , there is a hint of what this program does in the IOCCC page above.) (链接到这里的程序,有一个暗示这个程序在上面的IOCCC页面中做了什么。)

Also if I remember correctly these expressions as obfuscated macros for TRUE and FALSE were also covered in "Obfuscated C and Other Mysteries" book by Don Libes (1993). 此外,如果我没记错,这些表达式为TRUEFALSE混淆宏也包含在Don Libes(1993)的“混淆C和其他奥秘”一书中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值