Introduzione al C

Introduzione al C

Introduzione al C

Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni – BCOR Ingegneria Elettronica – BELR Introduzione al C Unità 2 - Variabili S. Salza, C. Ciccotelli, D. Bloisi, S. Peluso, A. Pennisi

Introduzione al C
  • Sommario – Unità 2 Pagina 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 2017/2018 Unità 2 - Variabili
Introduzione al C
  • Variabili Unità 2 - Variabili Pagina 3
  • 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 2017/2018
Introduzione al C
  • Identificatori di variabili Unità 2 - Variabili Pagina 4
  • 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 2017/2018
Introduzione al C
  • Analogia con le scatole di scarpe Unità 2 - Variabili Pagina 5 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 2017/2018
Introduzione al C

Rappresentazione grafica di variabili Unità 2 - Variabili Pagina 6 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 int var2 487 5640123 487 var2 indirizzo valore nome tipo NOTAZIONE SEMPLIFICATA 2017/2018

Dichiarazione di variabili Unità 2 - Variabili Pagina 7 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 2017/2018

  • Esempi di dichiarazione Unità 2 - Variabili Pagina 8 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 2017/2018

Assegnazione Unità 2 - Variabili Pagina 9 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 2017/2018

  • Esempi di assegnazione Unità 2 - Variabili Pagina 10 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 2017/2018
  • Inizializzazione di una variabile Unità 2 - Variabili Pagina 11
  • 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 2017/2018
  • Esempio: mancata inizializzazione Unità 2 - Variabili Pagina 12 #include 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 2017/2018
  • Inizializzazione: sintassi Unità 2 - Variabili Pagina 13
  • 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; 2017/2018
  • Lettura di una variabile Unità 2 - Variabili Pagina 14
  • 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 2017/2018
  • La funzione scanf Unità 2 - Variabili Pagina 15
  • 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 2017/2018

Specifiche di conversione Unità 2 - Variabili Pagina 16 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 doppia precisione %s stringa di caratteri %e reali in notazione virgola mobile 2017/2018

Esempio scanf Unità 2 - Variabili Pagina 17 #include int 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 2017/2018

Esempio scanf (esecuzione) Unità 2 - Variabili Pagina 18 2017/2018

  • Nome e indirizzo di una variabile Unità 2 - Variabili Pagina 19
  • 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 2017/2018

Esecuzione con x invece di &x Unità 2 - Variabili Pagina 20 2017/2018

  • Errori di input Unità 2 - Variabili Pagina 21
  • 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 2017/2018

Esempio: stampa del valore di ritorno Unità 2 - Variabili Pagina 22 #include int 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 2017/2018

