Я думаю, что это просто забавный способ определить TRUE как 1 и FALSE как 0
BlackDwarf
160
Обратите внимание, что это ужасная идея без скобок вокруг этих выражений. Я имею в виду, что это ужасная идея с ними, но без этого вы просто просите долгой ночи отладки.
TartanLlama
70
Могу ли я знать книгу кодирования, на которую вы ссылаетесь?
artm
47
Я надеюсь, что эта книга включила это как пример плохого или намеренно неясного кода.
Джон Ханна
31
@Daniel: Другая идея состоит в том, чтобы rand ()% 2 определял MAYBE как rand ()% 2, так что иногда это == TRUE, а иногда == FALSE.
Кайзерлуди
Ответы:
380
Посмотрим: '/' / '/'означает charлитерал /, разделенный на сам charлитерал '/'. Результат тот, который звучит разумно для TRUE.
А '-' - '-'значит charбуквальное '-', вычитаемое из себя. Это ноль ( FALSE).
Есть две проблемы с этим: во-первых, он не читается. Использование 1и 0абсолютно лучше. Кроме того, как отметили TartanLlama и KerrekSB, если вы когда-либо собираетесь использовать это определение, пожалуйста, добавьте круглые скобки вокруг них, чтобы у вас не было никаких сюрпризов:
Это напечатает значение charлитерала '-'(45 в моей системе).
С круглыми скобками:
#define TRUE ('/'/'/')#define FALSE ('-'-'-')
программа правильно печатает ноль, даже если нет смысла умножать значение истинности на целое число, но это всего лишь пример неожиданных ошибок, которые могут укусить вас, если вы не заключите в скобки макрос.
Черт, мне потребовалось много времени, чтобы понять это: я даже подумал, что это странная вещь, как глифы ... не знаю xD
Луис Масуэлли
8
На самом деле имеет смысл умножить значение истины. Например, для отступа * should_indent будет либо 0, либо отступ, в зависимости от того, следует ли делать must_indent без ветвления. (Полагаю, что это плохой пример, когда работа с одиночным переходом текста не имеет значения, (я видел эту технику в шейдерах и в XPATH (оба слишком разные, и я не помню точную форму))
Alpedar
2
Alpedar - но это не концептуально и математически не делает senso, чтобы сделать это - в этом случае было бы более понятно (и концептуально имеет смысл) использовать ifвместо умножения TRUEна целое число.
Джей
4
Отличное объяснение. Имейте золотой значок!
Майкл Хэмптон
2
Логическое отрицание может быть реализовано как notx = TRUE- x;и работает отлично. За исключением того, что TRUE-FALSE-44 (при условии ASCII)
Хаген фон Айцен
89
Это просто еще один способ написания
#define TRUE 1#define FALSE 0
Выражение '/'/'/'разделит значение char '/'само по себе, что в результате даст 1.
Выражение '-'-'-'вычтет значение char '-'из самого себя, что в результате даст 0.
defineТем не менее, скобки вокруг целых выражений отсутствуют, что может привести к ошибкам в коде с использованием этих макросов. Ответ Джея говорит об этом довольно хорошо.
Примером сценария «реальной жизни», в котором забывание скобок может быть вредным, является комбинированное использование этих макросов с оператором приведения в стиле C. Если кто-то решит привести эти выражения boolв C ++, например:
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);}
(Ссылка на программу здесь , есть подсказка о том, что эта программа делает на странице IOCCC выше.)
Также, если я правильно помню эти выражения как запутанные макросы для TRUEи FALSEбыли также охвачены в книге «Запутанный C и другие тайны» Дона Либеса (1993).
Это веселый способ написания макросов для Trueи False.
Так как было дано много объяснений, это /означает, что 1-байтовое число (согласно ASCII) при делении само по себе дает вам значение, 1которое также будет рассматриваться как Trueаналогичное -число байтов при вычитании того же значения, которое оно дает вам, 0что будет интерпретироваться какfalse
#define TRUE '/'/'/'#define FALSE '-'-'-'
следовательно, мы можем заменить /или -любым другим символом, который нам нравится, например:
#define TRUE '!'/'!'#define FALSE 'o'-'o'
Сохранит то же значение, что и исходное выражение.
Давайте начнем с истины. Вы можете прочитать это как '/' / '/', что означает «символ» / «разделенный на символ« / »». Поскольку каждый символ в C является числовым значением (на один байт), его можно прочитать как «значение ASCII символа '/', разделенное на значение ASCII этого же символа», что означает 1 (потому что, очевидно, х / х равно 1). Следовательно, TRUE1.
Ибо FALSE, это то же самое рассуждение: '-'-'-'читает '-' - '-', то есть "значение ASCII '-' минус значение ASCII '-'", которое равно 0. Следовательно, FALSEравно 0.
@Fabien: Это не зависит от ASCII. '/'/'/'равен 1 для любого допустимого набора символов, будь то '/' == 47(как в ASCII) или '/' == 97(как в EBCDIC), или любого другого значения.
Кит Томпсон
4
@Pawel: Соответствующая реализация C не может отображаться '/'на 0. Это значение зарезервировано для нулевого символа.
Кит Томпсон
2
Вы педантичны.
Matheus208
3
@ Matheus208 Если Павел вел себя педантично, то это ('-'-'-'), поскольку его точка зрения была основана на неустановленном состоянии; описание замечаний Кейта как педантичных может быть более ('/' / '/'), но я бы назвал их "разъясняющими" (и с добавленными смайликами "педантичные" определенно кажутся мне "/ '-' /"). Может быть ('-' / '-'), что собранные вместе комментарии можно назвать педантичными, но, 1) не является ли это в некоторой степени обязательным в этой области? 2) они заставили меня задуматься; и 3) Я немного более ясен в некоторых вещах, чем был. И да, я думаю, я сам педантичен! (Но я понимаю, что значит «педантичный», чем я был; ;-)
Ответы:
Посмотрим:
'/' / '/'
означаетchar
литерал/
, разделенный на самchar
литерал'/'
. Результат тот, который звучит разумно дляTRUE
.А
'-' - '-'
значитchar
буквальное'-'
, вычитаемое из себя. Это ноль (FALSE
).Есть две проблемы с этим: во-первых, он не читается. Использование
1
и0
абсолютно лучше. Кроме того, как отметили TartanLlama и KerrekSB, если вы когда-либо собираетесь использовать это определение, пожалуйста, добавьте круглые скобки вокруг них, чтобы у вас не было никаких сюрпризов:Это напечатает значение
char
литерала'-'
(45 в моей системе).С круглыми скобками:
программа правильно печатает ноль, даже если нет смысла умножать значение истинности на целое число, но это всего лишь пример неожиданных ошибок, которые могут укусить вас, если вы не заключите в скобки макрос.
источник
if
вместо умноженияTRUE
на целое число.notx = TRUE- x;
и работает отлично. За исключением того, чтоTRUE-FALSE
-44 (при условии ASCII)Это просто еще один способ написания
Выражение
'/'/'/'
разделит значение char'/'
само по себе, что в результате даст 1.Выражение
'-'-'-'
вычтет значение char'-'
из самого себя, что в результате даст 0.define
Тем не менее, скобки вокруг целых выражений отсутствуют, что может привести к ошибкам в коде с использованием этих макросов. Ответ Джея говорит об этом довольно хорошо.Примером сценария «реальной жизни», в котором забывание скобок может быть вредным, является комбинированное использование этих макросов с оператором приведения в стиле C. Если кто-то решит привести эти выражения
bool
в C ++, например:Вот что мы получаем:
Так
(bool) TRUE
что на самом деле оценил быfalse
и(bool) FALSE
оценил быtrue
.источник
Это эквивалентно написанию
Что на
'/'/'/'
самом деле делает выражение , так это деление символа/
(каким бы ни было его числовое значение) на себя, так что оно становится1
.Точно так же выражение
'-'-'-'
вычитает символ-
из себя и вычисляет до0
.Было бы лучше написать
чтобы избежать случайного изменения значений при использовании с другими операторами с более высоким приоритетом.
источник
Джей уже ответил, почему значения этих выражений
0
и1
.Ради истории, эти выражения
'/'/'/'
и'-'-'-'
взяты из одной из статей 1- го Международного конкурса кодов с запутанным кодом C в 1984 году :(Ссылка на программу здесь , есть подсказка о том, что эта программа делает на странице IOCCC выше.)
Также, если я правильно помню эти выражения как запутанные макросы для
TRUE
иFALSE
были также охвачены в книге «Запутанный C и другие тайны» Дона Либеса (1993).источник
Это веселый способ написания макросов для
True
иFalse
.Так как было дано много объяснений, это
/
означает, что 1-байтовое число (согласно ASCII) при делении само по себе дает вам значение,1
которое также будет рассматриваться какTrue
аналогичное-
число байтов при вычитании того же значения, которое оно дает вам,0
что будет интерпретироваться какfalse
следовательно, мы можем заменить
/
или-
любым другим символом, который нам нравится, например:Сохранит то же значение, что и исходное выражение.
источник
Давайте начнем с истины. Вы можете прочитать это как
'/' / '/'
, что означает «символ» / «разделенный на символ« / »». Поскольку каждый символ в C является числовым значением (на один байт), его можно прочитать как «значение ASCII символа '/', разделенное на значение ASCII этого же символа», что означает 1 (потому что, очевидно, х / х равно 1). Следовательно,TRUE
1.Ибо
FALSE
, это то же самое рассуждение:'-'-'-'
читает'-' - '-'
, то есть "значение ASCII '-' минус значение ASCII '-'", которое равно 0. Следовательно,FALSE
равно 0.Это неприятный способ заявить об очевидном.
источник
'/'/'/'
равен 1 для любого допустимого набора символов, будь то'/' == 47
(как в ASCII) или'/' == 97
(как в EBCDIC), или любого другого значения.'/'
на0
. Это значение зарезервировано для нулевого символа.