2010-04-12 18 views
35
vector<int> l; 
for(int i=1;i<=10;i++){ 
    l.push_back(i); 
} 

Ora, per esempio, come faccio a cambiare la 5th element del vettore per -1?Come cambiare un particolare elemento di uno STL vettore C++

Ho provato l.assign(4, -1); Non si comporta come previsto. Nessuno degli altri metodi vettoriali sembra adattarsi.

Ho utilizzato il vettore in quanto ho bisogno di funzionalità di accesso casuale nel mio codice (utilizzando l.at(i)).

+8

Qualsiasi problema con l [4] = -1; Oppure l.at (4) = -1, se preferisci. –

risposta

85

at e operator[] entrambi restituiscono un riferimento all'elemento indicizzato, in modo da poter utilizzare semplicemente:

l.at(4) = -1; 

o

l[4] = -1; 
+9

E faresti meglio a prendere l'abitudine di usare "a", meno idiomatico, ma il controllo dei limiti non ha prezzo. –

+2

@Matt: anche se gli errori fuori dai limiti tendono ad essere un errore del programmatore, mentre "at" lancia un'eccezione. Vale a dire, un 'assert' sarebbe meglio, e penso che sia MSVC che gcc abbiano controllato gli iteratori. – GManNickG

+0

@GMan Personalmente, ho più o meno smesso di usare assert. Tendo ad usare a() in situazioni in cui potrei fare un errore di codifica (ad esempio, non ne userei uno in un ciclo for) - qualcosa che ho la stessa probabilità di fare quando scrivo un assert. –

6

Questo dovrebbe farlo:

l[4] = -1 
5

È possibile utilizzare subscript operator

l[4] = -1 
+1

Ciao Tom, puoi dire come ottenere ciò per i vettori 2D, come "vettore > VC" o "vettore VC (100,100)". –

7

Anche se @JamesMcNellis risposta è uno valido vorrei spiegare qualcosa sulla gestione degli errori e anche il fatto che c'è un altro modo di fare ciò che si vuole.

Ci sono tre modi di accesso a un elemento specifico in un vettore:

  • Utilizzando la [] operatore
  • Utilizzando la funzione di membro at(...)
  • Utilizzando un iteratore in combinazione con un dato di offset

Negli esempi seguenti utilizzerò il seguente vettore come topo da laboratorio:

static const int arr[] = {1, 2, 3, 4}; 
std::vector<int> v(arr, arr+sizeof(arr)/sizeof(arr[0])); 

Questo crea un vettore come si vede qui sotto:

1 2 3 4 

prima cosa diamo un'occhiata al [] modo di fare le cose. Funziona più o meno nello stesso modo in cui ti aspetti lavorando con un array normale. Si fornisce un indice e possibilmente si accede all'elemento desiderato. Dico possibilmente perché l'operatore [] non controlla se il vettore contiene effettivamente molti elementi. Ciò porta a un accesso non valido alla memoria non valida. Esempio:

v[10] = 9; 

Ciò può causare o non causare un arresto anomalo istantaneo. Il caso peggiore è ovviamente se non lo fa e in effetti ottieni quello che sembra essere un valore valido. Analogamente agli array, questo potrebbe portare a perdite di tempo nel tentativo di trovare il motivo per cui 1000 righe di codice in un secondo momento otterrete il valore di 100 anziché 234, che è in qualche modo collegato a quella stessa posizione in cui si recupera un elemento dal proprio vettore.

Un modo molto migliore è utilizzare at(...). Verificherà automaticamente il comportamento out of bounds e interromperà il lancio di un numero std::out_of_range. Quindi, nel caso in cui abbiamo

v.at(10) = 9; 

Avremo:

Termina chiamata dopo aver lanciato un caso di 'std :: out_of_range'
cosa(): vector :: _ M_range_check: __n (che è 10)> = this-> dimensioni() (che è 4)

il terzo modo è simile al [] operatore nel senso che è possibile avvitare le cose. Un vettore come un array è una sequenza di blocchi di memoria continua contenenti dati dello stesso tipo. Ciò significa che è possibile utilizzare l'indirizzo di partenza assegnandolo a un iteratore e quindi aggiungere un offset a questo iteratore. L'offset semplicemente l'acronimo di quanti elementi dopo il primo elemento da attraversare:

std::vector<int>::iterator it = v.begin(); // First element of your vector 
*(it+0) = 9; // offest = 0 basically means accessing v.begin() 
// Now we have 9 2 3 4 instead of 1 2 3 4 
*(it+1) = -1; // offset = 1 means first item of v plus an additional one 
// Now we have 9 -1 3 4 instead of 9 2 3 4 
// ... 

Come potete vedere possiamo anche fare

*(it+10) = 9; 

che è ancora un accesso alla memoria non valida. Questo è fondamentalmente lo stesso di usare at(0 + offset) ma senza il controllo degli errori fuori dai limiti.

Suggerirei di utilizzare at(...) quando possibile non solo perché è più leggibile rispetto all'accesso iteratore ma a causa del controllo degli errori per l'indice non valido che ho menzionato sopra per l'iteratore con la combinazione di offset e l'operatore [].


EDIT: ho dimenticato il std::for_each dal algorithm intestazione della libreria standard C++. Questo è un altro modo che posso raccomandare (usa internamente un iteratore). Puoi leggere ulteriori informazioni al riguardo, ad esempio here.

Problemi correlati