Esempio: esecuzione Unità 2 - Variabili Pagina 23 2017/2018

  • Esercizio Unità 2 - Variabili Pagina 24 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. 2017/2018
  • La funzione square Unità 2 - Variabili Pagina 25 int square ( int num ) { int prodotto; prodotto = num * num; 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 tipo della funzione nome della funzione parametri (tipo e nome) assegna il valore di ritorno 2017/2018
  • La funzione square Unità 2 - Variabili Pagina 26 int square ( int num ) { int prodotto; prodotto = num * num; 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 tipo della funzione nome della funzione parametri assegna il valore di ritorno 2017/2018

Il programma completo Unità 2 - Variabili Pagina 27 #include int square(int); int main() { int x, quadrato; 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; return prodotto; } Prototipo della funzione square Definizione della funzione square Definizione della funzione main (programma principale) Attenzione al & 2017/2018

  • Esercizi Unità 2 - Variabili Pagina 28 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 2017/2018

Tipi di dato Unità 2 - Variabili Pagina 29 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 2017/2018

  • Tipi scalari e aggregati Unità 2 - Variabili Pagina 30
  • I domini dei tipi scalari sono insiemi ordinati
  • I tipi aggregati sono costruiti a partire dagli scalari 2017/2018

Tipi aritmetici Unità 2 - Variabili Pagina 31 2017/2018

Domini dei tipi scalari numerici Unità 2 - Variabili Pagina 32 N.B. Gli intervalli dipendono dal sistema (piattaforma hw/sw) 2017/2018

  • Tipo intero Unità 2 - Variabili Pagina 33
  • 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 2017/2018
  • Tipi short e long Unità 2 - Variabili Pagina 34
  • 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 è possibile 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 2017/2018
  • Valori massimi e minimi Unità 2 - Variabili Pagina 35
  • 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 #include 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; } 2017/2018
  • Overflow Unità 2 - Variabili Pagina 36
  • 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 2017/2018

Esempio: overflow Unità 2 - Variabili Pagina 37 #include int 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; } 2017/2018

Esempio: overflow (esecuzione) Unità 2 - Variabili Pagina 38 N.B. Rappresentazione in complemento a 2 di si nel caso short int : (0111111111111111)CA2 → (+32767) 10 sommando 1 → (100000000000000)CA2 - 32768) 10 2017/2018

  • Tipo float Unità 2 - Variabili Pagina 39
  • 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 2017/2018
  • Tipo double Unità 2 - Variabili Pagina 40
  • 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 2017/2018
  • Valori massimi e minimi (reali) Unità 2 - Variabili Pagina 41
  • Sono costanti la cui definizione è contenuta in float.h
  • Il file si trova nella directory MinGw\include
  • Verificare i valori con il seguente programma: #include #include int main() { printf("FLT_MIN =%E\n", FLT_MIN ); printf("FLT_MAX =%E\n", FLT_MAX ); printf("DBL_MIN =%E\n", DBL_MIN ); printf("DBL_MAX =%E\n", DBL_MAX ); return 0; } 2017/2018
  • Operatori assegnazione composta Unità 2 - Variabili Pagina 42
  • 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: % % = 2017/2018
  • Operatori di incremento e decremento Unità 2 - Variabili Pagina 43
  • 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--; 2017/2018
  • Operatori di pre-post incremento Unità 2 - Variabili Pagina 44 2017/2018
  • Esistono due forme di incremento:
  • Pre-incremento: l’operatore è prefisso alla variabile ++x;
  • Post-incremento: l’operatore è postfisso alla variabile x++;
  • Entrambe le forme hanno l’effetto di incrementare la variabile di 1 (proprio come += 1)
  • La differenza sta nell'ordine cui avvengono le due azioni di incremento e di calcolo dell'espressione
  • Lo stesso discorso vale per il decremento: --x; pre-decremento x--; post-decremento

Pre-incremento in espressioni Unità 2 - Variabili Pagina 45 2017/2018 Nel caso di pre-incremento, l'ordine delle operazioni è: 1.

Viene incrementata la variabile che compare nell'espressione 2. Viene calcolata l'espressione ESEMPIO x = 5; int y = 3 * ++x; x = 5; x = x + 1; int y = 3 * x; equivale a In entrambi i casi alla fine x vale 6 e y vale 18

Post-incremento in espressioni Unità 2 - Variabili Pagina 46 2017/2018 Nel caso di pre-incremento, l'ordine delle operazioni è: 1. Viene calcolata l'espressione 2. Viene incrementata la variabile che compare nell'espressione ESEMPIO x = 5; int y = 3 * x++; x = 5; int y = 3 * x; x = x + 1; equivale a In entrambi i casi alla fine x vale 6 e y vale 15

  • Side-effect Unità 2 - Variabili Pagina 47 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 2017/2018
  • Side-effect: esempi Unità 2 - Variabili Pagina 48
  • 23*x+5 è una espressione senza side-effect 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 2017/2018
  • Stile sobrio con le espressioni Unità 2 - Variabili Pagina 49
  • 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); per meglio evidenziare l’effetto sul valore di y. 2017/2018
  • Costanti Unità 2 - Variabili Pagina 50
  • La maniera più semplice di utilizzare un valore costante in un programma è 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 rappresenti 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; 2017/2018

  • Definizione di costanti tramite #define Unità 2 - Variabili Pagina 51
  • 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 2017/2018

Esercizio: teorema di Pitagora Unità 2 - Variabili Pagina 52 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 2017/2018

Soluzione: teorema di Pitagora Unità 2 - Variabili Pagina 53 #include #include 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; } 2017/2018

Conversione di tipi Unità 2 - Variabili Pagina 54 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 2017/2018

Gerarchia di promozione Unità 2 - Variabili Pagina 55 long double double float unsigned long long unsigned int int short char TIPO SUPERIORE TIPO INFERIORE TIPO SUPERIORE TIPO INFERIORE PROMOZIONE PERDITA DI PRECISIONE 2017/2018

  • Conversione implicita - operatori binari Unità 2 - Variabili Pagina 56
  • 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) 2017/2018
  • Conversione implicita – funzioni Unità 2 - Variabili Pagina 57
  • 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 2017/2018

Conversione esplicita (cast) Unità 2 - Variabili Pagina 58 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 2017/2018

Esempio: cast Unità 2 - Variabili Pagina 59 #include 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; } 2017/2018

  • Esempio: cast (esecuzione) Unità 2 - Variabili Pagina 60
  • 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 2017/2018
  • Tipo char Unità 2 - Variabili Pagina 61
  • 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 2017/2018
  • Codice ASCII Unità 2 - Variabili Pagina 62
  • È 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 2017/2018

Codice ASCII (Hex 0-1F) Unità 2 - Variabili Pagina 63 2017/2018

Codice ASCII (Hex 20-7F) Unità 2 - Variabili Pagina 64 2017/2018

  • Conversioni intero - carattere Unità 2 - Variabili Pagina 65
  • 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) 2017/2018

Domande Vero/Falso Unità 2 - Variabili Pagina 66 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 2017/2018

  • Esercizio Unità 2 - Variabili Pagina 67 Esercizio 2.6
  • Si scriva un programma C in grado di visualizzare tutte le codifiche ASCII corrispondenti alle lettere del proprio nome. 2017/2018

Soluzione: Erika Unità 2 - Variabili Pagina 68 #include 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; } 2017/2018

  • Interi senza segno Unità 2 - Variabili Pagina 69
  • 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 2017/2018

Esempio: signed/unsigned Unità 2 - Variabili Pagina 70 #include 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 2017/2018

  • Esercizi Unità 2 - Variabili Pagina 71 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) 2017/2018

Domande Vero/Falso (soluzione) Unità 2 - Variabili Pagina 72 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) 2017/2018

Vai alle pagine successive ... Annulla