Nessun titolo diapositiva - PowerPoint PPT Presentation

1 / 43
About This Presentation
Title:

Nessun titolo diapositiva

Description:

Title: Nessun titolo diapositiva Last modified by: Valued Acer Customer Created Date: 1/1/1601 12:00:00 AM Document presentation format: Presentazione su schermo (4:3) – PowerPoint PPT presentation

Number of Views:49
Avg rating:3.0/5.0
Slides: 44
Provided by: unis198
Category:

less

Transcript and Presenter's Notes

Title: Nessun titolo diapositiva


1
Il linguaggio C
  • Utilizzo avanzato di array e puntatori
  • Gli array multidimensionali
  • Gli array di puntatori
  • I puntatori a puntatori
  • Le classi di memorizzazione
  • Durata fissa e durata automatica
  • Lambito di visibilità

C Language
2
Utilizzo avanzato di array e puntatori
3
Gli array multidimesionali ? 1
  • Un 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 dellarray

/ x è un array di tre elementi costituiti da
array di cinque elementi / int x35
4
Gli array multidimensionali ? 2
  • Gli array multidimensionali sono memorizzati con
    precedenza delle righe, cioè lultimo indice
    varia più velocemente
  • Esempio
  • int ar23 ? 0,1,2,
  • 3,4,5

ar00
0
1000
ar01
1
1004
ar02
2
1008
ar10
3
100C
ar11
4
1010
ar12
1014
5
1018
Nellinizializzazione, ogni riga di valori è
racchiusa fra parentesi graffe (in questo caso,
servono per migliorare la leggibilità)
5
Gli array multidimensionali ? 3
  • Laccesso allelemento ar12 viene
    interpretato come (ar1?2), ovvero ((ar?1)?2)
  • Poiché ar è un array di array, viene effettuato
    un doppio scaling
  • quando si valuta (ar?1), 1 rappresenta un
    array di tre interi (12 byte sulla macchina di
    riferimento)
  • quando si valuta ((ar?1)?2), 2 rappresenta 2
    interi (8 byte)
  • complessivamente si ha uno spostamento di 20 byte
    rispetto allindirizzo base (si ottiene
    lindirizzo esadecimale 1014)
  • Se vengono specificati meno indici rispetto alle
    dimensioni, il risultato è un puntatore al tipo
    base dellarray per esempio
  • ar1 è equivalente a ar10
  • 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

6
Linizializzazione di array multidimensionali ? 1
  • In fase di inizializzazione di un array
    multidimensionale, occorre specificare ogni riga
    tra parentesi graffe
  • Se i valori iniziali non sono sufficienti, ed il
    vettore è static, gli elementi mancanti vengono
    inizializzati a zero
  • Esempio
  • static int examp53 ? 1,2,3,
  • 4,
  • 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

7
Linizializzazione di array multidimensionali ? 2
  • Nel caso degli array multidimensionali, infatti,
    può essere omessa la dimensione dellarray più
    esterno, mentre è obbligatorio specificare le
    altre
  • Esempio
  • static int a_ar2 ?
    1,1,0,0,1,2
  • produce un array di dimensione 3?2, perché
    sono presenti 6 valori iniziali
  • Esempio
  • static int b_ar ?
    1,2,3,4,5,6 / SCORRETTO /
  • Non si può determinare se larray è 3?2 o 2?3
    (il raggruppamento dei dati di inizializzazione
    non è sufficiente!) specificare la seconda
    dimensione avrebbe risolto ogni ambiguità

8
Array multidimensionali come argomenti di
funzione ? 1
  • Per passare un array multidimensionale come
    argomento di funzione è sufficiente specificarne
    il nome il valore passato è un puntatore
    allelemento iniziale dellarray che è ancora un
    array
  • Nella funzione chiamata, largomento deve essere
    dichiarato in modo appropriato
  • È possibile omettere la dimensione dellarray che
    viene passato, ma è necessario specificare la
    dimensione di ogni elemento dellarray

void f2(received_arg) int received_arg6

int f1() static int ar56
f2(ar)
9
Array multidimensionali come argomenti di
funzione ? 2
  • Una modalità alternativa consiste nel passare
    esplicitamente un puntatore al primo elemento e
    la dimensione dellarray
  • Il vantaggio di questo approccio è la
    flessibilità non occorre conoscere a priori la
    dimensione degli elementi dellarray occorre
    però calcolare manualmente laritmetica degli
    indici received_argxy è memorizzato
    allindirizzo
  • received_arg ? x?dim2 ? y

