fondamenti di informatica i a.a. 2008-09 1 il linguaggio c utilizzo avanzato di array e puntatori...

43
damenti di Informatica I damenti di Informatica I a.a. 2008-09 a.a. 2008-09 1 Il linguaggio C Il linguaggio C Utilizzo avanzato di array e Utilizzo avanzato di array e puntatori puntatori Gli array multidimensionali Gli array multidimensionali Gli array di puntatori Gli array di puntatori I puntatori a puntatori I puntatori a puntatori Le classi di memorizzazione Le classi di memorizzazione Durata fissa e durata automatica Durata fissa e durata automatica L’ambito di visibilità L’ambito di visibilità C C Language Language

Upload: silvio-cara

Post on 01-May-2015

220 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 1

Il linguaggio CIl linguaggio C

Utilizzo avanzato di array e puntatoriUtilizzo avanzato di array e puntatoriGli array multidimensionaliGli array multidimensionali

Gli array di puntatoriGli array di puntatori

I puntatori a puntatoriI puntatori a puntatori

Le classi di memorizzazioneLe classi di memorizzazioneDurata fissa e durata automaticaDurata fissa e durata automatica

L’ambito di visibilitàL’ambito di visibilitàC Language

C Language

Page 2: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 2

Utilizzo avanzato di array e puntatoriUtilizzo avanzato di array e puntatori

Page 3: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 3

Un array di array è un array multidimensionalearray 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

Gli array multidimesionali Gli array multidimesionali 1 1

/* x è un array di tre elementi costituiti

* da array di cinque elementi

*/

int x[3][5];

Page 4: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 4

Gli array multidimensionali sono memorizzati con precedenza delle righe, cioè l’ultimo indice varia più velocementeEsempioEsempio:

int ar[2][3] { {0,1,2}, {3,4,5} };

Gli array multidimensionali Gli array multidimensionali 2 2

012

345

1018

100010041008100C10101014

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à)

Page 5: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 5

L’accesso all’elemento ar[1][2] viene interpretato come *(ar[1]2), ovvero *(*(ar1)2)Poiché ar è un array di array, viene effettuato un doppio scaling:

…quando si valuta *(ar1), “1” rappresenta un array di tre interi (12 byte sulla macchina di riferimento)…quando si valuta *(*(ar1)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]ar[1] è equivalente a &ar[1][0] e fornisce come risultato un puntatore adpuntatore ad intint

Lo standard ANSI non impone limiti al numero di dimensioni degli array; è comunque richiesto di gestire almeno array a sei dimensioni

Gli array multidimensionali Gli array multidimensionali 3 3

Page 6: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 6

L’inizializzazione di L’inizializzazione di array multidimensionali array multidimensionali 1 1

In fase di inizializzazione di un array multidimensionale, occorre specificare ogni riga tra parentesi graffeSe i valori iniziali non sono sufficienti, ed il vettore è staticstatic, gli elementi mancanti vengono inizializzati a zeroEsempioEsempio:

