Странные определения истинных и ложных макросов
Я видел следующие определения макросов в книге кодирования.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
не было никакого объяснения нет.
пожалуйста, объясните мне, как они будут работать как TRUE и FALSE.
6 ответов:
давайте посмотрим:
'/' / '/'означаетcharлитерал/, разделенное наcharлитерал'/'сам по себе. Результат один, который звучит разумно дляTRUE.и
'-' - '-'означаетcharлитерал'-', вычесть из себя. Это ноль (FALSE).есть две проблемы: во-первых, это не читается. Используя
1и0абсолютно лучше. Кроме того, как указали Тартанллама и Керрексб, если вы когда-либо чтобы использовать это определение, пожалуйста, добавьте круглые скобки вокруг них, чтобы у вас не было никаких сюрпризов:#include <stdio.h> #define TRUE '/'/'/' #define FALSE '-'-'-' int main() { printf ("%d\n", 2 * FALSE); return 0; }это выведет значение
charлитерал'-'(45 в моей системе).в скобки:
#define TRUE ('/'/'/') #define FALSE ('-'-'-')программа корректно выводит ноль, хотя это не делает много смысла, чтобы умножить это целое число, но это просто пример неожиданных ошибок, которые могут укусить вас, если вы не скобки ваш макросы.
это просто другой способ написания
#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. Вы можете прочитать его как
'/' / '/', Что означает "символ' / 'разделенный на символ'/'". Поскольку каждый символ в C является числовым значением (на один байт), его можно прочитать как "значение ASCII символа'/', разделенное на значение ASCII этого же символа", что означает 1 (потому что, очевидно, x/x равно 1). Следовательно,TRUEэто 1.на
FALSE, его же рассуждений:'-'-'-'читает'-' - '-', т. е. "значение ASCII' - 'минус значение ASCII' -'", которое является 0. Следовательно,FALSEравен 0.это неприятный способ говорить очевидное.
это веселый способ для написания макросов для
TrueиFalse.как много объяснений было предоставлено
/означает 1 байтовое число(согласно ASCII) при делении на себя он дает вам1который будет рассматриваться какTrue, а также-это снова число байтов, когда вычитается то же значение, которое он дает вам0который будет интерпретироваться какfalse#define TRUE '/'/'/' #define FALSE '-'-'-'следовательно, мы можем заменить
/или-С любым char нам нравится, для пример:#define TRUE '!'/'!' #define FALSE 'o'-'o'сохранит то же значение, что и исходное выражение.