utilizzando int
è più corretto dal punto di vista logico per indicizzare una matrice.
unsigned
semantico in C e C++ non significa "non negativo" ma è più simile a "maschera di bit" o "intero modulo".
Per comprendere il motivo per cui unsigned
non è un buon tipo per un numero "non negativo" perche
- Aggiunta di un intero possibilmente negativo ad un intero non negativo si ottiene un intero non negativo
- la differenza di due numeri interi non negativi è sempre un numero intero non negativo
- Moltiplicando un intero non negativo per un numero intero negativo si ottiene un risultato non negativo
Ovviamente nessuna delle frasi sopra ha senso ... ma è come C e C++ unsigned
semantico funziona davvero.
Utilizzare effettivamente un tipo unsigned
per la dimensione dei contenitori è un errore di progettazione di C++ e purtroppo ora siamo condannati a utilizzare questa scelta errata per sempre (per compatibilità con le versioni precedenti). Potrebbe piacerti il nome "unsigned" perché è simile a "non-negative" ma il nome è irrilevante e ciò che conta è il semantico ... e unsigned
è molto lontano da "non-negativo".
Per questo motivo quando codifica maggior anelli su vettori mia forma personalmente preferito è:
for (int i=0,n=v.size(); i<n; i++) {
...
}
(ovviamente assumendo la dimensione del vettore non cambia durante l'iterazione e che ho effettivamente bisogno l'indice nella corpo come altrimenti il for (auto& x : v)...
è migliore).
Questo allontanamento da unsigned
appena possibile e l'utilizzo di numeri interi semplici ha il vantaggio di evitare le trap che sono una conseguenza dell'errore di progettazione unsigned size_t
. Ad esempio si consideri:
// draw lines connecting the dots
for (size_t i=0; i<pts.size()-1; i++) {
drawLine(pts[i], pts[i+1]);
}
il codice sopra avrà problemi se il vettore pts
è vuoto perchè pts.size()-1
è un numero enorme dialogo in quel caso. Trattare con espressioni in cui lo a < b-1
non è lo stesso di a+1 < b
anche per valori comunemente usati è come ballare in un campo minato.
Storicamente la giustificazione per avere size_t
non firmato è per poter utilizzare il bit extra per i valori, ad es. essere in grado di avere 65535 elementi negli array anziché solo 32767 su piattaforme a 16 bit. A mio parere, anche in quel momento il costo extra di questa scelta semantica sbagliata non valeva il guadagno (e se 32767 elementi non sono sufficienti ora 65535 non sarà comunque sufficiente per molto tempo).
I valori non firmati sono grandi e molto utili, ma NON per rappresentare la dimensione del contenitore o per gli indici; per dimensioni e indice gli interi con segno regolare funzionano molto meglio perché la semantica è ciò che ti aspetteresti.
I valori senza segno sono il tipo ideale quando è necessaria la proprietà aritmetica modulo o quando si desidera lavorare a livello di bit.
È meno da scrivere. – slartibartfast
Inoltre: più leggibile – Alex
È come mai non chiami altre persone con il nome e il cognome per tutto il tempo, ma semplicemente chiamali con il loro nome? – user482594