Dovrei usare le parentesi nelle istruzioni logiche anche dove non sono necessarie?


100

Diciamo che ho una condizione booleana a AND b OR c AND de sto usando una lingua in cui il precedente ANDè un ordine di funzionamento superiore OR. Potrei scrivere questa riga di codice:

If (a AND b) OR (c AND d) Then ...

Ma in realtà, questo equivale a:

If a AND b OR c AND d Then ...

Ci sono argomenti a favore o contro tra cui le parentesi estranee? L'esperienza pratica suggerisce che vale la pena includerli per la leggibilità? O è un segno che uno sviluppatore deve davvero sedersi e diventare fiducioso nelle basi della loro lingua?


90
Potrei essere pigro, ma preferisco avere parentesi nella maggior parte di tali situazioni per leggibilità.
Thorsten Müller,

6
Anch'io. Spero solo di farlo di più per leggibilità e meno perché sono troppo pigro per diventare fiducioso / competente nelle basi della mia lingua.
Jeff Bridgman,

16
Un buon uso delle parentesi è come un buon uso della grammatica. 2 * 3 + 2potrebbe essere lo stesso di (2 * 3) + 2ma il secondo è più facile da leggere.
Reactgular,

16
@Mathew Forse se sei debole in matematica. Per i casi più complessi, utilizzare le parentesi. Ma per quelli palesemente ovvi (BODMAS ...) riducono la leggibilità più che aiutarla a causa del disordine.
Konrad Rudolph,

3
Detto questo, la stessa precedenza di AND / OR vale in Basic, Python, SQL ... la mia impressione è che questa sia la regola nella stragrande maggioranza dei linguaggi moderni (anche se non tutti).
Tim Goodman,

Risposte:


118

I buoni sviluppatori si sforzano di scrivere codice che sia chiaro e corretto . Le parentesi nei condizionali, anche se non sono strettamente necessarie, aiutano con entrambi.

Per quanto riguarda la chiarezza , pensa alle parentesi come ai commenti nel codice: non sono strettamente necessari e in teoria uno sviluppatore competente dovrebbe essere in grado di capire il codice senza di loro. Eppure, questi suggerimenti sono estremamente utili, perché:

  • Riducono il lavoro richiesto per comprendere il codice.
  • Forniscono la conferma dell'intenzione dello sviluppatore.

Inoltre, parentesi extra, proprio come rientri, spazi bianchi e altri standard di stile, aiutano a organizzare visivamente il codice in modo logico.

Per quanto riguarda la correttezza , le condizioni senza parentesi sono una ricetta per errori sciocchi. Quando accadono, possono essere bug difficili da trovare, perché spesso una condizione errata si comporterà correttamente per la maggior parte del tempo e solo occasionalmente fallirà.

E anche se hai capito bene, la persona successiva a lavorare sul tuo codice potrebbe non farlo, aggiungendo errori all'espressione o fraintendendo la tua logica e quindi aggiungendo errori altrove (come giustamente sottolinea LarsH).

Uso sempre le parentesi per le espressioni che combinano ande or(e anche per le operazioni aritmetiche con problemi di precedenza simili).


3
Anche se, ho sentito dire che i commenti sono scuse (per codice cattivo / difficile da leggere) ... c'è una buona possibilità che tu possa averlo scritto meglio. Immagino che potresti dire cose simili sulle parentesi.
Jeff Bridgman,

6
Un altro aspetto della correttezza è preservarlo attraverso i cambiamenti: mentre lo sviluppatore originale può avere la precedenza giusta senza parentesi quando scrive il codice per la prima volta con lo scopo e il contesto in mente, lui (o un altro) che viene dopo e non ricorda tutto i dettagli possono anche rovinarlo quando aggiungono più termini all'espressione. (Ciò era per lo più implicito già, ma mi sembrava che valesse la pena sottolineare.)
LarsH

1
@LarsH, grazie, l'ho aggiunto esplicitamente alla risposta.

8
+1 "Forniscono la conferma dell'intenzione dello sviluppatore." - qualsiasi programmatore (OK, forse non tutti, ma tutti quelli che risiedono qui ....) possono capire cosa farà il compilatore con la logica più complessa. Assolutamente nessuno può capire cosa intendesse lo sviluppatore originale (incluso se stesso) qualche settimana lungo la strada per qualcosa di oltre il più semplice .....
mattnz

