Когда я, например, пишу 7>1
в C (скажем, C99, если это не всегда была функция), могу ли я ожидать, что результат будет ровно 1 или просто отличным от нуля? Поддерживается ли это для всех операторов bool?
Является ли "истинный" результат из>, <,!, &&, || или == определено?
Ответ 1
В C99 §6.5.8 Реляционные операторы, пункт 6 (<
, >
, <=
и >=
):
Каждый из операторов < (меньше), > (больше), <= (меньше или равно) и >= (больше или равно) должно давать 1, если указанное отношение истинно и 0, если оно ложно) Результат имеет тип int.
Как и для операторов равенства, это немного больше в § 6.5.9 (==
и !=
):
Операторы == (равные) и!= (не равные) аналогичны реляционным операторов, за исключением их более низкого приоритета). Каждый из операторов дает 1, если указанное отношение истинно и 0, если оно ложно. Результат имеет тип int. Для любой пары операндов, верно одно из отношений.
Логическое И и логическое ИЛИ еще немного в разделе 6.5.13 (&&
)
& & оператор должен давать 1, если оба его операнда сравниваются не равными 0; в противном случае дает 0. Результат имеет тип int.
... и §6.5.14 (||
)
|| оператор должен давать 1, если любой из его операндов сравнивается не равным 0; в противном случае дает 0. Результат имеет тип int.
И семантика унарного арифметического оператора !
завершена в п. 6.5.3.3/4:
Результат оператора логического отрицания! 0, если значение его операнда сравнивается не соответствует 0, 1, если значение его операнда сравнивается с равным 0. Результат имеет тип int. Выражение! E эквивалентно (0 == E).
Тип результата int
по всей доске, с 0
и 1
как возможные значения. (Если я не пропустил некоторые.)
Ответ 2
C следует Postel Law для своих логических операторов: быть консервативным в том, что вы делаете, быть либеральным в том, что вы принимаете от других. Он будет обрабатывать любое ненулевое значение как истинное в булевых выражениях, но оно всегда будет производить либо сам 0, либо 1. 2 != 3
всегда 1
.
Ответ 3
Из стандарта ISO C99, раздел 6.5.8:
6 Каждый из операторов < (меньше), > (больше), <= (меньше, чем или равно), и >= (больше или равно) должно давать 1, если указанное отношение истинно и 0, если оно ложно. В результате тип int.
Из раздела 6.5.9:
3 Операторы == (равно) и!= (не равные) аналогичны реляционные операторы, за исключением их более низкого приоритета. каждый операторов дает 1, если указанное соотношение истинно и 0, если это неверно. Результат имеет тип int. Для любой пары операндов, верно одно из отношений.
То же самое происходит с операторами логического соединения (&&
) и disjunction (||
).
PS: Кстати, именно поэтому побитовые операторы (&
и |
) обычно могут использоваться в качестве короткозамкнутых версий логических операторов.
Ответ 4
Все операторы C, которые дают логически истинные/ложные значения, всегда дают результат типа int
со значением 0
для false, 1
для true.
Это не относится ко всем выражениям C, которые дают логически истинные/ложные значения. Например, функции классификации символов is*()
, объявленные в <ctype.h>
(isdigit()
, isupper()
и т.д.), Возвращают 0
, если условие ложно, но может возвращать любое ненулевое значение, если условие истинно.
Пока вы используете результат непосредственно как условие:
if (isdigit(c)) ...
if (!isdigit(c)) ...
if (isdigit(c) || islower(c)) ...
и не пытайтесь сравнивать его с чем-то:
if (isdigit(c) == 1) ... /* WRONG */
if (isdigit(c) == true) ... /* ALSO WRONG */
это не должно вызывать никаких проблем.
(Вы можете безопасно сравнивать результат с 0
или false
, но для этого нет веских оснований, для чего нужен оператор !
.)