Lezione 4 Espressioni ed operatori Espressioni e Operatori Lezione 4 ü Un’espressione è formata da una o più operazioni ü Le operazioni sono rappresentate da operandi ed operatori ® ® operatore = simbolo che identifica l’operazione operando = argomento su cui deve essere eseguita l’operazione a + b; ü Gli operatori del C++ sono unari, binari o ternari ®gli operandi di un operatore binario sono distinti in operando sinistro (primo argomento dell’operatore) e operando destro (secondo argomento dell’operatore) Laboratorio di Algoritmi e Strutture Dati 2001 -02 Espressioni 1 Laboratorio di Algoritmi e Strutture Dati 2001/02 1 Lezione 4 Espressioni ed operatori ü La valutazione di un’espressione richiede l’esecuzione di una o più operazioni ® L’ordine in cui vengono considerati gli operatori e gli operandi dipende dalle regole di precedenza e di associatività ü Il risultato dell’espressione è (quasi sempre) un R-value ü Il tipo del risultato dipende dal tipo degli operandi dell’espressione Laboratorio di Algoritmi e Strutture Dati 2001 -02 Valutazione delle Espressioni 2 ü Gli operatori aritmetici sono +, -, *, /, % ü Il tipo del risultato di un’operazione aritmetica è uguale al tipo dell’operando più grande 2 * 3.5 7 / 3; 21 % 3; 21 % 3.5; // risultato è double // risultato è intero (2) // risultato è intero (0) // ERRORE Possono verificarsi errori di eccezione aritmetica ® divisione per 0, underflow, overflow Laboratorio di Algoritmi e Strutture Dati 2001 -02 Operatori Aritmetici 3 Laboratorio di Algoritmi e Strutture Dati 2001/02 2 Lezione 4 Espressioni ed operatori ü Gli operatori logico-relazionali sono >, <, >=, <=, ==, !=, &&, ||, ! ü restituiscono un risultato di tipo vero-falso ® un’espressione è falsa se vale 0, vera altrimenti ü Gli operatori logici vengono valutati da sinistra a destra ® la valutazione termina non appena è stato determinato il valore dell’espressione expr1 || expr2; // expr2 non valutata se expr1 è vera !strcmp(s, t); // equivalente a (strcmp(s, t) == 0) Laboratorio di Algoritmi e Strutture Dati 2001 -02 Operatori Logico-Relazionali 4 Conta quanti elementi di ivec sono minori del valore di soglia #include <vector> int conta(const vector<int>& ivec, int soglia) { int cnt = 0; vector<int>::iterator iter = ivec.begin(); while(iter != ivec.end() ) { cnt = cnt + (*iter < soglia); ++iter; } return cnt; } Laboratorio di Algoritmi e Strutture Dati 2001 -02 Esempio Operatori Relazionali 5 Laboratorio di Algoritmi e Strutture Dati 2001/02 3 Lezione 4 Espressioni ed operatori ü Ci sono situazioni in cui un'operazione è legale solo se alcune precondizioni sono verificate ® Dereferenziazione di un puntatore w solo se il puntatore non è 0 ® Accesso ad un elemento di un array w solo se l'indice è corretto ® Divisione w solo se il divisore è diverso da 0 Laboratorio di Algoritmi e Strutture Dati 2001 -02 Utilizzo dei Controlli di Sentinella – 1 6 ü Se le precondizioni non sono soddisfatte si verifica un comportamento anomalo del programma ü Si possono usare gli operatori logici per effettuare queste operazioni solo se le precondizioni sono verificate int *ptr = 0, i; (ptr) && (i = *ptr); Laboratorio di Algoritmi e Strutture Dati 2001 -02 Utilizzo dei Controlli di Sentinella – 2 7 Laboratorio di Algoritmi e Strutture Dati 2001/02 4 Lezione 4 Espressioni ed operatori ü L’operatore di assegnamento è = ® L'operatore di assegnamento modifica il valore di una variabile (la variabile aveva gia un valore) ® L'operatore di inizializzazione assegna un valore ad una variabile appena creata ü L’operando di destra è un R-value e l’operando di sinistra è un L-value Laboratorio di Algoritmi e Strutture Dati 2001 -02 Operatori di Assegnamento – 1 8 Operatori di Assegnamento – 2 dell’operando destro ü Il tipo dell’assegnamento è il tipo dell’operando sinistro int i, *ip, ia[4] = {0}, j; i = ia[0] + 1; // risultato 1, intero int *ip = &j; *ip = i*2 + ia[i]; // risultato 2, intero Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü Il risultato di un assegnamento è l’R-value 9 Laboratorio di Algoritmi e Strutture Dati 2001/02 5 Lezione 4 Espressioni ed operatori Operatori di Assegnamento possibile concatenare operazioni di assegnamento se tutti gli operandi a cui si devono assegnare valori sono dello stesso tipo int i, j; i = j = 0; int i = j = 0; // CORRETTO // ERRORE ü L’operatore di assegnamento composto permette di compattare la notazione a op= b; ==> a = a op b; ü È possibile comporre Laboratorio di Algoritmi e Strutture Dati 2001 -02 üÈ +, -, *, /, %, &, |, <<, >>, ^ 10 Operatori di Incremento e Decremento ++ , -i++ ===> i = i + 1; i-- ===> i = i - 1; ü Esistono due versioni dello stesso operatore ® ® ++i prima incrementa il valore di e poi lo legge i++ prima legge il valore di i e poi lo incrementa int i = 0, ia[3] = { 0, 1, 2 }; int c = ia[i++]; c = ia[++i]; // c = 0, i = 1 // i = 2, c = ia[2] Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü Gli operatori di incremento e decremento sono 11 Laboratorio di Algoritmi e Strutture Dati 2001/02 6 Lezione 4 Espressioni ed operatori Operatore sizeof un oggetto o di un tipo ® ® Il risultato di un sizeof è di tipo size_t (tipo dipendente dalla macchina definito nell'header file cstddef) Il risultato di un sizeof è una costante sizeof( expr ); // dimensione del tipo di expr sizeof epxr; sizeof( int ); // dimensione di int ü L’operatore sizeof applicato ad un array restituisce il numero di byte occupati dall’array int ia[] = { 0, 1, 2 }; sizeof( ia ) / sizeof( int ); Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü L’operatore sizeof restituisce la dimensione in byte di // il risultato è 3 12 ü L’operatore condizionale (if aritmetico) è l’unico operatore ternario del C++ ü La sintassi è expr1 ? expr2 : expr3; ® se expr1 è vera il risultato è expr2, altrimenti è expr3 Laboratorio di Algoritmi e Strutture Dati 2001 -02 Operatore Condizionale – 1 13 Laboratorio di Algoritmi e Strutture Dati 2001/02 7 Lezione 4 Espressioni ed operatori #include <iostream> main() { // calcola parità int i; cout << “dammi un intero” << endl; cin >> i; cout << i << “ è “ ; cout << (i % 2) ? “dispari” : “pari” << endl; } Laboratorio di Algoritmi e Strutture Dati 2001 -02 Operatore Condizionale – 2 14 ü La virgola serve a separare sotto-espressioni ü Un espressione formata da sotto-espressioni separate da virgole ha come risultato il valore dell’ultima sotto-espressione int ia[3], m[3][4]; int i = ( ia != 0 ) ? ia[1]++, 1 : 0; m[1, 2] = 100; // dove abbiamo scritto? Laboratorio di Algoritmi e Strutture Dati 2001 -02 Operatore Virgola 15 Laboratorio di Algoritmi e Strutture Dati 2001/02 8 Lezione 4 Espressioni ed operatori Operatori ai Bit ® ® ® Leggono gli operandi come sequenze di bit Possono operare su uno (o più) specifico bit Il controllo sulla correttezza delle operazioni è delegato completamente al programmatore ü Gli operandi sono detti bitvector ® ® ® Utilizzati per rappresentare in modo compatto insiemi di flag Sono di tipo intero (int, short, long, char) È consigliabile che siano unsigned ü Nella libreria iostream i bitvector sono usati per rappresentare il formato del flusso (tipo rappresentazione, numero di cifre decimali, etc.) di Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü Gli operatori ai bit sono %, |, ^, ~, <<, >> 16 unisgned char i = 101; unsigned char j = 151; j = ~j; j << 1; j >> 2; j &= i; j ^= i; j |= i; // 01100101 // 10010111 // 01101000 // 11010000 // 00110100 // 00100100 // 01000001 // 01100101 (104) (208) (52) (36) (65) (101) Laboratorio di Algoritmi e Strutture Dati 2001 -02 Esempio Operatori ai Bit 17 Laboratorio di Algoritmi e Strutture Dati 2001/02 9 Lezione 4 Espressioni ed operatori ü La libreria standard fornisce la che implementa “sequenza di bit” ® il tipo di classe bitset dati astratto Fornisce operazioni per manipolare e testare insiemi di bit, indipendenti dalla rappresentazione dei bit ü Definizione di variabili bitset bitset<24> bitvec; Laboratorio di Algoritmi e Strutture Dati 2001 -02 Classe bitset 18 test(pos) any() none() count() size() [pos] flip(pos) set(pos) reset(pos) // controlla se il bit pos è 1 // controlla se qualche bit è 1 // controlla se nessun bit è 1 // conta quanti bit sono 1 // conta quanti sono i bit // accedi al bit pos // inverte il bit pos // mette a 1 il bit pos // mette a 0 il bit pos Laboratorio di Algoritmi e Strutture Dati 2001 -02 Principali operazioni su bitset 19 Laboratorio di Algoritmi e Strutture Dati 2001/02 10 Lezione 4 Espressioni ed operatori ü È possibile convertire oggetti bitset in altri tipi: ® ® string con la funzione to_string() unsigned long con la funzione to_long() ü Queste conversioni sono utili per passare oggetti bitset a funzioni C o C++ prestandard che non conoscono la classe bitset Laboratorio di Algoritmi e Strutture Dati 2001 -02 Conversioni di oggetti bitset 20 #include <bitset> bitset<32> bitvec(0xFFFF); // crea un bitset di 32 bit bool is_set = bitvec.any(); int count; if(is_set) // se c'è un bit a 1 conta quanti bit sono a 1 count = bitvec.count(); else bitvec.flip(); // inverte tutti i bit for(int i = 0; i<bitvec.size(); i++) if(i % 2) // setta a 1 i bit di posizione pari bitvec.set(i); else bitvec.reset(i); // e a 0 gli altri Laboratorio di Algoritmi e Strutture Dati 2001 -02 Esempio uso classe bitset 21 Laboratorio di Algoritmi e Strutture Dati 2001/02 11 Lezione 4 Espressioni ed operatori Espressioni New e Delete memoria utilizzabile in fase di esecuzione ü Per allocare la memoria si utilizza l'espressione new int* pi = new int(10); int* pia = new int[4]; // alloca un int e lo inizializza con 10 // alloca un vettore di interi con 4 elementi ü Gli oggetti allocati dinamicamente non hanno nome e devono essere referenziati tramite puntatori ü Per rilasciare la memoria dinamica si utilizza l'espressione delete delete pi; delete [] pia; //Cancella la memoria allocata a pi //Cancella il vettore allocato a pia Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü Ad ogni programma è assegnata una porzione di 22 ü Il C++ non prevede nessun operatore per effettuare operazioni di input/output ® La libreria standard fornisce classi e operatori che permettono di effettuare operazioni di input/output (iostream) ü I dispositivi di input/output dall'astrazione di flusso (stream) ® ® sono rappresentati cin è un oggetto istream che identifica lo standard input cout è un oggetto ostream che identifica lo standard output ü L'operatore << inserisce un oggetto nel flusso di output ü L'operatore >> estrae un oggetto dal flusso di input Laboratorio di Algoritmi e Strutture Dati 2001 -02 Operazioni di Input/Output 23 Laboratorio di Algoritmi e Strutture Dati 2001/02 12 Lezione 4 Espressioni ed operatori Regole di Precedenza sintassi del C++ definisce delle regole di precedenza tra gli operatori che vengono utilizzate per valutare espressioni composte ® un’espressione composta è valutata considerando prima gli operatori con più alta precedenza, in ordine da sinistra a destra 6+3*4/2+2; while(ch = nextChar() != '\n') // 6+((3*4)/2)+2 = 14 // che fa? ü È possibile modificare l’ordine di valutazione degli operatori utilizzando le parentesi ® una coppia di parentesi individua una sotto-espressione Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü La ® la valutazione di una sotto-espressione ha massima precedenza 24 ü Per ogni operatore è definito un livello di precedenza ed un tipo di associatività ® Associatività a destra o a sinistra ü La regola di associatività specifica come viene interpretata un'espressione in cui compare più volte lo stesso operatore ® Associatività a destra i = j = k = 1; // (i = (j = (k = 1))) ® Associatività a sinistra i + j + k; // (i + j) + k) Laboratorio di Algoritmi e Strutture Dati 2001 -02 Regole di Associatività 25 Laboratorio di Algoritmi e Strutture Dati 2001/02 13 Lezione 4 Espressioni ed operatori ü Quando in un’espressione sono presenti operandi di tipo diverso il programma deve operare delle conversioni di tipo ü Una conversione di tipo non provoca alterazioni nel contenuto della memoria ® Modifica solo il tipo di un dato ü Esistono tre tipi di conversioni ® Implicite, aritmetiche ed esplicite Laboratorio di Algoritmi e Strutture Dati 2001 -02 Regole di Conversione di Tipo 26 ü Le conversioni implicite sono automaticamente dal compilatore eseguite ü Le conversioni implicite sono eseguite secondo regole dette conversioni standard ü Il programma può introdurre proprie regole di conversione standard (ma non per i tipi predefiniti) Laboratorio di Algoritmi e Strutture Dati 2001 -02 Regole di Conversione Implicita 27 Laboratorio di Algoritmi e Strutture Dati 2001/02 14 Lezione 4 Espressioni ed operatori Regole di Conversione Implicita un assegnamento si converte automaticamente l’R-value dell’operando destro al tipo dell’operando sinistro ü Il tipo della variabile passata ad una funzione viene convertito nel tipo dell’argomento della funzione ü Il tipo dell'oggetto restituito dal return è convertito nel tipo del risultato della funzione ü Tutte queste conversioni sono realizzate con la creazione di variabili temporanee Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü In 28 Regole di Conversione Aritmetica operandi di un operatore binario siano dello stesso tipo ® Tutti gli operandi sono convertiti nel tipo dell’operando più grande ü Le regole sono ® ® Ogni operando può essere solo promosso Tutti gli operandi più piccoli di un int sono sempre promossi ad int prima di essere valutati ü Promuovere un operando char a int significa ® ® Leggere il valore ASCII del char Copiarlo in una variabile int temporanea Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü Le conversioni aritmetiche garantiscono che gli 29 Laboratorio di Algoritmi e Strutture Dati 2001/02 15 Lezione 4 Espressioni ed operatori Regole di Conversione Esplicita tipo_cast<tipo>(expr); ® L'operazione di cast è pericolosa perché aggira il sistema di controlli sui tipi del compilatore ü Non tutti i cast sono sicuri ® La conversione di un tipo in un tipo più piccolo è non sicura perché tronca la rappresentazione del dato ü Il compilatore non esegue mai automaticamente un cast non sicuro Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü Viene effettuata attraverso l’operazione di cast 30 ü Referenziare puntatori generici (void) ü Evitare delle conversioni inutili nella valutazione di un’espressione ü Scavalcare il controllo sui tipi predisposto dal compilatore ü Eliminare ambiguità nella valutazione di un’espressione ® se più conversioni implicite sono possibili il compilatore non sceglie e segnala un errore di ambiguità Laboratorio di Algoritmi e Strutture Dati 2001 -02 Utilizzo dei Cast 31 Laboratorio di Algoritmi e Strutture Dati 2001/02 16 Lezione 4 Espressioni ed operatori ü Il C++ standard distingue 4 diversi tipi di cast, a seconda dell'utilizzo ® Solo per migliorare la leggibilità del codice const_cast<T>(expr); // rende expr (non) costante static_cast<T>(expr); // trasforma il tipo di expr in T reinterpret_cast<T>(expr); /* legge il pattern di bit all'indirizzo di expr come se fosse di tipo T */ dynamic_cast<T>(expr) /* implementa il run time type identification */ Laboratorio di Algoritmi e Strutture Dati 2001 -02 Tipi di Cast 32 Cast C-style T (expr); (T) expr; // converte il tipo di expr a T int (3.14); // tronca la parte decimale (short) 123456l; // tronca la rappresentazione del numero ü Per motivi di compatibilità, nello standard è ancora supportato questo tipo di cast, ma ne è deprecato l'uso Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü Nel C++ pre-standard esisteva un solo di tipo di cast 33 Laboratorio di Algoritmi e Strutture Dati 2001/02 17 Lezione 4 Espressioni ed operatori ü Un’istruzione è la più piccola unità di codice eseguibile di un programma C++ ® Ogni istruzione è caratterizzata da un ; come carattere finale ü Un’istruzione composta è formata da più operazioni elementari ® un’operazione composta è racchiusa tra {} e non è seguita dal ; ü Un’istruzione composta può sostituire un’istruzione semplice ü Un blocco è un’istruzione composta che contiene definizioni Laboratorio di Algoritmi e Strutture Dati 2001 -02 Istruzioni 34 ü Dichiarano o definiscono una variabile ® Possono comparire in qualunque punto del codice ü Il C++ incoraggia a definire le variabili solo nel momento in cui servono ® ® ® Evita di definire variabili non inizializzate Evita inutili inizializzazioni Consente di allocare memoria solo alle variabili realmente utilizzate ü È possibile definire variabili nella linea di controllo di un'istruzione di controllo del flusso ® La variabile è visibile solo all'interno del blocco associato all'istruzione Laboratorio di Algoritmi e Strutture Dati 2001 -02 Istruzioni di Dichiarazione 35 Laboratorio di Algoritmi e Strutture Dati 2001/02 18 Lezione 4 Espressioni ed operatori ü L’ordine di esecuzione delle istruzioni di un programma è sequenziale, a partire dalla prima linea della funzione main() ü Le istruzioni di controllo del flusso servono a modificare l’ordine di esecuzione delle istruzioni del programma Laboratorio di Algoritmi e Strutture Dati 2001 -02 Istruzioni di Controllo del Flusso 36 if then else scegliere tra al più due casi if (expr) ist; ® l'istruzione ist è eseguita solo se expr è vera if (expr) ist1; else ist2; ® se expr è vera viene eseguita ist1, altrimenti viene eseguita ist2 ü Istruzioni di if annidate sono fonti di potenziali errori – dangling else Laboratorio di Algoritmi e Strutture Dati 2001/02 Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü L’if è un’istruzione condizionale che permette di 37 19 Lezione 4 Espressioni ed operatori switch permette di scegliere tra più casi switch (expr) { case i: ist-i; break; case j: ist-j; break; default: ist; } Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü Lo switch è un’istruzione condizionale che 38 ü Il while è un’istruzione di ciclo while (expr) ist; ® esegue ist fino a quando expr è vera ü L’ordine di esecuzione è ® 1) valuta expr ® 2) se expr è vera esegui ist e torna ad 1 ® 3) esegui la prossima istruzione Laboratorio di Algoritmi e Strutture Dati 2001 -02 while 39 Laboratorio di Algoritmi e Strutture Dati 2001/02 20 Lezione 4 Espressioni ed operatori ü Il for è un’istruzione di ciclo for( ist_iniz; expr1; expr2) ist; ® esegue ist_iniz, quindi esegue ist e expr2 fino a quando expr1 è vera ü L’ordine di esecuzione è ® 1) esegui ist_iniz ® 2) valuta expr1 ® 3) se expr1 è vera esegui prima ist, poi expr2 e torna a 2) ® 4) esegui prossima istruzione Laboratorio di Algoritmi e Strutture Dati 2001 -02 for 40 ü Il do è un’istruzione di ciclo do ist; while (expr); ® esegue ist fino a quando expr non diventa falsa ® almeno una volta l’istruzione ist viene eseguita ü L’ordine di esecuzione è ® 1) esegui ist ® 2) valuta expr ® 3) se expr è vera torna a 1), altrimenti esegui prossima Laboratorio di Algoritmi e Strutture Dati 2001 -02 do while istruzione 41 Laboratorio di Algoritmi e Strutture Dati 2001/02 21 Lezione 4 Espressioni ed operatori ü Le istruzioni di salto spostano il controllo del programma ü Esistono tre istruzioni di salto ® break w interrompe il ciclo che si sta eseguendo ® continue w interrompe l’iterazione del ciclo che si sta eseguendo ® goto label w salta incondizionatamente all’istruzione etichettata label w label deve stare nella stessa funzione che contiene goto Laboratorio di Algoritmi e Strutture Dati 2001 -02 Salti 42 Laboratorio di Algoritmi e Strutture Dati 2001/02 22