static int examp[5][3] static int examp[5][3] { {1,2,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

)(0 0 0 0 0 0

1 2 3 4 0 0 5 6 7

Page 7: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 7

Nel caso degli array multidimensionali, infatti, può essere omessa la dimensione dell’array più esterno, mentre è obbligatorio specificare le altreEsempioEsempio:

static int a_ar[][2] static int a_ar[][2] {{1,1},{0,0},{1,2}}; {{1,1},{0,0},{1,2}};

produce un array di dimensione 32, perché sono presenti 6 valori iniziali EsempioEsempio:

static int b_ar[][] static int b_ar[][] {{1,2,3},{4,5,6}}; /* SCORRETTO {{1,2,3},{4,5,6}}; /* SCORRETTO */*/

Non si può determinare se l’array è 32 o 23 (il raggruppamento dei dati di inizializzazione non è sufficiente!): specificare la seconda dimensione avrebbe risolto ogni ambiguità

L’inizializzazione di L’inizializzazione di array multidimensionali array multidimensionali 2 2

Page 8: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 8

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 Array multidimensionali come argomenti di funzione argomenti di funzione 1 1

void f2(received_arg)int received_arg[][6];{ … … …}

int f1(){ static int ar[5][6]; … … … f2(ar); … … …}

int (*received_arg)[6];

Page 9: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 9

Una modalità alternativa consiste nel passare esplicitamente un puntatore al primo elemento e la dimensione dell’array

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 received_arg x xdim2 dim2 y y

Array multidimensionali come Array multidimensionali come argomenti di funzione argomenti di funzione 2 2

int f1(){ static int ar[5][6]; … … … f2(ar,5,6); … … …}

void f2(received_arg,dim1,dim2)int **received_arg;int dim1,dim2;{ … … …} È un puntatore a un puntatore a intint

Page 10: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 10

Esempio array multidimensionali Esempio array multidimensionali 1 1

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 <stdio.h>

typedef enum {SPECIAL2, ILLEGAL, INT, FLOAT, DOUBLE, POINTER, LAST} TYPES;

TYPES type_needed(type1,type2)TYPES type1, type2;{ static TYPES result_type[LAST][LAST] {

/* int float double pointer */ /*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;}

Page 11: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 11

Esempio array multidimensionali Esempio array multidimensionali 2 2

La parte principale del programma è costituita dalla dichiarazione ed inizializzazione dell’array result_typeresult_type:

Ogni tipo di dati viene fatto corrispondere ad un valore intero per mezzo della dichiarazione enumenum

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

La dichiarazione enumenum 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)

Page 12: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 12

Esempio array multidimensionali Esempio array multidimensionali 3 3

La stessa dichiarazione (almeno per il compilatore) avrebbe potuto essere scritta per mezzo di interi

char result_type[4][4] char result_type[4][4] {0,1,2,3,1,1,2, {0,1,2,3,1,1,2,1,2,2,2,1,2,2,2,1,3,1,3,1,1,1,1,2};2};

diminuendo sensibilmente la comprensibilità e la mantenibilità

del programma

Nel caso SPECIALSPECIAL, l’operazione è corretta solo se i puntatori riferiscono oggetti dello stesso tipo e l’operatore è il segno meno: il risultato è un intint

Page 13: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 13

Errori di accesso ad Errori di accesso ad array multidimensionaliarray multidimensionali

ar[1,2] 0; /* Lecito, ma probabilmente scorretto */ar[1][2] 0; /* Corretto */

Nella prima istruzione……la virgola viene interpretata come operatore, si valuta quindi espressione1espressione1, che vale 1 ed il cui risultato non viene utilizzato, e, successivamente, espressione2espressione2, che vale 2 (le due espressioni sono costanti)…si ottiene l’accesso ad ar[2]

Se arar è un array bidimensionale di intint, ar[2]ar[2] è un puntatore ad int puntatore ad int (costante)

Viene segnalato un errore di incompatibilità di tipo: fuorviante dato che la causa dell’errore è l’uso della virgola

Page 14: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 14

Gli array di puntatori Gli array di puntatori 1 1

Si consideri la dichiarazione: char *ar_of_p[5];char *ar_of_p[5];

La variabile ar_of_par_of_p è un array di cinque elementi di tipo puntatore e nonnon un puntatore ad un array di cinque elementi

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

Page 15: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 15

Gli array di puntatori Gli array di puntatori 2 2

EsempioEsempio:

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]

1014

20002000

996

1004

1008

100C

1010

20012001

non definitonon definito

non definitonon definito

non definitonon definito

ar_of_p[4]

1000

c1

2002

c0

1FFF

2000

2001bb

aa

Page 16: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 16

Esempio array di puntatori Esempio array di puntatori 1 1

Gli array di puntatoriarray di puntatori vengono usati per gestire array di stringhe

EsempioEsempio: Realizzare una funzione che, dato un intero compreso fra 1 e 12, in ingresso, stampa il nome del mese corrispondenteinclude <stdio.h>

include <stdlib.h>

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];}

Page 17: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 17

Esempio array di puntatori Esempio array di puntatori 2 2

La variabile monthmonth è un array di puntatori a charchar 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

Non definendo “Badmonth”, si dovrebbe cambiare l’istruzione di ritorno al chiamante in

return month[mreturn month[m1];1];

Page 18: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 18

Esempio array di puntatori Esempio array di puntatori 3 3

NotaNota:

I caratteri che costituiscono una stringa devono essere consecutiviLe stringhe corrispondenti ai nomi dei mesi vengono memorizzate dal compilatore in qualunque posizione libera della memoria

2000

2009

2011

2500

2800

3000

3006

300A

300F

4000

400A

4011

401A

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]

