Operatore Virgola in C++
- L'operatore
sizeofrestituisce la dimensione, in byte, di un'espressione o di un nome di tipo. sizeofè associativo a destra e restituisce un'espressione costante di tiposize_t.sizeofnon valuta il suo operando, rendendolo sicuro da usare con puntatori non validi.- La dimensione restituita da
sizeofdipende dal tipo coinvolto, comechar, puntatori, array e tipi di classe. sizeofdi un array restituisce la dimensione totale dell'array, non convertendolo in un puntatore.- Il risultato di
sizeofpuò essere utilizzato per specificare la dimensione di un array.
Operatore Virgola
L'operatore virgola prende due operandi, che valuta da sinistra a destra. Come l'AND logico e l'OR logico e l'operatore condizionale, l'operatore virgola garantisce l'ordine in cui i suoi operandi vengono valutati.
L'espressione a sinistra viene valutata e il suo risultato viene scartato. Il risultato di un'espressione virgola è il valore del suo operando destro. Il risultato è un l-value se l'operando destro è un l-value.
Un uso comune per l'operatore virgola è in un ciclo for:
vector<int>::size_type cnt = ivec.size();
// assegna valori da size ... 1 agli elementi in ivec
for(vector<int>::size_type ix = 0;
ix != ivec.size(); ++ix, --cnt)
ivec[ix] = cnt;
Questo ciclo incrementa ix e decrementa cnt nell'espressione nell'intestazione del for. Sia ix che cnt vengono modificati ad ogni iterazione del ciclo. Finché il test di ix ha successo, impostiamo l'elemento corrente al valore corrente di cnt.
Esercizi
-
Il programma di sopra ha usato gli operatori di incremento e decremento prefissi. Spiega perché abbiamo usato il prefisso e non il postfisso. Quali cambiamenti dovrebbero essere fatti per usare le versioni postfisse? Riscrivi il programma usando operatori postfissi.
Soluzione:
Per capire meglio come funziona il programma di sopra, possiamo riscriverlo usando un ciclo
while:vector<int>::size_type cnt = ivec.size(); // assegna valori da size ... 1 agli elementi in ivec // Inizializzazione vector<int>::size_type ix = 0; while(ix != ivec.size()) { ivec[ix] = cnt; ++ix, --cnt; }Come si può osservare, in questo caso l'uso dell'operatore prefisso è completamente indifferente. Infatti, possiamo riscrivere l'ultima riga del ciclo
whilecome segue:ix++, cnt--;In entrambi i casi, il risultato dell'operatore virgola è il valore di
cnt--o--cnt, che viene scartato. Quindi, in questo caso, non c'è differenza tra l'uso del prefisso o del postfisso. Tuttavia, l'uso del prefisso è generalmente preferito quando non è necessario il valore precedente, poiché può essere più efficiente per i tipi di dati complessi. -
Spiega il seguente ciclo.
constexpr int size = 5; int ia[size] = {1,2,3,4,5}; for (int *ptr = ia, ix = 0; ix != size && ptr != ia+size; ++ix, ++ptr) { /* *...* */ }Soluzione:
Questo ciclo
forutilizza due variabili di controllo: un puntatoreptrche inizia all'inizio dell'arrayia, e un indiceixche inizia da 0. La condizione del ciclo verifica cheixsia diverso dasize(5) e cheptrnon abbia raggiunto la fine dell'array (ia + size). Ad ogni iterazione, entrambiixeptrvengono incrementati. Questo permette di iterare attraverso l'arrayia, conptrche punta all'elemento corrente eixche tiene traccia dell'indice corrente. -
Usando la tabella degli operatori spiega cosa fa la seguente espressione:
valore ? ++x, ++y : --x, --ySoluzione:
La precedenza degli operatori determina l'ordine in cui le operazioni vengono eseguite in un'espressione. In questo caso, l'operatore condizionale
? :ha una precedenza più alta rispetto all'operatore virgola,. Quindi, l'espressione viene valutata come:valore ? (++x, ++y) : (--x, --y)Se
valoreè vero, vengono eseguiti++xe++y, incrementando entrambixeye viene restituito il valore di++y. Sevaloreè falso, vengono eseguiti--xe--y, decrementando entrambixeye viene restituito il valore di--y. In entrambi i casi, l'operatore virgola consente di eseguire due operazioni in sequenza, ma solo il risultato dell'ultima operazione viene restituito come risultato dell'intera espressione condizionale.