6. Tipi di dati Ing. Simona Colucci Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari • • • • • • Indice Tipi di dati astratti Classificazione dei tipi di dati Tipi semplici predefiniti Costruzione di nuovi tipi semplici Tipi strutturati Regole di compatibilità Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari • Tipi di dati astratti Tipo di dato : tipo di informazione, di natura eterogenea(interi, reali, caratteri, array, fatture, conti correnti, pagine web, …) • Definizione generale di tipo di dato: Insieme di valori e di operazioni ad esso applicabili • Tipo astratto: conta la visione esterna, non la rappresentazione interna, ovvero il punto di vista di chi usa il tipo, non di chi lo realizza – Immaginiamo di dover trattare direttamente come stringhe di bit la divina commedia, una pagina web, … – Inoltre potremo talvolta usare diverse rappresentazioni concrete per la stessa astrazione Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Dichiarazioni di tipo • In C è necessario associare un tipo a tutte le variabili, al momento della dichiarazione; ciò comporta che: – Per ogni variabile è possibile determinare l’insieme dei valori ammissibili e delle operazioni ad essa applicabili – Per ogni variabile è calcolabile a priori la quantità di memoria necessaria: la memoria per l’esecuzione di tutto il programma può essere calcolata in fase di compilazione(eccezione:allocazione dinamica) – E’ possibile rilevare errori nell’uso delle variabili durante la compilazione del programma: espressioni o assegnamenti coinvolgenti variabili eterogenee Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Tipi di dato: classificazioni • In base alla complessità delle informazioni rappresentate: – Tipi semplici (interi, caratteri, reali, …): rappresentano informazione logicamente indivisibile – Tipi strutturati (array, …): rappresentano informazione logicamente scomponibile • In base all’ utilizzabilità nel linguaggio: – Tipi predefiniti nel linguaggio(built in): interi, caratteri, … – Tipi definiti dall’utente per soddisfare le infinite e imprevedibili esigenze(user defined): fattura, data,… – N:B. tale classificazione dipende dal linguaggio: in C variabili come età, data, conto_corrente non sono predefiniti(devono essere costruiti dal programmatore); in altri linguaggi “special purpose” potrebbero esserlo (e.g. data nei fogli elettronici) Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Tipo predefinito char signed char unsigned char signed short int signed int signed long int unsigned short int unsigned int unsigned long int float double long double Tipi semplici predefiniti del C Tipi base Denominazioni alternative signed short, short signed, int long int, signed long, long unsigned short unsigned unsigned long char caratteri int interi float reali double reali in precisione doppia Qualificatori short condizionano lo spazio allocato per le variabili long signed unsigned Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 condizionano i valori assumibili dalle variabili Sistemi Informativi DEE - Politecnico di Bari Il tipo int: dominio • Il tipo int in C è un approssimazione del tipo intero matematico, dai valori infiniti • Lo spazio allocato per la rappresentazione e l’insieme dei valori dipendono dalla macchina: in genere un variabile di tipo int è memorizzata in una parola di memoria • Se il compilatore gestisce short e long int vale la regola: spazio allocato (short int)≤ spazio allocato (int) ≤ spazio allocato (long int) • I tipi unsigned int e signed int sono gestiti come visto per i naturali e i relativi nel capitolo 4 – – spazio allocato (signed int)= spazio allocato (unsigned int) cambia l’insieme dei valori rappresentabili, ma non lo spazio di rappresentazione Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Il tipo int: operazioni Operazioni built-in per dati di tipo int = Assegnamento di un valore int a una variabile int + Somma (tra int ha come risultato un int) - Sottrazione (tra int ha come risultato un int) * Moltiplicazione (tra int ha come risultato un int) / Divisione con troncamento della parte non intera (risultato int) % Resto della divisione intera ==Relazione di uguaglianza != Relazione di diversità < Relazione “minore di” > Relazione “maggiore di” <=Relazione “minore o uguale a” >=Relazione “maggiore o uguale a” Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi I tipi float e double: dominio DEE - Politecnico di Bari • • Approssimano i numeri reali come limite e precisione di rappresentazione Due diverse rappresentazioni: 1. la normale rappresentazione decimale, o in virgola fissa: 3.14 1 234.543 328 543. 0.000 076 2. la rappresentazione in virgola mobile (floating point) mantissa ed esponente (della base 10), separate dal carattere “E” 1 780 000.000 0023 può essere rappresentato in virgola mobile nei modi seguenti: 178 000.000 000 23E1 17 800 000 000 023E-7 1.780 000 000 0023E+6, …. • • Le notazioni sono interscambiabili e la macchina provvede automaticamente alle necessarie conversioni La quantità di memoria allocata dipende dalla macchina ma vale la seguente regola: Spazio allocato (float) spazio allocato (double) spazio allocato (long double) Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari I tipi float e double: operazioni Operazioni built-in per dati di tipo float e double = + * / == != < > <= >= Assegnamento Somma Sottrazione Moltiplicazione Divisione (a risultato reale) Relazione di uguaglianza Relazione di diversità Relazione “minore di” Relazione “maggiore di” Relazione “minore o uguale a” Relazione “maggiore o uguale a” Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari I tipi float e double • La standard library fornisce anche diverse funzioni matematiche predefinite: (sqrt, pow, exp, sin, cos, tan...) (per double ). • Attenzione agli arrotondamenti: – (x/y) * y == x potrebbe risultare falsa ! – Invece di scrivere if (x == y) ...è meglio scrivere: if (x <= y + .000001 && y <= x + .000001) .. Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Il tipo char • L’insieme dei dati di tipo char, è l’insieme dei caratteri ASCII, e contiene tutte le lettere, le cifre e i simboli disponibili sulle normali tastiere. • caratteri di controllo: – \n = “a capo”, \b = “backspace”, \t = “horizontal tab”, \r = “carriage return”, ETX, EOF, .... • La codifica ASCII consente la rappresentazione di ciascun carattere attraverso un opportuno valore intero, per cui le operazioni sono quelle definite sugli interi: – È definito l’ordinamento dei valori: per qualsiasi coppia di caratteri x e y, x < y se e solo se x precede y nell’elenco dei caratteri – Sono definite le operazioni di assegnamento (=), le operazioni aritmetiche (+, –, *, /, %) e quelle relazionali (==, !=, < ecc.) • La memoria allocata è di un byte, anche con i qualificatori signed e unsigned Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Esempio /* Programma Manipolazione Caratteri */ #include <stdio.h> main() { char C, CM; printf("Inserire un carattere – # per terminare il programma\n"); scanf(“ %c", &C); /*NB lo spazio prima di %*/ while (C != '#') { printf("Il codice ASCII del carattere %c è %d\n", C, C); /* Se il carattere è una lettera minuscola */ if (C >= 'a' && C <= 'z') { /* La differenza 'a' – 'A' è lo scarto fra la rappresentazione ASCII delle lettere maiuscole e minuscole dell'alfabeto */ CM = C – ('a' –'A'); printf("La lettera maiuscola per %c è %c e il suo codice ASCII è %d\n", C, CM, CM); } printf("Inserire un carattere – # per terminare il programma\n"); scanf(“ %c", &C); } } Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari La costruzione di nuovi tipi in C • Regola sintattica: typedef int anno; • Una volta definito e identificato un nuovo tipo ogni variabile può essere dichiarata di quel tipo come di ogni altro tipo già esistente: – – char anno x; y; • NB: typedef non consente di costruire veri e propri nuovi tipi astratti (mancano le operazioni …) Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Ridefinizione typedef TipoEsistente NuovoTipo; • TipoEsistente può essere sia un tipo built-in (predefinito), sia un tipo precedentemente definito: – – – – typedef typedef typedef typedef int char tipo1 tipo2 tipo1; tipo2; tipo3; tipo4; Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi Enumerazione esplicita dei valori DEE - Politecnico di Bari typedef typedef typedef typedef enum enum enum enum {lun, mar, mer, gio, ven, sab, dom} GiornoDellaSettimana; {rosso, verde, giallo, arancio, marrone, nero} colore; {Giovanni, Claudia, Carla, Simone, Serafino} persone; {gen, feb, mar, apr, mag, giu, lug, ago, set, ott, nov, dic} mese; • Dichiarazioni: – persone individuo, individuo1, individuo2; • Istruzioni: – individuo = Giovanni; – if (individuo1 == individuo2) individuo = Claudia; Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Enumerazione esplicita dei valori • Alcune osservazioni: – Spesso i valori del nuovo tipo sono rappresentati da nomi; però il compilatore associa a tali nomi un progressivo valore intero – Per esempio, x di tipo mese: • gen è in realtà 0, apr è in realtà 3, ecc. • Operazioni applicabili: le stesse degli interi – Le seguenti operazioni: apr < giu rosso < arancio producono come risultato un intero diverso da 0 (valore logico “true”); – Le seguenti operazioni: dom < lun Simone < Giovanni producono 0 (valore “false”). Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Enumerazione esplicita dei valori • Un importante caso particolare: typedef boolean enum {false, true} boolean; flag, ok; • flag e ok possono così essere definite come variabili in grado di assumere valore vero (true) o falso (false) durante l’esecuzione di un programma che le usi. • NB: non invertire l’ordine! Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Tipi strutturati • Il C non mette a disposizioni tipi strutturati built in • E’ possibile usare dei costruttori di tipo per definire tipi strutturati: – Array : costruisce un tipo di dato i cui elementi sono sequenze omogenee di valori appartenenti ad un unico tipo – Struct: costruisce un tipo di dato i cui elementi sono sequenze eterogenee di valori appartenenti a tipi diversi – Puntatore: costruisce tipi semplici tramite l’indirizzo della cella di memoria che li contiene Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari I tipi strutturati: Il costruttore array • Gli array si dichiarano come segue: – Tipo di dato Identificatore array[numero elementi] – Esempio: int lista[20]; • La dichiarazione è un’abbreviazione per: typedef int arrayAnonimo lista; arrayAnonimo[20]; /*Definizione del nuovo tipo arrayAnonimo*/ /*Dichiazione di variabile di tipo arrayAnonimo*/ • Si possono costruire array che contengono elementi di tipo user defined typedef enum colore{bianco, rosso, verde} colore colori[20] Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Array: Quando esplicitare il nome del tipo? • Dichiarazione mediante nuovo tipo: typedef double VettoreDiReali[20]; VettoreDiReali v1, v2, v3; • Più semplice e altrettanto chiara: double v1[20], v2[20], v3[20]; • Dichiarazione mediante nuovi tipi: typedef double PioggeMensili[12]; typedef double IndiciBorsa[12]; PioggeMensili Piogge01, Piogge02, Piogge03; IndiciBorsa Indici01, Indici02, Indici03; • Preferibile a: double Piogge01[12], Piogge02[12], Piogge03[12], Indici01[12], Indici02[12], Indici03[12]; Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi Matrici DEE - Politecnico di Bari • E’ possibile definire un array typedef typedef MatriceIntera20Per20 di array (una matrice): int Vettore[20]; Vettore MatriceIntera20Per20[20]; matrice1; – Oppure, più brevemente: typedef int MatriceIntera20Per20 MatriceIntera20Per20[20][20]; matrice1; – Ancor più brevemente: int matrice1[20][20]; • E’ possibile definire array di array di array…: int matriceTridimensionale1[10][20][30] Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi Dimensione degli array DEE - Politecnico di Bari • Un array ha dimensioni fisse minor flessibilità del linguaggio typedef char String String[30]; Nome, Cognome; – Parole corte provocano spreco di memoria (fisica) – Parole lunghe: dovremmo anche prevedere istruzioni del tipo: if (LunghezzaParola == 30) printf("Parola troppo lunga"); • Perché? Principio dell’allocazione statica della memoria: stimando a priori la grandezza delle variabili si evita di ricercare parti della memoria fisicamente disponibili sulla macchina stessa durante l’esecuzione Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Un parziale rimedio (1) /* Programma InvertiSequenza */ #include <stdio.h> main() { int Contatore; int Memorizzazione[100]; Contatore = 0; while (Contatore < 100) /* si ricordi che il valore dell'indice di un array di 100 elementi varia da 0 a 99 */ { scanf("%d", &Memorizzazione[Contatore]); Contatore = Contatore + 1; } Contatore = Contatore – 1; while (Contatore >= 0) { printf("%d\n", Memorizzazione[Contatore]); Contatore = Contatore – 1; } } E se invece di 100 la sequenza fosse lunga 1000? Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Un parziale rimedio (2) /* Program InvertiSequenza */ #include <stdio.h> #define LunghezzaSequenza 100 main() { int Contatore; int Memorizzazione[LunghezzaSequenza]; Contatore = 0; while (Contatore < LunghezzaSequenza) { scanf("%d", &Memorizzazione[Contatore]); Contatore = Contatore + 1; } Contatore = Contatore – 1; while (Contatore >= 0) { printf("%d\n", Memorizzazione[Contatore]); Contatore = Contatore – 1; } } NB: la stessa cosa non si poteva fare con la dichiarazione const Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi Assegnamento tra array: attenzione! DEE - Politecnico di Bari Dati i seguenti array: typedef int anArray anArray[10]; Array1, Array2; L’istruzione: Array2 = Array1; E’ scorretta! Sarà necessaria un’istruzione ciclica che “scorra” i singoli elementi dell’array(capiremo il perché in seguito) Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Programma concatenazione stringhe (1) #include <stdio.h> #define LunghezzaArray 50 main() { int i, j, k; char TempCar; char Array1[LunghezzaArray], Array2[LunghezzaArray]; /* Nella seguente dichiarazione il valore LunghezzaArray]*2 è un valore costante calcolato a tempo di compilazione */ char ArrayConc[LunghezzaArray*2]; /* Legge la prima stringa assicurandosi che essa non superi la dimensione dell'array, 50 caratteri /* i = 0; while (i < LunghezzaArray) /* Si ricordi che il valore dell'indice di un array di LunghezzaArray elementi è compreso fra 0 e LunghezzaArray–1 */ { scanf("%c", &TempCar); Array1[i] = TempCar; i = i + 1; } Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Programma concatenazione stringhe (2) … /* Legge la seconda stringa assicurandosi che essa non superi la dimensione dell'array, 50 caratteri /* i = 0; while (i < LunghezzaArray) { scanf("%c", &TempCar); Array2[i] = TempCar; i = i + 1; } /* Confronta le due stringhe per capire quale precede l'altra in ordine alfabetico */ i = 0; while (i < LunghezzaArray && Array1[i] == Array2[i]) i = i+1; if (i == LunghezzaArray || Array1[i] < Array2[i]) /* Le due stringhe sono uguali o la prima precede la seconda in ordine alfabetico */ … Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Programma concatenazione stringhe (3) … /* Le due stringhe sono uguali o la prima precede la seconda in ordine alfabetico */ { k = 0; j = 0; while (j < LunghezzaArray) { ArrayConc[k] = Array1[j]; k = k + 1; j = j + 1; } j = 0; while (j < LunghezzaArray) { ArrayConc[k] = Array2[j]; k = k + 1; j = j + 1; } } else … Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Programma concatenazione stringhe (4) … /* Se la seconda stringa precede la prima in ordine alfabetico, ossia se (Array2[i] < Array1[i]) */ { k = 0; j = 0; while (j < LunghezzaArray) { ArrayConc[k] = Array2[j]; k = k + 1; j = j + 1; } j = 0; while (j < LunghezzaArray) { ArrayConc[k] = Array1[j]; k = k + 1; j = j + 1; } } /* Stampa la stringa ottenuta dalla concatenazione */ k = 0; while (k < (LunghezzaArray*2)) {printf("%c", ArrayConc[k]); k = k + 1;} } Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari I tipi strutturati: Il costruttore struct • Esempi di informazioni da formalizzare con i tipi strutturati: – Tipo impiegato: nome, cognome, codice fiscale, indirizzo, numero di telefono, eventuali stipendio, data di assunzione… – Tipo famiglia: un certo insieme di persone, un patrimonio, costituito a sua volta da un insieme di beni, ognuno con un suo valore, un reddito annuo, spese varie, … • Queste strutture informative sono eterogenee: l’array non si presta a questo tipo di aggregazione. • Il costruttore di record (parola chiave struct in C) è la risposta a questo tipo di esigenze • Gli elementi eterogenei aggregati in un’unica struttura si chiamano campi della struttura Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Il costruttore struct: Esempi typedef char String[50]; typedef struct { } typedef struct { } int Giorno; int Mese; int Anno; Data; String Destinatario; int Importo; Data DataEmissione; DescrizioneFatture; Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Il costruttore struct: Esempi typedef enum {On, Off} typedef struct { } AccType; int Canale; AccType Accensione; double CursoreLuminosita, CursoreColore, CursoreVolume; CanaliTV; Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Il costruttore struct: Esempi typedef enum {Dirigente, Impiegato, Operaio} CatType; typedef struct { } String String int char Data CatType Dipendenti; Nome; Cognome; Stipendio; CodiceFiscale[16]; DataAssunzione; Categoria; Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Il costruttore struct: Sistemi Informativi DEE - Politecnico di Bari • Dichiarazione di variabili La dichiarazione di variabili procede poi come al solito: Dipendenti Dip1, Dip2; • Oppure è possibile definire il nuovo tipo in forma anonima e nello stesso tempo dichiarare le variabili: struct { } String Nome; String Cognome; int Stipendio; char CodiceFiscale[16]; Data DataAssunzione; CatType Categoria; Dip1, Dip2; Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Accesso alle componenti del record • Per accedere alle singole componenti del record, si usa una notazione detta dot notation: Dip1.Stipendio = Dip1.Stipendio + (Dip1.Stipendio*10) / 100; Dip1.DataAssunzione.Giorno = 3; Dip1.DataAssunzione.Mese = 1; Dip1.DataAssunzione.Anno = 1993; if (Dip1.Cognome[0] == 'A') … DichiarazioneFatture ArchivioFatture[1000]; if (ArchivioFatture[500].DataEmissione.Anno <= 2000) printf("%d", ArchivioFatture[500].Importo); else printf("La fattura in questione è stata emessa dopo il 2000\n"); Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi Assegnamento tra record DEE - Politecnico di Bari • Una stranezza del C: come abbiamo visto, non è permesso scrivere un assegnamento tra array Array2 = Array1; • Invece: Dip1 = Dip2; • E’ lecito e fa esattamente ciò che ci si aspetta: copia l’intera struttura Dip1 in Dip2, comprese le sue componenti che sono costituite da array! Il perché di questa stranezza risiede nel modo in cui in C sono realizzati gli array Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi Il costruttore puntatore (1) DEE - Politecnico di Bari • Puntatore ad una variabile: • Dichiarazione di una variabile puntatore: – indica l’indirizzo della variabile a cui fa riferimento – costruisce tipi semplici – Consente di riferirsi ad una variabile tramite indirizzo e non solo tramite nome typedef TipoDato *TipoPuntatore; definisce il tipo TipoPuntatore come un puntatore ad una cella di memoria contenente un valore di tipo TipoDato P Valore di tipo TipoDato • Dereferenziazione: *P indica la cella di memoria il cui indirizzo è contenuto in P typedef TipoPuntatore TipoDato x; TipoDato *TipoPuntatore; P; Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi Il costruttore puntatore (2) DEE - Politecnico di Bari • L’operatore unario & significa “indirizzo di” ed è il duale dell’operatore ‘*’. typedef TipoPuntatore TipoDato TipoDato *TipoPuntatore; P, Q; y, z; P = &y; Q = &z; P = Q; • y e z sono di tipo TipoDato mentre P e Q sono puntatori a variabili di tipo TipoDato. Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi Il costruttore puntatore : Esempi DEE - Politecnico di Bari P 14 *P = 14; x x = 23; 23 P 23 *P = x; x 23 Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Il costruttore puntatore : Esempi P 14 x 23 P 14 x = *P; x 14 Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi Il costruttore puntatore : Esempi DEE - Politecnico di Bari P 14 P = &y; Q Q = &z; y z 23 P = Q; • Attenzione: è vero che P = Q; *P = *Q; ?? Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari typedef TipoDato typedef AltroTipoDato TipoDato TipoDato TipoPuntatore AltroTipoPuntatore TipoDato AltroTipoDato Puntatori e tipi *TipoPuntatore; *AltroTipoPuntatore; *Puntatore; **DoppioPuntatore; P, Q; P1, Q1; x, y; z, w; istruzioni corrette: istruzioni scorrette: Puntatore = &y; DoppioPuntatore = &P; Q1 = &z; P = &x; P = Q; *P = *Q; *Puntatore = x; P = *DoppioPuntatore; z = *P1; Puntatore = P; P1 = P; w = *P; *DoppioPuntatore = y; Puntatore = DoppioPuntatore; *P1 = *Q; Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 (warning) (error) (warning) (warning) (error) Sistemi Informativi DEE - Politecnico di Bari Una tipica abbreviazione del C... • Definiamo un record e dichiariamo una variabile puntatore: typedef struct { int char TipoDato; } TipoDato P = &x; PrimoCampo; SecondoCampo; x, *P; • Accesso al campo PrimoCampo di x, attraverso il puntatore P, usando la dot notation: (*P).PrimoCampo = 12; /* Inserisce 12 nel campo PrimoCampo di x */ • Esiste una sintassi abbreviata: P–>PrimoCampo = 12; /* Inserisce 12 nel campo PrimoCampo di x */ Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Costruttore puntatore: operazioni • Operazioni applicabili a variabili puntatori: – assegnamento dell’indirizzo di una variabile tramite l’operatore unario &; – assegnamento del valore di un altro puntatore; – assegnamento del valore speciale NULL. Se una variabile puntatore ha valore NULL, *P è indefinito: P non punta ad alcuna informazione significativa. – – – – l’operazione di dereferenziazione, indicata dall’operatore *; il confronto basato sulle relazioni ==, !=, >, <, <=, >=; operazioni aritmetiche l’assegnamento di indirizzi di memoria a seguito di operazioni di allocazione esplicita di memoria (gli ultimi due casi verranno trattati in seguito); Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi Esempio DEE - Politecnico di Bari /* Programma Dirigenti */ #include <stdio.h> main() { typedef enum typedef struct Lavoratore Lavoratore { { dirigente, impiegato, operaio CatLav; char Nome[30]; char Cognome[30]; CatLav Categoria; int Stipendio; char CodiceFiscale[16]; } Lavoratore; DatiLavoratori[300]; *Management[10]; ... Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Esempio /* Programma Dirigenti (continuazione) */ ... i = 0; while (i < 10) { if (Management[i]–>Stipendio > 5000000) { j = 0; while (j < 30) { printf("%c", Management[i]–>Cognome[j]); j = j + 1; } printf("%d \n", Management[i]–>Stipendio); } } i = i + 1; } Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi “Rischi” dei puntatori DEE - Politecnico di Bari • Effetti collaterali (side effects): – Esempio *P = 3; *Q = 5; P = Q; /* a questo punto *P = 5 */ *Q = 7; A questo punto *Q = 7, ma anche *P = 7 • Un assegnamento esplicito alla variabile puntata da Q determina un assegnamento nascosto alla variabile puntata da P. • Caso particolare di aliasing, ovvero del fatto che uno stesso oggetto viene identificato in due modi diversi Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Array e puntatori (1) • L’operatore sizeof produce il numero di byte occupati da ciascun elemento di un array o da un array nel suo complesso. – Se si usano quattro byte per la memorizzazione di un valore int: int a[5]; allora sizeof(a[2]) restituisce il valore 4 e: sizeof(a) restituisce il valore 20. • Il nome di una variabile di tipo array viene considerato in C come l’indirizzo della prima parola di memoria che contiene il primo elemento della variabile di tipo array (lo 0-esimo …). • Se ne deduce: – a “punta” a una parola di memoria esattamente come un puntatore; – a punta sempre al primo elemento della variabile di tipo array (è un puntatore “fisso” al quale non è possibile assegnare l’indirizzo di un’altra parola di memoria) Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari • • • • • • Array e puntatori (2) Il C consente di eseguire operazioni di somma e sottrazione su puntatori. Se p e a forniscono l’indirizzo di memoria di elementi di tipo opportuno, p+i e a+i forniscono l’indirizzo di memoria dell’i-esimo elemento successivo di quel tipo Se i è una variabile intera: la notazione a[i] è equivalente a *(a+i) Analogamente, se p è dichiarato come puntatore a una variabile di tipo int: la notazione p[i] è equivalente a *(p+i). Ne segue che: p=a è equivalente a p = &a[0]; p = a+1 è equivalente a p = &a[1]; Mentre non sono ammessi assegnamenti ad a del tipo: a = p; a = a +1; Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Array e puntatori (3) • Se p e q puntano a due diversi elementi di un array, p–q restituisce un valore intero pari al numero di elementi esistenti tra l’elemento cui punta p e l’elemento cui punta q, non la differenza tra il valore dei puntatori • Supponendo che il risultato di p–q sia pari a 3 e supponendo che ogni elemento dell’array sia memorizzato in 4 byte, la differenza tra l’indirizzo contenuto in p e l’indirizzo contenuto in q darebbe 12 Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Compatibilità tra tipi (1) Espressioni che coinvolgono elementi eterogenei in tipo • Un’espressione aritmetica come x + y è caratterizzata dal valore e dal tipo del risultato. • Il tipo degli operandi condiziona l’operazione che deve essere eseguita. (A operandi di tipo int si applica l’operazione di somma propria di tale tipo, diversa è l’operazione di somma che si applica a operandi di tipo float ecc.) • Se x è di tipo short e y di tipo int è necessario convertire una delle due variabili per rendere omogenea l’espressione e applicare la corretta operazione. x viene temporaneamente convertita in int e la somma tra interi restituisce un risultato intero Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Compatibilità tra tipi (2) • Regole di conversione implicita: – ogni variabile di tipo char o short (incluse le rispettive versioni signed o unsigned) viene convertita in variabile di tipo int; – se dopo l’esecuzione del passo 1 l’espressione risulta ancora eterogenea rispetto al tipo degli operandi coinvolti, rispetto alla gerarchia int < long < unsigned < unsigned long < float < double < long double si converte temporaneamente l’operando di tipo inferiore facendolo divenire di tipo superiore; il risultato dell’espressione avrà tipo uguale a quello di più alto livello gerarchico Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Compatibilità tra tipi (3) Assegnamenti che coinvolgono elementi eterogenei in tipo • Le regole di conversione implicita esposte vengono utilizzate anche per la valutazione di assegnamenti tra variabili eterogenee in tipo: – Esempio • Double d; int i; d = i; provoca una temporanea conversione del valore dell’intero i a double e successivamente l’assegnamento di tale valore double a d • Invece: i = d; comporta, normalmente, una perdita di informazione. Il valore di d subisce infatti un troncamento alla parte intera con perdita della parte decimale. • Puntatori e tipizzazione delle variabili puntate: Viene segnalato dal compilatore il tentativo di utilizzo congiunto di puntatori dichiarati come puntanti a dati di tipo differente Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010 Sistemi Informativi DEE - Politecnico di Bari Errori a Compile-time ed errori a Run-time • Le regole di uso dei tipi del C sono tutte verificabili “a compile-time” • Questa caratteristica viene anche indicata come tipizzazione forte; non tutti i linguaggi ne sono dotati • Altri errori “a compile-time”: – Errato annidamento di parentesi – Mancata o errata dichiarazione di variabile – … • Errori a run-time: – Divisione per 0 – Indice di un array fuori dai limiti – Accesso ad una variabile non inizializzata – … Fondamenti di Informatica CDL in Ingegneria Meccanica (B) - A.A. 2009-2010