Я видел определения в C
#define TRUE (1==1)
#define FALSE (!TRUE)
Это необходимо? Какая польза от простого определения TRUE как 1 и FALSE как 0?
c
precompiler
Роберт Харви
источник
источник
#define TRUE (’/’/’/’)
;#define FALSE (’-’-’-’)
(взято с сайта coding-guidelines.com/cbook/cbook1_1.pdf 871)Ответы:
Этот подход будет использовать фактический
boolean
тип (и разрешатьtrue
иfalse
), если его поддерживает компилятор. (в частности, C ++)Однако было бы лучше проверить, используется ли C ++ (с помощью
__cplusplus
макроса), и использовать на самом делеtrue
иfalse
.В компиляторе C это эквивалентно
0
и1
.(обратите внимание, что удаление скобок нарушит порядок операций)
источник
1==1
являетсяint
. (см. stackoverflow.com/questions/7687403/… .)boolean
типом?true
илиfalse
.#define TRUE true
и#define FALSE false
всякий раз , когда__cplusplus
определяется.Ответ - мобильность. Числовые значения
TRUE
иFALSE
не важны. Что является важным является то , что такое заявление имеетif (1 < 2)
значениеif (TRUE)
и заявление , как имеетif (1 > 2)
значениеif (FALSE)
.Конечно, в C он
(1 < 2)
оценивает1
и(1 > 2)
оценивает0
, так что, как говорили другие, нет никакой практической разницы в том, что касается компилятора. Но позволяя компилятору определятьTRUE
и вFALSE
соответствии с его собственными правилами, вы делаете их значения явными для программистов и гарантируете согласованность в своей программе и любой другой библиотеке (при условии, что другая библиотека соответствует стандартам C ... вы бы удивляться)Немного истории
Некоторые бейсики определены
FALSE
как0
иTRUE
как-1
. Как и многие современные языки, они интерпретировали любое ненулевое значение какTRUE
, но они оценивали логические выражения, которые были истинными как-1
. ИхNOT
работа была реализована путем добавления 1 и переключения знака, потому что это было эффективно сделать таким образом. Так что «НЕ х» стало-(x+1)
. Побочным эффектом этого является то, что значение как5
оцениваетTRUE
, ноNOT 5
оценивает-6
, что такжеTRUE
! Находить такого рода ошибку не весело.Наилучшие практики.
Учитывая фактические правила, что ноль интерпретируется как,
FALSE
а любое ненулевое значение интерпретируется какTRUE
, вы никогда неTRUE
FALSE
должны сравнивать логически выглядящие выражения с или . Примеры:Зачем? Потому что многие программисты используют ярлык для обработки
int
s какbool
s. Они не одинаковы, но компиляторы обычно позволяют это. Так, например, совершенно законно писатьЭто выглядит законно, и компилятор с радостью примет это, но, вероятно, не будет делать то, что вы хотите. Это потому , что возвращаемое значение
strcmp()
IS0 если
yourString == myString
<0 если
yourString < myString
> 0 если
yourString > myString
Таким образом, строка выше возвращается
TRUE
только тогда, когдаyourString > myString
.Правильный способ сделать это либо
или
Так же:
Некоторые из этих «плохих примеров» вы часто найдете в рабочем коде, и многие опытные программисты клянутся ими: они работают, некоторые короче, чем их (педантично?) Правильные альтернативы, и идиомы почти повсеместно признаны. Но учтите: «правильные» версии не менее эффективны, они гарантированно переносимы, они будут проходить даже самые строгие линтеры, и даже новые программисты поймут их.
Разве это не стоит того?
источник
(1==1)
не более портативный, чем1
. Собственные правила компилятора - это правила языка Си, который ясен и однозначен в отношении семантики равенства и операторов отношений. Я никогда не видел, чтобы компилятор ошибался.strcmp
меньше, равно, равно или больше 0. Не гарантируется, что оно равно -1, 0 или 1, и существуют платформы, которые не возвращают эти значения, чтобы ускорить реализацию. Так что еслиstrcmp(a, b) == TRUE
тогда,a > b
но обратное значение может не иметь места.(1==1)
и1
оба являются постоянными выражениями типаint
со значением 1. Они являются семантически идентичны. Я полагаю, вы можете написать код, который обслуживает читателей, которые этого не знают, но где это заканчивается?(1 == 1)
Трюк полезен для определенияTRUE
таким образом , что является прозрачным для C, но обеспечивает лучшее набрав в C ++. Тот же код можно интерпретировать как C или C ++, если вы пишете на диалекте под названием «Чистый C» (который компилируется как C или C ++) или если вы пишете заголовочные файлы API, которые могут использоваться программистами на C или C ++.В переводных единицах C
1 == 1
имеет точно такое же значение, как1
; и1 == 0
имеет то же значение, что и0
. Однако в модулях перевода C ++1 == 1
есть типbool
. Таким образом,TRUE
определенный таким образом макрос лучше интегрируется в C ++.Пример того, как он лучше интегрируется, состоит в том, что, например, если функция
foo
имеет перегрузки дляint
и дляbool
, тоfoo(TRUE)
выберетbool
перегрузку. ЕслиTRUE
это просто определено как1
, то это не будет хорошо работать в C ++.foo(TRUE)
захочетint
перегрузку.Конечно, C99 введены
bool
,true
и ,false
и они могут быть использованы в заголовочных файлах , которые работают с C99 и с C.Тем не мение:
TRUE
иFALSE
как(0==0)
и(1==0)
предшествует C99.Если вы работаете в смешанном C и C ++ проекте, и не хотите , C99, определяет нижний регистр
true
,false
аbool
вместо этого.При этом
0==0
хитрость (была?) Использовалась некоторыми программистами даже в коде, который никогда не предназначался для взаимодействия с C ++ каким-либо образом. Это ничего не значит и говорит о том, что программист неправильно понимает, как логические функции работают в C.В случае, если объяснение C ++ не было ясным, вот тестовая программа:
Выход:
Что касается вопроса из комментариев о том, как перегружены функции C ++, относящиеся к смешанному программированию на C и C ++. Это просто иллюстрирует разницу в типах. Действительная причина, по которой
true
нужно, чтобыbool
при компиляции в C ++ была константа, - это чистая диагностика. На самых высоких уровнях предупреждения компилятор C ++ может предупредить нас о преобразовании, если мы передадим целое число в качествеbool
параметра. Одна из причин написания на чистом C заключается не только в том, что наш код более переносим (поскольку его понимают компиляторы C ++, а не только компиляторы C), но мы можем извлечь пользу из диагностических мнений компиляторов C ++.источник
TRUE
будут различаться в C ++.#ifdef __cplusplus
для более ясного выражения своих намерений.bool
иint
не имеют большого значения на практике, так как они неявно конвертируемы друг в друга (и в C фактически «одинаковы» , обратите внимание на кавычки) хотя) и не так много ситуаций, в которых вам действительно необходимо устранить неоднозначность между ними. «не так много» было, вероятно, слишком тяжело, «гораздо меньше по сравнению с кодом, использующим шаблоны и перегрузки», возможно, было бы лучше.эквивалентно
в С.
Результатом реляционных операторов является
0
или1
.1==1
гарантированно будет оцениваться1
и!(1==1)
гарантированно будет оцениваться0
.Нет абсолютно никаких причин использовать первую форму. Обратите внимание, что первая форма, однако, не менее эффективна, поскольку почти во всех компиляторах константное выражение оценивается во время компиляции, а не во время выполнения. Это разрешено согласно этому правилу:
PC-Lint будет даже выдавать сообщение (506, постоянное значение логическое) , если вы не используете Буквальное для
TRUE
иFALSE
макросов:Также в C99
stdbool.h
определены определения для логических макросовtrue
иfalse
непосредственно используются литералы:источник
1==1
гарантированно будет оцениваться по1
if(foo == true)
, который превратится из просто плохой практики в плоскую ошибку.(x == TRUE)
может иметь другое значение истинности, чемx
.Помимо C ++ (уже упоминалось), еще одним преимуществом являются инструменты статического анализа. Компилятор покончит с любой неэффективностью, но статический анализатор может использовать свои собственные абстрактные типы, чтобы различать результаты сравнения и другие целочисленные типы, поэтому он неявно знает, что TRUE должен быть результатом сравнения и не должен считаться совместимым с целым числом.
Очевидно, что C говорит, что они совместимы, но вы можете запретить преднамеренное использование этой функции, чтобы помочь выявить ошибки - например, когда кто-то может запутаться
&
и&&
, или они испортили свой операторский приоритет.источник
if (boolean_var == TRUE)
путем расширения, вif (boolean_var == (1 == 1))
которое благодаря расширенной информации о типе(1 == 1)
узла попадает шаблонif (<*> == <boolean_expr>)
.Практическая разница - нет.
0
оцениваетсяfalse
и1
оцениваетсяtrue
. Тот факт, что вы используете логическое выражение (1 == 1
) или1
, для определенияtrue
, не имеет никакого значения. Они оба получают оценкуint
.Обратите внимание , что стандартная библиотека C предоставляет специальный заголовок для определения булевых:
stdbool.h
.источник
true
оценивается1
иfalse
оценивается0
. Си не знает о родных булевых типах, они просто целые числа.int
со значением0
или1
. C действительно имеет логический тип (_Bool
с макросом,bool
определенным в<stdbool.h>
, но он был добавлен только в C99, который не изменил семантику операторов для использования нового типа._Bool
и<stdbool.h>
имеет#define bool _Bool
.1 == 1
что вас оценивают какint
. Ред.Мы не знаем точного значения, которому равно TRUE, и компиляторы могут иметь свои собственные определения. Итак, что вы привели, так это использование внутреннего компилятора для определения. Это не всегда необходимо, если у вас есть хорошие навыки программирования, но вы можете избежать проблем из-за плохого стиля программирования, например:
if ((a> b) == ИСТИНА)
Это может быть катастрофой, если вы вручную определите TRUE как 1, а внутреннее значение TRUE - другое.
источник
>
оператор всегда выдает 1 для истины, 0 для ложных. Нет никакой возможности того, чтобы компилятор C понял это неправильно. Сравнение равенстваTRUE
иFALSE
плохой стиль; вышесказанное более четко написано какif (a > b)
. Но идея о том, что разные компиляторы C могут по-разному трактовать истину и ложь, неверна.Обычно на языке программирования C 1 определяется как true, а 0 определяется как false. Поэтому вы часто видите следующее:
Однако любое число, не равное 0, будет также оценено как истинное в условном выражении. Поэтому, используя ниже:
Вы можете просто явно показать, что вы пытаетесь не рисковать, делая ложь равной тому, что не соответствует действительности.
источник