Creo que es una forma divertida de definir VERDADERO como 1 y FALSO como 0
BlackDwarf
160
Tenga en cuenta que esta es una idea terrible sin corchetes alrededor de esas expresiones. Quiero decir que es una idea terrible con ellos, pero sin que solo estés pidiendo una larga noche de depuración.
TartanLlama
70
¿Puedo conocer el libro de codificación al que hace referencia?
artm
47
Espero que el libro incluya esto como un ejemplo de código malo o deliberadamente oscuro.
Jon Hanna
31
@Daniel: Otra idea sería rand ()% 2 definir MAYBE como rand ()% 2, por lo que a veces es == VERDADERO y a veces == FALSO.
Kaiserludi
Respuestas:
380
Veamos: '/' / '/'significa el charliteral /, dividido por el charliteral '/'mismo. El resultado es uno, lo que parece razonable TRUE.
Y '-' - '-'significa lo charliteral '-', sustraído de sí mismo. Esto es cero ( FALSE).
Hay dos problemas con esto: primero, no es legible. Usando 1y 0es 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:
Esto imprimirá el valor del charliteral '-'(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.
Maldición, me costó mucho entenderlo: incluso pensé que era algo extraño como glifos ... no sé xD
Luis Masuelli
8
Realmente tiene sentido multiplicar con el valor de verdad. Para la sangría de examen * should_indent dará como resultado 0 o sangría en función de si should_indent sin ramificación. (Supongo que este es un mal ejemplo, cuando se trabaja con ramificación única de texto no importa, (he visto esta técnica en sombreadores y en XPATH (ambos muy diferentes y no recuerdo la forma exacta))
Alpedar
2
Alpedar, pero no tiene sentido conceptual y matemáticamente para hacerlo, en este caso sería más claro (y tiene sentido conceptual) usar un en iflugar de multiplicar TRUEpor un entero.
Jay
44
Gran explicación ¡Ten una insignia de oro!
Michael Hampton
2
La negación lógica podría implementarse como notx = TRUE- x;y funciona bien. Excepto que TRUE-FALSEes -44 (suponiendo ASCII)
Hagen von Eitzen
89
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 defineembargo, 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 boolen C ++, por ejemplo:
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 TRUEy FALSEtambién fueron cubiertas en el libro "C ofuscado y otros misterios" de Don Libes (1993).
Es una forma divertida de escribir macros para Truey False.
Como se han proporcionado muchas explicaciones, /significa un número de 1 byte (según ASCII) cuando se divide por sí mismo, lo 1que se tratará como Truey, de -nuevo, también es un número de byte cuando se resta el mismo valor que le da, 0que 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, TRUEes 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, FALSEes 0.
@Fabien: No depende de ASCII. '/'/'/'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.
Keith Thompson, el
44
@Pawel: una implementación de C conforme no se puede asignar '/'a 0. Ese valor está reservado para el carácter nulo.
Keith Thompson, el
2
Estás siendo pedante.
Matheus208
3
@ Matheus208 Si Pawel estaba siendo pedante, entonces eso es ('-'-'-') ya que su punto se basaba en una condición no declarada; describir los comentarios de Keith como pedantes podría ser más ('/' / '/') pero los llamaría "clarificadores" (y con los emoticonos añadidos "pedante" definitivamente me parece '/' - '/'). Puede ser ('-' / '-') que los comentarios tomados juntos pueden llamarse pedantes pero, 1) ¿no es algo obligatorio en este campo? 2) me hicieron pensar; y 3) Soy un poco más claro en algunas cosas de lo que era. Y sí, ¡supongo que estoy siendo pedante! (¡Pero soy más claro sobre lo que significa "pedante" que lo que era! ;-)
Respuestas:
Veamos:
'/' / '/'
significa elchar
literal/
, dividido por elchar
literal'/'
mismo. El resultado es uno, lo que parece razonableTRUE
.Y
'-' - '-'
significa lochar
literal'-'
, sustraído de sí mismo. Esto es cero (FALSE
).Hay dos problemas con esto: primero, no es legible. Usando
1
y0
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:Esto imprimirá el valor del
char
literal'-'
(45 en mi sistema).Con paréntesis:
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.
fuente
if
lugar de multiplicarTRUE
por un entero.notx = TRUE- x;
y funciona bien. Excepto queTRUE-FALSE
es -44 (suponiendo ASCII)Es solo otra forma de escribir
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:Esto es lo que obtenemos:
Entonces
(bool) TRUE
realmente evaluaría afalse
, y(bool) FALSE
evaluaría atrue
.fuente
Es equivalente a escribir
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 en1
.De manera similar, la expresión
'-'-'-'
resta el carácter-
de sí misma y se evalúa como0
.Sería mejor escribir
para evitar el cambio accidental de valores cuando se usa con otros operadores de mayor precedencia.
fuente
Jay ya respondió por qué los valores de estas expresiones son
0
y1
.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 :(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
yFALSE
también fueron cubiertas en el libro "C ofuscado y otros misterios" de Don Libes (1993).fuente
Es una forma divertida de escribir macros para
True
yFalse
.Como se han proporcionado muchas explicaciones,
/
significa un número de 1 byte (según ASCII) cuando se divide por sí mismo, lo1
que se tratará comoTrue
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
por lo tanto, podemos reemplazar
/
o-
con cualquier char que nos guste, por ejemplo:Mantendrá el mismo significado que la expresión original.
fuente
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.
fuente
'/'/'/'
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.'/'
a0
. Ese valor está reservado para el carácter nulo.