Относительно логического типа в C
Булевый тип был введен довольно поздно в языке C, в 1999 году. До этого C не имел булева типа, а вместо этого использовался intдля всех булевых выражений. Поэтому все логические операторы, такие как > == !etc, возвращают intзначение 1или 0.
В приложениях было принято использовать домашние типы, такие как typedef enum { FALSE, TRUE } BOOL;, который также сводится к intтипам.
C ++ имел гораздо лучший и явный логический тип bool, который был не больше 1 байта. В то время как в худшем случае логические типы или выражения в C будут иметь размер 4 байта. Некоторый способ совместимости с C ++ был введен в C со стандартом C99. Затем C получил логический тип, _Boolа также заголовок stdbool.h.
stdbool.hобеспечивает некоторую совместимость с C ++. Этот заголовок определяет макрос bool(то же самое, что и ключевое слово C ++), который расширяется до _Boolтипа, представляющего собой небольшой целочисленный тип, вероятно, размером 1 байт. Точно так же заголовок обеспечивает два макроса trueи то falseже самое написание, что и ключевые слова C ++, но с обратной совместимостью со старыми программами на Си . Поэтому trueи falseрасширяются до 1и 0в С и их тип есть int. Эти макросы на самом деле не имеют логического типа, как соответствующие ключевые слова C ++.
Точно так же в целях обратной совместимости логические операторы в C все еще возвращают значение intпо сей день, хотя C в настоящее время получил логический тип. В то время как в C ++ логические операторы возвращают bool. Таким образом, выражение, такое как sizeof(a == b)даст размер intв C, но размер boolв C ++.
По поводу условного оператора ?:
Условный оператор ?:- это странный оператор с несколькими причудами. Это распространенная ошибка, полагать, что это на 100% эквивалентно if() { } else {}. Не совсем.
Между оценкой 1-го и 2-го или 3-го операнда существует точка последовательности. ?:Оператор гарантированно только оценить либо 2 - го или 3 - го операнда, поэтому он не может выполнить какие - либо побочные эффекты операнда, не оценивается. Код вроде true? func1() : func2()не будет выполняться func2(). Все идет нормально.
Однако существует специальное правило, согласно которому 2-й и 3-й операнд должны быть неявно продвинуты по типу и сбалансированы друг с другом с помощью обычных арифметических преобразований . ( Неявные правила продвижения типов в C объяснены здесь ). Это означает, что 2-й или 3-й операнд всегда будет по крайней мере таким же большим, как и int.
Таким образом, это не имеет значения, trueи false, как оказалось, имеет тип intв C, потому что выражение всегда будет давать по крайней мере размер, intневажно.
Даже если вы перепишите выражение, оно все равно вернет размер !sizeof(a ? (bool)true : (bool)false) int
Это из-за неявного продвижения типов посредством обычных арифметических преобразований.
sizeof(true)аsizeof(false)также 4: ide.geeksforgeeks.org/O5jvuN