1000

1004

1008

100C

1010

1014

1018

101C

1020

1024

1028

102C

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’

2000

2001

2002

2003

2004

2005

2006

2007

2008

2009

200A

200B

200C

200D

200E

200F

2010

2011

2012

2013

2014

2015

2016

2017

2018

2019

2500

2501

2502

2503

2504

2505

Page 19: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 19

I puntatori a puntatori I puntatori a puntatori 1 1

I puntatori a puntatoripuntatori 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;int **p;

dichiara p come puntatore ad un puntatore ad intint

Per accedere al valore dell’intint, è necessario utilizzare i doppi asterischi:

j j **p; **p;

assegna un intero a j

Page 20: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 20

I puntatori a puntatori I puntatori a puntatori 2 2

EsempioEsempio:

int r int r 5; 5; int *q int *q &r; &r; int **p int **p &q; &q;

È possibile assegnare valori ad r come: r r 10; /* Assegnamento diretto */ 10; /* Assegnamento diretto */ *q *q 10; /* Assegnamento con un livello di indirezione */ 10; /* Assegnamento con un livello di indirezione */ **p **p 10; /* Assegnamento con due livelli di indirezione */ 10; /* Assegnamento con due livelli di indirezione */

4 byte

r

q

p

5

1004

99C

100C

99C

1004

Page 21: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 21

Esempio: Prodotto Esempio: Prodotto matricematricevettorevettore