2
Penso che @JeffBridgman si riferisse a un punto di vista abbastanza noto di "i commenti a volte possono essere un odore di codice". Ad esempio, vedere il riepilogo di Jeff Atwood che include la domanda "È possibile effettuare il refactoring del codice in modo che i commenti non siano richiesti?". Direi che se il tuo commento spiega perché il tuo codice è così dannatamente non intuitivo, può sicuramente essere un indizio che qualcosa non va. In momenti come questo, è una buona idea semplificare il codice. Sono completamente d'accordo con la tua vera risposta e, comunque, assumo parentesi.
Daniel B

94

Poco importa se sei sicuro della tua padronanza della lingua. Ciò che conta di più è la comprensione del linguaggio dell'n00b che ti segue.

Scrivi il tuo codice nel modo più chiaro e inequivocabile possibile. Le parentesi extra spesso (ma non sempre) aiutano. Mettere solo una frase su una riga spesso aiuta. La coerenza nello stile di programmazione spesso aiuta.

Esistono troppe parentesi, ma è una di quelle situazioni in cui non avrai bisogno di consigli: lo saprai quando la vedrai. A quel punto refactoring il codice per ridurre la complessità dell'istruzione anziché rimuovere la parentesi.


72
Non dimenticare che anche se sei uno sviluppatore solista quando sei malato, stanco o hai a che fare con il codice che hai scritto l'anno scorso; il tuo livello di comprensione è ridotto a quello di un n00b.
Dan Neely,

30
There is such a thing as too many parenthesis- ovviamente non sei un lisper;)
paul

18
È un cattivo consiglio: non scrivere per nessuno. Ciò ridurrà la qualità del tuo codice (considerevolmente) perché non puoi usare modi di dire ben consolidati che vanno oltre i primi due capitoli di un libro per principianti.
Konrad Rudolph,

10
@KonradRudolph: forse è così, ma non scrivere per gli unici ragazzi che conoscono l'Arte della Programmazione Computer dalla copertina alla copertina, o essere preparati a dover eseguire il debug del loro codice in seguito, e non avere la minima idea del perché hai fatto le cose in quel modo . Il codice viene letto molto più di quanto sia scritto.
haylem,

15
@dodgethesteamroller: ho visto troppi sviluppatori competenti / rispettati introdurre bug di precedenza (tutti hanno una brutta giornata di tanto in tanto) che rimangono inosservati per anni. Per i buoni sviluppatori che conoscono le regole di precedenza, il rischio di errori / errori di battitura non rilevati è troppo elevato. Per tutti gli altri il rischio è più alto. I migliori sviluppatori sono gli sviluppatori che ricordavano le regole di precedenza del linguaggio, ma le hanno dimenticate a causa dell'uso abituale della parentesi per qualcosa di non ovvio.
Brendan,

32

Dovresti sempre usare le parentesi ... non controlli l'ordine di precedenza ... fa lo sviluppatore del compilatore. Ecco una storia che mi è successa sul non uso delle parentesi. Ciò ha interessato centinaia di persone in un periodo di due settimane.

La ragione del mondo reale

Ho ereditato un'applicazione del frame principale. Un giorno, di punto in bianco, ha smesso di funzionare. È tutto ... ma è appena finito.

Il mio compito era farlo funzionare il più velocemente possibile. Il codice sorgente non era stato modificato per due anni, ma all'improvviso si è fermato. Ho provato a compilare il codice e si è rotto sulla linea XX. Ho guardato la linea XX e non riuscivo a capire cosa avrebbe interrotto la linea XX. Ho chiesto le specifiche dettagliate per questa applicazione e non ce ne sono state. La linea XX non era il colpevole.

Ho stampato il codice e ho iniziato a esaminarlo dall'alto verso il basso. Ho iniziato a creare un diagramma di flusso di ciò che stava succedendo. Il codice era così contorto che non riuscivo nemmeno a capirlo. Ho rinunciato a provare a disegnarlo. Avevo paura di apportare modifiche senza sapere come avrebbe influito sul resto del processo, soprattutto perché non avevo dettagli su cosa facesse l'applicazione o su dove si trovasse nella catena delle dipendenze.

