He visto las siguientes definiciones de macro en un libro de codificación.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
No había explicación allí.
Por favor explíqueme cómo funcionarán estos TRUE
y FALSE
.
He visto las siguientes definiciones de macro en un libro de codificación.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
No había explicación allí.
Por favor explíqueme cómo funcionarán estos TRUE
y FALSE
.
Respuestas:
Veamos: '/' / '/'
significa el char
literal /
, dividido por el char
literal '/'
mismo. El resultado es uno, lo que parece razonable TRUE
.
Y '-' - '-'
significa lo char
literal '-'
, sustraído de sí mismo. Esto es cero ( FALSE
).
Hay dos problemas con esto: primero, no es legible. Usando 1
y 0
es absolutamente mejor. Además, como han señalado TartanLlama y KerrekSB, si alguna vez va a utilizar esa definición, agregue paréntesis a su alrededor para que no tenga sorpresas:
#include <stdio.h>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
printf ("%d\n", 2 * FALSE);
return 0;
}
Esto imprimirá el valor del char
literal '-'
(45 en mi sistema).
Con paréntesis:
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
el programa imprime correctamente cero, a pesar de que no tiene mucho sentido multiplicar un valor de verdad por un número entero, pero es solo un ejemplo del tipo de errores inesperados que podrían morderlo si no pone entre paréntesis sus macros.
if
lugar de multiplicar TRUE
por un entero.
notx = TRUE- x;
y funciona bien. Excepto que TRUE-FALSE
es -44 (suponiendo ASCII)
Es solo otra forma de escribir
#define TRUE 1
#define FALSE 0
La expresión '/'/'/'
dividirá el valor de char '/'
por sí mismo, lo que dará 1 como resultado.
La expresión '-'-'-'
restará el valor char de '-'
sí misma, lo que dará 0 como resultado.
Sin define
embargo, faltan paréntesis alrededor de las expresiones completas , lo que puede provocar errores en el código al usar estas macros. La respuesta de Jay aborda eso bastante bien.
Un ejemplo de escenario de la "vida real" donde olvidar los corchetes puede ser dañino es el uso combinado de estas macros con un operador de conversión de estilo C. Si alguien decide convertir estas expresiones bool
en C ++, por ejemplo:
#include <iostream>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
std::cout << "True: " << (bool) TRUE << std::endl;
std::cout << "False: " << (bool) FALSE << std::endl;
return 0;
}
Esto es lo que obtenemos:
True: 0
False: -44
Entonces (bool) TRUE
realmente evaluaría a false
, y (bool) FALSE
evaluaría a true
.
Es equivalente a escribir
#define TRUE 1
#define FALSE 0
Lo que '/'/'/'
realmente hace la expresión es dividir el carácter /
(cualquiera que sea su valor numérico) por sí mismo, de modo que se convierte en 1
.
De manera similar, la expresión '-'-'-'
resta el carácter -
de sí misma y se evalúa como 0
.
Sería mejor escribir
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
para evitar el cambio accidental de valores cuando se usa con otros operadores de mayor precedencia.
Jay ya respondió por qué los valores de estas expresiones son 0
y 1
.
Por el bien de la historia, estas expresiones '/'/'/'
y '-'-'-'
provienen de una de las entradas del concurso ofuscado C Código primera internacional en 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);}
(Enlace al programa aquí , hay una pista de lo que hace este programa en la página de IOCCC arriba).
Además, si recuerdo correctamente estas expresiones como macros ofuscadas para TRUE
y FALSE
también fueron cubiertas en el libro "C ofuscado y otros misterios" de Don Libes (1993).
Es una forma divertida de escribir macros para True
y False
.
Como se han proporcionado muchas explicaciones, /
significa un número de 1 byte (según ASCII) cuando se divide por sí mismo, lo 1
que se tratará como True
y, de -
nuevo, también es un número de byte cuando se resta el mismo valor que le da, 0
que se interpretará comofalse
#define TRUE '/'/'/'
#define FALSE '-'-'-'
por lo tanto, podemos reemplazar /
o -
con cualquier char que nos guste, por ejemplo:
#define TRUE '!'/'!'
#define FALSE 'o'-'o'
Mantendrá el mismo significado que la expresión original.
Comencemos con la verdad. Puede leerlo como '/' / '/'
, que significa "caracter '/' dividido por caracter '/'". Como cada carácter, en C, es un valor numérico (en un byte), puede leerse como "el valor ASCII del carácter '/' dividido por el valor ASCII de ese mismo carácter", lo que significa 1 (porque, obviamente, x / x es 1). Por lo tanto, TRUE
es 1.
Para FALSE
, es el mismo razonamiento: '-'-'-'
lee '-' - '-'
, es decir, "el valor ASCII de '-' menos el valor ASCII de '-'", que es 0. Por lo tanto, FALSE
es 0.
Esta es una forma desagradable de decir lo obvio.
'/'/'/'
es 1 para cualquier conjunto de caracteres válido, ya sea '/' == 47
(como está en ASCII) o '/' == 97
(como está en EBCDIC), o cualquier otro valor.
'/'
a 0
. Ese valor está reservado para el carácter nulo.