Perché (position <size) è un modello così diffuso nei condizionali?


9

In una dichiarazione di condizione (IF) tutti usano (position < size), ma perché?
Solo una convenzione o c'è una buona ragione per questo?

Trovato in natura:

if (pos < array.length) {
   // do some with array[pos];
}

Raramente trovato:

if (array.length > pos) {
   // do some with array[pos];
}

7
Un caso in cui non mi dispiace avere la "variabile" sulla destra è if (MIN <= x && x <= MAX). (In alcune lingue questo può essere scritto come MIN <= x <= MAX; in C, è perfettamente legale ma non significa che cosa potresti pensare che significhi).
Keith Thompson,


5
Potrebbe essere correlato al modo in cui gli intervalli sono scritti [min, max]e non [max, min]. Pertanto, è naturale verificare che un elemento xappartenga all'intervallo scrivendo min <= x <= max.
Andres F.

Che confusione.
Tulains Córdova,

Il secondo esempio può essere ulteriormente chiarito come se (! (Array.lengh <= pos)) ...
OldFart

Risposte:


48

Il modello più profondo è che usiamo naturalmente "[cosa che varia] [confronto] [cosa che non varia]" come ordine standard. Questo principio vale per il tuo esempio perché la posizione può variare, mentre la dimensione no.

L'unica eccezione comune è quando testano l'uguaglianza alcuni programmatori si allenano per usare l'ordine opposto (noto come condizioni di Yoda ) al fine di evitare il comune variable = constantpiuttosto che il variable == constantbug. soprattutto molto più leggibile, principalmente perché è il modo in cui esprimiamo l'idea in inglese e perché la maggior parte dei compilatori moderni lo rileverà e emetterà un avviso.


3
A seconda degli strumenti di sviluppo, molti avvertiranno (o errori) il variable = constantcostrutto.
GalacticCowboy

5
+1. Cerca "Condizioni Yoda" per maggiori dettagli sul constant == variablefenomeno.
John M Gant,