/* Funzione per il calcolo di Ab, con…** A: matrice mn 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 (i0; im; i) { x[i] 0.0; for (j0; jn; j) x[i] a[i][j]b[j]; } return x;}

Page 22: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 22

Le classi di memorizzazioneLe classi di memorizzazione

Page 23: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 23

Introduzione Introduzione 1 1

Nel linguaggio C, viene offerta la possibilità di condividere variabili e di delimitare le porzioni di codice che sfruttano tali condivisioni, mediante la definizione dell’ambito di visibilitàambito di visibilità, o scopescope, delle variabili

L’ambito di visibilitàambito di visibilità è il termine tecnico che denota la parte del testo sorgente C in cui è attiva la dichiarazione di un nome

Inoltre, le variabili hanno una duratadurata, che descrive il lasso temporale di memorizzazione dei valori di una variabile:

Nel caso di variabili con durata fissadurata fissa, i valori memorizzati vengono mantenuti anche all’esterno dell’ambito di visibilità

Le proprietà di visibilità e di durata individuano la classe di memorizzazioneclasse di memorizzazione di una variabile

Page 24: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 24

Introduzione Introduzione 2 2

La variabile jj ha durata automaticadurata automatica, mentre arar ha durata durata fissafissa, perché dichiarata staticstatic:

A jj viene automaticamente allocata memoria ogni volta che viene eseguito il blocco che la contiene (può avere indirizzi diversi per esecuzioni diverse del blocco di codice)

arar viene allocato la prima volta che viene eseguito il blocco e mantiene l’indirizzo originale per l’intera esecuzione del programma

void func(){ int j; static int ar[] {1,2,3,4} … … … }

Le variabili jj ed arar hanno entrambe visibilità a livello di visibilità a livello di bloccoblocco, perché definite all’interno di un blocco: possono essere referenziate solo dalle istruzioni che appartengono al blocco (il corpo della funzione funcfunc)Le variabili jj ed arar sono dette localilocali

EsempioEsempio

Page 25: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 25

Durata fissa e durata automaticaDurata fissa e durata automatica

Le variabili con durata fissadurata fissa sono permanenti, mentre le variabili con durata automaticadurata automatica sono allocate più volte durante l’esecuzione del programma

Ad una variabile fissa viene associata una locazione di memoria all’inizio del programma, che non cambia fino al termine dello stessoAd una variabile automatica viene allocata memoria ogni volta che si entra nel suo ambito di visibilità; se il codice che appartiene all’ambito di visibilità della variabile viene rieseguito, la variabile viene generalmente allocata altrove: non si mantiene il valore della variabile fra due esecuzioni successive

Le variabili locali sono automatiche per default, ma possono essere rese fisse se dichiarate staticstaticLa parola chiave autoauto definisce esplicitamente una variabile automatica, ma è usata raramente perché ridondante

Page 26: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 26

L’inizializzazione delle variabili L’inizializzazione delle variabili 11

void increment(){ int j1; static int k1;

j; k; printf(“j: %d\t k: %d\n”, j, k);}

main(){ increment(); increment(); increment();}

La funzione increment()increment() incrementa i valori delle variabili jj e kk, entrambe inizializzate a 1Il risultato dell’esecuzione del programma è:

j: 2j: 2 k: 2k: 2

j: 2j: 2 k: 3k: 3

j: 2j: 2 k: 4k: 4

Le variabili fisse vengono inizializzate una sola volta, mentre quelle automatiche vengono inizializzate ogni volta che viene eseguito il blocco che le contiene

Page 27: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 27

L’inizializzazione delle variabili L’inizializzazione delle variabili 22

Le variabili fisse vengono inizializzate di default al valore zero, quelle automatiche non vengono inizializzate (e sono normalmente allocate sullo stackstack)

Le variabili scalari automatiche possono essere inizializzate con una qualunque espressione, con il solo vincolo che tutte le variabili contenute nell’espressione siano state dichiarate (e inizializzate) in precedenza

Le variabili con durata fissa possono essere inizializzate solo per mezzo di espressioni costanti, ossia non contenenti nomi di variabili

Page 28: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 28

L’uso di variabili con durata fissaL’uso di variabili con durata fissa

Le variabili con durata fissa sono comunemente impiegate per tenere traccia del numero di volte che una funzione viene eseguita e per modificarne il comportamento ad intervalli regolari

La variabile page_typepage_type agisce da elemento di controllo: quando il numero della pagina è dispari, la funzione stampa la stringa puntata da chap_titlechap_title sul lato destro della pagina; se il numero della pagina è pari, la stringa appare spostata a sinistra

page_typepage_type deve essere fissa, altrimenti si stamperebbe sempre l’intestazione relativa alle pagine dispari

#define ODD 0#define EVEN 1

void print_header(chap_title)char *chap_title;{ static char page_typeODD;

if (page_type ODD) { printf(“\t\t\t\t\t%s\n\n”, chap_title); page_type EVEN; } else { printf(“%s\n\n”, chap_title); page_type ODD; }}

Page 29: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 29

L’ambito di visibilità L’ambito di visibilità 1 1

L’ambito di visibilitàambito di visibilità di una variabile definisce la regione di codice da cui è possibile accedere alla variabileEsistono quattro tipi di ambiti di visibilità: programmaprogramma, filefile, funzionefunzione e bloccoblocco

L’ambito di visibilità a livello di programmaambito di visibilità a livello di programma implica che una variabile è accessibile da tutti i file sorgente; le variabili con ambito di visibilità a livello di programma sono variabili globalivariabili globaliL’ambito di visibilità a livello di fileambito di visibilità a livello di file implica che una variabile è accessibile dal punto in cui è dichiarata fino alla fine del file sorgente in cui si trovaL’ambito di visibilità a livello di funzioneambito di visibilità a livello di funzione implica che il nome di una variabile è accessibile dall’inizio alla fine della funzione in cui è dichiarataL’ambito di visibilità a livello di bloccoambito di visibilità a livello di blocco implica che una variabile è accessibile dal punto in cui è dichiarata fino alla fine del blocco in cui si trova

Page 30: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 30

L’ambito di visibilità L’ambito di visibilità 2 2

Le variabili dichiarate all’interno di un blocco hanno ambito di visibilità a livello di bloccoLe variabili dichiarate all’esterno di un blocco hanno ambito di visibilità a livello di file se sono staticstatic, oppure a livello di programmaSolo le etichette dell’istruzione gotogoto hanno ambito di visibilità a livello di funzione

L’ambito di visibilità di una variabile è determinato dalla posizione della dichiarazione:

Ambito di visibilità a livello di blocco

Ambito di visibilità a livello di programma

Ambito di visibilità a livello di file

Ambito di visibilità a livello di funzione

Le relazioni gerarchiche tra Le relazioni gerarchiche tra gli ambiti di visibilitàgli ambiti di visibilità

Page 31: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 31

EsempioEsempio:

I parametri delle funzioni hanno ambito di visibilità a livello di blocco: sono trattati come se fossero la prima dichiarazione di variabile nel blocco di livello più alto contenuto nella funzione

L’ambito di visibilità L’ambito di visibilità 3 3

int i; /* ambito di visibilità a livello di programma */static int j; /* ambito di visibilità a livello di file */

