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 TRUEe 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 TRUEe FALSE.
Respostas:
Vamos ver: '/' / '/'significa o charliteral /, dividido pelo próprio charliteral '/'. O resultado é um, que parece razoável TRUE.
E '-' - '-'significa o charliteral '-', subtraído de si mesmo. Isso é zero ( FALSE).
Existem dois problemas com isso: primeiro, não é legível. Usando 1e 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 charliteral '-'(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.
ifvez de multiplicar TRUEpor 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 defineentanto, 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 boolno 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) TRUEseria realmente avaliar falsee (bool) FALSEavaliar 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 0e 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 TRUEe FALSEtambém foram abordadas no livro "Obfuscated C and Other Mysteries" de Don Libes (1993).
É uma maneira hilária de escrever macros para TrueeFalse .
Como muitas explicações foram fornecidas /, um número de 1 byte (conforme ASCII), quando dividido por si só, fornece a você o 1que será tratado Truee, da mesma forma, -é novamente um número de byte ao subtrair o mesmo valor 0que 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.