Обладают ли бинарные логические операторы ассоциативностью?

StackOverflow https://stackoverflow.com//questions/20053030

Вопрос

Является a && b && c определяется языком как означает (a && b) && c или a && (b && c)?

Ух ты, Джерри был быстр.Чтобы усилить вопрос:действительно ли это имеет значение?Будет ли заметна разница между a && b && c интерпретируется как (a && b) && c или a && (b && c)?

Это было полезно?

Решение

§5.14 / 1: «Группы операторов && Оператора слева направо. [...] В отличие от &, && гарантии влево вправо Оценка: Второй операнд не оценивается, если первый операнд ложный. "

Как к тому, когда или как это имеет значение: я не уверен, что это действительно делает для встроенных типов.Это возможно, однако, перегружать его таким образом, чтобы это было бы дело.Например:

#include <iostream>

class A;

class M {
    int x;
public:
    M(int x) : x(x) {}
    M &operator&&(M const &r); 
    M &operator&&(A const &r); 
    friend class A;
};

class A {
    int x;
    public:
    A(int x) : x(x) {}
    A &operator&&(M const &r); 
    A &operator&&(A const &r);
    operator int() { return x;}
    friend class M;
};

M & M::operator&&(M const &r) {
    x *= r.x;
    return *this;
}

M & M::operator&&(A const &r) {
    x *= r.x;
    return *this;
}

A &A::operator&&(M const &r) {
    x += r.x;
    return *this;
}

A &A::operator&&(A const &r) {
    x += r.x;
    return *this;
}

int main() {
    A a(2), b(3);
    M c(4);

    std::cout << ((a && b) && c) << "\n";
    std::cout << (a && (b && c)) << "\n";
}
.

Результат:

9
16
.

Предостережение: это только показывает, как он может быть сделан в вопросе.Я не Особенно рекомендую, чтобы кто-нибудь сделать это, только показывая, что если вы хотите достаточно плохо, вы можете создать ситуацию, в которой это имеет значение.

Другие советы

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

Следовательно, математик описал бы их как левоассоциативные, например
a && b && c(a && b) && c, потому что для математика это означает a и b рассматриваются в первую очередь.Однако в педагогических целях было бы полезно написать a && (b && c) вместо этого, чтобы подчеркнуть, что ни то , ни другое b ни c будет оценено, если a это ложь.

Круглые скобки в C изменяют порядок вычисления только тогда, когда они переопределяют приоритет.И то , и другое a && (b && c)
и (a && b) && c будет оцениваться как a во-первых, тогда b, тогда c.Аналогично, порядок оценки обоих
a + (b + c) и (a + b) + c является неуказанным.Контраст a + (b * c) против (a + b) * c, где компилятор по - прежнему волен оценивать a, b, и c в любом порядке, но круглые скобки определяют, происходит ли умножение или сложение первым.Также контрастируйте с FORTRAN, где по крайней мере в некоторых случаях выражения, заключенные в скобки, должны быть вычислены первыми.

На самом деле очень важно, чтобы выражение вычисляется слева направо.Это используется для определения короткого замыкания в некоторых выражениях.Вот случай, когда это имеет значение:

vector<vector<int> > a;
if (!a.empty()  && !a[0].empty() && a[0].back() == 3) 
.

Могу поспорить, вы пишете подобные заявления несколько раз в день.И если ассоциативность не была определена, вы были бы в огромных проблемах.

Если a && b ложно, то && c часть никогда не проверяется.Так что да, это имеет значение (по крайней мере, в том смысле, что вам нужно упорядочить операции слева направо). && по своей природе является ассоциативной операцией.

Ассоциативное свойство

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

Поэтому не имеет значения (логически), если вы напишете это как a && (b && c) или (a && b) && c.Оба эквивалентны.Но вы не можете изменить порядок операций (например, a && c && b не эквивалентно a && b && c).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top