int func(k) /* ambito di visibilità a livello di programma */int k; /* ambito di visibilità a livello di blocco */{ int m; /* ambito di visibilità a livello di blocco */ start: ; /* ambito di visibilità a livello di funzione */ … … …}

Page 32: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 32

L’ambito di visibilità L’ambito di visibilità 4 4

Il C consente l’attribuzione dello stesso nome a variabili diverse con ambiti di visibilità distintiÈ anche possibile che variabili con lo stesso nome abbiano ambiti parzialmente intersecati: la variabile con l’ambito di visibilità più limitato preclude temporaneamente la visibilità dell’altra

int j10; /* ambito di visibilità a livello di programma */

main(){ int j; /* ambito di visibilità a livello di blocco: nasconde la variabile globale j */ for (j0; j<5; j) printf(“j: %d”, j);}

L’esecuzione del programma produce:

j: 0j: 1j: 2j: 3j: 4

La variabile globale j mantiene inalterato il valore iniziale 10

Page 33: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 33

L’ambito di visibilità L’ambito di visibilità a livello di blocco e funzionea livello di blocco e funzione

Una variabile con ambito di visibilità a livello di blocco non può essere acceduta dall’esterno del blocco in cui è dichiarata

consente di proteggere la variabile da effetti collaterali non desideratiriduce la complessità del programma, rendendolo più leggibile e mantenibile

Variabili possono essere dichiarate all’interno di blocchi innestati, nascondendo temporaneamente le variabili con lo stesso nome eventualmente definite in blocchi più esterni Le etichette dell’istruzione gotogoto sono gli unici nomi con ambito di visibilità a livello di funzione: devono avere nomi univoci all’interno della stessa funzione, mentre nomi coincidenti in funzioni diverse non originano conflitti

Page 34: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 34

L’ambito di visibilitàL’ambito di visibilitàa livello di file e programmaa livello di file e programma

Associare un ambito di visibilità a livello di file a una variabile significa renderla referenziabile nella parte rimanente del file in cui è definita

Se il file contiene più funzioni, tutte le funzioni che seguono la dichiarazione della variabile sono in grado di referenziarla

Per dichiarare una variabile con ambito di visibilità a livello di file occorre inserire la dichiarazione al di fuori delle funzioni e usare la parola chiave staticstaticLe variabili con ambito di visibilità a livello di programma, dette variabili globalivariabili globali, sono visibili in tutti i file sorgente (compreso quello in cui vengono dichiarate)Una variabile globale deve essere dichiarata al di fuori delle funzioni e non usando la parola chiave staticstatic

