Domanda

È a && b && c definito dalla lingua per significare (a && b) && c O a && (b && c)?

Wow, Jerry è stato veloce.Per rinforzare la domanda:ha davvero importanza?Ci sarebbe una differenza osservabile tra a && b && c essere interpretato come (a && b) && c O a && (b && c)?

È stato utile?

Soluzione

§5.14 / 1: "I gruppi di operatori && sono da sinistra a destra. [...] A differenza e, && garantisce da sinistra a destra Valutazione: il secondo operando non viene valutato se il primo operando è falso. "

Per quanto riguarda quando o come conta: non sono sicuro che lo faccia davvero per i tipi incorporati.È possibile, tuttavia, per sovraccaricarlo in un modo che lo renderebbe importante.Ad esempio:

#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";
}
.

Risultato:

9
16
.

Caveat: questo mostra solo come può essere effettuato .Sono non Consigliamo in particolare che qualcuno lo faccia, mostrandolo solo se vuoi abbastanza, puoi creare una situazione in cui fa la differenza.

Altri suggerimenti

IL && E || operatori in cortocircuito:se l'operando di sinistra determina il risultato dell'espressione complessiva, l'operando di destra non verrà nemmeno valutato.

Pertanto, un matematico li descriverebbe come associativi di sinistra, ad es.
a && b && c(a && b) && c, perché per un matematico questo significa a E b vengono considerati per primi.Per scopi pedagogici, però, potrebbe essere utile scrivere a && (b && c) invece, per sottolinearlo nessuno dei due bc verrà valutato se a è falso.

Le parentesi in C cambiano l'ordine di valutazione solo quando eseguono l'override precedenza.Entrambi a && (b && c)
E (a && b) && c sarà valutato come a prima poi b, Poi c.Allo stesso modo, l'ordine di valutazione di entrambi
a + (b + c) E (a + b) + c non è specificato.Contrasto a + (b * c) contro (a + b) * c, dove il compilatore è ancora libero di valutare a, b, E c in qualsiasi ordine, ma le parentesi determinano se avviene prima la moltiplicazione o l'addizione.Contrastare anche con FORTRAN, dove almeno in alcuni casi le espressioni tra parentesi devono essere valutate per prime.

In effetti è molto importante che l'espressione sia calcolata da sinistra a destra.Questo è usato per avere un cortocircuito in alcune espressioni.Ecco un caso in cui importa:

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

Scommetto che scrivi dichiarazioni simili poche volte al giorno.E se l'associatività non è stata definita, saresti in difficoltà enormi.

Se a && b è falso, la porzione && c non viene mai testata.Quindi sì, importa (almeno in quanto è necessario avere le tue operazioni ordinate da sinistra a destra).&& è un'operazione associativa per natura.

Proprietà associativa

.

all'interno di un'espressione contenente due o più occorrenze in una riga di Lo stesso operatore associativo, l'ordine in cui sono le operazioni eseguito non importa finché la sequenza degli operandi è non cambiato.Cioè, riorganizzando le parentesi in tale L'espressione non cambierà il suo valore.

Quindi non importa (logicamente) se lo scrivi come a && (b && c) o (a && b) && c.Entrambi sono equivalenti.Ma non è possibile modificare l'ordine delle operazioni (E.G a && c && b non è equivalente a a && b && c).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top