Sei sulla pagina 1di 68

Corso di Fondamenti di Informatica

Ingegneria delle Comunicazioni – BCOR


Ingegneria Elettronica – BELR

Introduzione al C

Unità 2 - Variabili

D. Bloisi, S. Peluso, A. Pennisi, S. Salza


Sommario – Unità 2
• Variabili e identificatori di variabile
• Inizializzazione di variabili
• Assegnazione e letture
• Tipi di dato scalari: interi,reali e caratteri
• Intervalli e precisione nelle rappresentazioni
• Conversioni di tipo, implicite ed esplicite

Variabili 2013/2014 Pagina 2


Unità 2
Variabili
• In C una variabile rappresenta una locazione di memoria usata
per la memorizzazione di un valore ed è caratterizzata da:
• NOME
− Sequenza di caratteri che permette di identificare la variabile
− Risponde a regole precise
• TIPO
− Specifica il tipo di dato che la variabile può immagazzinare
− Es: intero, reale, carattere, …..
• INDIRIZZO
− Locazione di memoria nella quale la variabile è memorizzata
− La dimensione (uno o più byte) dipende dal tipo
• VALORE
− Valore immagazzinato nella variabile ad un certo istante

Variabili e tipi 2013/2014 Pagina 3


Unità 2
Identificatori di variabili
• Sequenza di caratteri composta da lettere, cifre e da _
• Inizia per lettera o per _
• Lunghezza qualsiasi (31 caratteri nello standard ANSI)
• Lettere maiuscole e minuscole sono considerate caratteri
diversi: il C è case sensitive
• Alcuni identificatori sono riservati perché considerati parole
chiave del linguaggio, es.: include, return, main,
function
• ESEMPIO: identificatori validi
Pippo, a117, _418, sono_una_variabile
• ESEMPIO: identificatori non validi
3d7, un cane, return

Variabili e tipi 2013/2014 Pagina 4


Unità 2
Analogia con le scatole di scarpe
Si può comprendere intuitivamente il significato di una variabile
attraverso l’analogia con una scatola di scarpe etichettata in uno
scaffale
• NOME
− Etichetta della scatola: la identifica univocamente
• TIPO
− Forma e dimensioni della scatola
− Dipendono dal tipo di scarpe che ci devono stare
• INDIRIZZO
− Posizione nello scaffale: dove andarla a cercare
• VALORE
− Il paio di scarpe che, ad un certo istante è contenuto nella
scatola

Variabili e tipi 2013/2014 Pagina 5


Unità 2
Rappresentazione grafica di variabili
Una variabile è un riferimento ad una locazione di memoria in
cui è memorizzato un valore. Per rappresentare le variabili e i
loro valori usiamo la seguente notazione grafica

indirizzo
tipo 5640123

int var2 487 var2 487


valore

nome NOTAZIONE SEMPLIFICATA

Variabili e tipi 2013/2014 Pagina 6


Unità 2
Dichiarazione di variabili
Il C prevede che le variabili, per poter essere usate, siano sempre
esplicitamente dichiarate
SINTASSI
tipo identificatore1, …., identificatoreN
− tipo: è il tipo della variabile (predefinito o definito nel
programma)
− identificatoreK: i nomi con cui le variabili saranno identificate
SEMANTICA
− La dichiarazione riserva spazio in memoria per la variabile
− Rende la variabile disponibile nella parte del programma
(blocco) dove appare la dichiarazione.

N.B. è possibile dichiarare più variabili dello stesso tipo in


un’unica dichiarazione
Variabili e tipi 2013/2014 Pagina 7
Unità 2
Esempi di dichiarazione
int x;
int y;
int z;
float alfa, beta, gamma;
char iniziale, finale;
• Tutte queste variabili appartengono a tipi predefiniti
• Fra i più comuni tipi elementari in C
• int : valori interi
• float: valori reali in singola precisione
• double: valori reali in doppia precisione
• char: carattere

Variabili e tipi 2013/2014 Pagina 8


