Eccoci al settimo appuntamento con il nostro Corso Completo di Programmazione in C. Ora che abbiamo imparato dichiarare e inizializzare le nostre variabili è il momento di iniziare a scrivere qualche programma che le utilizzi per davvero, parleremo quindi delle principali funzioni matematiche e logiche. Per fare qualche esempio, però, avremo prima bisogno di capire come visualizzare a schermo il valore delle variabili.
Visualizzazione delle variabili
I programmi che scriveremo in questo corso saranno soprattutto programmi di tipo “console”, non avranno interfaccia grafica quindi per poter visualizzare a schermo il risultato delle nostre operazioni sarà necessario utilizzare la funzione printf, una funzione molto versatile che ci permetterà di scrivere del testo sul terminale.
La funzione printf, in realtà, non fa propriamente parte del linguaggio C, il linguaggio non possiede infatti alcuna funzione di “input/output”, queste funzioni vengono messe invece a disposizione da alcune librerie esterne, che possono essere aggiunte o meno ai nostri programmi.
La libreria che contiene la funzione printf si chiama “standar input output” e per specificare al compilatore che vogliamo utilizzarla nel nostro programma dovremo scrivere, in cima e prima di qualsiasi altra istruzione:
#include
stdio.h è detto “file header” ed è uno dei, solitamente due, file che compongono una libreria. Più avanti nel corso creeremo anche noi una nostra personale libreria di funzioni, per il momento ci basta sapere che nei file *.h è presente una sorta di “indice” di tutte le funzioni che compongono la libreria stessa.
Se siamo curiosi e vogliamo esaminare il contenuto del file “stdio.h” possiamo trovarlo all’interno della cartella “/usr/include”

L’utilizzo della funzione “printf” è molto semplice, ma ci sono alcuni parametri che bisogna ricordare. La sintassi della funzione è la seguente:
printf("Stringa da visualizzare",variabile1 , variabile2, … variabileN);
La potenzialità sta nel fatto che all’interno della “Stringa da visualizzare” si possono inserire dei caratteri speciali, dei placeholder che in fase di esecuzione del programma vengono sostituiti con la variabile in posizione corrispondente nella lista delle variabili.
Ad esempio, se la variabile “nome_variabile” ha valore “42” per visualizzare a schermo la dicitura: “Il valore della variabile è: 42” dobbiamo scrivere:
printf("Il valore della variabile è: %d\n", nome_variabile);
In questo caso il carattere %d è il placeholder e viene sostituito in fase di esecuzione con il valore di nome_variabile.
Per chiarezza ecco il codice completo:
#include
int main(int argc, char **argv)
{
int pippo;
pippo = 42;
printf("Il valore della variabile è: %d\n",pippo );
return 0;
}
Una volta compilato il risultato sarà il seguente:

Esistono diversi tipi di placeholder, a seconda della variabile che vogliamo visualizzare, in questo elenco ho inserito i più comuni.
- %c: carattere (char);
- %d: numero intero (int);
- %e: numero decimale (float) in notazione esponenziale;
- %le: numero decimale (double) in notazione esponenziale;
- %f: numero decimale (float) in notazione decimale;
- %lf: numero decimale (double) in notazione decimale;
- %Lf: numero decimale (long double) in notazione decimale;
La lista è parecchio lunga, vi rimando alla pagina di wikipedia per l’elenco completo (link).
Nota: i caratteri “\n” che vedete alla fine della riga indicano un “a capo” e anche se sono due simboli è a tutti gli effetti considerato come un unico carattere, quindi potrebbe essere memorizzato anche all’interno di una variabile di tipo char.
Operatori matematici
Le prime operazioni che incontriamo con le variabili sono le quattro operazioni aritmetiche di base. Per somma, differenza e prodotto non ci sono paricolarità, infatti per calcolarle, supponento che a, b e risultato siano tre variabili intere, potremmo scrivere:
risultato = a + b;
risultato = a - b;
risultato = a * b;
Qualche piccola differenza la presenta invece la divisione, perché il simbolo comunemente utilizzato per la divsione (” / “) ha un comportamento diverso a seconda dei valori del dividendo e del divisore.
Se entrambi sono numeri interi, allora la divisione restituisce un valore intero, troncando quindi eventuali cifre decimali, viceversa se almeno uno tra dividendo e divisore è di tipo float o double il risultato sarà di tipo float.
Possiamo vedere un esempio di questo comportamento in questo programma:
#include
int main(int argc, char **argv)
{
int p,q,r;
float x,y,z;
p = 10;
q = 3;
r = p / q;
x = 10.0;
y = 3.0;
z = x / y;
printf("Risultato divisione intera: %d\n"r);
printf("Risultato divisione tra float: %f\n",z);
return 0;
}
L’output di questo programma è:
Risultato divisione intera: 3
Risultato divisione tra float: 3.333333
Un’altra operazione molto usata è la funzione modulo, che in matematica è una funzione ben definita e rigorosa, ma per tutti gli altri è semplicemente il resto della divisione.
Il suo simbolo è ” % ” e si usa in questo modo:
risultato = 10 % 3;
In questo caso il valore assegnato a risultato sarà 1.
La funzione modulo è utilissima per riconoscere se un numero è multiplo di un’altro, perché in quel caso il resto della divisione (il modulo) è zero.
Rivediamo in un programma completo un pò di esempi:
#include
int main(int argc, char **argv)
{
int a,b,c,risultato;
a = 10;
b = 5;
c = 2;
risultato = a + b;
printf("Somma 10 + 5: %d\n", risultato);
risultato = a - b;
printf("Differenza 10 - 5: %d\n",risultato);
risultato = a * b;
printf("Prodotto 10 per 5: %d\n", risultato);
risultato = a / b;
printf("Divisione 10 per 5: %d\n",risultato);
risultato = a % b;
printf("Resto della divisione %d",risultato);
return 0;
}
Esistono altre operazioni matematiche, tutte memorizzate nella libreria “Math.h”, per utilizzarle è quindi necessario aggiungere in cima al file il testo “#include
Questa tabella è stata presa dalla pagina di wikipedia
| Membro | Descrizione |
| acos | arcocoseno |
| asin | arcoseno |
| atan | arcotangente |
| atan2 | arcotangente di due parametri |
| ceil | l’intero minore non minore del parametro |
| cos | coseno |
| cosh | coseno iperbolico |
| exp(double x) | funzione esponenziale, calcola ex |
| fabs | valore assoluto |
| floor | l’intero maggiore non maggiore del parametro |
| fmod | resto del numero in virgola mobile |
| frexp | frazione e potenza di due. |
| ldexp | operazione in virgola mobile |
| log | logaritmo naturale |
| log10 | logaritmo in base 10 |
| pow(x,y) | eleva un valore dato ad esponente, xy |
| sin | seno |
| sinh | seno iperbolico |
| sqrt | radice quadrata |
| tan | tangente |
| tanh | tangente iperbolica |
Operatori logici
Particolare importanza in tutti i linguaggi di programmazione rivestono le funzioni logiche.
Certo che tutti, qui, hanno avuto a che fare con la logica booleana non mi soffermerò molto su che cos’è una funzione logica, ma vedremo come queste sono implementate nel linguaggio C.
Nel linguaggio ANSI C non esiste alcun tipo di dato per esprimere il concetto di “vero” o “falso” e viene utilizzato lo zero come simbolo per identificare il falso e qualsiasi valore diverso da zero come vero. Con lo standard registrato nel 1999 è stato introdotto il tipo di dato “boolean”, ma soprattutto per compatibilità con altri linguaggi.
Gli operatori logici sono:
| Operatore | Simbolo in C | Significato | Esempio |
| AND | && | vera se e solo se sia a, sia b sono vere | (a && b) |
| OR | || | vera se a o b o entrambe sono vere | (a || b) |
| NOT | ! | vera solo se a è falsa | !a |
Operatori relazionali
In C sono presenti anche tutti gli operatori relazionali:
| Significato | Simbolo | Esempio |
| minore a | < | (a < b) |
| minore o uguale a | <= | (a <= b) |
| maggiore di | > | (a > b) |
| maggiore o uguale a (1) | >= | (a >= b) |
| uguale a | == | (a == b) |
| diverso da | != | (a != b) |
(1) Attenzione a non confondere l’operatore di assegnazione (a = b) con l’operatore relazionale (a == b) il primo si usa per assegnare ad “a” lo stesso valore di “b”, mentre il secondo è una funzione booleana che restituisce “true” se le due variabili sono uguali e “false” viceversa.
Faremo qualche esempio concreto di utilizzo di operatori logici e relazionali nella prossima lezione, quando parleremo del controllo condizionale.
Il casting delle variabili
Ho deciso di inserire qui questo argomento perché è più facile da comprendere dopo aver fatto qualche esempio con le operazioni matematiche.
Il casting è il metodo per dire al compilatore C di trattare una variabile come se fosse di un tipo diverso. Il compilatore effettua questo cambio se questa cosa è possibile, anche se in alcuni casi possono esserci perdite di informazione. Ad esempio è possibile “castare” una variabile di tipo intero (int) in una di tipo (float) senza nessuna perdita di informazioni in quanto il tipo float è più grande del tipo int, il viceversa, invece, comporta perdita di informazione, in quanto il numero a virgola mobile viene “trocato” fino a diventare un intero.
L’operazione di casting avviene inserendo il nome del tipo verso il quale effettuare il cast tra parentesi, prima del nome della variabile.
Vediamo in questo esempio:
float f = 5.25;
int i = (int)f; //cast esplicito da float a intero.
La precedenza
Qualche utente più smaliziato si sarà reso conto che non ho parlato della precedenza degli operatori.
Senza delle regole di precedenza operazioni come:
risultato = (3 * 5 + 7);
non sarebbero univocamente interpretabili, ecco quindi l’elenco degli operatori C in ordine decrescente di priorità:
| Livello di precedenza | Operatore | Nome |
| 1 | ! | Not, negazione |
| 2 | * | Moltiplicazione |
| 2 | / | Divisione |
| 2 | % | Modulo |
| 3 | + | Addizione |
| 3 | – | Sottrazione |
| 4 | < | Minore |
| 4 | <= | Minore uguale |
| 4 | > | Maggiore |
| 4 | >= | Maggiore uguale |
| 5 | == | Uguale (confronto) |
| 5 | != | Diverso |
| 6 | && | AND |
| 7 | || | OR |
| 8 | = | Assegnamento |
In base a questa tabella l’istruzione precedente verrà valutata com ((3 * 5) + 7).
I motivi per cui non ho dato tanta importanza alle relazioni di precedenza sono principalmente due, il primo è che per le operazioni matematiche di base valgono le stesse regole della matematica classica, prima moltiplicazioni e divisioni e poi sottrazioni e somme; Il secondo è perché sono convinto (mi ha convinto Kernighan con il suo libro “The pratice of programming” (link) ) che il codice sorgente dei nostri programmi non deve essere soltanto corretto da un punto di vista sintattico, ma deve anche essere chiaro e comprensibile per l’uomo, quindi ove ci possano essere dei fraintendimenti del codice è sicuramente più corretto utilizzare una coppia in più di parentesi così da rimuovere ogni ambiguità.
Alla prossima e buono studio!
Letture consigliate:
Il linguaggio C. Principi di programmazione e manuale di riferimento (Accademica)
Brian W. Kernighan – Dennis M. Ritchie
Editore: Pearson | Lingua: Italiano | Brossura: 313 pagine
Prezzo Listino: EUR 27,00
Prezzo Promozione: EUR 22,95 con Spedizione gratuita
C. Corso completo di programmazione
Paul J. Deitel – Harvey M. Deitel
Editore: Apogeo | Lingua: Italiano | Brossura: 640 pagine
Prezzo Listino: EUR 39,00
Prezzo Promozione: EUR 33,15 con Spedizione gratuita










