Можете ли вы объяснить, почему они являются лучшим выбором для худшего?
эндолит
1
@endolith Выравнивание, оптимизации и способ сохранения выбранных <stdbool.h>boolкомпилятором могут быть более подходящими для предполагаемого назначения логического значения, чем использование int(то есть компилятор может выбрать реализацию, boolотличную от int). Это также может привести к более строгой проверке типов во время компиляции, если вам повезет.
blubberdiblub
1
Зачем использовать intдля bool? Это расточительно. Использование unsigned char. Или используйте встроенный Си _Bool.
user12211554
@ NoBody Использование меньшего типа может сэкономить память, но это может не сделать это быстрее. Часто быстрее использовать собственный размер слова процессора, а не меньший размер, так как это может потребовать, чтобы компилятор выполнил битовые сдвиги, чтобы выровнять его должным образом
Тед Кляйн Бергман
241
Несколько мыслей о логических значениях в C:
Я достаточно intвзрослый , чтобы просто использовать простой s в качестве моего логического типа без каких-либо определений типов, специальных определений или перечислений для значений true / false. Если вы последуете моему предложению никогда не сравнивать с булевыми константами, тогда вам все равно нужно будет использовать 0/1 для инициализации флагов. Однако такой подход может считаться слишком реакционным в эти современные времена. В этом случае, безусловно, следует использовать, <stdbool.h>поскольку он, по крайней мере, имеет преимущество от стандартизации.
Какие бы логические константы ни назывались, используйте их только для инициализации. Никогда не пиши что-то вроде
if(ready == TRUE)...while(empty == FALSE)...
Они всегда могут быть заменены на более четкие
if(ready)...while(!empty)...
Обратите внимание, что они могут быть разумно и понятно прочитаны вслух.
Дайте вашим логическим переменным положительные имена, т.е. fullвместо notfull. Последнее приводит к коду, который трудно прочитать легко. сравнить
if(full)...if(!full)...
с
if(!notfull)...if(notfull)...
Обе первые пары читают естественно, хотя !notfullчитать неловко, как есть, и становится намного хуже в более сложных логических выражениях.
Обычно следует избегать логических аргументов. Рассмотрим функцию, определенную следующим образом
void foo(bool option){...}
В теле функции очень ясно, что означает аргумент, поскольку он имеет удобное и, мы надеемся, содержательное имя. Но сайты вызова выглядят так
foo(TRUE);
foo(FALSE):
Здесь, по сути, невозможно сказать, что имел в виду параметр, не всегда просматривая определение или объявление функции, и становится намного хуже, как только вы добавляете еще больше логических параметров. Я предлагаю либо
А как вы сравниваете две переменные на равенство? Никогда не используйте булевы константы, это прекрасно работает, но это не решает проблему при сравнении с непостоянной.
Барух
Прости меня, но я не понимаю вопроса. Вы спрашиваете, как я сравниваю две булевы переменные на равенство? Если так, не a == bработает?
Дейл Хэгглунд
5
@ Кендзи То, что вы говорите, правда, хотя я считаю, что использование значений, отличных от единицы, в качестве эквивалента для истины - почти всегда плохая идея. Так что в вашем примере, предполагая это aи считая bс нуля, я бы рекомендовал a > 0 == b > 0вместо этого. Если вы настаиваете на использовании правдивости произвольных ненулевых значений, !!varвыдает логическое значение 0/1, эквивалентное var, так что вы можете написать !!a == !!b, хотя многие читатели сочтут это запутанным.
Дейл Хэгглунд
3
!a == !bтакже достаточно для проверки равенства, ненули становятся равными нулю, а нули равны единице.
ryanpattison
5
@rpattiso Вы, конечно, правы, но я думаю, что я бы прочитал !!aкак «преобразовать небулево a в его эквивалентное значение истинности», тогда как я бы прочитал !aкак «логически инвертировать логическую переменную a». В частности, я бы искал по какой-то конкретной причине, что логическая инверсия была желательна.
Дейл Хэгглунд
88
Логическое значение в C является целым числом: ноль для false и ненулевое значение для true.
Он также хорошо работает с логическими операторами (&& и ||).
Вультрао
74
Вот версия, которую я использовал:
typedefenum{false=0,true=!false}bool;
Поскольку ложь имеет только одно значение, но логическое истина может иметь много значений, но метод устанавливает истину так, чтобы компилятор использовал ее в противоположность ложному.
Это решает проблему того, что кто-то кодирует что-то, что сводится к следующему:
if(true==!false)
Я думаю, что мы все согласны с тем, что это не очень хорошая практика, но за единовременную стоимость выполнения операции «true =! False» мы устраняем эту проблему.
Первый (самый правый)! преобразует ненулевое целое число в 0, затем второе (самое левое)! преобразует 0 в myfalseзначение. Я оставлю читателю в качестве упражнения преобразование нулевого целого числа.
[РЕДАКТИРОВАТЬ] Мой стиль заключается в использовании явной установки значения в перечислении, когда требуется конкретное значение, даже если значение по умолчанию будет таким же. Пример: поскольку false должно быть равно нулю, я использую, false = 0,а неfalse,
Кроме того, еще одно преимущество использования перечислений является интеграция IDE - true, falseи boolвыделяются в большинстве IDE, потому что они являются значениями перечислений и ЬурейеЕ, в отличие от #defines, которые редко когда - либо подсветки синтаксиса.
Любопытно: не обращая внимания на то, действительно ли это работает, действительно ли это C (99+), чтобы позволить перечислению ссылаться на предыдущее значение в том же перечислении ?
@ tgm1024 не gcc -ansi -pedantic -Wallвыдает предупреждений, поэтому я верю gcc; Если это работает даже для c89этого, должно работать на c99aswell.
yyny
1
«Потому что ложь имеет только одно значение, но логическое истина может иметь много значений, но метод устанавливает истину так, чтобы компилятор использовал ее в противоположность ложному». Оператор отрицания !может только возвращать значения 0и 1, таким образом true = !false, всегда будет присваивать значение 1. Этот метод не дает никакой дополнительной безопасности typedef enum { false, true } bool;.
user694733
1
Самое раннее, что я обнаружил, это из C90 (6.3.3.3 Унарные арифметические операторы): «Результат оператора логического отрицания! Равен 0, если значение его операнда сравнивается с неравным 0. 1, если значение его операнда сравнивается равным 0. Результат имеет тип int. Выражение! E эквивалентно (O == E). " Это должно охватывать любой компилятор, который когда-либо утверждал, что поддерживает стандарт C. Компиляторы, конечно, могут по закону игнорировать это правило в тех случаях, когда оно не имеет значения для наблюдаемого поведения (например if(!value)), но это исключение не применимо в данном конкретном случае.
user694733
48
Если вы используете компилятор C99, он имеет встроенную поддержку типов bool:
#include<stdbool.h>int main(){bool b =false;
b =true;}
Обо всем по порядку. C, то есть ISO / IEC 9899 имеет логический тип уже 19 лет . Это намного больше времени, чем ожидаемая продолжительность карьеры программиста на Си с любительскими / академическими / профессиональными частями, объединенными при посещении этого вопроса . Моя превосходит это всего лишь на 1-2 года. Это означает, что в то время , когда среднестатистический читатель вообще что-то узнал о C, C фактически имел логический тип данных .
Для типа данных, #include <stdbool.h>и использовать true, falseи bool. Или не включать его и использовать _Bool, 1и 0вместо этого.
В других ответах на эту тему представлены различные опасные методы. Я обращусь к ним:
typedefintbool;#definetrue1#definefalse0
Это нет-нет, потому что случайный читатель - который изучил C в течение этих 19 лет - ожидал, что это boolотносится к фактическомуbool типу данных и будет вести себя аналогично, но это не так! Например
double a =...;bool b = a;
С C99 bool/ _Bool, bбыло бы установлено, falseесли быa был ноль, и в trueпротивном случае. C11 6.3.1.2p1
Когда любое скалярное значение преобразуется в _Bool, результат равен 0, если значение сравнивается равным 0; в противном случае результат равен 1. 59)
Сноски
59) NaN не сравниваются равными 0 и, следовательно, преобразуются в 1.
При наличии на typedefместе значение doubleбудет приведено к int- если значение double не находится в диапазоне для int, поведение не определено .
Естественно, то же самое относится, если trueи falseбыли объявлены в enum.
Что еще опаснее, так это декларировать
typedefenumbool{false,true}bool;
поскольку теперь все значения, кроме 1 и 0, являются недопустимыми, и если такое значение будет присвоено переменной этого типа, поведение будет полностью неопределенным .
Поэтому, если вы не можете использовать C99 по какой-то необъяснимой причине, для логических переменных вы должны использовать:
тип intи значения 0и 1как есть ; и тщательно делайте доменные преобразования из любых других значений в них с двойным отрицанием!!
или если вы настаивать вы не помните , что 0 является falsy и ненулевая truish, по крайней мере , использование верхнего регистра , так что они не запутаться с понятиями C99: BOOL, TRUEи FALSE!
Какая часть стандарта C будет ограничивать объекты перечислимых типов для хранения значений, явно перечисленных в них? Если наибольшее значение для перечисляемой константы меньше, чем UCHAR_MAX или USHRT_MAX, реализация может использовать тип, меньший intили unsigned intдля хранения перечисления, но я не знаю ничего в Стандарте, которое могло бы привести к тому, что перечисление будет вести себя как что-то отличное от целого числа тип.
От 2 до MAX_INT также следует оценить как истинное
технозавр
2
@technosaurus Такой подход не гарантирует! false == true, поскольку! false может быть любым ненулевым числом. Простой обходной путь - явно назначить true для! False.
Андрей
3
@ Андрей Это не правда. !0 = 1по стандарту C, и !a = 0для любого ненулевого значения a. Проблема в том, что любое ненулевое значение считается истинным. Таким образом, если aи bоба являются «истиной», это не обязательно тот случай, когда `a == b`.
Джереми Уэст
14
C имеет логический тип: bool (по крайней мере, за последние 10 (!) Лет)
Включите stdbool.h, и true / false будет работать как положено.
10 лет в стандарте, но не 10 лет в компиляторах! Компиляция C MSVC ++ вообще не поддерживает C99, кроме разрешения // комментариев, и вряд ли когда-либо сделает это. Также _Bool определен в C99 как встроенный тип, в то время как bool является typedef в заголовке <stdbool.h>.
Клиффорд
5
@ Clifford 4 года с момента вашего комментария ... ничего не изменилось. MSVC - это компилятор C ++, и я полагаю, MS заявляет, что на самом деле они не заинтересованы в поддержке всех новых функций C (C99 и C11). Но я не могу принять тот факт, что MSVC не поддерживает новые функции C в качестве причины (особенно если вы говорите это против 10 лет ответа). 10 лет - это действительно много времени в мире программирования. Любой достойный компилятор должен иметь поддержку для него менее чем за 10 лет, если поставщик намерен поддерживать его.
PP
2
@KingsIndian: Я не уверен, почему вы направили свой комментарий мне или даже почувствовали необходимость комментировать вообще. Я только констатировал ситуацию на момент написания статьи. Я не поддерживал эту ситуацию, просто указывал, что «ответ» может применяться не при всех обстоятельствах.
Клиффорд
@Clifford: Строго говоря, стандарт boolдолжен быть макросом, который расширяется до _Bool. Разница имеет значение, потому что вы можете #undefмакрос (и это разрешено, по крайней мере, в качестве переходной меры), но вы не можете untypedeftypedef. Это не меняет основную направленность вашего первого комментария.
Джонатан Леффлер
2
VS2015 и более поздние версии (и, возможно, ранее, до определенного момента) не имеют проблем со boolсквозной <stdbool.h>компиляцией под Си. Это решает до _Bool.
11
Все, что не равно нулю, оценивается как истинное в логических операциях, так что вы можете просто
но используйте их с осторожностью: поскольку истинным результатом может быть любое ненулевое значение, тесты if (t == TRUE) {...} и if (t), которые эквивалентны в других языках, не эквивалентны в C .
Fortega
1
Вы правы, но это также верно для C ++, который имеет тип bool, верно? Во время отладки я видел переменные bool со значениями 5837834939 ...
ggambett
1
В C ++ тест if (t == true) равен тесту if (t), потому что C ++ выполняет некоторое преобразование (все, что не равно 0 или значение нулевого указателя преобразуется в true)
Fortega
6
Все, что вы должны предположить о булевом истинном значении, это то, что оно ненулевое. Так что код вроде if (b) безопасен, а if (b == TRUE) - нет; последнее - плохая практика (и бессмысленная).
Клиффорд
5
Просто дополнение к другим ответам и некоторым разъяснениям, если вам разрешено использовать C99.
+-------+----------------+-------------------------+--------------------+|Name|Characteristic|Dependence in stdbool.h |Value|+-------+----------------+-------------------------+--------------------+|_Bool|Native type |Don't need header ||+-------+----------------+-------------------------+--------------------+|bool|Macro|Yes|Translate to _Bool|+-------+----------------+-------------------------+--------------------+|true|Macro|Yes|Translate to 1|+-------+----------------+-------------------------+--------------------+|false|Macro|Yes|Translate to 0|+-------+----------------+-------------------------+--------------------+
Некоторые из моих предпочтений:
_Boolили bool? Оба в порядке, но boolвыглядит лучше, чем ключевое слово _Bool.
Допустимые значения boolи _Bool: falseили true. Назначение 0или 1вместо falseили trueявляется действительным, но сложнее для чтения и понимания логического потока.
Некоторая информация из стандарта:
_BoolНЕ unsigned int, но является частью группы целочисленных типов без знака . Он достаточно большой, чтобы содержать значения 0или 1.
НЕ, но да, вы можете переопределить booltrueи, falseконечно, не очень хорошая идея. Эта способность считается устаревшей и будет удалена в будущем.
Назначение скалярного типа (арифметические типы и типы указателей) к _Boolили bool, если скалярное значение равно 0или сравнивает 0это будет 0, в противном случае результат 1: _Bool x = 9;9преобразуется в , 1когда назначен x.
_Bool1 байт (8 бит), обычно у программиста возникает соблазн попытаться использовать другие биты, но это не рекомендуется, поскольку гарантируется только то, что для хранения данных используется только один бит, а не тип char, имеющий 8 биты доступны.
Также в C это обычно int, и это может вызвать потерю точности предупреждений другим кодом, который использует int.
Thomas Bonini
Если вы не оптимизируете пространство вручную, всегда лучше использовать аппаратный нормальный размер слова (например, обычно an int), поскольку на некоторых архитектурах вы получаете значительное снижение производительности от необходимости распаковывать / маскировать проверки этих переменных.
Кингсли
2
Вы можете использовать _Bool, но возвращаемое значение должно быть целым числом (1 для true, 0 для false). Тем не менее, рекомендуется включать и использовать BOOL как в C ++, как сказано в
этом ответе от daniweb форума , а также этот ответ , от этого другого StackOverflow вопрос:
_Bool: логический тип C99. Использование _Bool напрямую рекомендуется только в том случае, если вы поддерживаете устаревший код, который уже определяет макросы для bool, true или false. В противном случае эти макросы стандартизированы в заголовке. Включите этот заголовок, и вы можете использовать bool, как в C ++.
Условные выражения считаются истинными, если они ненулевые, но стандарт C требует, чтобы сами логические операторы возвращали либо 0, либо 1.
@Tom: #define TRUE! FALSE - это плохо и совершенно бессмысленно. Если заголовочный файл попадает в скомпилированный код C ++, то это может привести к проблемам:
void foo(bool flag);...int flag = TRUE;
foo(flag);
Некоторые компиляторы генерируют предупреждение о преобразовании int => bool. Иногда люди избегают этого, делая:
foo(flag == TRUE);
заставить выражение быть C ++ bool. Но если вы #define TRUE! FALSE, вы получите:
foo(flag ==!0);
который заканчивает тем, что делает сравнение типа int-to-bool, которое в любом случае может вызвать предупреждение.
Если вы используете C99, то вы можете использовать _Boolтип. Нет #includeнеобходимости. Вы должны рассматривать это как целое число, хотя, где 1есть trueи 0есть false.
Затем вы можете определить TRUEи FALSE.
_Bool this_is_a_Boolean_var =1;//or using it with true and false#define TRUE 1#define FALSE 0_Bool var = TRUE;
НЕ макрос должен быть защищен в скобках argи выражение в целом: #define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE). Тем не менее, было бы лучше проверить на ложность (это даст правильный ответ, даже если argбыло 23 вместо 0 или 1:. #define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)Но все выражение можно уменьшить до #define NOT(arg) (!(arg)), конечно, что дает тот же результат.
Ответы:
От лучшего к худшему:
Вариант 1 (С99)
Вариант 2
Вариант 3
Вариант 4
объяснение
Если вы не определились, идите с # 1!
источник
<stdbool.h>
bool
компилятором могут быть более подходящими для предполагаемого назначения логического значения, чем использованиеint
(то есть компилятор может выбрать реализацию,bool
отличную отint
). Это также может привести к более строгой проверке типов во время компиляции, если вам повезет.int
дляbool
? Это расточительно. Использованиеunsigned char
. Или используйте встроенный Си_Bool
.Несколько мыслей о логических значениях в C:
Я достаточно
int
взрослый , чтобы просто использовать простой s в качестве моего логического типа без каких-либо определений типов, специальных определений или перечислений для значений true / false. Если вы последуете моему предложению никогда не сравнивать с булевыми константами, тогда вам все равно нужно будет использовать 0/1 для инициализации флагов. Однако такой подход может считаться слишком реакционным в эти современные времена. В этом случае, безусловно, следует использовать,<stdbool.h>
поскольку он, по крайней мере, имеет преимущество от стандартизации.Какие бы логические константы ни назывались, используйте их только для инициализации. Никогда не пиши что-то вроде
Они всегда могут быть заменены на более четкие
Обратите внимание, что они могут быть разумно и понятно прочитаны вслух.
Дайте вашим логическим переменным положительные имена, т.е.
full
вместоnotfull
. Последнее приводит к коду, который трудно прочитать легко. сравнитьс
Обе первые пары читают естественно, хотя
!notfull
читать неловко, как есть, и становится намного хуже в более сложных логических выражениях.Обычно следует избегать логических аргументов. Рассмотрим функцию, определенную следующим образом
В теле функции очень ясно, что означает аргумент, поскольку он имеет удобное и, мы надеемся, содержательное имя. Но сайты вызова выглядят так
Здесь, по сути, невозможно сказать, что имел в виду параметр, не всегда просматривая определение или объявление функции, и становится намного хуже, как только вы добавляете еще больше логических параметров. Я предлагаю либо
или
В любом случае сайт вызова теперь выглядит так
что у читателя есть хотя бы шанс понять, не углубляясь в определение
foo
.источник
a == b
работает?a
и считаяb
с нуля, я бы рекомендовалa > 0 == b > 0
вместо этого. Если вы настаиваете на использовании правдивости произвольных ненулевых значений,!!var
выдает логическое значение 0/1, эквивалентноеvar
, так что вы можете написать!!a == !!b
, хотя многие читатели сочтут это запутанным.!a == !b
также достаточно для проверки равенства, ненули становятся равными нулю, а нули равны единице.!!a
как «преобразовать небулево a в его эквивалентное значение истинности», тогда как я бы прочитал!a
как «логически инвертировать логическую переменную a». В частности, я бы искал по какой-то конкретной причине, что логическая инверсия была желательна.Логическое значение в C является целым числом: ноль для false и ненулевое значение для true.
См. Также логический тип данных , раздел C, C ++, Objective-C, AWK .
источник
Вот версия, которую я использовал:
Поскольку ложь имеет только одно значение, но логическое истина может иметь много значений, но метод устанавливает истину так, чтобы компилятор использовал ее в противоположность ложному.
Это решает проблему того, что кто-то кодирует что-то, что сводится к следующему:
Я думаю, что мы все согласны с тем, что это не очень хорошая практика, но за единовременную стоимость выполнения операции «true =! False» мы устраняем эту проблему.
[РЕДАКТИРОВАТЬ] В конце концов я использовал:
чтобы избежать конфликта имен с другими определяющими схемами
true
иfalse
. Но концепция остается прежней.[EDIT] Чтобы показать преобразование целого числа в логическое значение:
Первый (самый правый)! преобразует ненулевое целое число в 0, затем второе (самое левое)! преобразует 0 в
myfalse
значение. Я оставлю читателю в качестве упражнения преобразование нулевого целого числа.[РЕДАКТИРОВАТЬ] Мой стиль заключается в использовании явной установки значения в перечислении, когда требуется конкретное значение, даже если значение по умолчанию будет таким же. Пример: поскольку false должно быть равно нулю, я использую,
false = 0,
а неfalse,
источник
true
,false
иbool
выделяются в большинстве IDE, потому что они являются значениями перечислений и ЬурейеЕ, в отличие от#defines
, которые редко когда - либо подсветки синтаксиса.gcc -ansi -pedantic -Wall
выдает предупреждений, поэтому я верюgcc
; Если это работает даже дляc89
этого, должно работать наc99
aswell.!
может только возвращать значения0
и1
, таким образомtrue = !false
, всегда будет присваивать значение 1. Этот метод не дает никакой дополнительной безопасностиtypedef enum { false, true } bool;
.if(!value)
), но это исключение не применимо в данном конкретном случае.Если вы используете компилятор C99, он имеет встроенную поддержку типов bool:
http://en.wikipedia.org/wiki/Boolean_data_type
источник
Обо всем по порядку. C, то есть ISO / IEC 9899 имеет логический тип уже 19 лет . Это намного больше времени, чем ожидаемая продолжительность карьеры программиста на Си с любительскими / академическими / профессиональными частями, объединенными при посещении этого вопроса . Моя превосходит это всего лишь на 1-2 года. Это означает, что в то время , когда среднестатистический читатель вообще что-то узнал о C, C фактически имел логический тип данных .
Для типа данных,
#include <stdbool.h>
и использоватьtrue
,false
иbool
. Или не включать его и использовать_Bool
,1
и0
вместо этого.В других ответах на эту тему представлены различные опасные методы. Я обращусь к ним:
Это нет-нет, потому что случайный читатель - который изучил C в течение этих 19 лет - ожидал, что это
bool
относится к фактическомуbool
типу данных и будет вести себя аналогично, но это не так! НапримерС C99
bool
/_Bool
,b
было бы установлено,false
если быa
был ноль, и вtrue
противном случае. C11 6.3.1.2p1При наличии на
typedef
месте значениеdouble
будет приведено кint
- если значение double не находится в диапазоне дляint
, поведение не определено .Естественно, то же самое относится, если
true
иfalse
были объявлены вenum
.Что еще опаснее, так это декларировать
поскольку теперь все значения, кроме 1 и 0, являются недопустимыми, и если такое значение будет присвоено переменной этого типа, поведение будет полностью неопределенным .
Поэтому, если вы не можете использовать C99 по какой-то необъяснимой причине, для логических переменных вы должны использовать:
int
и значения0
и1
как есть ; и тщательно делайте доменные преобразования из любых других значений в них с двойным отрицанием!!
BOOL
,TRUE
иFALSE
!источник
int
илиunsigned int
для хранения перечисления, но я не знаю ничего в Стандарте, которое могло бы привести к тому, что перечисление будет вести себя как что-то отличное от целого числа тип.источник
!0 = 1
по стандарту C, и!a = 0
для любого ненулевого значенияa
. Проблема в том, что любое ненулевое значение считается истинным. Таким образом, еслиa
иb
оба являются «истиной», это не обязательно тот случай, когда `a == b`.C имеет логический тип: bool (по крайней мере, за последние 10 (!) Лет)
Включите stdbool.h, и true / false будет работать как положено.
источник
bool
должен быть макросом, который расширяется до_Bool
. Разница имеет значение, потому что вы можете#undef
макрос (и это разрешено, по крайней мере, в качестве переходной меры), но вы не можетеuntypedef
typedef. Это не меняет основную направленность вашего первого комментария.bool
сквозной<stdbool.h>
компиляцией под Си. Это решает до_Bool
.Все, что не равно нулю, оценивается как истинное в логических операциях, так что вы можете просто
и использовать константы.
источник
Просто дополнение к другим ответам и некоторым разъяснениям, если вам разрешено использовать C99.
Некоторые из моих предпочтений:
_Bool
илиbool
? Оба в порядке, ноbool
выглядит лучше, чем ключевое слово_Bool
.bool
и_Bool
:false
илиtrue
. Назначение0
или1
вместоfalse
илиtrue
является действительным, но сложнее для чтения и понимания логического потока.Некоторая информация из стандарта:
_Bool
НЕunsigned int
, но является частью группы целочисленных типов без знака . Он достаточно большой, чтобы содержать значения0
или1
.bool
true
и,false
конечно, не очень хорошая идея. Эта способность считается устаревшей и будет удалена в будущем._Bool
илиbool
, если скалярное значение равно0
или сравнивает0
это будет0
, в противном случае результат1
:_Bool x = 9;
9
преобразуется в ,1
когда назначенx
._Bool
1 байт (8 бит), обычно у программиста возникает соблазн попытаться использовать другие биты, но это не рекомендуется, поскольку гарантируется только то, что для хранения данных используется только один бит, а не типchar
, имеющий 8 биты доступны.источник
Вот это:
источник
Вы можете использовать символ или другой контейнер с небольшим числом для него.
Псевдо-код
источник
int
), поскольку на некоторых архитектурах вы получаете значительное снижение производительности от необходимости распаковывать / маскировать проверки этих переменных.Вы можете использовать _Bool, но возвращаемое значение должно быть целым числом (1 для true, 0 для false). Тем не менее, рекомендуется включать и использовать BOOL как в C ++, как сказано в этом ответе от daniweb форума , а также этот ответ , от этого другого StackOverflow вопрос:
источник
Условные выражения считаются истинными, если они ненулевые, но стандарт C требует, чтобы сами логические операторы возвращали либо 0, либо 1.
@Tom: #define TRUE! FALSE - это плохо и совершенно бессмысленно. Если заголовочный файл попадает в скомпилированный код C ++, то это может привести к проблемам:
Некоторые компиляторы генерируют предупреждение о преобразовании int => bool. Иногда люди избегают этого, делая:
заставить выражение быть C ++ bool. Но если вы #define TRUE! FALSE, вы получите:
который заканчивает тем, что делает сравнение типа int-to-bool, которое в любом случае может вызвать предупреждение.
источник
Если вы используете C99, то вы можете использовать
_Bool
тип. Нет#include
необходимости. Вы должны рассматривать это как целое число, хотя, где1
естьtrue
и0
естьfalse
.Затем вы можете определить
TRUE
иFALSE
.источник
#include <stdbool.h>
и использоватьbool
,true
иfalse
как стандарт хочет, чтобы вы.В настоящее время C99 поддерживает логические типы, но вам нужно
#include <stdbool.h>
.Пример:
Вывод:
источник
Это то, что я использую:
_Bool
является встроенным типом в C. Он предназначен для логических значений.источник
Вы можете просто использовать
#define
директиву следующим образом:И использовать следующим образом:
и так далее
источник
arg
и выражение в целом:#define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE)
. Тем не менее, было бы лучше проверить на ложность (это даст правильный ответ, даже еслиarg
было 23 вместо 0 или 1:.#define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)
Но все выражение можно уменьшить до#define NOT(arg) (!(arg))
, конечно, что дает тот же результат.