Unità 2
Assegnazione
L’istruzione di assegnazione serve per memorizzare un valore in
una variabile
SINTASSI
nome variabile = espressione
− nome variabile: è il nome di una variabile
− espressione: è un’espressione che, una volta valutata, deve
restituire un valore dello stesso tipo della variabile
SEMANTICA
− Alla variabile viene assegnato il valore dell’espressione che
si trova a destra del simbolo =
− Il valore dell’espressione deve essere ‘compatibile’ con il
tipo della variabile
− Dopo l’assegnazione il valore rimane immutato fino
all’assegnazione successiva
Variabili e tipi 2013/2014 Pagina 9
Unità 2
Esempi di assegnazione

x = 5;
r = 471.035;
m = 7 * 8;
• x e m sono variabili intere, cioè dichiarate di tipo int
• r è una variabile reale, cioè dichiarata di tipo float
• Le prime due espressioni sono costanti dello stesso tipo
delle variabili che compaiono a primo membro
• La terza espressione è un’espressione aritmetica a valore
intero
• Dopo l’esecuzione dell’assegnazione, la variabile m vale 56

Variabili e tipi 2013/2014 Pagina 10


Unità 2
Inizializzazione di una variabile
• Inizializzare una variabile significa specificare un valore che
viene assegnato ad essa prima di qualsiasi suo utilizzo
• Una variabile non inizializzata ha valore indefinito
• Se il valore di una variabile non inizializzata viene acceduto
prima che essa sia oggetto di una assegnazione, ciò può
comportare errori nell’esecuzione del programma
• Questo tipo di errore non è segnalato dal compilatore, si tratta
di un errore semantico, anche piuttosto subdolo

Alla variabile viene assegnata una locazione di memoria, come


conseguenza della dichiarazione. La locazione contiene comunque
un valore (non prevedibile e non significativo). Questo viene usato
in caso di mancata inizializzazione

Variabili e tipi 2013/2014 Pagina 11


Unità 2
Esempio: mancata inizializzazione
int main() {
int x, y, x2, y2, z;
x2 = x*x; y2 = y*y;
z = (x2+y2)*(x2-y2);
printf("%d\n", z);
return 0;
}
• Le variabili x e y vengono accedute senza essere inizializzate
• x2 , y2 e z sono invece oggetto di assegnazione prima di
essere accedute
• Il programma stampa un valore errato (ed imprevedibile):
-325873392

Variabili e tipi 2013/2014 Pagina 12


Unità 2
Inizializzazione: sintassi
• L’inizializzazione può essere fatta contestualmente alla
dichiarazione, nella forma:
tipo nomevariabile = espressione;
• Il che è del tutto equivalente a:
tipo nomevariabile;
nomevariabile = espressione;
ESEMPIO
int x = 5;
è del tutto equivalente a:
int x;
x = 5

Variabili e tipi 2013/2014 Pagina 13


Unità 2
Lettura di una variabile
• Il valore di una variabile può anche essere acquisito o
modificato tramite lettura, cioè acquisendone il valore un
dispositivo di input (nel nostro caso la tastiera)
• Tramite l’operazione di lettura il valore acquisito sostituisce il
valore precedente della variabile, se ne aveva uno
• La lettura si effettua tramite la funzione scanf
• scanf è parte della libreria stdio del C
• La struttura di scanf è del tutto analoga a quella di printf

Variabili e tipi 2013/2014 Pagina 14


Unità 2
La funzione scanf
• Legge da input il valore di una sequenza di variabili
• Fa parte della libreria stdio.h e ha la forma:
scanf (stringa di controllo del formato, altri argomenti )
• La stringa di controllo del formato descrive il formato dell’input
• Gli altri argomenti specificano le variabili che si intende leggere
• Restituisce come valore il numero di variabili lette con successo
• La stringa di controllo del formato è composta da una serie di
specifiche di conversione che indicano:
− Il tipo del dato che si vuole leggere
− Il formato nel quale andrà letto
− Il numero di caratteri da leggere

Variabili e tipi 2013/2014 Pagina 15


Unità 2
Specifiche di conversione

Alcune specifiche di conversione di uso frequente sono:


%c singolo carattere
%d intero in rappresentazione decimale con o senza segno
%o intero in rappresentazione ottale
%x intero in rappresentazione esadecimale
%u intero in rappresentazione decimale senza segno
%f reale in singola precisione (virgola fissa o mobile)
%lf reale in dopia precisione
%s stringa di caratteri
%e reali in notazione virgola mobile

Variabili e tipi 2013/2014 Pagina 16


Unità 2
Esempio scanf
#include <stdio.h>
main()
{
int x;
printf("Inserisci un intero: ");
scanf("%d", &x);
printf("Ho letto %d", x);
return 0;
}

ATTENZIONE
Nella scanf le variabili da leggere devono essere indicate non
con il nome ma con l’indirizzo: &x è l’indirizzo di x
Variabili e tipi 2013/2014 Pagina 17
Unità 2
Esempio scanf (esecuzione)

Variabili e tipi 2013/2014 Pagina 18


Unità 2
Nome e indirizzo di una variabile
• Nella scanf le variabili da leggere devono essere indicate non
con il nome ma con l’indirizzo
• Per conoscere l’indirizzo si usa l’operatore di indirizzo & , il
quale, applicato ad una variabile, restituisce l’indirizzo della
locazione in cui è contenuta la variabile
• Nell’esempio precedente &x è l’indirizzo di x
• Se invece di scrivere &x avessi scritto x avrei avuto il seguente
effetto:
− Dato che x è una variabile intera, viene preso il valore di x in
quell’istante come indirizzo della variabile da leggere
− Nella fattispecie, non essendo x inizializzata, il risultato
oltre che sbagliato è imprevedibile

Variabili e tipi 2013/2014 Pagina 19


Unità 2
Esecuzione con x invece di &x

Variabili e tipi 2013/2014 Pagina 20


Unità 2
Errori di input

• Ho dato da input qualcosa che non è un numerale corretto


• La funzione non ha effettuato la lettura con successo
• Modifichiamo il programma per vedere quale valore viene
restituito dalla funzione
Variabili e tipi 2013/2014 Pagina 21
Unità 2
Esempio: stampa del valore di ritorno
#include <stdio.h>

main()
{
int x, code;
printf("Inserisci un intero: ");
code = scanf("%d", &x);
printf("Codice di ritorno della scanf: %d \n", code);
printf("Ho letto %d", x);
return 0;
}

N.B. Il valore di ritorno di scanf è il numero di variabili lette


correttamente. In questo caso, se c’è un errore varrà 0

Variabili e tipi 2013/2014 Pagina 22


Unità 2
Esempio: esecuzione

Variabili e tipi 2013/2014 Pagina 23


Unità 2
Esercizio
Esercizio 2.1
• Si scriva una funzione in linguaggio C che sia in grado di
calcolare il quadrato di un intero.
• Scrivere inoltre una funzione main che legge un intero e ne
stampa il quadrato.

Variabili e tipi 2013/2014 Pagina 24


Unità 2
La funzione square
tipo della funzione
nome della funzione

int square ( int num )


{ parametri (tipo e nome)
int prodotto;
prodotto = num * num; assegna il valore
di ritorno
return prodotto;
}
• Ha la stessa struttura della funzione main, con la differenza
che sono specificati gli argomenti
• La funzione restituisce il valore che deve calcolare, cioè il
quadrato di quello che è stato passato come parametro

Variabili e tipi 2013/2014 Pagina 25


Unità 2
La funzione square
tipo della funzione
nome della funzione

int square ( int num )


{ parametri
int prodotto;
prodotto = num * num; assegna il valore
di ritorno
return prodotto;
}
• Ha la stessa struttura della funzione main, con la differenza
che sono specificati gli argomenti
• La funzione restituisce il valore che deve calcolare, cioè il
quadrato di quello che è stato passato come parametro

Variabili e tipi 2013/2014 Pagina 26


Unità 2
Il programma completo
#include <stdio.h> Prototipo della funzione square

int square(int); Attenzione al &


int main() { Definizione della funzione main
int x, quadrato; (programma principale)
printf("Scrivi un numero intero ");
scanf ("%d", &x);
printf("quadrato di %d = ", x);
quadrato = square(x);
printf("%d\n", quadrato);
return 0;
}
int square ( int num )
{
int prodotto;
prodotto = num * num; Definizione della funzione square
return prodotto;
}

Variabili e tipi 2013/2014 Pagina 27