12 Responses to “7. Operazioni matematiche e logiche”
13 Aprile 2011
RagazzettoCome sempre …………..
……….grande Ignazio !
13 Aprile 2011
TuxWow! Quindi da adesso in poi una lezione ogni 5 giorni?
13 Aprile 2011
FabioPross input?
14 Aprile 2011
Ignazioc?? non capisco
14 Aprile 2011
Andrea96tra quante lezioni arriveremo alla UI?….
so benissimo che dovete fare tutto passo passo per gli utenti meno esperti
14 Aprile 2011
Ignazioccosa intendi per UI? User Interface?
16 Aprile 2011
Andrea96certo 😉
20 Aprile 2011
Paradiseprintf(“Risultato divisione intera: %d\n”r);
printf(“Risultato divisione tra float: %f\n”,z);
qui ci hai mancato una virgola 😉
ne approfitto per dirti che stia facendo un’ottimo lavoro! 🙂
3 Settembre 2011
Corso di programmazione in C - Costrutti decisionali | devAPP[…] “==” con l’operatore di assegnamento “=” (vi avevo avvisato nella precedente lezione! Avreste dovuto notarlo!) L’operatore di assegnamento in C da come valore di ritorno il […]
3 Settembre 2011
Corso di programmazione in C - I puntatori (parte 1) | devAPP[…] In questo caso il termine “void” indica che si tratta di un puntatore generico, che non ha specificato nessun tipo di dato, quindi punta in modo generico ad un intero blocco della memoria. Per utilizzarlo è sempre possibile utilizzare l’operazione di cast (lezione 7). […]
20 Settembre 2011
Francesconon capisco dove sia l’errore nel codice, invece di valori int e float mi ritorna come risultati %d e %f…dove posso aver sbagliato? Ho riportato pari pari, ecco:
#include
int main(int argc, char **argv)
{
int p,q,r;
float x,y,z;
p = 10;
q = 3;
r = p / q;
x = 10.0;
y = 3.0;
z = x / y;
printf(“Risultato divisione intera: &d\n”,r);
printf(“Risultato divisione tra float: &f\n”,z);
return 0;
}
22 Settembre 2011
Ignaziocnon so se è un problema dell’html ma devi scrivere
printf("Risultato della divisione intera: %d\n", r);