lunedì 26 novembre 2012

Piccolo tutorial sul linguaggio C - Gli operatori aritmetici e logici

Operatori aritmetici

Nel nostro termostato avremo bisogno di fare calcoli! Vediamo cosa ci offre il C a questo scopo. Il linguaggio C comprende i consueti operatori:
Operatori binari
+ Somma;
- Sottrazione;
/ Divisione;
* Moltiplicazione;
% Resto (mod);

Operatori unari (prefissi e suffissi)

++ incremento di 1
-- decremento di 1
In un precedente post, avevamo già visto quali possono essere i pericoli derivanti dall'uso non attento dei semplici operatori aritmetici binari in presenza di variabili e costanti di tipi diversi dal tipo del risultato. Per riassumere, il segno di diviso tra due interi è interpretato come divisione tra interi. Ovvero, 1/3 è uguale a 0! Anche gli operatori unari di incremento/decremento possono presentare dei comportamenti, a prima vista, bizzarri se non se ne conosce bene il funzionamento.  Commentiamo insieme un esempio:
i=1;     //istr. 1
j=ì++;  //istr. 2
k=++ì; //istr. 3
Secondo voi, dopo il precedente blocco di istruzioni, quanto vale j? Chi ha detto 2?Nessuno  dice 1? La risposta esatta è 1! Infatti, l'operatore suffisso viene applicato alla fine della valutazione dell'espressione nella quale si trova. Se il gioco è chiaro, la prossima domanda dovrebbe essere facile: quanto vale k? Bravi! Avete risposto bene. Il valore assunto da k è proprio 3, perché dopo l'istruzione 2 i vale 2 e quando viene valutata l'istruzione 3, i viene prima incrementato di 1, quindi vale 3, e poi usato nell'espressione a destra del segno uguale.

Operatori relazionali

Abbiamo già detto che il linguaggio C non prevede un tipo booleano primitivo? Se non lo abbiamo detto, lo diciamo qui :). In C, 0 (zero) corrisponde al valore booleano False, qualunque altro valore è True.
Gli operatori relazionali operano su valori interi o decimali e restituiscono il valore 0 oppure 1.
  • == Uguale a
  • != Non uguale a, Diverso da
  • > Maggiore di
  • < Minore di
  • >= Maggiore o uguale a
  • <= Minore o uguale a
Attenzione: per testare l'uguaglianza si usa l'operatore == e non l'operatore =, che è invece l'operatore di assegnamento.
Commentiamo insieme un esempio per capire cosa può succedere se usiamo l'operatore sbagliato.
Immaginano di voler disporre di una variabile di nome manuale che ci dica se è stat impostata la modalità manuale del termostato, vi ricordo che le specifiche del termostato sono in questo post e che la modalità manuale si seleziona premendo il tasto 'a'. Quindi, da qualche parte nel nostro programmino potremmo scrivere:
manuale = (comandotastiera='a'); // istr. 1
...
if (manuale) fai_qualcosa();          // istr. 2
Purtroppo, invece di scrivere comandotastiera=='a' abbiamos scritto comandotastiera='a', con il risultato di assegnare alla variabile manuale il risultato dell'espressione comandotastiera='a' che è esattamente 'a', ovvero il codice numerico del carattere 'a' che è pari a 97. Poiché 97 è maggiore di 0, il test sulla variabile manuale è sempre verificato e quindi il nostro termostato sarebbe sempre in modalità manuale acceso.
Si noti che l'istruzione 1, benché non faccia ciò che volevamo che facesse, è perfettamente legittima e quindi il compilatore non segnala alcun errore!
Visto cosa può succedere scrivendo = invece di ==?

Operatori logici

Lo abbiamo già detto: 0 è False, qualunque altro valore è vero!
Gli operatori logici sono
  • ! not, negazione Booleana (unario)
  • && and Booleano 
  • || or Booleano 

Operatori logici bit a bit

  • ~ Negazione bit a bit (unario) – cambia tutti gli 0 in 1 e gli 1 in 0 
  • & esegue l'And dei bit dell'operando di sinistra con i bit dell'operando di destra
  • | esegue l'Ordei bit dell'operando di sinistra con i bit dell'operando di destra
  • ^ esegue l'Or esclusivo dei bit dell'operando di sinistra con i bit dell'operando di destra
  • >> Shifta a destra di un numero di bit pari all'operando a destra (=divisione per potenze di 2)
  • <<  Shifta a sinistradi un numero di bit pari all'operando a destra (=moltiplicazione per potenze di 2)
Anche qui, attenzione a non confondere gli operatori logici con quelli bit a bit, il compilatore non vi aiuterà nel caso di errori!

Operatori di assegnamento 

Oltre al classico operatore di assegnamento il linguaggio C prevede le seguenti "scorciatoie":per effettuare operazioni di assegnamento e modifica di una variabile con un solo riferimento alla variabile stessa. La sintassi è la seguente:
var op= espr;
dove op può essere uno qualunque tra gli operatori: + - * / % & | ^ << >>.  Il significato è il seguente: assegna a var il risultato di var op espressione. Vediamo con un esempio a cosa servono. L'istruzione 
i  =  i * 10;
può essere riscritta con l'operatore di assegnamento è equivalente a
ì *=10;
Gli ideatori del C  hanno pensato che questo tipo di operatori avrebbe aumentato la leggibilità dei programmi  introducendo questo modo di rappresentare di modifica ad una variabile basata su se stessa.
Inoltre, l'uso di questi operatori può contribuire alla scrittura di codice più efficiente. Il compilatore quando incontra un operatore di assegnamento può implementare l'operatore con un istruzioni più veloci che nel caso di assegnamento semplice.

Nessun commento:

Posta un commento