int f1() static int ar56
f2(ar,5,6)
void f2(received_arg,dim1,dim2) int
received_arg int dim1,dim2
È un puntatore a un puntatore a int
10
Esempio array multidimensionali ? 1
  • Scrivere una funzione che determina il tipo del
    risultato di unespressione binaria in base ai
    tipi degli operandi

?include ltstdio.hgt typedef enum SPECIAL??2,
ILLEGAL, INT, FLOAT,
DOUBLE, POINTER, LAST TYPES TYPES
type_needed(type1,type2) TYPES type1, type2
static TYPES result_typeLASTLAST ?
/ 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_typetype1type2
if (result ?? ILLEGAL)
printf(Operazione scorretta su puntatori\n)
return result
La funzione riceve due argomenti interi che
rappresentano i tipi degli operandi e fornisce un
intero che rappresenta il tipo del risultato
11
Esempio array multidimensionali ? 2
  • La parte principale del programma è costituita
    dalla dichiarazione ed inizializzazione
    dellarray result_type
  • Ogni tipo di dati viene fatto corrispondere ad un
    valore intero per mezzo della dichiarazione enum
  • In base alle modalità di definizione dellarray
    bidimensionale, i due valori di ingresso sono
    indici, che individuano univocamente lelemento
    dellarray corrispondente al tipo del risultato
  • La 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 dellarray)

12
Esempio array multidimensionali ? 3
  • La stessa dichiarazione (almeno per il
    compilatore) avrebbe potuto essere scritta per
    mezzo di interi
  • char result_type44 ? 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
  • Nel caso SPECIAL, loperazione è corretta solo se
    i puntatori riferiscono oggetti dello stesso tipo
    e loperatore è il segno meno il risultato è un
    int

13
Errori di accesso ad array multidimensionali
ar1,2 ? 0 / Lecito, ma probabilmente
scorretto / ar12 ? 0 / Corretto /
  • Nella prima istruzione
  • 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)
  • si ottiene laccesso ad ar2
  • Se ar è un array bidimensionale di int, ar2 è
    un puntatore ad int (costante)
  • Viene segnalato un errore di incompatibilità di
    tipo fuorviante dato che la causa dellerrore è
    luso della virgola

14
Gli array di puntatori ? 1
  • Si consideri la dichiarazione
  • char ar_of_p5
  • La variabile ar_of_p è un array di cinque
    elementi di tipo puntatore e non un puntatore ad
    un array di cinque elementi
  • Loperatore di accesso allelemento di un array
    ha precedenza superiore alloperatore di
    accesso allindirizzo contenuto in un puntatore
  • I puntatori non sono stati inizializzati, per cui
    puntano a posizioni di memoria qualsiasi

15
Gli array di puntatori ? 2
996
  • Esempio

2000
1000
ar_of_p0
char ar_of_p5 char c0 a char c1
b ar_of_p0 c0 ar_of_p1 c1
1004
ar_of_p1
2001
1008
non definito
ar_of_p2
100C
non definito
ar_of_p3
1010
non definito
ar_of_p4
1014
1FFF
a
c0
2000
2001
c1
b
2002
16
Esempio array di puntatori ? 1
  • Gli array di puntatori vengono usati per gestire
    array di stringhe
  • Esempio Realizzare una funzione che, dato un
    intero compreso fra 1 e 12, in ingresso, stampa
    il nome del mese corrispondente

?include ltstdio.hgt ?include ltstdlib.hgt char
month_text(m) int m static char
month13 ? Badmonth, January, February,
March, April, May,
June, July,
August, September, October,
November,
December
if (mgt12)
printf(Valore scorretto)
exit(1)
return monthm
17
Esempio array di puntatori ? 2
  • La variabile month è un array di puntatori a char
    costituito da 13 elementi come conseguenza
    dellinizializzazione, ogni puntatore fa
    riferimento allelemento iniziale di una stringa
  • La motivazione delluso di un puntatore
    aggiuntivo con un valore inutile consiste nel non
    voler effettuare sottrazioni dallindice è
    comune non utilizzare lelemento iniziale di un
    array quando il valore dellindice comincia
    logicamente da 1
  • Non definendo Badmonth, si dovrebbe cambiare
    listruzione di ritorno al chiamante in
  • return monthm?1