Unità 2
Esercizi
Esercizio 2.2
• Si scriva una funzione in linguaggio C che sia in grado di
calcolare il cubo di un intero.
• Scrivere inoltre una funzione main in grado di utilizzare la
funzione realizzata.
Esercizio 2.3
• Si scriva una funzione in linguaggio C che sia in grado di
calcolare il numero dei giorni corrispondenti all’età di una
persona (espressa in anni)
• Scrivere una funzione main che chiede l’età di una persona e
stampa il numero di giorni corrispondente
Esercizio 2.4
• Si scriva una funzione in linguaggio C che richieda all’utente due
interi e li stampi in ordine inverso rispetto all’inserimento

Variabili e tipi 2013/2014 Pagina 28


Unità 2
Tipi di dato
Per descrivere efficacemente la natura dei dati rappresentabili
in un programma e le operazioni per manipolarli si usa il
concetto di tipo di dato, caratterizzato da:
DOMINIO
− Insieme dei possibili valori
− Es: numeri interi, reali, razionali, ecc.
OPERAZIONI
− Funzioni che operano sugli elementi del dominio
− Es: per gli interi, somma, moltiplicazione, ecc.
LETTERALI
− Valori costanti appartenenti al dominio
− Es: 457 è un letterale per il dominio degli interi

Variabili e tipi 2013/2014 Pagina 29


Unità 2
Tipi scalari e aggregati

• I domini dei tipi scalari sono insiemi ordinati


• I tipi aggregati sono costruiti a partire dagli scalari

Variabili e tipi 2013/2014 Pagina 30


Unità 2
Tipi aritmetici

Variabili e tipi 2013/2014 Pagina 31


Unità 2
Domini dei tipi scalari numerici

N.B. Gli intervalli dipendono dal sistema (piattaforma hw/sw)

Variabili e tipi 2013/2014 Pagina 32


Unità 2
Tipo intero

• Il dominio dipende dal sottotipo e dal sistema hw/sw


• Gli operatori sono:
+ somma
- sottrazione
* prodotto
/ divisione
% divisione modulo (resto della divisione intera)
• Valgono le consuete precedenze tra operatori dell’aritmetica
• Letterali: sequenze di cifre che denotano costanti intere
• Valori limite definiti dalle costanti INT_MIN e INT_MAX

Variabili e tipi 2013/2014 Pagina 33


Unità 2
Tipi short e long

• Oltre al tipo int il C prevede anche due tipi short int e


long int, spesso abbreviati come short e long
• In genere vengono memorizzati rispettivamente con 2 Byte e
4 Byte (ma è meglio controllare)
• Tuttavia ciò può variare da implementazione a implementazione
• Su piattaforme a 64 bit è verosimile che alle variabili long
vengano assegnati 8 Byte
• È possibile scegliere tra questi due tipi in base al range che si
prevede per le variabili intere
• Occorre però prestare la massima attenzione, perché il pericolo
di overflow è sempre in agguato

Variabili e tipi 2013/2014 Pagina 34


Unità 2
Valori massimi e minimi
• Sono costanti la cui definizione è contenuta in limits.h
• Il file si trova nella directory MinGw\include
• Verificare i valori con il seguente programma:

#include <stdio.h>
#include <limits.h>
int main() {
printf("SHRT_MIN=%d\n", SHRT_MIN); printf("SHRT_MAX=%d\n", SHRT_MAX);
printf("INT_MIN=%d\n", INT_MIN); printf("INT_MAX=%d\n", INT_MAX);
printf("LONG_MIN=%d\n", LONG_MIN); printf("LONG_MAX=%d\n", LONG_MAX);
printf("USHRT_MAX=%u\n", USHRT_MAX);
printf("UINT_MAX=%u\n", UINT_MAX);
printf("ULONG_MAX=%u\n", ULONG_MAX);
return 0;
}
Variabili e tipi 2013/2014 Pagina 35
Unità 2
Overflow

• Il problema nasce dalla rappresentazione interna dei numeri, con


numero limitato di cifre
• Si verifica quando il risultato di un calcolo non è rappresentabile
nel dominio del tipo dato
• Tipicamente non è segnalato come errore e produce effetti
imprevedibili
• Il valore massimo per uno short int (rappresentato con
16 bit) è 32767=215-1
• Il valore massimo per uno long int (rappresentato con 32
bit) è 2,147,483,647=231-1
• Un semplice programma mostra gli effetti dell’overflow

