1 / 42

Array e puntatori

Array e puntatori. Corso di Informatica A Vito Perrone. Indice. Tipi di dati strutturati: Array Puntatori Tipi di dati strutturati: Array Esempio. I tipi strutturati: 1. Il costruttore array. Definizione del nuovo tipo anArray : typedef int anArray[20];

nigel-west
Download Presentation

Array e puntatori

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Array e puntatori Corso di Informatica A Vito Perrone

  2. Indice • Tipi di dati strutturati: Array • Puntatori • Tipi di dati strutturati: Array • Esempio Strutture di controllo in C Informatica A – V. Perrone

  3. I tipi strutturati:1.Il costruttore array • Definizione del nuovo tipo anArray:typedef int anArray[20]; • dichiazione di variabili di tipo anArray:anArray lista1, lista2; • La dichiarazione:int lista[20]; • Va perciò interpretata come un’abbreviazione per:typedefint arrayAnonimo[20];arrayAnonimo lista; Strutture di controllo in C Informatica A – V. Perrone

  4. Quando esplicitare il nome del tipo? • Dichiarazione mediante nuovo tipo: • typedef doubleVettoreDiReali[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]; Strutture di controllo in C Informatica A – V. Perrone

  5. Matrici • E’ possibile definire un array di array (una matrice): • typedef intVettore[20]; • typedefVettore MatriceIntera20Per20[20]; • MatriceIntera20Per20 matrice1; • Oppure, più brevemente: • typedefint MatriceIntera20Per20[20][20]; MatriceIntera20Per20 matrice1; • Anche una matrice può essere definita in modo abbreviato: • int matrice1[20][20]; • E’ possibile definire array di array di array…: • int matriceTridimensionale1[10][20][30]; • Per accedere agli elementi di matriceTridimensionale1: • matriceTridimensionale1[2][8][15] • colore ListaColori[10]; Strutture di controllo in C Informatica A – V. Perrone

  6. Dimensione degli array • Un array ha dimensioni fisse minor flessibilità del linguaggio typedef charString[30]; String 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. Strutture di controllo in C Informatica A – V. Perrone

  7. 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; } … Strutture di controllo in C Informatica A – V. Perrone

  8. Un parziale rimedio (2) /* Programma InvertiSequenza (continuazione) */ … Contatore = Contatore – 1; while (Contatore >= 0) { printf("%d\n", Memorizzazione[Contatore]); Contatore = Contatore – 1; } } E se invece di 100 la sequenza fosse lunga 1000? Strutture di controllo in C Informatica A – V. Perrone

  9. Un parziale rimedio (3) /* 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; } … Strutture di controllo in C Informatica A – V. Perrone

  10. Un parziale rimedio (4) /* Program InvertiSequenza (continuazione) */ … 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 Strutture di controllo in C Informatica A – V. Perrone

  11. Assegnamento tra array: attenzione! • Dati i seguenti array:typedef intanArray[10]; anArray Array1, Array2; • L’istruzione:Array2 = Array1; • E’ scorretta! • Sarà necessaria un’istruzione ciclica che “scorra” i singoli elementi dell’array • i = 0; while (i < 10) array2[i] = array1[i]; • Capiremo il perché in seguito Strutture di controllo in C Informatica A – V. Perrone

  12. 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; } … Strutture di controllo in C Informatica A – V. Perrone

  13. 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 */ … Strutture di controllo in C Informatica A – V. Perrone

  14. 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 … Strutture di controllo in C Informatica A – V. Perrone

  15. 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;} } Strutture di controllo in C Informatica A – V. Perrone

  16. Alcune precisazioni sugli array 1/2 • La dichiarazione: int a[100]; alloca memoria per 100 elementi interi, a partire da un certo indirizzo di memoria scelto dal calcolatore • n.b. il numero degli elementi dell’array e la dimensione del tipo base devono essere noti al compilatore • Per accedere a un elemento dell’array a • Si calcola il valore dell’indice (può essere una espressione qualsiasi purchè produca un risultato di tipo integral) • Si somma il valore calcolato moltiplicato per la dimensione (in byte) del tipo base all’indirizzo della prima cella dell’array • Esempio: • Supponendo che l’array a sia allocato a partire dal byte 10000 in memoria. L’elemento a[3] corrisponde all’indirizzo 10000+3*dimInt = 10012 supponendo che un int sia rappresentato con 32 bit (4 byte) • Importante: non viene fatto alcun controllo sul rispetto dei limiti dell’array (Tipico errore) Strutture di controllo in C Informatica A – V. Perrone

  17. Alcune precisazioni sugli array 2/2 • Le stringhe in C sono array di caratteri terminate dal carattere speciale ‘\0’ • Esempio: • char parola[20]; • scanf(“%s”, parola); /* si noti l’assenza del & */ • printf(“%c”, parola[0]); • Esercizio: ….. Strutture di controllo in C Informatica A – V. Perrone

  18. Il costruttore puntatore (1) P Valore di tipoTipoDato • Dichiarazione di una variabile puntatore:typedef TipoDato *TipoPuntatore; • Dereferenziazione: *P indica la cella di memoria il cui indirizzo è contenuto in PtypedefTipoDato *TipoPuntatore; TipoPuntatore P; TipoDato x; Strutture di controllo in C Informatica A – V. Perrone

  19. Il costruttore puntatore (2) • L’operatore unario & significa “indirizzo di” ed è il duale dell’operatore ‘*’.typedefTipoDato *TipoPuntatore; TipoPuntatore P, Q; TipoDato 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. Strutture di controllo in C Informatica A – V. Perrone

  20. P 14 P = 14; x 23 x = 23; P 23 *P = x; x 23 Esempi (1) Strutture di controllo in C Informatica A – V. Perrone

  21. P 14 x 23 P 14 x = *P; x 14 Esempi (2) Strutture di controllo in C Informatica A – V. Perrone

  22. y P 14 P = &y; z Q 23 Q = &z; Esempi (3) P = Q; • Attenzione: è vero che P = Q; *P = *Q; ?? Strutture di controllo in C Informatica A – V. Perrone

  23. Puntatori e tipi typedef TipoDato *TipoPuntatore; typedef AltroTipoDato *AltroTipoPuntatore; TipoDato *Puntatore; TipoDato **DoppioPuntatore; TipoPuntatore P, Q; AltroTipoPuntatore P1, Q1; TipoDato x, y; AltroTipoDato z, w; istruzioni corrette:istruzioni scorrette: Puntatore = &y; P1 = P; (warning) DoppioPuntatore = &P; w = *P; (error) Q1 = &z; *DoppioPuntatore = y; (warning) P = &x; Puntatore = DoppioPuntatore;(warning) P = Q; *P1 = *Q; (error) *P = *Q; *Puntatore = x; P = *DoppioPuntatore; z = *P1; Puntatore = P; Strutture di controllo in C Informatica A – V. Perrone

  24. Valore iniziale di un puntatore • Il valore iniziale di un puntatore dovrebbeessere NULL • NULL significa che non si riferisce ad alcuna celladi memoria • Dereferenziando NULL si ha un errore inesecuzione • Non fare MAI affidamento sulleinizializzazioni implicite delle variabili che Cpotrebbe fare (alcune implementazioni lo fannoa NULL, molte altre no) Strutture di controllo in C Informatica A – V. Perrone

  25. Aritmetica tra puntatori 1/3 • C permette operazioni di somma e sottrazione tra puntatori • Il valore viene incrementato di un multiplo dell’ingombro (sizeof) del tipo puntato • Esempio: • int i; • IntRef p = &i; • p = p + 5; • Se supponiamo che i sia allocata alla cella 1000 allora l’assegnamento p = &i assegna a p il valore 1000 e l’assegnamento p = p + 5 assegna a p il valore 1020 (si suppone che sizeof(int) sia 4) Strutture di controllo in C Informatica A – V. Perrone

  26. Aritmetica tra puntatori 2/3 • Sia: • int a[5]; • int i; • int * p; • Allora: • – a[i] è equivalente a *(a+i) • – p = a è equivalente a p = &a[0] • – p = a+1 è equivalente a p = &a[1] • – a = p errore, a è puntatore costante • – a = a + 1 errore, a è puntatore costante • – p = p + 1 corretto Strutture di controllo in C Informatica A – V. Perrone

  27. Aritmetica tra puntatori 3/3 • Se p e q puntano a due diversi elementi di un array • p – q dà la distanza nell’array tra gli elementi puntati • Questo in generale non coincide con la differenza “aritmetica” tra il valore dei puntatori • Esempio: Se p e q sono puntatori a int e sizeof(int) è 4 e p è 1000 e q è 1040 allora: • p – q è 10 e non 40 Strutture di controllo in C Informatica A – V. Perrone

  28. 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: • inta[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). Strutture di controllo in C Informatica A – V. Perrone

  29. 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è unavariabile 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 ap = &a[0]; • p = a+1 è equivalente ap = &a[1]; • Mentre non sono ammessi assegnamenti ad a del tipo: • a = p; • a = a +1; Strutture di controllo in C Informatica A – V. Perrone

  30. 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. Strutture di controllo in C Informatica A – V. Perrone

  31. I tipi strutturati:2.Il costruttore struct • Tipo impiegato: nome, cognome, codice fiscale, indirizzo, numero di telefono, eventuali stipendio, data di assunzione e via di seguito. • 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. Strutture di controllo in C Informatica A – V. Perrone

  32. Esempi (1) typedef charString[50]; typedef struct{ int Giorno; int Mese; int Anno; } Data; typedef struct{ String Destinatario; intImporto; Data DataEmissione; } DescrizioneFatture; Strutture di controllo in C Informatica A – V. Perrone

  33. Esempi (2) typedef enum{On, Off}AccType; typedef struct {intCanale; AccType Accensione; double CursoreLuminosita,CursoreColore,CursoreVolume; } CanaliTV; Strutture di controllo in C Informatica A – V. Perrone

  34. Esempi (3) typedef enum{Dirigente, Impiegato, Operaio} CatType; typedefstruct{ String Nome; String Cognome; int Stipendio; char CodiceFiscale[16]; Data DataAssunzione; CatType Categoria; } Dipendenti; Strutture di controllo in C Informatica A – V. Perrone

  35. 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; intStipendio; charCodiceFiscale[16]; Data DataAssunzione; CatType Categoria; }Dip1, Dip2; Strutture di controllo in C Informatica A – V. Perrone

  36. 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"); Strutture di controllo in C Informatica A – V. Perrone

  37. Una tipica abbreviazione del C... • Definiamo un record e dichiariamo una variabile puntatore: • typedef struct{int PrimoCampo; char SecondoCampo; • } TipoDato; TipoDato x, *P; P = &x; • 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 sistassi abbreviata: • P–>PrimoCampo = 12; /* Inserisce 12 nel campo PrimoCampo di x */ Strutture di controllo in C Informatica A – V. Perrone

  38. Assegnamento tra record • Una stranezza del C: come abbiamo visto, non è permesso scrivere un assegnamento tra arrayArray2 = 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 e potrà essere capito tra breve Strutture di controllo in C Informatica A – V. Perrone

  39. Programma Dirigenti (1) /* Programma Dirigenti */ #include <stdio.h> main() { typedef enum{ dirigente, impiegato, operaio CatLav; typedef struct{ char Nome[30]; char Cognome[30]; CatLav Categoria; int Stipendio; char CodiceFiscale[16]; } Lavoratore; Lavoratore DatiLavoratori[300]; Lavoratore *Management[10]; ... Strutture di controllo in C Informatica A – V. Perrone

  40. Programma Dirigenti (2) /* 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; } Strutture di controllo in C Informatica A – V. Perrone

  41. Attenzione ai “rischi” dei puntatori • Effetti collaterali (side effects): • *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 daQdetermina un assegnamento nascosto alla variabile puntata daP. • Caso particolare di aliasing, ovvero del fatto che uno stesso oggetto viene identificato in due modi diversi. Strutture di controllo in C Informatica A – V. Perrone

  42. Riassumendo e completando • 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); Strutture di controllo in C Informatica A – V. Perrone

More Related