Quindi, ho deciso di iniziare nella parte superiore del codice sorgente e aggiungere whitespce e freni di linea per rendere il codice più leggibile. Ho notato, in alcuni casi, che c'erano delle condizioni che si combinavano ANDe ORche non era chiaramente distinguibile tra quali dati venivano modificati ANDe quali dati venivano modificati OR. Così ho iniziato a mettere tra parentesi le condizioni ANDe ORper renderle più leggibili.

Mentre procedevo lentamente pulendola, salvavo periodicamente il mio lavoro. A un certo punto ho provato a compilare il codice e una cosa strana è accaduta. L'errore era passato oltre la riga di codice originale e ora era più in basso. Così ho continuato, speparando le condizioni ANDe ORcon le parentesi. Quando ho finito di pulirlo ha funzionato. Vai a capire.

Ho quindi deciso di visitare il negozio operativo e chiedere loro se avevano recentemente installato nuovi componenti sul telaio principale. Hanno detto di sì, abbiamo recentemente aggiornato il compilatore. Hmmmm.

Si scopre che il vecchio compilatore ha valutato l'espressione da sinistra a destra, indipendentemente. La nuova versione del compilatore ha anche valutato le espressioni da sinistra a destra ma il codice ambiguo, il che significa che la combinazione poco chiara di ANDe ORnon poteva essere risolta.

Lezione che ho imparato da questo ... SEMPRE, SEMPRE, SEMPRE usare i genitori per separare le ANDcondizioni e le ORcondizioni quando vengono usati in congiunzione tra loro.

Esempio semplificato

IF Product = 191 OR Product = 193 AND Model = "ABC" OR Product = 201 OR Product = 202 AND Model = "DEF" ...(codice disseminato di molti di questi)

Questa è una versione semplificata di ciò che ho incontrato. Vi erano anche altre condizioni con le dichiarazioni logiche booleane composte.

Ricordo di averlo insegnato a:
IF ((Product = 191 OR Product = 193) AND Model = "ABC") OR ((Product = 201 OR Product = 202) AND Model = "DEF") ...



Non ho potuto riscriverlo perché non c'erano specifiche. L'autore originale era scomparso da tempo. Ricordo un'intensa pressione. Un'intera nave mercantile rimase bloccata in porto e non poté essere scaricata perché questo piccolo programma non funzionava. Nessun avvertimento Nessuna modifica al codice sorgente. Mi è venuto in mente di chiedere alle Operazioni di rete se hanno modificato qualcosa dopo che ho notato che l'aggiunta di parentesi ha spostato gli errori.


22
Sembra un'illustrazione migliore del perché è importante avere un buon compilatore.
Ruakh,

6
@CapeCodGunny: Sono sicuro che non l'hai fatto. Ma il problema qui è che hai avuto un cattivo fornitore di compilatore che ha apportato un cambiamento radicale. Non vedo come hai imparato una lezione su "SEMPRE, SEMPRE, SEMPRE" aggirare quel problema, anche quando si usano compilatori migliori.
Ruakh,

5
@ruakh - No, il fornitore ha semplicemente cambiato il proprio parser di codice. Sono vecchia scuola, non faccio affidamento sulla mia capacità di ricordare ogni sistema in cui sono stato codificato o in cui sono stato coinvolto. Senza documentazione tutto ciò che hai è il codice sorgente. Quando il codice sorgente è difficile da leggere e seguire crea una situazione estremamente stressante. I programmatori che non usano gli spazi bianchi probabilmente non hanno mai avuto a che fare con una situazione come quella che ho dovuto affrontare. Ho anche imparato che ha più senso scrivere codice come: Vedi Dick; Vedi Jane; Vedi Dick AND Jane; Dichiarazioni semplici che sono facili da leggere ... commentare ... e seguire.
Michael Riley - AKA Gunny l'