Page 35: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 35

I due significati di I due significati di staticstatic

All’interno di un blocco, staticstatic attribuisce ad una variabile durata fissa, anziché automatica

All’esterno di una funzione, staticstatic non è correlata alla durata della variabile, ma ne controlla l’ambito di visibilità a livello di file, anziché di programma

La parola chiave staticstatic specifica sia l’ambito di visibilità che la durata di una variabile:

All’interno di un blocco, le regole di visibilità del blocco sono più stringenti di quelle a livello di file: la durata fissa è l’unico effetto che si manifestaAll’esterno di una funzione, la durata è già fissa: l’ambito di visibilità a livello di file è l’unico effetto che si manifesta

Page 36: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 36

Le variabili globaliLe variabili globali

L’uso delle variabili globalivariabili globali dovrebbe essere evitato perché aumenta la complessità dei programmi e li rende difficilmente mantenibili

Le variabili globali possono portare a conflitti tra moduli se, per errore, vengono scelti nomi uguali per variabili globali distinte

Quando occorre condividere dati tra procedure diverse, è buona regola passare i dati come parametri o passare puntatori all’area di memoria condivisa

Le regole di attribuzione di nomi alle variabili globali sono diverse: i nomi globali devono essere riconoscibili non solo al compilatore, ma anche al linkerlinker ed al binderbinder : lo standard ANSI garantisce il riconoscimento dei primi sei caratteri (tuttavia, nulla vieta di aggiungere caratteri per rendere i nomi più significativi)

Page 37: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 37

Finora, la dichiarazione di variabile corrispondeva all’allocazione di memoria per quella variabile: l’allocazione di memoria è, in realtà, il risultato di un solo tipo di dichiarazione, detta definizionedefinizioneLe variabili globali consentono un secondo tipo di dichiarazione, detta allusioneallusione: non si alloca memoria, ma si informa il compilatore che esiste una variabile del tipo specificato definita altrove

Le variabili globali seguono le stesse regole delle funzioni: ogni volta che si utilizzano variabili definite in altro file, è necessario dichiararle con allusioni

Definizioni e allusioni Definizioni e allusioni 1 1