18
Esempio array di puntatori ? 3
  • 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

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

2000
2009
2011
2500
2800
3000
3006
300A
300F
4000
400A
4011
401A
1000
1004
1008
100C
1010
1014
1018
101C
1020
1024
1028
102C
1030
month0
month1
month2
month3
month4
month5
month6
month7
month8
month9
month10
month11
month12
19
I puntatori a puntatori ? 1
  • I 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
  • dichiara p come puntatore ad un puntatore ad
    int
  • Per accedere al valore dellint, è necessario
    utilizzare i doppi asterischi
  • j ? p
  • assegna un intero a j

20
I puntatori a puntatori ? 2
4 byte
  • Esempio
  • int r ? 5
  • int q ? r
  • int p ? q
  • È possibile assegnare valori ad r come
  • r ? 10 / Assegnamento diretto /
  • q ? 10 / Assegnamento con un livello di
    indirezione /
  • p ? 10 / Assegnamento con due livelli di
    indirezione /

99C
r
5
1004
q
99C
100C
1004
p
21
Esempio Prodotto matrice?vettore
/ 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 a100, b, x / ma, nella
funzione, sono puntatori / int m, n
int i, j for (i?0 i?m i??)
xi ? 0.0
for (j?0 j?n j??)
xi ?? aij?bj
return x
22
Le classi di memorizzazione
23
Introduzione ? 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 dellambito di
    visibilità, o scope, delle variabili
  • Lambito 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 durata, che
    descrive il lasso temporale di memorizzazione dei
    valori di una variabile
  • Nel caso di variabili con durata fissa, i valori
    memorizzati vengono mantenuti anche allesterno
    dellambito di visibilità
  • Le proprietà di visibilità e di durata
    individuano la classe di memorizzazione di una
    variabile

24
Introduzione ? 2
Esempio
  • Le variabili j ed ar hanno entrambe visibilità a
    livello di blocco, perché definite allinterno di
    un blocco possono essere referenziate solo dalle
    istruzioni che appartengono al blocco (il corpo
    della funzione func)
  • Le variabili j ed ar sono dette locali

void func() int j static int
ar ? 1,2,3,4
  • La variabile j ha durata automatica, mentre ar ha
    durata fissa, perché dichiarata static
  • A j 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)
  • ar viene allocato la prima volta che viene
    eseguito il blocco e mantiene lindirizzo
    originale per lintera esecuzione del programma

25
Durata fissa e durata automatica
  • Le variabili con durata fissa sono permanenti,
    mentre le variabili con durata automatica sono
    allocate più volte durante lesecuzione del
    programma
  • Ad una variabile fissa viene associata una
    locazione di memoria allinizio del programma,
    che non cambia fino al termine dello stesso
  • Ad una variabile automatica viene allocata
    memoria ogni volta che si entra nel suo ambito di
    visibilità se il codice che appartiene
    allambito 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 static
  • La parola chiave auto definisce esplicitamente
    una variabile automatica, ma è usata raramente
    perché ridondante

26
Linizializzazione delle variabili ? 1
  • Le variabili fisse vengono inizializzate una sola
    volta, mentre quelle automatiche vengono
    inizializzate ogni volta che viene eseguito il
    blocco che le contiene

void increment() int j?1
static int k?1 j??
k?? printf(j d\t k d\n, j,
k) main() increment()
increment() increment()
  • La funzione increment() incrementa i valori delle
    variabili j e k, entrambe inizializzate a 1
  • Il risultato dellesecuzione del programma è
  • j 2 k 2
  • j 2 k 3
  • j 2 k 4

27
Linizializzazione delle variabili ? 2
  • Le variabili fisse vengono inizializzate di
    default al valore zero, quelle automatiche non
    vengono inizializzate (e sono normalmente
    allocate sullo stack)
  • Le variabili scalari automatiche possono essere
    inizializzate con una qualunque espressione, con
    il solo vincolo che tutte le variabili contenute
    nellespressione 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

28
Luso 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

