Странные определения истинных и ложных макросов


Я видел следующие определения макросов в книге кодирования.

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

не было никакого объяснения нет.

пожалуйста, объясните мне, как они будут работать как TRUE и FALSE.

6 290

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'

сохранит то же значение, что и исходное выражение.