2
Grande storia, ma concordo sul fatto che non è un motivo per usare le parentesi. e / o la precedenza è quasi universale e circa la cosa meno probabile da cambiare che si possa pensare. Se non puoi fare affidamento su un comportamento coerente per un'operazione di base così standard, il tuo compilatore è spazzatura e non hai problemi, qualunque cosa tu faccia. La tua storia è al 100% un problema al compilatore e allo 0% un problema al codice. Soprattutto dato che il comportamento predefinito era una semplice valutazione da sinistra a destra - l'ordine sarebbe sempre chiaro, quindi perché qualcuno dovrebbe usare le parentesi?

7
Penso che ci siano lezioni apprese qui su entrambi i lati ... Stai molto meglio usando le parentesi soprattutto quando l'alternativa si basa sul comportamento non documentato di un compilatore rispetto al codice ambiguo . E se il programmatore non sa quali espressioni sono ambigue, meglio usare le parentesi. D'altra parte, è pericoloso cambiare il comportamento di un compilatore, ma almeno ha generato un errore nei casi in cui il comportamento è cambiato. Sarebbe stato peggio se il compilatore non avesse generato un errore, ma avesse iniziato a compilare diversamente. L'errore ti ha protetto da bug inosservati.
LarsH,

18

Sì, se ci sono misti "e" e "o".

Anche una buona idea di () cosa è logicamente un controllo.

Anche se la cosa migliore è usare funzioni predicate ben denominate e sfrattare la maggior parte dei controlli e delle condizioni lì, lasciando se semplice e leggibile.


6
È vero, c'è una buona probabilità che a AND bprobabilmente debba essere sostituito con una funzione o un valore boolen precalcolato che abbia un nome più descrittivo.
Jeff Bridgman,

14

Le parentesi sono semanticamente ridondanti, quindi al compilatore non importa, ma si tratta di un'aringa rossa: la vera preoccupazione è la leggibilità e la comprensione del programmatore.

Prenderò la posizione radicale qui e darò un "no" alle parentesi a AND b OR c AND d. Ogni programmatore dovrebbe sapere a memoria che la precedenza nelle espressioni booleane NON è AND> E> OR , proprio come ricordare Please Excuse My Dear Aunt Sally per le espressioni algebriche. La punteggiatura ridondante aggiunge solo disordine visivo la maggior parte delle volte nel codice senza alcun vantaggio nella leggibilità del programmatore.

Inoltre, se usi sempre le parentesi nelle espressioni logiche e algebriche, allora rinunci alla possibilità di usarle come marker per "qualcosa di complicato sta accadendo qui - guarda fuori!" Cioè, nei casi in cui si desidera sovrascrivere la precedenza predefinita e fare valutare l'aggiunta prima della moltiplicazione, o OR prima di AND, le parentesi sono una bella bandiera rossa per il programmatore successivo. Troppo uso di loro quando non sono necessari, e tu diventi il ​​ragazzo che piangeva lupo.

Vorrei fare un'eccezione per qualsiasi cosa al di fuori del regno dell'algebra (booleana o no), come le espressioni puntatore in C, dove qualcosa di più complicato degli idiomi standard come *p++o p = p->nextprobabilmente dovrebbe essere tra parentesi per mantenere il dereferenziamento e l'aritmetica. E, naturalmente, nulla di tutto ciò si applica a lingue come Lisp, Forth o Smalltalk che usano una qualche forma di notazione polacca per le espressioni; ma per la maggior parte dei linguaggi tradizionali, la precedenza logica e aritmetica sono totalmente standardizzate.


1
+1, le parentesi per chiarezza vanno bene, ma ANDvs ORè un caso abbastanza semplice che vorrei che gli altri sviluppatori della mia squadra sapessero. Temo che a volte "usare le parentesi per chiarezza" significhi davvero "usare le parentesi, quindi non devo mai preoccuparmi di imparare la precedenza".
Tim Goodman,

1
In tutte le lingue con cui lavoro regolarmente è .memberprima di operatori unari, unari prima di operatori binari, *e /prima +e -prima <e >e ==prima di &&prima di ||prima assegnazione. Queste regole sono facili da ricordare perché corrispondono al mio "buon senso" su come vengono normalmente utilizzati gli operatori (ad esempio, non daresti ==maggiore precedenza +o 1 + 1 == 2smetti di funzionare) e coprono il 95% delle domande di precedenza che avrei avuto .
Tim Goodman,

