Eu vi as seguintes definições de macro em um livro de codificação.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Não havia explicação lá.
Por favor, explique-me como isso funcionará como TRUE
e FALSE
.
Eu vi as seguintes definições de macro em um livro de codificação.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Não havia explicação lá.
Por favor, explique-me como isso funcionará como TRUE
e FALSE
.
Respostas:
Vamos ver: '/' / '/'
significa o char
literal /
, dividido pelo próprio char
literal '/'
. O resultado é um, que parece razoável TRUE
.
E '-' - '-'
significa o char
literal '-'
, subtraído de si mesmo. Isso é zero ( FALSE
).
Existem dois problemas com isso: primeiro, não é legível. Usando 1
e 0
é absolutamente melhor. Além disso, como o TartanLlama e o KerrekSB apontaram, se você alguma vez usar essa definição, adicione parênteses em torno deles para não ter surpresas:
#include <stdio.h>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
printf ("%d\n", 2 * FALSE);
return 0;
}
Isso imprimirá o valor do char
literal '-'
(45 no meu sistema).
Entre parênteses:
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
o programa imprime corretamente zero, mesmo que não faça muito sentido multiplicar um valor de verdade por um número inteiro, mas é apenas um exemplo do tipo de bugs inesperados que poderiam mordê-lo se você não colocar parênteses suas macros.
if
vez de multiplicar TRUE
por um número inteiro.
notx = TRUE- x;
e funciona bem. Excepto que TRUE-FALSE
é -44 (ASCII assumindo)
É apenas outra maneira de escrever
#define TRUE 1
#define FALSE 0
A expressão '/'/'/'
dividirá o valor do caractere '/'
por si só, o que fornecerá 1 como resultado.
A expressão '-'-'-'
subtrairá o valor de char de '-'
si mesmo, o que fornecerá 0 como resultado.
No define
entanto, faltam colchetes em torno das expressões inteiras , o que pode levar a erros no código usando essas macros. A resposta de Jay aborda isso muito bem.
Um exemplo de cenário "real" em que esquecer os colchetes pode ser prejudicial é o uso combinado dessas macros com um operador de conversão no estilo C. Se alguém decidir converter essas expressões bool
no C ++, por exemplo:
#include <iostream>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
std::cout << "True: " << (bool) TRUE << std::endl;
std::cout << "False: " << (bool) FALSE << std::endl;
return 0;
}
Aqui está o que temos:
True: 0
False: -44
Então, (bool) TRUE
seria realmente avaliar false
e (bool) FALSE
avaliar true
.
É equivalente a escrever
#define TRUE 1
#define FALSE 0
O que a expressão '/'/'/'
realmente faz é dividir o caractere /
(qualquer que seja seu valor numérico) por si mesmo, para que ele se torne 1
.
Da mesma forma, a expressão '-'-'-'
subtrai o caractere -
de si e avalia como 0
.
Seria melhor escrever
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
para evitar alterações acidentais de valores quando usadas com outros operadores de alta precedência.
Jay já respondeu por que os valores dessas expressões são 0
e 1
.
Para a história bem, estas expressões '/'/'/'
e '-'-'-'
vêm de uma das entradas de Concurso código ofuscado C 1st International, em 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);}
(Link para o programa aqui , há uma dica do que esse programa faz na página da IOCCC acima.)
Além disso, se eu me lembro corretamente dessas expressões como macros ofuscadas TRUE
e FALSE
também foram abordadas no livro "Obfuscated C and Other Mysteries" de Don Libes (1993).
É uma maneira hilária de escrever macros para True
eFalse
.
Como muitas explicações foram fornecidas /
, um número de 1 byte (conforme ASCII), quando dividido por si só, fornece a você o 1
que será tratado True
e, da mesma forma, -
é novamente um número de byte ao subtrair o mesmo valor 0
que será interpretado comofalse
#define TRUE '/'/'/'
#define FALSE '-'-'-'
portanto, podemos substituir /
ou -
por qualquer caractere que desejarmos, por exemplo:
#define TRUE '!'/'!'
#define FALSE 'o'-'o'
Manterá o mesmo significado que a expressão original.
Vamos começar com true. Você pode lê-lo como '/' / '/'
, o que significa "caractere '/' dividido pelo caractere '/'". Como cada caractere, em C, é um valor numérico (em um byte), ele pode ser lido como "o valor ASCII do caractere '/' dividido pelo valor ASCII desse mesmo caractere", o que significa 1 (porque, obviamente, x / x é 1). Conseqüentemente,TRUE
é 1.
Pois FALSE
, é o mesmo raciocínio: '-'-'-'
lê '-' - '-'
, ie "o valor ASCII de '-' menos o valor ASCII de '-'", que é 0. Portanto, FALSE
é 0.
Esta é uma maneira desagradável de afirmar o óbvio.
'/'/'/'
é 1 para qualquer conjunto de caracteres válido, seja '/' == 47
(como em ASCII) ou '/' == 97
(como em EBCDIC) ou qualquer outro valor.
'/'
a 0
. Esse valor é reservado para o caractere nulo.