Variabili e tipi 2013/2014 Pagina 36


Unità 2
Esempio: overflow
#include <stdio.h>

main()
{
short int si = 32767 ;
long int li = 32767 ;
printf("Valore di si prima dell'incremento: %d \n", si);
printf("Valore di li prima dell'incremento: %d \n", li);
si = si+1;
li = li+1;
printf("Valore di si dopo l'incremento: %d \n", si);
printf("Valore di li dopo l'incremento: %d \n", li);
return 0;
}
Variabili e tipi 2013/2014 Pagina 37
Unità 2
Esempio: overflow (esecuzione)

N.B. Rappresentazione in complemento a 2 di si nel caso short int :


(0111111111111111)CA2 → (+32767) 10
sommando 1 → (100000000000000)CA2 → ( -32768) 10

Variabili e tipi 2013/2014 Pagina 38


Unità 2
Tipo float
• Corrisponde al dominio dei numeri reali in semplice precisione,
tipicamente a 32 bit (Notazione IEEE 754)
• Gli operatori sono:
+ somma
- sottrazione
* prodotto
/ divisione
• Valgono le consuete precedenze tra operatori dell’aritmetica
• Letterali: sequenze di cifre contenenti il punto decimale e che
terminano con una f . Es: 3.1415f
• Anche letterali in notazione esponenziale. Es: 314E-2f

Variabili e tipi 2013/2014 Pagina 39


Unità 2
Tipo double
• Corrisponde al dominio dei numeri reali in doppia precisione,
tipicamente a 64 bit (Notazione IEEE 754)
• Gli operatori sono:
+ somma
- sottrazione
* prodotto
/ divisione
• Valgono le consuete precedenze tra operatori dell’aritmetica
• Letterali: sequenze di cifre contenenti il punto decimale e che
opzionalmente terminano con una d . Es: 3.1415,3.1415d
• Anche letterali in notazione esponenziale. Es: 314E-2

Variabili e tipi 2013/2014 Pagina 40


Unità 2
Operatori assegnazione composta

• In C è possibile usare delle notazioni composte in quelle


assegnazioni in cui la variabile a primo membro compare
anche a secondo
somma = somma + addendo;
salario = salario * aumento;
si può abbreviare in:
somma += addendo;
salario *= aumento;
• Per ogni operatore esiste il corrispondente:
+ - * / %
+= -= *= /= %=
Variabili e tipi 2013/2014 Pagina 41
Unità 2
Operatori di incremento e decremento

• Accade molto spesso di dover incrementare o decrementare


una variabile di una unità
• Oltre agli operatori di assegnazione composta, il C prevede
un’ulteriore notazione semplificata
• Forme equivalenti:
x = x + 1;
x += 1;
x++;

x = x - 1;
x -= 1;
x--;

Variabili e tipi 2013/2014 Pagina 42


Unità 2
Side-effect
Il C estende il significato del termine espressione:
A. Espressioni che hanno come effetto solamente il calcolo di
un valore, che si possono comporre secondo le regole delle
espressioni matematiche.
B. Espressioni che, oltre a calcolare un valore, modificano lo
stato della memoria, come ad esempio un'assegnazione
(semplice o composta) oppure un post-incremento.
• Per il secondo tipo di espressioni si usa il termine di
espressioni-con-side-effect
• Il termine side-effect indica che il calcolo dell’espressione ha
degli effetti collaterali, che sono appunto le variazioni indotte
nello stato della memoria, le quali permangono anche dopo
che il calcolo dell’espressione si è concluso

Variabili e tipi 2013/2014 Pagina 43


Unità 2
Side-effect: esempi

• 23*x+5 è una espressione senza side-effect


• x = 7 è una espressione con side-effect: la sua valutazione
provoca il cambiamento del valore di x
• Essendo un’espressione valida x = 7 può comparire a
secondo membro di una assegnazione: y = x = 7;
• Come risultato dell’assegnazione, ad y viene assegnato il
valore dell’espressione x = 7 (cioè 7), il side-effect è
costituito dal fatto che da quel momento x vale 7