define ODD 0 define EVEN 1 void
print_header(chap_title) char chap_title
static char page_type?ODD
if (page_type ?? ODD)
printf(\t\t\t\t\ts\n\n, chap_title)
page_type ? EVEN
else
printf(s\n\n, chap_title)
page_type ? ODD
La variabile page_type agisce da elemento di
controllo quando il numero della pagina è
dispari, la funzione stampa la stringa puntata da
chap_title sul lato destro della pagina se il
numero della pagina è pari, la stringa appare
spostata a sinistra page_type deve essere fissa,
altrimenti si stamperebbe sempre lintestazione
relativa alle pagine dispari
29
Lambito di visibilità ? 1
  • Lambito di visibilità di una variabile definisce
    la regione di codice da cui è possibile accedere
    alla variabile
  • Esistono quattro tipi di ambiti di visibilità
    programma, file, funzione e blocco
  • Lambito 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
    globali
  • Lambito 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 trova
  • Lambito di visibilità a livello di funzione
    implica che il nome di una variabile è
    accessibile dallinizio alla fine della funzione
    in cui è dichiarata
  • Lambito 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

30
Lambito di visibilità ? 2
  • Lambito di visibilità di una variabile è
    determinato dalla posizione della dichiarazione
  • Le variabili dichiarate allinterno di un blocco
    hanno ambito di visibilità a livello di blocco
  • Le variabili dichiarate allesterno di un blocco
    hanno ambito di visibilità a livello di file se
    sono static, oppure a livello di programma
  • Solo le etichette dellistruzione goto hanno
    ambito di visibilità a livello di funzione

Le relazioni gerarchiche tra gli ambiti di
visibilità
31
Lambito di visibilità ? 3
  • Esempio
  • 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

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 /

32
Lambito di visibilità ? 4
  • Il C consente lattribuzione 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 lambito di visibilità più limitato
    preclude temporaneamente la visibilità dellaltra

Lesecuzione del programma produce j 0 j 1 j
2 j 3 j 4 La variabile globale j mantiene
inalterato il valore iniziale 10
int j?10 / ambito di visibilità a livello
di programma / main() int j /
ambito di visibilità a livello di blocco
nasconde la variabile globale j /
for (j?0 jlt5 j??) printf(j
d, j)
33
Lambito di visibilità a livello di blocco e
funzione
  • Una variabile con ambito di visibilità a livello
    di blocco non può essere acceduta dallesterno
    del blocco in cui è dichiarata
  • consente di proteggere la variabile da effetti
    collaterali non desiderati
  • riduce la complessità del programma, rendendolo
    più leggibile e mantenibile
  • Variabili possono essere dichiarate allinterno
    di blocchi innestati, nascondendo temporaneamente
    le variabili con lo stesso nome eventualmente
    definite in blocchi più esterni
  • Le etichette dellistruzione goto sono gli unici
    nomi con ambito di visibilità a livello di
    funzione devono avere nomi univoci allinterno
    della stessa funzione, mentre nomi coincidenti in
    funzioni diverse non originano conflitti

34
Lambito di visibilitàa 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 static
  • Le variabili con ambito di visibilità a livello
    di programma, dette variabili 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 static

35
I due significati di static
  • Allinterno di un blocco, static attribuisce ad
    una variabile durata fissa, anziché automatica
  • Allesterno di una funzione, static non è
    correlata alla durata della variabile, ma ne
    controlla lambito di visibilità a livello di
    file, anziché di programma
  • La parola chiave static specifica sia lambito di
    visibilità che la durata di una variabile
  • Allinterno di un blocco, le regole di visibilità
    del blocco sono più stringenti di quelle a
    livello di file la durata fissa è lunico
    effetto che si manifesta
  • Allesterno di una funzione, la durata è già
    fissa lambito di visibilità a livello di file è
    lunico effetto che si manifesta

36
Le variabili globali
  • Luso delle variabili 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 allarea 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 linker ed al binder lo standard ANSI
    garantisce il riconoscimento dei primi sei
    caratteri (tuttavia, nulla vieta di aggiungere
    caratteri per rendere i nomi più significativi)

37
Definizioni e allusioni ? 1
  • Finora, la dichiarazione di variabile
    corrispondeva allallocazione di memoria per
    quella variabile lallocazione di memoria è, in
    realtà, il risultato di un solo tipo di
    dichiarazione, detta definizione
  • Le variabili globali consentono un secondo tipo
    di dichiarazione, detta allusione 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

