Я видел следующие определения макросов в книге по кодированию.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Там не было никакого объяснения.
Пожалуйста, объясните мне, как они будут работать, как TRUE
и FALSE
.
Я видел следующие определения макросов в книге по кодированию.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Там не было никакого объяснения.
Пожалуйста, объясните мне, как они будут работать, как TRUE
и FALSE
.
Ответы:
Посмотрим: '/' / '/'
означает char
литерал /
, разделенный на сам char
литерал '/'
. Результат тот, который звучит разумно для TRUE
.
А '-' - '-'
значит char
буквальное '-'
, вычитаемое из себя. Это ноль ( FALSE
).
Есть две проблемы с этим: во-первых, он не читается. Использование 1
и 0
абсолютно лучше. Кроме того, как отметили TartanLlama и KerrekSB, если вы когда-либо собираетесь использовать это определение, пожалуйста, добавьте круглые скобки вокруг них, чтобы у вас не было никаких сюрпризов:
#include <stdio.h>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
printf ("%d\n", 2 * FALSE);
return 0;
}
Это напечатает значение char
литерала '-'
(45 в моей системе).
С круглыми скобками:
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
программа правильно печатает ноль, даже если нет смысла умножать значение истинности на целое число, но это всего лишь пример неожиданных ошибок, которые могут укусить вас, если вы не заключите в скобки макрос.
if
вместо умножения TRUE
на целое число.
notx = TRUE- x;
и работает отлично. За исключением того, что TRUE-FALSE
-44 (при условии ASCII)
Это просто еще один способ написания
#define TRUE 1
#define FALSE 0
Выражение '/'/'/'
разделит значение char '/'
само по себе, что в результате даст 1.
Выражение '-'-'-'
вычтет значение char '-'
из самого себя, что в результате даст 0.
define
Тем не менее, скобки вокруг целых выражений отсутствуют, что может привести к ошибкам в коде с использованием этих макросов. Ответ Джея говорит об этом довольно хорошо.
Примером сценария «реальной жизни», в котором забывание скобок может быть вредным, является комбинированное использование этих макросов с оператором приведения в стиле C. Если кто-то решит привести эти выражения bool
в C ++, например:
#include <iostream>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
std::cout << "True: " << (bool) TRUE << std::endl;
std::cout << "False: " << (bool) FALSE << std::endl;
return 0;
}
Вот что мы получаем:
True: 0
False: -44
Так (bool) TRUE
что на самом деле оценил бы false
и (bool) FALSE
оценил бы true
.
Это эквивалентно написанию
#define TRUE 1
#define FALSE 0
Что на '/'/'/'
самом деле делает выражение , так это деление символа /
(каким бы ни было его числовое значение) на себя, так что оно становится 1
.
Точно так же выражение '-'-'-'
вычитает символ -
из себя и вычисляет до 0
.
Было бы лучше написать
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
чтобы избежать случайного изменения значений при использовании с другими операторами с более высоким приоритетом.
Джей уже ответил, почему значения этих выражений 0
и 1
.
Ради истории, эти выражения '/'/'/'
и '-'-'-'
взяты из одной из статей 1- го Международного конкурса кодов с запутанным кодом C в 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);}
(Ссылка на программу здесь , есть подсказка о том, что эта программа делает на странице 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). Следовательно, TRUE
1.
Ибо FALSE
, это то же самое рассуждение: '-'-'-'
читает '-' - '-'
, то есть "значение ASCII '-' минус значение ASCII '-'", которое равно 0. Следовательно, FALSE
равно 0.
Это неприятный способ заявить об очевидном.
'/'/'/'
равен 1 для любого допустимого набора символов, будь то '/' == 47
(как в ASCII) или '/' == 97
(как в EBCDIC), или любого другого значения.
'/'
на 0
. Это значение зарезервировано для нулевого символа.