4
@TimGoodman Sì, esattamente, entrambi i tuoi commenti. Gli altri intervistati qui sembrano pensare che sia una domanda in bianco o nero: utilizzare le parentesi tutto il tempo, senza eccezioni, o volare con noncuranza dal sedile dei pantaloni attraverso un mare di regole arbitrarie e impossibili da ricordare, il codice che ribolle con potenziali bug difficili da individuare. (Metafore miste molto intenzionali.) Ovviamente il modo giusto è la moderazione; la chiarezza del codice è importante, ma lo è anche la conoscenza dei tuoi strumenti e dovresti essere in grado di aspettarti una certa minima comprensione della programmazione e dei principi CS dai tuoi compagni di squadra.
dodgethesteamroller,

8

Per come la vedo:

Pro:

  • L'ordine delle operazioni è esplicito.
  • Ti protegge dai futuri sviluppatori che non comprendono l'ordine delle operazioni.

Contro:

  • Può risultare in codice ingombrante, difficile da leggere

NO Pro:

  • ?

NO contro:

  • L'ordine delle operazioni è implicito
  • Il codice è meno gestibile per gli sviluppatori senza una buona comprensione dell'ordine delle operazioni.

Ben detto, anche se penso che "Può risultare in codice ingombrante, difficile da leggere" è piuttosto soggettivo.
FrustratedWithFormsDesigner l'

2
In che modo rendere esplicita la semantica del tuo codice rende difficile la lettura?
Mason Wheeler,

1
Sono d'accordo con gli altri nel mettere in discussione il tuo "Sì Contro". Penso che sia quasi sempre il contrario.

@Frustrato soggettivo come l'affermazione opposta. Significa, per niente, davvero. Difficile da misurare.
Konrad Rudolph,

1
@MasonWheeler: Mentre sono d'accordo sul fatto che i parens espliciti sono molto importanti in molti casi, posso vedere come si può esagerare nel rendere esplicita la semantica. Trovo 3 * a^2 + 2 * b^2più facile da leggere rispetto a (3 * (a^2)) + (2 * (b^2)), perché il formato e la precedenza sono familiari e standard. Allo stesso modo, potresti (per essere estremo) vietare l'uso di funzioni e macro (o compilatori!) Al fine di rendere più esplicita la semantica del tuo codice. Ovviamente non lo sto sostenendo, ma spero di rispondere alla tua domanda sul perché ci siano limiti (un equilibrio) nel rendere esplicite le cose.
LarsH,

3

Ci sono argomenti a favore o contro tra cui le parentesi estranee? L'esperienza pratica suggerisce che vale la pena includerli per la leggibilità? O è un segno che uno sviluppatore deve davvero sedersi e diventare fiducioso nelle basi della loro lingua?

Se nessun altro dovesse mai rivedere il mio codice, non credo che mi importerebbe.

Ma, dalla mia esperienza:

  • Guardo di nuovo il mio codice di tanto in tanto (a volte anni dopo averlo scritto)
  • Altri a volte guardano il mio codice
    • O addirittura devi espanderlo / ripararlo!
  • Né me stesso né l'altro ricordiamo esattamente cosa stavo pensando quando lo scrissi
  • Scrivere codice criptico "minimizza il conteggio dei caratteri" danneggia la leggibilità

Lo faccio quasi sempre perché mi fido della mia capacità di leggere rapidamente e di non commettere piccoli errori molto più con i genitori che altro.

Nel tuo caso, farei quasi sicuramente qualcosa del tipo:

if (a AND b) then ab = true
if (c AND d) then cd = true
If (ab OR cd) Then ...

Sì, è più codice. Sì, invece posso fare fantastici operatori bool. No, non mi piace la possibilità di sfogliare il codice 1+ anni in futuro, fraintendo gli operatori di bool fantasia. E se stavo scrivendo codice in una lingua con precedenza AND / OR diversa e dovessi tornare indietro per risolvere il problema? Ho intenzione di dire "aha! Ricordo questa piccola cosa intelligente che ho fatto! Non ho dovuto includere le parentesi quando ho scritto l'anno scorso, buona cosa che ricordo adesso!" se ciò accade (o peggio, qualcun altro che non era a conoscenza di questa intelligenza o era stato gettato in una situazione di tipo "aggiusta al più presto")?