Tutta questa ricchezza espressiva deve essere usata con


molta cautela, evitando acrobazie e virtuosismi: l’obiettivo
primario è garantire la leggibilità del programma

Variabili e tipi 2013/2014 Pagina 44


Unità 2
Stile sobrio con le espressioni
• Sebbene il linguaggio C consenta un uso indifferenziato dei
due tipi di espressioni, è preferibile usare le espressioni
semplici con side-effect per formare delle istruzioni, evitando
sempre l’uso di espressioni con side-effect all’interno di
espressioni matematiche più complesse.
• Ad esempio x = 7 è una espressione con side-effect, e la
uso per formare l’istruzione di assegnazione x = 7;
• Ma l’istruzione:
x = 5 * (y = 7);
è meglio riscriverla come:
(y = 7); x = 5 * y ;
per meglio evidenziare l’effetto sul valore di y.

Variabili e tipi 2013/2014 Pagina 45


Unità 2
Costanti
• La maniera più semplice di utilizzare un valore costante in un
programma e di usare un letterale, per un numero un numerale
• Es: int compenso = 20000 * orelavoro;
• Questo pone due problemi:
A. A chi legge il programma non è immediatamente chiaro
cosa rappresenta il numero 20000
B. Se questo numero compare in molte parti del programma
e dovesse cambiare, dovrei modificarlo dappertutto
• Il C consente di associare a quel numero un nome, e poi
utilizzare questo nome invece del letterale:
const int COMPENSO_ORARIO = 20000;
...
int compenso = COMPENSO_ORARIO * orelavoro;

Variabili e tipi 2013/2014 Pagina 46


Unità 2
Definizione di costanti tramite #define
• In realtà const è un modificatore di una definizione di
variabile con inizializzazione
• Il suo effetto è che il valore della variabile, non può più essere
modificato dopo l’inizializzazione: resta quindi costante
• Oltre alla definizione di costanti tramite il modificatore const,
è possibile definire costanti tramite la direttiva #define
• ESEMPIO
#define COMPENSO_ORARIO 20000
• Si tratta di una direttiva che deve essere messa nella
intestazione del programma
• La direttiva è recepita dal compilatore che da allora in poi
rimpiazza la stringa COMPENSO_ORARIO con 20000

Variabili e tipi 2013/2014 Pagina 47


Unità 2
Esercizio: teorema di Pitagora
Esercizio 2.5
Scrivere un programma che riceva in input da tastiera il valore di
due cateti di un triangolo rettangolo e restituisca il valore
dell’ipotenusa.

Esempio d’uso

Inserisci il primo cateto:


3
Inserisci il secondo cateto:
4
Valore ipotenusa: 5

Variabili e tipi 2013/2014 Pagina 48


Unità 2
Soluzione: teorema di Pitagora
#include <stdio.h>
#include <math.h>

