Является ли "истинный" результат из>, <,!, &&, || или == определено?

Когда я, например, пишу 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, но для этого нет веских оснований, для чего нужен оператор !.)