main() extern int f()
/ allusione a funzione /
extern int j / allusione
a variabile / extern float
f_array_of_f / allusione a variabile /

38
Definizioni e allusioni ? 2
  • La parola chiave extern specifica che la
    variabile è definita altrove
  • Le 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
    definizione
  • Lo standard ANSI prevede che, per definire una
    variabile globale, sia necessario inserire
    allesterno di una funzione una dichiarazione con
    inizializzazione la presenza o meno della parola
    chiave extern non ha alcun effetto
  • Se il valore iniziale fosse stato omesso, il
    compilatore avrebbe prodotto unallusione, se è
    specificato extern, o una definizione di prova,
    che si trasforma
  • in una definizione effettiva, con
    inizializzazione a 0, se nel file non compare
    altra dichiarazione
  • in unallusione, se nel file sorgente è
    contenuta una definizione reale

39
Lo specificatore register
  • La parola chiave register consente di suggerire
    al compilatore quali variabili dovrebbero essere
    memorizzate nei registri
  • Il livello di supporto offerto dai compilatori
    allo specificatore register è molto variabile
    alcuni compilatori memorizzano effettivamente
    tutte le variabili register 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 registro
  • Ad una variabile register non è assegnato alcun
    indirizzo di memoria anche se il suggerimento
    register non viene seguito dal compilatore, se si
    tenta di accedere allindirizzo della variabile,
    si ottiene una segnalazione di errore
  • Sono candidati ideali per la memorizzazione
    register i contatori dei cicli for, sui quali
    vengono effettuate molte operazioni,
    temporalmente vicine

40
Il modificatore di classe const
  • La parola chiave const (derivata dal C??) indica
    che una variabile non può essere modificata dopo
    linizializzazione
  • La parola chiave const può essere impiegata in
    alternativa alla direttiva define

const char str9 ? Costante str0 ? a
/ non ammesso /
41
Riepilogo delle classi di memorizzazione
La semantica degli specificatori di classe di
memorizzazione
Posizione della dichiarazione
Specificatore di classe di memorizzazione Allesterno di una funzione Allinterno di una funzione Argomenti di una funzione
auto o register NON PERMESSO Visibilità blocco Durata automatica Visibilità blocco Durata automatica
static Visibilità file Durata fissa Visibilità blocco Durata fissa NON PERMESSO
extern Visibilità programma Durata fissa Visibilità blocco Durata fissa NON PERMESSO
nessuno specificatore di classe Visibilità programma Durata fissa Visibilità blocco Durata automatica Visibilità blocco Durata automatica
42
Lallocazione dinamica della memoria ? 1
  • Alle variabili con durata fissa viene riservata
    memoria per lintera 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 loccupazione di memoria
    dipende strettamente dai dati in ingresso
  • In C, esistono quattro funzioni della libreria di
    run?time (stdlib.h) che permettono lallocazione
    dinamica della memoria
  • malloc() ? alloca un numero specificato di byte
    in memoria e restituisce un puntatore allinizio
    del blocco allocato
  • calloc() ? come malloc(), ma inizializza a zero i
    byte allocati consente di allocare la memoria
    per più di un oggetto alla volta
  • realloc() ? cambia la dimensione di un blocco
    precedentemente allocato
  • free() ? libera la memoria che era stata allocata
    con malloc(), calloc() o realloc()

43
Lallocazione dinamica della memoria ? 2
  • Esempio
  • Largomento di malloc() è la dimensione in byte
    del blocco da allocare
  • Usando calloc(), listruzione di allocazione
    della memoria sarebbe
  • list (int ) calloc(sort_num, sizeof(int))
  • La funzione calloc() accetta due argomenti il
    primo è il numero di oggetti a cui riservare
    memoria, il secondo è la dimensione di ciascun
    oggetto
  • Le funzioni malloc() e calloc() memorizzano gli
    elementi in modo contiguo in un singolo blocco

?include ltstdio.hgt ?include ltstdlib.hgt 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 jltsort_num j??)
scanf(d, list?j)
bubble_sort(list, sort_num)
exit(0)
Write a Comment
User Comments (0)
About PowerShow.com