int main ()
{
double a, b, c;
printf(“Inserisci il primo cateto:\n");
scanf("%lf", &a);
printf(“Inserisci il secondo cateto:\n");
scanf("%lf", &b);
c = sqrt(a*a + b*b);
printf("valore ipotenusa: %f\n", c);
return 0;
}

Variabili e tipi 2013/2014 Pagina 49


Unità 2
Conversione di tipi
Le conversioni di tipo si rendono necessarie in vari casi:
• Assegnazioni tra due variabili di tipo diverso (ma ‘compatibile’).
Es: x = y; , con x di tipo float e y di tipo int
• Operazioni tra variabili di tipo diverso nella stessa espressione.
Es: x = y * z; (x e y tipo float e z tipo long)
• Il C prevede due tipi di conversione
A. IMPLICITA (PROMOZIONE)
• Il compilatore ne rileva la necessità e provvede d’ufficio a
promuovere la variabile al tipo superiore
• Nel primo esempio y è promossa da int a float
B. ESPLICITA
• Viene effettuata direttamente dal programmatore

Variabili e tipi 2013/2014 Pagina 50


Unità 2
Gerarchia di promozione

TIPO SUPERIORE long double TIPO SUPERIORE

double
float
unsigned long PERDITA DI
PROMOZIONE PRECISIONE
long
unsigned int
int
short
TIPO INFERIORE
char TIPO INFERIORE

Variabili e tipi 2013/2014 Pagina 51


Unità 2
Conversione implicita - operatori binari

• Nel caso di operatori binari con operandi di tipo diverso: il tipo


inferiore viene promosso al superiore ed il risultato è del tipo
superiore
• Nel caso di assegnazione è il tipo della variabile assegnata che
comanda: l’espressione viene convertita a tale tipo

ESEMPIO
a = c + b; ( c di tipo float e b di tipo double)
• c è promosso a double e l’espressione è di tipo double
• Ma se a è float allora il valore dell’espressione verrà poi
riconvertito a float (con perdita di informazione)

Variabili e tipi 2013/2014 Pagina 52


Unità 2
Conversione implicita – funzioni

• Gli argomenti passati ad una funzione vengono convertiti


secondo quanto specificato nel prototipo con potenziale
perdita di informazione
• All’atto del return, il valore dell’espressione assegnata a
return viene convertito a quello della funzione (potenziale
perdita di informazione)
ESEMPIO
int f(float,int);
• Chiamata f(a,b) con a di tipo int e b di tipo float
• a è convertito a float e b a int
• Nella funzione, l’esecuzione di return a * b converte il
risultato float di a * b in int
Variabili e tipi 2013/2014 Pagina 53
Unità 2
Conversione esplicita (cast)
Per convertire esplicitamente dati da un tipo ad un altro si
deve effettuare un’operazione di cast
SINTASSI
(tipo) espressione
− tipo: è un nome di tipo
− espressione: è l’espressione della quale si desidera
convertire il tipo
SEMANTICA
− Converte il tipo di una espressione ad un altro tipo
− Ciò rende possibili operazioni che coinvolgono tipi
altrimenti incompatibili

Valutare sempre con cura l’effetto delle conversioni di tipo.


Il compilatore non segnala, eventuali situazioni rischiose

Variabili e tipi 2013/2014 Pagina 54


Unità 2
Esempio: cast

#include <stdio.h>

int main () {
long b = 90000L;
short a = (short) 3.75; // cast a short
// dell’espressione 3.75
// (di tipo double)
printf("%d\n", a);
a = b; //assegno long a short
printf("%d\n", a);
printf("%d\n", b);
return 0;
}

Variabili e tipi 2013/2014 Pagina 55


Unità 2
Esempio: cast (esecuzione)

• Il valore 3.75 è troncato all’intero e viene stampato 3 (casting esplicito)


• Il valore 90000 eccede l’intervallo dello short int e quindi il casting
implicito produce un effetto devastante

Variabili e tipi 2013/2014 Pagina 56


Unità 2
Tipo char
• In C i caratteri fanno parte del tipo intero
• Sono memorizzati con il valore corrispondente al loro codice:
− ASCII (American Standard Code for Information Interchange)
− EBCDIC (usato in casa IBM)
• Letterali di tipo char sono caratteri tra apici
ESEMPI
char c;
c = 'A'; c vale 65 in entrambi i casi
c = 65; (il codice ASCII di A è 65)
char a, b;
a = 5; a vale 5
a = '5'; a vale 53 , il codice ASCII di 5
Variabili e tipi 2013/2014 Pagina 57
Unità 2
Codice ASCII
• È un codice a 8 bit , del quale però il codice base copre solo le
prime 128 combinazioni (ASCII standard)
• 33 di questi 128 caratteri sono non stampabili
• È tuttora il codice più diffuso
• È stato pensato per la lingua inglese
• Non copre caratteri accentati, segni dicroici, ecc.
• Le estensioni a 256 bit non sono univoche
• Essendo un codice ad 8 bit a ciascun carattere è associato un
numerale esadecimale di due cifre, che rappresentano gli 8 bit
ESEMPIO
− Il codice HEX per il carattere G è 47
− Il codice binario per G è 01000111
− Il codice decimale per G è 71
Variabili e tipi 2013/2014 Pagina 58
Unità 2
Codice ASCII (Hex 0-1F)

Variabili e tipi 2013/2014 Pagina 59


Unità 2
Codice ASCII (Hex 20-7F)

Variabili e tipi 2013/2014 Pagina 60


Unità 2
Conversioni intero - carattere
• La conversione da char a int corrisponde a calcolare il codice
ASCII del carattere
• La conversione da int a char produce il carattere il cui codice
ASCII corrisponde al valore della variabile intera
ESEMPI
char c; int i;
c = 'A'; c contiene il carattere A
i = (int)c; i vale 65, il codice ASCII di A
c = '5'; c contiene il carattere 5
i = (int)c i vale 53, il codice ASCII di 5
i = (int)c-(int)'0'; i vale 5=53-48 (codice di 0)
c = (char)i; c = ♣ (codice ASCII = 5)

Variabili e tipi 2013/2014 Pagina 61


Unità 2
Domande Vero/Falso
1 char c = 48;
2 int i = 2;
3 printf("%c\n", c);
4 printf("%d\n", i);
5 printf("%d\n", c);
6 printf("%c %d\n", c, c + '2');
7 printf("%d\n", '2' + c);

Sapendo che il codice ASCII di 0 è 48 e che il codice ASCII di 2 è 50,


rispondere con vero o falso alle seguenti affermazioni
1. La riga 3 stampa 0
2. La riga 4 stampa 50
3. La riga 5 stampa 48
4. La riga 6 stampa 48 98
5. La riga 7 stampa 2
Variabili e tipi 2013/2014 Pagina 62
Unità 2
Esercizio
Esercizio 2.6
• Si scriva un programma C in grado di visualizzare tutte le
codifiche ASCII corrispondenti alle lettere del proprio nome.

Variabili e tipi 2013/2014 Pagina 63


Unità 2
Soluzione: Erika
#include <stdio.h>

int main()
{
char c = 'E';
printf("%c corrisponde a %d\n", c, c);
c = 'r';
printf("%c corrisponde a %d\n", c, c);
c = 'i';
printf("%c corrisponde a %d\n", c, c);
c = 'k';
printf("%c corrisponde a %d\n", c, c);
c = 'a';
printf("%c corrisponde a %d\n", c, c);
return 0;
}
Variabili e tipi 2013/2014 Pagina 64
Unità 2
Interi senza segno

• Per tutti i tipi interi, int, short e long è possibile


aggiungere la clausola unsigned per indicare che si vogliono
rappresentare interi senza segno
• In questo caso gli interi vengono rappresentati come binari
naturali, invece che in complemento a 2 o in eccesso
• I corrispondenti intervalli di rappresentazione raddoppiano
ESEMPI
unsigned int i;
unsigned short int k;
signed long m;
La clausola signed e prevista ma non usata essendo il default

Variabili e tipi 2013/2014 Pagina 65


Unità 2
Esempio: signed/unsigned
#include <stdio.h>
int main() {
int x; unsigned int u;
x = 2147483647; u = x;
printf("%d %u\n", x, u);
x = 2147483647+1; u = x;
printf("%d %u\n", x, u);
return 0;
}
Valori stampati
2147483647 2147483647
-2147483648 2147483648

Variabili e tipi 2013/2014 Pagina 66


Unità 2
Esercizi
Esercizio 2.7
• Scrivere un programma che legga un importo in Euro x e
restituisca il corrispondente importo in Dollari.
Esercizio 2.8
• Scrivere un programma che legga da tastiera due numeri interi e
stampi su schermo:
− la loro media aritmetica (la loro somma divisa per 2)
− la loro media geometrica (la radice quadrata del loro
prodotto)

Variabili e tipi 2013/2014 Pagina 67


Unità 2
Domande Vero/Falso (soluzione)
1 char c = 48;
2 int i = 2;
3 printf("%c\n", c);
4 printf("%d\n", i);
5 printf("%d\n", c);
6 printf("%c %d\n", c, c + '2');
7 printf("%d\n", '2' + c);

Sapendo che il codice ASCII di 0 è 48 e che il codice ASCII di 2 è 50,


rispondere con vero o falso alle seguenti affermazioni
1. La riga 3 stampa 0 VERO
2. La riga 4 stampa 50 FALSO stampa 2
3. La riga 5 stampa 48 VERO
4. La riga 6 stampa 48 98 FALSO stampa 0 98 (48+50)
5. La riga 7 stampa 2 FALSO stampa 98 (50+48)
Variabili e tipi 2013/2014 Pagina 68
Unità 2