2

a [8] - массив булевых элементов. Я пытаюсь вычислить логическое выражение, похожее на следующее.Являются * и + эквивалентными, соответственно, && и || на булевых операндах?

bool a[8]; 
..... 
bool result=a[0]*(a[3]+a[6]*(a[4]+a[7]*a[5]))+a[1]*(a[6]*a[3]+a[4]+a[7]*a[5])+a[2]*(a[5]+a[7]*(a[4]+a[6]*a[3])); 

Выражение длинное, но концептуально ничего сложного. Единственная ошибка, кажется, что результат отличается, когда я заменяю * в выражении & & (в обоих случаях я ожидаю логическое И) или заменяю + на || (ожидая логического ИЛИ).

Я не уверен, какие из них были бы правильными, логические операторы или математические обозначения умножения, добавления и т. Д. Хуже того, ни одна из них не дает никакой ошибки, то есть компилятор доволен обоими. Какой из них безопаснее и правильнее?

+1

@EdHeal: Пожалуйста, напишите ответы в области ответа. –

+0

Приобретено за его исключительную интригующую особенность. – Bathsheba

ответ

8

Это почти то же самое для bool операндов. Но есть тонкие различия:

  1. * и + расширятся аргументы типа в bool для int типов.

  2. Тип выражения a || b является bool, в то время как это a + bint. То же самое для && и *.

  3. * и + не секвенирование точек, тогда как && и || есть.

  4. * и + не закорочены, в то время как && и || есть.

  5. Они занимают очень разные позиции в таблице приоритетов оператора. Таким образом, замена не является простой.

  6. Если a является bool и b также bool, но не инициализирован, то поведение a || b определяется, но a + b является неопределенными поскольку boolможет содержать представление ловушки в C++. Аналогичные выражения могут быть вызваны для && и *.

  7. Очень длинная цепочка a + b + c + ... может переполнять тип int, поведение которого не определено.

(3) означает, что a++ * a++ не определено поведение, но a++ || a++ не является.

(Не важно здесь, но стоит отметить: обратите внимание, что && и || теряют свойство короткого замыкания, если они перегружены).

+0

Так логично, что это не так;) –

+0

Да, «логично» трудно объяснить. Я просто закрепил этот термин. – Bathsheba

+0

Кроме того, переполнение может привести к перевороту от логического 1 до 0. – LogicStuff

5

В дополнение к короткому замыканию в логических операциях, что здесь не имеет значения, решающее значение для объяснения изменений в поведении - operator precedence.

При замене * с && или + с ||, порядок изменения приоритета: * имеет более высокий приоритет, чем+, но && имеет нижний приоритет, чем +. Вот почему вам нужно полностью заключить в скобки свое выражение, чтобы принудительно установить желаемый порядок операций только с заменой * на &&.

Замена обоих * и + с && и || будет поддерживать относительный приоритет двух операторов то же самое, так что вы бы в конечном итоге с тем же результатом.

+0

Упрощенный; Я признаюсь, что украл ваш приоритет, как только попытался, чтобы сделать мой ответ всеобъемлющим. – Bathsheba

+0

Не стесняйтесь брать взаймы и другие мои вопросы в своем ответе: ваши ответы, как правило, оказываются в моем превосходном качестве. – Bathsheba

+0

@ Bathsheba. Ваш ответ объясняет различия в названии вопроса, что более важно в долгосрочной перспективе - для посетителей, которые попадают в поисковый хит. В некотором смысле, я делаю здесь боковую точку, что логические и арифметические операторы не могут использоваться в смешанном режиме. Поскольку это то, что делают OP, этот момент объясняет различия для него. Для остальных, остальные шесть пунктов более актуальны. – dasblinkenlight

Смежные вопросы