Ho visto le seguenti macro definizioni in un libro di programmazione.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Non c'era spiegazione lì.
Per favore, spiegami come funzioneranno come TRUE
e FALSE
.
Ho visto le seguenti macro definizioni in un libro di programmazione.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Non c'era spiegazione lì.
Per favore, spiegami come funzioneranno come TRUE
e FALSE
.
Risposte:
Vediamo: '/' / '/'
significa char
letterale /
, diviso per il char
letterale '/'
stesso. Il risultato è uno, che suona ragionevole TRUE
.
E '-' - '-'
significa char
letterale '-'
, sottratto da se stesso. Questo è zero ( FALSE
).
Ci sono due problemi con questo: in primo luogo, non è leggibile. Utilizzando 1
ed 0
è assolutamente migliore. Inoltre, come hanno sottolineato TartanLlama e KerrekSB, se hai mai intenzione di utilizzare quella definizione, ti preghiamo di aggiungere parentesi attorno a loro in modo da non avere sorprese:
#include <stdio.h>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
printf ("%d\n", 2 * FALSE);
return 0;
}
Questo stamperà il valore del valore char
letterale '-'
(45 sul mio sistema).
Tra parentesi:
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
il programma stampa correttamente zero, anche se non ha molto senso moltiplicare un valore di verità per un numero intero, ma è solo un esempio del tipo di bug imprevisti che potrebbero morderti se non parentesi le tue macro.
if
invece di moltiplicare TRUE
per un numero intero.
notx = TRUE- x;
e funziona bene. Tranne che TRUE-FALSE
è -44 (supponendo ASCII)
È solo un altro modo di scrivere
#define TRUE 1
#define FALSE 0
L'espressione '/'/'/'
dividerà il valore del carattere '/'
per se stesso, il che darà 1 come risultato.
L'espressione '-'-'-'
sottrarrà il valore del carattere di '-'
da se stesso, che darà come risultato 0.
Mancano parentesi attorno a tutte le define
espressioni, il che può portare a errori nel codice usando queste macro. La risposta di Jay si rivolge piuttosto bene.
Un esempio di scenario di "vita reale" in cui dimenticare le parentesi può essere dannoso è l'uso combinato di queste macro con un operatore di cast di tipo C. Se qualcuno decide di trasmettere queste espressioni bool
in C ++ per esempio:
#include <iostream>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
std::cout << "True: " << (bool) TRUE << std::endl;
std::cout << "False: " << (bool) FALSE << std::endl;
return 0;
}
Ecco cosa otteniamo:
True: 0
False: -44
Quindi (bool) TRUE
valuterei effettivamente false
e (bool) FALSE
valuteremmo true
.
È equivalente alla scrittura
#define TRUE 1
#define FALSE 0
Quello che '/'/'/'
effettivamente fa l'espressione è dividere il personaggio /
(qualunque sia il suo valore numerico) da solo, così diventa 1
.
Allo stesso modo, l'espressione '-'-'-'
sottrae il personaggio -
da se stessa e valuta 0
.
Sarebbe meglio scrivere
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
per evitare la modifica accidentale dei valori se utilizzato con altri operatori con precedenza superiore.
Jay ha già risposto perché i valori di queste espressioni sono 0
e 1
.
Per amor di storia, queste espressioni '/'/'/'
e '-'-'-'
provengono da una delle voci del 1 ° Concorso internazionale per codice C offuscato nel 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 al programma qui , c'è un suggerimento su cosa fa questo programma nella pagina IOCCC sopra.)
Anche se ricordo correttamente queste espressioni come macro offuscate per TRUE
e FALSE
sono state anche trattate nel libro "Obfuscated C and Other Mysteries" di Don Libes (1993).
È un modo esilarante per scrivere macro per True
e False
.
Poiché sono state fornite molte spiegazioni /
significa un numero di 1 byte (come da ASCII) quando diviso per se stesso ti dà 1
quale sarà trattato come True
e allo stesso modo -
è di nuovo un numero di byte quando viene sottratto lo stesso valore che ti dà 0
che verrà interpretato comefalse
#define TRUE '/'/'/'
#define FALSE '-'-'-'
quindi possiamo sostituire /
o -
con qualsiasi carattere che ci piace, ad esempio:
#define TRUE '!'/'!'
#define FALSE 'o'-'o'
Manterrà lo stesso significato dell'espressione originale.
Cominciamo con vero. Puoi leggerlo come '/' / '/'
, che significa "carattere" / "diviso per carattere" / "". Poiché ogni carattere, in C, è un valore numerico (su un byte), può essere letto come "il valore ASCII del carattere '/' diviso per il valore ASCII dello stesso carattere", che significa 1 (perché, ovviamente, x / x è 1). Quindi, TRUE
è 1.
Per FALSE
lo stesso ragionamento: '-'-'-'
legge '-' - '-'
, cioè "il valore ASCII di '-' meno il valore ASCII di '-'", che è 0. Quindi, FALSE
è 0.
Questo è un modo brutto per affermare l'ovvio.
'/'/'/'
è 1 per qualsiasi set di caratteri valido, sia '/' == 47
(come in ASCII), sia '/' == 97
(come in EBCDIC) o qualsiasi altro valore.
'/'
a 0
. Tale valore è riservato al carattere null.