main(){ extern int f(); /* allusione a funzione */ extern int j; /* allusione a variabile */ extern float f_array_of_f[]; /* allusione a variabile */ … … …

Page 38: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 38

La parola chiave externextern specifica che la variabile è definita altroveLe allusioni consentono al compilatore di effettuare i controlli di tipo: per ogni variabile globale, possono essere presenti un numero qualunque di allusioni, ma una sola definizioneLo standard ANSI prevede che, per definire una variabile globale, sia necessario inserire all’esterno di una funzione una dichiarazione con inizializzazione: la presenza o meno della parola chiave externextern non ha alcun effettoSe il valore iniziale fosse stato omesso, il compilatore avrebbe prodotto un’allusione, se è specificato extern,extern, o una definizione di provadefinizione di prova, che si trasforma…

…in una definizione effettiva, con inizializzazione a 0, se nel file non compare altra dichiarazione…in un’allusione, se nel file sorgente è contenuta una definizione reale

Definizioni e allusioni Definizioni e allusioni 2 2

Page 39: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 39

La parola chiave registerregister consente di suggerire al compilatore quali variabili dovrebbero essere memorizzate nei registriIl livello di supporto offerto dai compilatori allo specificatore registerregister è molto variabile: alcuni compilatori memorizzano effettivamente tutte le variabili registerregister in registri, fino a quando ce ne sono disponibili, altri lo ignorano, altri lo interpretano per determinare se è davvero proficuo memorizzare una data variabile in un registroAd una variabile register register non è assegnato alcun indirizzo di memoria: anche se il suggerimento registerregister non viene seguito dal compilatore, se si tenta di accedere all’indirizzo della variabile, si ottiene una segnalazione di erroreSono candidati ideali per la memorizzazione registerregister i contatori dei cicli forfor, sui quali vengono effettuate molte operazioni, temporalmente vicine

Lo specificatore Lo specificatore registerregister

Page 40: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 40

Il modificatore di classe Il modificatore di classe const const

La parola chiave constconst (derivata dal C) indica che una variabile non può essere modificata dopo l’inizializzazione:

La parola chiave constconst può essere impiegata in alternativa alla direttiva ##definedefine

const char str[9] “Costante”;str[0] ‘a’; /* non ammesso */

Page 41: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 41

Riepilogo delle Riepilogo delle classi di memorizzazioneclassi di memorizzazione

Specificatore di classe di memorizzazione

All’esterno di una funzione

All’interno di una funzione

Argomenti di una funzione

autoauto o register register NON PERMESSO Visibilità: bloccoDurata: automatica

Visibilità: bloccoDurata: automatica

staticstatic Visibilità: fileDurata: fissa

Visibilità: bloccoDurata: fissa

NON PERMESSO

externextern Visibilità: programmaDurata: fissa

Visibilità: bloccoDurata: fissa

NON PERMESSO

nessuno specificatore di classe

Visibilità: programmaDurata: fissa

Visibilità: bloccoDurata: automatica

Visibilità: bloccoDurata: automatica

Posizione della dichiarazione

La semantica degli specificatori di classe di memorizzazione La semantica degli specificatori di classe di memorizzazione

Page 42: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 42

Alle variabili con durata fissa viene riservata memoria per l’intera durata del programma, mentre alle variabili con durata automatica la memoria viene allocata ogni volta che si esegue il blocco relativo: in entrambi i casi si suppone di conoscere la quantità di memoria da allocare nel momento i cui si scrive il codice sorgente Tuttavia, talvolta l’occupazione di memoria dipende talvolta l’occupazione di memoria dipende strettamente dai dati in ingressostrettamente dai dati in ingressoIn C, esistono quattro funzioni della libreria di runtime (stdlib.h) che permettono l’allocazione dinamica della allocazione dinamica della memoriamemoria

malloc()malloc() alloca un numero specificato di byte in memoria e restituisce un puntatore all’inizio del blocco allocatocalloc()calloc() come malloc()malloc(), ma inizializza a zero i byte allocati; consente di allocare la memoria per più di un oggetto alla voltarealloc()realloc() cambia la dimensione di un blocco precedentemente allocatofree()free() libera la memoria che era stata allocata con malloc()malloc(), calloc()calloc() o realloc()realloc()

L’allocazione dinamica L’allocazione dinamica della memoria della memoria 1 1

Page 43: Fondamenti di Informatica I a.a. 2008-09 1 Il linguaggio C Utilizzo avanzato di array e puntatori Gli array multidimensionali Gli array di puntatori I

Fondamenti di Informatica I Fondamenti di Informatica I a.a. 2008-09 a.a. 2008-09 43

L’argomento di malloc()malloc() è la dimensione in byte del blocco da allocareUsando calloc()calloc(), l’istruzione di allocazione della memoria sarebbe

list = (int *) calloc(sort_num, sizeof(int));

La funzione calloc()calloc() accetta due argomenti: il primo è il numero di oggetti a cui riservare memoria, il secondo è la dimensione di ciascun oggettoLe funzioni malloc()malloc() e calloc()calloc() memorizzano gli elementi in modo contiguo in un singolo blocco

L’allocazione dinamica L’allocazione dinamica della memoria della memoria 2 2

include <stdio.h>include <stdlib.h>

main(){ extern void bubble_sort(); int *list, j, sort_num; printf(“Numero dei valori da introdurre:”); scanf(“%d”, &sort_num); list (int *) malloc(sort_numsizeof(int)); for (j0; j<sort_num; j) scanf(“%d”, listj); bubble_sort(list, sort_num); exit(0);}

EsempioEsempio: