Anno accademico 2010-2011 1 Utilizzo avanzato di array e puntatori.

Slides:



Advertisements
Presentazioni simili
Introduzione al linguaggio C++
Advertisements

I tipi Strutturati.
LINGUAGGIO DI PROGRAMMAZIONE C
Introduzione al linguaggio C
© 2007 SEI-Società Editrice Internazionale, Apogeo Unità F2 Selezione.
PUNTATORI Introduzione
Introduzione al linguaggio C
Introduzione al linguaggio C Dr. Francesco Fabozzi Corso di Informatica.
Anno accademico Gli operatori e le espressioni in C.
Fondamenti di Informatica I a.a Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I.
Anno accademico Array e puntatori in C.
INFORMATICA Strutture iterative
Programmazione Procedurale in Linguaggio C++
Indirizzi delle variabili A ogni variabile sono associati tre concetti fondamentali: il valore memorizzato; il tipo dati di appartenenza; lindirizzo. Il.
FUNZIONI DI BIBLIOTECA
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Caratteri e stringhe di caratteri
Funzioni definite dall’utente
Corso di Fondamenti di programmazione a.a.2009/2010
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di programmazione a.a. 2009/2010 Prof.ssa Chiara Petrioli.
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Corso di Programmazione 1 a.a.2006/2007 Prof.ssa Chiara Petrioli Corso di Laurea.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 21 Marzo 2013.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Stringhe e Puntatori Marco D. Santambrogio – Ver. aggiornata al 18 Marzo 2013.
Process synchronization
Informatica 2. Concetti fondamentali di programmazione Programmare vuol dire scrivere un algoritmo in un linguaggio che faccia funzionare un calcolatore.
Allocazione dinamica della memoria
Laboratorio di Linguaggi P R I M O C O M P I T I N O Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese.
1 Corso di Laurea in Biotecnologie Informatica (Programmazione) Introduzione a JAVA Anno Accademico 2009/2010.
1 Corso di Laurea in Biotecnologie Informatica (Programmazione) Variabili e tipi primitivi Anno Accademico 2009/2010.
1 Corso di Laurea in Biotecnologie Informatica (Programmazione) Array Anno Accademico 2009/2010.
1 Corso di Laurea in Biotecnologie Informatica (Programmazione) Assegnamento di valore a una variabile Anno Accademico 2009/2010.
1 Corso di Informatica (Programmazione) Lezione 13 (21 novembre 2008) Programmazione in Java: stringhe e array.
Fondamenti di Informatica I a.a Il linguaggio C Il controllo di flusso La selezione condizionale Listruzione switch I cicli Le istruzioni break,
Struct, enum, Puntatori e Array dinamici
Esercizi Puntatori, struct con campi puntatore, puntatori a struct, rapporto tra array e puntatori. FUNZIONI Passaggio di parametri per indirizzo, passaggio.
Dichiarazioni e tipi predefiniti nel linguaggio C
Algebra Lineare Esercizi assegnati.
I File.
Il Linguaggio C.
Le funzioni.
Espressioni condizionali
2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario Introduzione Vettori Dichiarazione di vettori 6.4.
CODIFICA Da flow-chart a C++.
2000 Prentice Hall, Inc. All rights reserved. Capitolo 10 (Deitel) Strutture, unioni ed enumerazioni Sommario Introduzione Definire le strutture.
Il linguaggio C Le funzioni C Language Il passaggio dei parametri
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di programmazione a.a. 2009/2010 Prof.ssa Chiara Petrioli.
Unità Didattica 3 Linguaggio C
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Array e stringhe Marco D. Santambrogio – Ver. aggiornata al 9 Agosto 2013.
Fopndamenti di programmazione. 2 La classe String Una stringa è una sequenza di caratteri La classe String è utilizzata per memorizzare caratteri La classe.
Complessità di un algoritmo
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Approfondimenti sulle Classi.
Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni – BCOR Ingegneria Elettronica – BELR Introduzione al C Esercitazione 5 D. Bloisi, A.
Strutture dati elementari
Anno accademico Le istruzioni di controllo in C.
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Corso di Programmazione 1 a.a.2006/2007 Prof.ssa Chiara Petrioli Corso di Laurea.
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
GLI ARRAY MONODIMENSIONALI. Utilizzando le nostre attuali conoscenze, proviamo a risolvere il seguente problema: Calcolare la media dei voti conseguiti.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Puntatori e Stringhe.
Il linguaggio C Puntatori e dintorni.
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Corso di Programmazione 1 a.a.2006/2007 Prof.ssa Chiara Petrioli Corso di Laurea.
Vettori (a una dimensione)
Variabili Numeriche –Interi (byte, short, int, long): complemento a 2 –A virgola mobile (float, double): IEEE 745 Alfanumeriche –Carattere (char): Unicode.
Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a – 3° ciclo.
1 Il linguaggio C Precisazioni sull’esperienza in laboratorio.
Operatori di incremento e decremento
Linguaggio C: Le basi Stefano Cagnoni e Monica Mordonini
Laboratorio di Linguaggi... altre D O M A N D E ! Marco Tarini Università dell’Insubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.
Il C `e un linguaggio di programmazione di uso generale, originariamente sviluppato per la scrittura del sistema operativo Unix, ed oggi disponibile su.
Transcript della presentazione:

Anno accademico Utilizzo avanzato di array e puntatori

Anno accademico Sommario Utilizzo avanzato di array e puntatoriUtilizzo avanzato di array e puntatori  Gli array multidimensionali  Gli array di puntatori  I puntatori a puntatori  Allocazione dinamica della memoria

Anno accademico array multidimensionaleUn array di array è un array multidimensionale e viene dichiarato per mezzo di una sequenza di coppie di parentesi quadre Anche se un array multidimensionale viene memorizzato come una sequenza di elementi, può essere manipolato come un array di array Per accedere ad un elemento di un array multidimensionale occorre specificare tanti indici quante sono le dimensioni dell’array /* x è un array di tre elementi costituiti * da array di cinque elementi (interi) */ int x[3][5]; Gli array multidimensionali  1

Anno accademico Gli array multidimensionali sono memorizzati con precedenza delle righe, cioè l’ultimo indice varia più velocemente Esempio:Esempio: int ar[2][3]  {{0,1,2}, {3,4,5} {3,4,5} }; }; C ar[1][0] ar[1][1] ar[1][2] ar[0][0] ar[0][1] ar[0][2] Nell’inizializzazione, ogni riga di valori è racchiusa fra parentesi graffe (in questo caso, servono per migliorare la leggibilità) Gli array multidimensionali  2

Anno accademico ar[1][2] *(ar[1]  2)*(*(ar  1)  2)L’accesso all’elemento ar[1][2] viene interpretato come *(ar[1]  2), ovvero *(*(ar  1)  2) arPoiché ar è un array di array, viene effettuato un doppio scaling: *(ar  1)  …quando si valuta *(ar  1), “1” rappresenta un array di tre interi (12 byte sulla macchina di riferimento) *(*(ar  1)  2)  …quando si valuta *(*(ar  1)  2), “2” rappresenta 2 interi (8 byte)  complessivamente si ha uno spostamento di 20 byte rispetto all’indirizzo base (si ottiene l’indirizzo esadecimale 1014) Se vengono specificati meno indici rispetto alle dimensioni, il risultato è un puntatore al tipo base dell’array; per esempio… ar[1] è equivalente a &ar[1][0] puntatore ad int e fornisce come risultato un puntatore ad int Lo standard ANSI non impone limiti al numero di dimensioni degli array; è comunque richiesto di gestire almeno array a sei dimensioni Gli array multidimensionali  3

Anno accademico In fase di inizializzazione di un array multidimensionale, occorre specificare ogni riga tra parentesi graffe staticSe i valori iniziali non sono sufficienti, e l’array è static, gli elementi mancanti vengono inizializzati a zero Esempio:Esempio: static int examp[5][3]  { {1,2,3}, {4}, {4}, {5,6,7} {5,6,7} }; }; In modo analogo al caso dei vettori, se viene “parzialmente” omessa la dichiarazione della dimensione di un array multidimensionale, il compilatore la calcola sulla base del numero dei valori iniziali specificati ) ( L’inizializzazione di array multidimensionali  1

Anno accademico Nel caso degli array multidimensionali, infatti, può essere omessa la dimensione dell’array più esterno, mentre è obbligatorio specificare le altre Esempio:Esempio: static int a_ar[][2]  {{1,1},{0,0},{1,2}}; produce un array di dimensione 3  2, perché sono presenti 6 valori iniziali Esempio:Esempio: static int b_ar[][]  {{1,2,3},{4,5,6}}; /*SCORRETTO*/ Non si può determinare se l’array è 3  2 o 2  3 (il raggruppamento dei dati di inizializzazione non è sufficiente!): specificare la seconda dimensione avrebbe risolto ogni ambiguità L’inizializzazione di array multidimensionali  2

Anno accademico Per passare un array multidimensionale come argomento di funzione è sufficiente specificarne il nome: il valore passato è un puntatore all’elemento iniziale dell’array che è ancora un array Nella funzione chiamata, l’argomento deve essere dichiarato in modo appropriato È possibile omettere la dimensione dell’array che viene passato, ma è necessario specificare la dimensione di ogni elemento dell’array Array multidimensionali come argomenti di funzione  1 int f1() { static int ar[5][6]; static int ar[5][6]; … … … … … … f2(ar); f2(ar); … … … … … …} int (*received_arg)[6]; void f2(received_arg) int received_arg[][6]; { … … … … … …}

Anno accademico Una modalità alternativa consiste nel passare esplicitamente un puntatore al primo elemento e la dimensione dell’array received_arg[x][y]Il vantaggio di questo approccio è la flessibilità: non occorre conoscere a priori la dimensione degli elementi dell’array; occorre però calcolare manualmente l’aritmetica degli indici: received_arg[x][y] è memorizzato all’indirizzo received_arg  x  dim2  y received_arg  x  dim2  y int f1() { static int ar[5][6]; static int ar[5][6]; … … … … … … f2(ar,5,6); f2(ar,5,6); … … … … … …} void f2(received_arg,dim1,dim2) int **received_arg; int dim1,dim2; { … … … … … …} puntatore a unpuntatore aint È un puntatore a un puntatore a int Array multidimensionali come argomenti di funzione  2

Anno accademico Scrivere una funzione che determina il tipo del risultato di un’espressione binaria in base ai tipi degli operandi La funzione riceve due argomenti interi che rappresentano i tipi degli operandi e fornisce un intero che rappresenta il tipo del risultato  include typedef enum {SPECIAL  2, ILLEGAL, INT, FLOAT, DOUBLE, POINTER, LAST} TYPES; TYPES type_needed(type1,type2) TYPES type1, type2; { static TYPES result_type[LAST][LAST]  { /* intfloat doublepointer */ /*int*/ INT,FLOAT,DOUBLE,POINTER, /*float*/ FLOAT,FLOAT,DOUBLE,ILLEGAL, /*double*/ DOUBLE,DOUBLE,DOUBLE,ILLEGAL, /*pointer*/ POINTER,ILLEGAL,ILLEGAL,SPECIAL }; TYPES result  result_type[type1][type2]; if (result  ILLEGAL) printf(“Operazione scorretta su puntatori\n”); return result; } Esempio  1

Anno accademico result_typeLa parte principale del programma è costituita dalla dichiarazione ed inizializzazione dell’array result_type : enum  Ogni tipo di dati viene fatto corrispondere ad un valore intero per mezzo della dichiarazione enum In base alle modalità di definizione dell’array bidimensionale, i due valori di ingresso sono indici, che individuano univocamente l’elemento dell’array corrispondente al tipo del risultato enum LASTLa dichiarazione enum assicura che ogni costante venga associata ad un unico valore intero e che LAST rappresenti il numero totale di tipi (viene usato nella dichiarazione dell’array) Esempio  2

Anno accademico La stessa dichiarazione (almeno per il compilatore) avrebbe potuto essere scritta per mezzo di interi char result_type[4][4]  {0,1,2,3,1,1,2,  1,2,2,2,  1,3,  1,  1,  2}; char result_type[4][4]  {0,1,2,3,1,1,2,  1,2,2,2,  1,3,  1,  1,  2}; diminuendo sensibilmente la comprensibilità e la mantenibilità del programma SPECIAL intNel caso SPECIAL, l’operazione è corretta solo se i puntatori riferiscono oggetti dello stesso tipo e l’operatore è il segno meno: il risultato è un int Esempio  3

Anno accademico ar[1,2]  0; /* Lecito, ma probabilmente scorretto */ ar[1][2]  0; /* Corretto */ Nella prima istruzione… espressione1 espressione2  …la virgola viene interpretata come operatore, si valuta quindi espressione1, che vale 1 ed il cui risultato non viene utilizzato e, successivamente, espressione2, che vale 2 (le due espressioni sono costanti) ar[2]  …si ottiene l’accesso ad ar[2] ar int ar[2] puntatore ad intSe ar è un array bidimensionale di int, ar[2] è un puntatore ad int (costante, ma potrebbe anche essere non valido)  Viene segnalato un errore di incompatibilità di tipo: fuorviante dato che la causa dell’errore è l’uso della virgola Errori di accesso ad array multidimensionali

Anno accademico Si consideri la dichiarazione: char *ar_of_p[5]; ar_of_p non La variabile ar_of_p è un array di cinque elementi di tipo puntatore a carattere e non un puntatore ad un array di cinque caratteri L’operatore di accesso all’elemento di un array “[]” ha precedenza superiore all’operatore di accesso all’indirizzo contenuto in un puntatore I puntatori non sono stati inizializzati, per cui puntano a posizioni di memoria qualsiasi Gli array di puntatori  1

Anno accademico Esempio:Esempio: char *ar_of_p[5]; char c0=‘a’; char c1=‘b’; ar_of_p[0]=&c0;ar_of_p[1]=&c1; ar_of_p[0] ar_of_p[1] ar_of_p[2] ar_of_p[3] C non definito ar_of_p[4] 1000 c c0 1FFF b a Gli array di puntatori  2

Anno accademico array di puntatoriGli array di puntatori vengono usati per gestire array di stringhe Esempio:Esempio: Realizzare una funzione che, dato un intero compreso fra 1 e 12, in ingresso, stampa il nome del mese corrispondente  include char *month_text(m) int m; { static char *month[13]  {“Badmonth”, “January”, “February”, “March”, “April”, “May”, “June”, “July”, “August”, “September”, “October”, “November”, “December” }; if (m>12) { printf(“Valore scorretto”); exit(1); } return month[m]; } Esempio array di puntatori  1

Anno accademico month puntatori a charLa variabile month è un array di puntatori a char costituito da 13 elementi: come conseguenza dell’inizializzazione, ogni puntatore fa riferimento all’elemento iniziale di una stringa La motivazione dell’uso di un puntatore aggiuntivo con un valore inutile consiste nel non voler effettuare sottrazioni dall’indice: è comune non utilizzare l’elemento iniziale di un array quando il valore dell’indice comincia logicamente da 1 “Badmonth”Non definendo “Badmonth”, si dovrebbe cambiare l’istru- zione di ritorno al chiamante in return month[m  1]; Esempio array di puntatori  2

Anno accademico Nota : I caratteri che costituiscono una stringa devono essere consecutivi Le stringhe corrispondenti ai nomi dei mesi vengono memorizzate dal compilatore in qualunque posizione libera della memoria A 300F A A month[0] month[1] month[2] month[3] month[4] month[5] month[6] month[7] month[8] month[9] month[10] month[11] month[12] C C C 1030 ‘B’ ‘a’ ‘d’ ‘m’ ‘o’ ‘n’ ‘t’ ‘h’ ‘\0’ ‘J’ ‘a’ ‘n’ ‘u’ ‘a’ ‘r’ ‘y’ ‘\0’ ‘F’ ‘e’ ‘b’ ‘r’ ‘u’ ‘a’ ‘r’ ‘y’ ‘\0’ ‘M’ ‘a’ ‘r’ ‘c’ ‘h’ ‘\0’ A 200B 200C 200D 200E 200F Esempio array di puntatori  3

Anno accademico puntatori a puntatoriI puntatori a puntatori sono costrutti usati in programmi sofisticati: per dichiarare un puntatore a puntatore occorre far precedere il nome della variabile da due asterischi consecutivi int **p; p puntatore ad unpuntatore ad int dichiara p come puntatore ad un puntatore ad int intPer accedere al valore dell’int, è necessario utilizzare i doppi asterischi: j  **p; j assegna un intero a j I puntatori a puntatori  1

Anno accademico Esempio:Esempio: int r  5; int *q  &r; int *q  &r; int **p  &q; int **p  &q; r È possibile assegnare valori ad r come: r  10; /*Assegnamento diretto*/ *q  10; /*Assegnamento con un livello di indirezione*/ *q  10; /*Assegnamento con un livello di indirezione*/ **p  10; /*Assegnamento con due livelli di indirezione*/ **p  10; /*Assegnamento con due livelli di indirezione*/ 4 byte r q p C 100C 99C 1004 I puntatori a puntatori  2

Anno accademico /* Codice per la costruzione di I (matrice identità) */ #include main() { int id[100][100]; int n, i, j; printf(“Introdurre la dimensione della matrice identità\n”); scanf(“%d”, &n); for (i  0; i  n; i  ) for (j  0; j  n; j  ) id[i][j]  (i  j)?1:0; exit(0); } Esempio 1: Matrice identità

Anno accademico /* Si valuta se a è simmetrica… */ sim  1; r  0; do { c  r  1; do { if (a[r][c] !  a[c][r]) sim  0; c  ; } while (c<DIM && sim  1); r  ; } while (r<DIM  1 && sim  1); if (sim  1) printf(“Matrice simmetrica”); else printf(“Matrice non simmetrica”); exit(0); } Esempio 2: Matrice simmetrica /* Si legge una matrice quadrata ** composta da numeri reali ** e si stabilisce se è simmetrica */ #include #define DIM 100 main() { char r, c, sim; float a[DIM][DIM]; /* Lettura della matrice a */ for(r  0;r  DIM;r  ) { for(c  0;c<DIM;c  ) scanf(“%f”,&a[r][c]); }

Anno accademico /* Funzione per il calcolo di A  b, con… ** A: matrice m  n di float (in input) ** b: vettore di dimensione n di float (in input) ** m, n: interi, numero di righe e colonne di A (in input) ** x: vettore di float di dimensione m, risultato (in output) */ float *prod_mv(a, b, m, n, x) float a[][100], b[], x[]; /* ma, nella funzione, sono puntatori */ int m, n; { int i, j; for (i  0; i  m; i  ) { x[i]  0.0; for (j  0; j  n; j  ) x[i]  a[i][j]  b[j]; } return x; } Esempio 3: Prodotto matrice  vettore

Anno accademico Esempio 4: Prodotto matrice  matrice ProblemaProblema Calcolo della matrice prodotto A  B, con A e B matrici rettangolari di dimensioni, rispettivamente, m  n e n  c  

Anno accademico Dichiarare array equivale a fare un’ipotesi (una stima) sulla dimensione massima possibile dei vettori che potranno essere fonte di elaborazione per il particolare programma  Si suppone di conoscere la quantità di memoria da allocare nel momento in cui si scrive il codice sorgente  Generalmente si sovrastima, quindi si spreca memoria  Se la stima è sufficientemente stringente per la situazione corrente, può essere una sottostima per il futuro (occorre aggiornare il sorgente) Di norma, l’occupazione di memoria dipende strettamente dai dati in ingressoDi norma, l’occupazione di memoria dipende strettamente dai dati in ingresso L’allocazione dinamica della memoria  1

Anno accademico stdlib.h allocazione dinamica della memoriaIn C, esistono quattro funzioni della libreria di run  time ( stdlib.h ) che permettono l’allocazione dinamica della memoria  malloc()  malloc()  alloca un numero specificato di byte in memoria e restituisce un puntatore all’inizio del blocco allocato  calloc()malloc()  calloc()  come malloc(), ma inizializza a zero i byte allocati; consente di allocare la memoria per più di un oggetto alla volta  realloc()  realloc()  cambia la dimensione di un blocco preceden- temente allocato  free() malloc()calloc()realloc()  free()  libera la memoria che era stata allocata con malloc(), calloc() o realloc() L’allocazione dinamica della memoria  2

Anno accademico Esempio:Esempio: malloc()L’argomento di malloc() è la dimensio- ne in byte del blocco da allocare calloc()Usando calloc(), l’istruzione di alloca- zione della memoria sarebbe list=(int*)calloc(sort_num,sizeof(int)); calloc()La funzione calloc() accetta due argo- menti: il primo è il numero di oggetti a cui riservare memoria, il secondo è la dimensione di ciascun oggetto malloc() calloc()Le funzioni malloc() e calloc() me- morizzano gli elementi in modo contiguo in un singolo blocco  include main() { extern void bubble_sort(); int *list, j, sort_num; printf(“Numero dei valori da introdurre:”); scanf(“%d”, &sort_num); list  (int *)malloc(sort_num  sizeof(int)); for (j  0; j<sort_num; j  ) scanf(“%d”, list  j); bubble_sort(list, sort_num); exit(0); } L’allocazione dinamica della memoria  3