Separare con () rende molto più semplice scorrere rapidamente e capire in seguito ...


7
Se hai intenzione di farlo, perché no ab = a AND b?
Eric,

1
Forse perché abrimarrà invariato in caso contrario a AND b.
Armali,

3

Caso generale

In C #, la moltiplicazione e la divisione hanno la precedenza su addizione e sottrazione.

Tuttavia, StyleCop, uno strumento che impone uno stile comune in tutta la base di codice con un ulteriore obiettivo per mitigare il rischio di bug introdotti dal codice che potrebbe non essere abbastanza chiaro, ha la regola SA1407 . Questa regola produrrà un avviso con un pezzo di codice come questo:

var a = 1 + 2 * 3;

È chiaro che il risultato è 7e non 9, ma comunque, StyleCop suggerisce di mettere tra parentesi:

var a = 1 + (2 * 3);

Il tuo caso particolare

Nel tuo caso particolare, esiste una precedenza di AND rispetto a OR nella lingua specifica che usi.

Non è così che si comportano tutte le lingue. Molti altri trattano allo stesso modo AND e OR.

Come sviluppatore che lavora principalmente con C #, quando ho visto la tua domanda per la prima volta e ho letto il pezzo di codice senza leggere quello che hai scritto prima, la mia prima tentazione è stata quella di commentare che le due espressioni non sono uguali. Spero di aver letto l'intera domanda prima di commentare.

Questa particolarità e il rischio che alcuni sviluppatori possano ritenere che AND e OR abbiano la stessa priorità rendono ancora più importante aggiungere parentesi.

Non scrivere codice con l'obiettivo di dimostrare che sei intelligente. Scrivi codice con un obiettivo di leggibilità, anche da parte di persone che potrebbero non avere familiarità con ogni aspetto del linguaggio.


1
"Questo è molto raro": Secondo Stroustrup2013, C ++ 11 sembra avere una diversa precedenza di AND e OR (p. 257). Lo stesso vale
Dirk,