Di recente ho visto la stessa cosa nella mia base di codice (ad esempio, if(DBNull == row["fieldName"]) methodCall()e mi chiedevo se stavo impazzendo perché la maggior parte delle volte l'ho visto fare il contrario
Andrew Gray

1
Vorrei anche aggiungere che (position < size)spesso esprime un limite superiore, quindi in effetti è parte lowerbound <= position < upperboundrestante di , con la dimensione come limite superiore. Con i due vincoli espliciti, il positionpuò andare solo nel mezzo.
Steve314,

4
Probabilmente è legato al linguaggio; analizziamo " operatore X Y " come " X è ( operatore Y )", come il rapporto è un tratto di X . Chiedendo il confronto, ci chiediamo se X ha un valore buono o cattivo (e Y è localmente trattato come una costante). Chiedere "pos <array.length" è come chiedere: "La posizione è ok (più piccola della lunghezza dell'array)?" Se no, qualcosa non va nella posizione; dammi un'altra posizione, e sarei felice di fare quello che volevi. Ma non c'è nulla di sbagliato nella lunghezza dell'array. Chiedere "array.length> pos" sembra che dovremmo aumentare l'array se è troppo corto.

14

L'unica giustificazione che io abbia mai visto è che è come linee di numeri o altre cose ordinanti che abbiamo imparato a scuola. Ad esempio, scriviamo righe di numeri come questa:

<--|--|--|--|--|--|-->
   1  2  3  4  5  6

Le cose più piccole appaiono a sinistra delle cose più grandi. Lo stesso vale per altre cose come le date (pensa a come è organizzato un calendario).

Fondamentalmente si riduce a come naturalmente pensiamo all'ordine delle cose. È più facile leggere il primo modulo perché non è necessario eseguire molta elaborazione mentale su di esso.


1
Vuoi dire che l'espressione che valuta il valore più piccolo viene prima nella condizione? Come puoi essere sicuro che sarà vero se i valori cambiano un runtime?
Tulains Córdova,

@ user61852 Non è necessario sapere quali sono i valori in fase di esecuzione. Es: ho 2 valori che calcolo al valore di runtime A e valueB e voglio testare che valueA sia minore di valueB. Scriverei "if (valueA <valueB)". Se il valore A finisce per essere inferiore al valore B è irrilevante. È più facile (almeno per me) guardarlo e sapere che sto cercando quando valueA è più piccolo di valueB. Se dovessi vedere "if (valueB> valueA)", dovrei fermarmi e pensare a quale sia la cosa più piccola quando seguirò questo ramo di codice.
Becuzz,

1
Ho capito male. Ho votato verso il basso la risposta. Ora voglio votare, ma il sito richiede che la risposta sia modificata in modo da poter cambiare il mio voto. Per favore, fai qualche modifica in modo che io possa votare.
Tulains Córdova,

@ user61852 Dovresti essere in grado di cambiare il tuo voto ora.
Becuzz,

11

Sebbene sia principalmente una questione di convenzioni, è mia opinione che ciò corrisponda al modo in cui pensiamo - mostra l'elemento su cui poniamo l'accento.

Se li traduciamo in inglese, sarebbe la frase "Se la posizione è inferiore alla lunghezza dell'array", dove l'oggetto della frase è l'elemento transitorio.

Per esprimerlo in altro modo, "se la lunghezza della matrice è maggiore della posizione" inserisce la lunghezza della matrice (presumibilmente un valore fisso) nel soggetto e la posizione (transitoria) diventa l'oggetto diretto.


3
In realtà (nell'ultima frase) la posizione diventa l'oggetto di una preposizione. Ma sono d'accordo con quello che stai cercando di dire. In linguistica diremmo che la posizione è l' argomento e che " commento è meno della lunghezza dell'array" . "La tendenza a posizionare i componenti attualizzati inizialmente a frase (argomento) è molto diffusa." en.wikipedia.org/wiki/…
LarsH

4

La mia opinione, e questa è solo la mia opinione, è che è una convenzione per la leggibilità. Sebbene i due siano identici, si sentono diversi nel mio cervello. Non voglio sapere se la dimensione dell'array è maggiore di pos. Voglio sapere se pos è più piccolo delle dimensioni dell'array.

È come una discussione semivuota contro mezza piena. Matematicamente identico, ma il mio cervello li vedrà in modo diverso a seconda del contesto.

Personalmente, se vedo

if (array.lengh > pos) {
    // do some with array[pos];
}

Inizierò a pensare se si tratta o meno di un bug e del significato del programmatore. Sta cercando di fare qualcosa di diverso dal controllo dei limiti?

Forse non sono brillante, ma se devo fare quel tipo di analisi su ogni riga di codice, il mio cervello fa male.


3

Per esprimere ciò che alcuni hanno cercato di ottenere, in un modo diverso ...

Quando l'ordine non fa alcuna differenza nel comportamento del programma, la differenza è chiaramente una questione di ciò che è più leggibile per l'uomo. Ecco un motivo linguistico per cui ha senso mettere "l'argomento" a sinistra:

In linguistica, l' argomento di una frase è ciò di cui si parla, e il commento è ciò che viene detto sull'argomento. In questo esempio, possiamo supporre che positionsia l' argomento e " commento di lunghezza inferiore all'array" è il commento . In inglese e in molte altre lingue, l'argomento viene solitamente espresso prima del commento.
" La tendenza a posizionare i componenti attualizzati inizialmente a frase (argomento) è molto diffusa. "

Quindi, una buona regola generale è quella di pensare alla vostra linea di codice come una frase (o di una clausola, in questo caso), decidere che cosa la frase è su , e mettere quel primo, se è possibile. Spesso, ciò che la frase è "circa" sarà una variabile piuttosto che una costante. Ma a volte il commento coinvolgerà anche una variabile, quindi non puoi limitarti a farlo.


1

È una combinazione di due cose, entrambe provenienti dall'assemblatore sottostante in cui sono state compilate le prime lingue (e anche molte di quelle attuali).

  1. Le matrici sono offset a base zero in memoria (ovvero il primo blocco di dati è all'inizio del blocco di memoria allocato ... l'indice 0). Da qui l'uso di 0..n-1 per il pezzo variabile.

  2. La diramazione se un valore è inferiore a un altro valore (o registro, ecc.) È in genere una singola istruzione. Da qui l'uso dell'operatore less-than (<) semplice.

Quindi, il modello è passato da un vecchio assemblatore ad ANSI-C (che in qualche modo è più simile ad un assemblatore di macro) e da lì a Java e agli altri linguaggi simili a C.


0

Come hanno già detto molte altre risposte, molto spesso è più facile da leggere:

[thing that varies] [comparison] [thing that does not vary]

Quasi tutti quelli che conosco usano questo stile esclusivamente.

C'è un'eccezione, per i linguaggi in stile C che usano =per l'assegnazione e ==per il confronto. Se si digita accidentalmente:

if (variable = 5) ...

invece di:

if (variable == 5) ...

quindi non verrà visualizzato un errore perché si tratta di una riga di codice valida. (Alcuni compilatori e IDE ti avvertiranno di farlo, ma è ancora molto facile avere un errore di battitura così semplice.)

Tuttavia, se scrivi:

if (5 == variable) ...

il compilatore / interprete commetterà un errore perché non è un costrutto valido (nella maggior parte delle lingue, comunque).

Questo passaggio viene spesso chiamato Condizione Yoda .

AGGIORNAMENTO : ecco un elenco di luoghi in cui le condizioni di Yoda sono utili .


-1

Personalmente, preferisco questo:

bool positionIsWithinBounds = pos < array.length;
if (positionIsWithinBounds) {
   // do some with array[pos];
}

... è più codice, ma è anche molto facile da leggere.


4
+1 per dare un nome al confronto. In realtà, però, mi piace questo approccio meglio per i condizionali più complessi, e non tanto per casi semplici come questo. In realtà mi fa smettere di pensare a "array", "limiti", "dentro" e cosa significano tutti, quando istintivamente so cosa significa posessere > array.length. In altre parole, anche se rende molto chiaro il significato del condizionale, in realtà rende un po 'più difficile leggere l'IMO.
John M Gant,

Ancora un altro nome per tenere traccia di ...
Deduplicator,

-1

È una questione di preferenza o di convenzione. Se vuoi essere coerente, ci sono due modi ugualmente ragionevoli per farlo:

  1. Metti sempre prima il "soggetto" (pensalo come una frase) - il valore su cui si basa il test. Quindi, per esempio, scriverestiif (age>5)

  2. O metti sempre prima l'elemento più piccolo (pensalo come i valori sono ordinati sullo schermo nell'ordine naturale). Quindi, per esempio, scriveresti if (a<b)indipendentemente dal fatto che questo codice riguardi principalmente a o principalmente su b.

Entrambe le convenzioni raccomanderebbero il primo frammento che hai mostrato invece del secondo, quindi immagino che in questo caso particolare tu abbia la tua risposta. Direi che è saggio evitare di scrivere codice che viola entrambi (1) e (2) qui, poiché renderà più difficile la lettura per la maggior parte delle persone.

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.