2010-12-25 16 views
25

In primer C++, pg 95 l'autore dice che i programmatori C++ tendono a usare! = Preferendo < quando si scrivono i loop.Perché i programmatori C++ usano! = Invece di <

for (vector<int>::size_type i = 0; i != 10; ++i) is preferred instead of 
for (vector<int>::size_type i = 0; i < 10; ++i) 

Ho letto la stessa cosa in C++ accelerato. Qualcuno può spiegare le ragioni alla base di questo

+7

Chiunque scriva il codice sopra deve essere eseguito. Vedi http://blogs.csoonline.com/node/151 – ybungalobill

+2

@ybungalobill: buon articolo, conclusioni errate :) – Kos

+1

@Kos: scherzando :) e ovviamente non è così critico in un ciclo for. – ybungalobill

risposta

42

Quando si utilizzano alcuni tipi di iteratori STL (quelli che non sono ad accesso casuale), è necessario uso !=:

for (map<int,int>::iterator i = a.begin(); i != a.end(); ++i) ... 

Tuttavia, non vedo alcun motivo per preferire != per i tipi scalari ben ordinati come nell'esempio. Di solito preferisco < per i tipi scalari e != per tutti i tipi di iteratore.

+2

Bene, immagino che il motivo sia che tutti i loop di lettura leggano la stessa correzione –

+10

: quando si usano gli iteratori STL, eccetto quelli ad accesso casuale, è necessario usare! =. Quindi nel caso del vettore , zeuxcg

+1

Non è necessario utilizzare '! =' Per tutti gli iteratori STL. Gli iteratori di accesso casuale funzionano altrettanto bene con '<'. – ltjax

31

È un'abitudine per la programmazione generica; ad esempio, è possibile utilizzare facilmente < con indici, ma non è possibile utilizzarlo con tutti i tipi di iteratore. Un iteratore di elenchi non può implementare in modo efficiente < - tuttavia, lo != può essere implementato anche per i tipi di iteratore più semplici. Pertanto, è buona norma utilizzare sempre il confronto più generico: rende il codice più resistente al cambiamento.

8

Perché, in generale, non tutti gli iteratori supportano l'operazione "<". Vedere the manual per operazioni supportate da ciascun tipo di iteratore. Solo gli iteratori di accesso casuale (di cui, i puntatori semplici sono un sottoinsieme) supportano i confronti di disuguaglianza (< e>) tra gli iteratori

7

Il requisito di essere "relazionalmente confrontabili" è molto più forte del requisito di essere "paragonabile" . Quando si tratta di iterare su contenitori, la possibilità di effettuare confronti relazionali tra iteratori o indici generici (come <, >, <= ecc.) È fortemente associata a contenitori ad accesso casuale, mentre i confronti di uguaglianza sono più universalmente applicabili (e spesso il solo quelli disponibili quando si lavora con contenitori ad accesso sequenziale).

In generale, è una buona pratica rendere il codice il più generico possibile, ovvero non dovresti mai fare affidamento su requisiti più forti quando i requisiti più deboli sono perfettamente sufficienti. In altre parole, se è possibile implementare il proprio algoritmo utilizzando solo i confronti di uguaglianza, è meglio farlo in questo modo, senza introdurre alcun confronto relazionale. In questo modo è possibile rendere il proprio algoritmo più utilizzabile con una gamma più ampia di strutture di dati sottostanti (contenitori).

Naturalmente se non ti interessa questo tipo di genericità o semplicemente non ne hai bisogno, puoi semplicemente ignorare queste considerazioni e utilizzare entrambi gli approcci.

+0

+1 per la razionalizzazione su base matematica, in particolare per _ "non dovresti mai fare affidamento su requisiti più forti quando più debole i requisiti sono perfettamente sufficienti "_. – legends2k

7

Se si scrive !=, è possibile invertire l'iterazione del ciclo con modifica minima.

supporti prima di scrittura:

for (int i = m; i != n ; i++) 

Successivamente è invertire tale tendenza:

for (int i = n ; i != m ; i--) 

Non è così attraente, ma ancora richiede meno analisi di "<" e ">".

+0

Tuttavia, il primo ciclo coprirà l'intervallo [m, n) mentre il secondo coprirà (m, n). – ltjax

+0

@itjax: bella cattura, non me ne sono accorto, grazie per averlo indicato :-) – Nawaz

10

Pensate al caso in cui una persona deve incrementare di diciamo 3 invece di 1.

for (vector<int>::size_type i = 0; i != 10; i+=3) 

Questo verrà eseguito sempre dal momento che salterà 10 e andare a 12 invece e incrementare sempre.

for (vector<int>::size_type i = 0; i < 10; i+=3) 

Anche in questo caso funziona bene. Quindi! = Non è sempre una buona scelta.

+6

il primo si fermerà su un computer binario, perché 3 è un generatore del gruppo ℤ/2^nℤ. – ybungalobill

+1

Err .. questo è vero, ma in realtà non risponde alla domanda posta. –

+2

Questo è solo un contro-argomento per l'uso di! = – ismail

0

Forse chi preferisce questo è perché si sono abituati a controllare null, ecc ... quindi il preffer usa lo stesso! = In tutto.

if(x != null) { ... } 

for(int i=0; i != 10; i++) { ... } 

quindi per chi everyting tende ad essere! = O ==

leggere ! = come DIVERSI/Non uguale, seguendo lo stesso principio == è EQUAL ,

Problemi correlati