java — круглые скобки и логические операторы

рассмотрим этот код (C ++):

int x = -4 , y = 5 ;
bool result = x > 0 && y++ < 10 ;

выражение (x> 0) будет вычислено первым, и потому что (x> 0 = false) и из-за оценки короткого замыкания, другое выражение (y ++ < 10) не будет оцениваться и значение у останется 5.

Теперь рассмотрим следующий код:

int x = -4 , y = 5 ;
bool result = (x > 0) && (y++ < 10) ;

Ожидается, что выражения в скобках будут оцениваться в первую очередь, так что перед выполнением логического И выражение (y ++) < 10) была бы оценена и значение у стало 6
, но реальность такова, что значение у остается 5. Это означает, что даже с круглыми скобками оценка закорочена и выражение (y ++ < 10) игнорируется.

Чем объясняется этот случай ?!

4

Решение

Объяснение в вопросе — короткое замыкание.

В C ++ оценка && (а также || в этом отношении) гарантированно будет слева направо, и как только false встречается (соответственно true за ||), оценка гарантированный прекратить.

Похоже на Java.

Скобки в этом случае избыточны и не имеют отношения к делу — они не имеют ничего общего с приоритетом оператора. Это просто связано с тем, как && работает:

На самом деле, две версии

x > 0 && y++ < 10
(x > 0) && (y++ < 10)

эквивалентны, потому что ++ имеет наивысший приоритет, затем <,>, и наконец &&, Педантично, вы должны были написать это как:

(x > 0) && ((y++) < 10)

5.14 Логический оператор И [expr.log.and]

1 && оператор группы слева направо. Оба операнда неявно преобразуются в тип bool (пункт 4). Результат
верно, если оба операнда true а также false иначе. В отличие от &, && гарантирует оценку слева направо: второе
операнд не оценивается, если первый операнд false,
(акцент мой)

10

Другие решения

Когда левая сторона определяет результат, правая сторона не оценивается.

В первом случае правая сторона y++ < 10и это не оценивается. Во втором случае правая сторона (y++ < 10)и это не оценивается.

Нет правила, что выражения в скобках вычисляются первыми. Скобки только групповые операнды.

1

Даже с круглыми скобками должен все еще состоится. Подумайте, есть ли у вас выражение с указателями:

int* ptr = 0;
int bar = 5;
bool result = (ptr != 0) && (*ptr == bar || bar > 10);

Вы явно не можете безопасно оценить правую часть && там, но скобки требуются, чтобы сделать приоритетность работы, как предполагалось. Скобки просто определяют порядок операций которые на самом деле выполняются не то, что они происходят в определенном порядке.

0
По вопросам рекламы [email protected]