10
Ri: "Ogni lingua che conosco tratta AND e OR ugualmente": dubito che sia vero. Se è vero, allora non conosci nessuna delle dieci lingue più popolari (C, Java, C ++, PHP, JavaScript, Python, C #, Perl, SQL e Ruby) e non sei in grado di commentare ciò che è "non comune", figuriamoci "molto raro".
Ruakh,

1
Sono d'accordo con ruakh e ho cercato C ++ 11, Python, Matlab e Java.
Dirk,

3
Le lingue in cui AND e OR sono operatori binari e che non considerano AND con una precedenza più alta di OR, sono una merda intrecciata i cui autori sono frammenti di informatica. Questo deriva dalla notazione logica. Ciao, "somma dei prodotti" non significa nulla? Esiste persino una notazione booleana che utilizza la moltiplicazione (giustapposizione di fattori) per AND e il simbolo + per OR.
Kaz,

3
@ruakh Mi hai appena fatto notare. Perché ci sono una manciata di casi limite patologici non significa che non dovresti imparare la precedenza booleana standard e assumere che valga fino a prova contraria. Non stiamo parlando di decisioni di progettazione arbitrarie qui; L'algebra booleana è stata inventata molto prima dei computer. Inoltre, mostrami le specifiche Pascal di cui stai parlando. Qui e qui mostrano E prima dell'OR.
dodgethesteamroller,

1

Come tutti hanno detto, usa le parentesi ogni volta che rende l'espressione più leggibile. Tuttavia, se l'espressione è complicata, consiglierei di introdurre nuove funzioni per le sottoespressioni .


0

O è un segno che uno sviluppatore deve davvero sedersi e diventare fiducioso nelle basi della loro lingua?

Se usi rigorosamente la lingua al singolare, forse. Ora prendi tutte le lingue che conosci, dai vecchi ai più moderni, dalla compilazione allo scripting a SQL al tuo DSL che hai inventato il mese scorso.

Ti ricordi le regole di precedenza esatte per ciascuna di queste lingue, senza guardare?


1
E come ha notato @Cape Cod Gunny sopra, anche se pensi di conoscere la lingua fredda, il compilatore / tempo di esecuzione potrebbe cambiare sotto di te.
Giordania,

0

"Dovrei usare le parentesi nelle istruzioni logiche anche dove non è necessario."

Sì, perché due persone li troveranno utili:

  • Il prossimo programmatore, che ha conoscenza, competenza o stile può essere diverso

  • Il futuro tu che ritorni a questo codice in un secondo momento!


-1

I condizionali complessi sono "algebra booleana", che scrivi in ​​un modo che, beh, lo fa sembrare praticamente esattamente algebra, e useresti sicuramente le parentesi per l' algebra , vero?

Le regole davvero utili sono quelle di negazione:

!(A || B) <=> !A && !B
!(A && B) <=> !A || !B

Oppure, in un formato un po 'più chiaro:

!(A + B) <=> !A * !B
!(A * B) <=> !A + !B

che è in realtà in modo chiaro solo l'algebra quando scritto come:

-1*(A + B) = -A + -B
-1*(A * B) = -A * -B

Ma possiamo anche applicare il pensiero per la semplificazione e l'espansione algebrica:

(A && B) || (C && D) => 
((A && B) || C) && ((A && B) || D) => 
(AC && BC) && (AD && BD) =>
AC && BC && AD && BD

anche se nel codice devi scrivere:

(A||C) && (B||C) && (A||D) && (B||D)

o, in un formato un po 'più chiaro:

(A + B) * (C + D) => 
((A + B) * C) + ((A + B) * D) => 
(AC + BC) + (AD + BD) =>
AC + BC + AD + BD

Fondamentalmente, un condizionale è ancora solo un'espressione algebrica e, usando chiaramente la parentesi, è possibile applicare più facilmente le varie regole algebriche che già conosci all'espressione, incluso il vecchio concetto di "semplificare o espandere questa formula".


2
Non sono sicuro che tu stia effettivamente rispondendo alla domanda, poiché porti la tua risposta con un presupposto che non è necessariamente vero. Userei le parentesi per l'algebra? Non tutto il tempo. Se aiuta con la leggibilità, certamente, ma altri l'hanno già espresso qui. E l'espansione dell'algebra matematica in altre forme non ha esattamente una corrispondenza individuale con la programmazione: cosa succede se si controlla lo stato di alcuni valori di stringa?
Derek,

Se l'algebra booleana corrispondente è abbastanza complicata da giustificare le parentesi, il tuo condizionale dovrebbe probabilmente usare le parentesi. Se è abbastanza semplice non giustificare i genitori, o non è necessario o non si dovrebbe. Ad ogni modo, pensarlo come faresti con un'espressione matematica probabilmente chiarisce il problema.
Narfanator,

I miei esempi sopra usano due e quattro booleani. Se stai controllando lo stato di due o più valori di stringa, esegue il mapping. Ogni controllo corrisponde a una variabile booleana; indipendentemente dal fatto che tale controllo sia uguale a intero o stringa; inclusione di stringhe, array o hash; un'espressione complessa stessa ... Non importa; tutto ciò che conta è che hai più di una misura di vero / falso nella tua espressione.
Narfanator,

2
Basta fare i difficili, ma in !(A + B) <=> !A + !Be -1*(A + B) = -A + -Bnon dovrebbe l'operatore è stato capovolto dalla +a *alla seconda espressione?
Jeff Bridgman,

-1

Userò la parentesi anche se è facoltativa, perché aiuta a capire meglio per tutti, per chi scrive il codice e per chi è pronto a vederlo. Nel tuo caso anche gli operatori booleani hanno la precedenza che all'inizio potrebbe funzionare bene, ma non possiamo dire che ti aiuterà in ogni caso. quindi preferisco utilizzare la parentesi dell'utente in qualsiasi condizione che possa richiederla o facoltativamente.


-1

Sì. Dovresti usare in ogni caso quando ritieni che il tuo codice sarà più chiaro. Ricorda che il tuo codice dovrebbe essere abbastanza chiaro in modo che gli altri possano capire senza leggere i tuoi commenti all'interno del codice. Quindi è una buona pratica usare parentesi e parentesi graffe. Inoltre, tieni presente che potrebbe dipendere dalla particolare pratica della tua azienda / squadra. Mantenere solo un approccio e non mescolare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.