Title: Nessun titolo diapositiva
1Il 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
2Utilizzo avanzato di array e puntatori
3Gli 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
4Gli 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à)
5Gli 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
6Linizializzazione 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
7Linizializzazione 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à
8Array 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)
9Array 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
10Esempio 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
11Esempio 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)
12Esempio 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
13Errori 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
14Gli 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
15Gli array di puntatori ? 2
996
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
16Esempio 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
17Esempio 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
18Esempio 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
19I 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
20I 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
21Esempio 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
22Le classi di memorizzazione
23Introduzione ? 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
24Introduzione ? 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
25Durata 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
26Linizializzazione 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
27Linizializzazione 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
28Luso 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
29Lambito 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
30Lambito 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à
31Lambito 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 /
32Lambito 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)
33Lambito 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
34Lambito 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
35I 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
36Le 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)
37Definizioni 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 /
38Definizioni 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
39Lo 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
40Il 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 /
41Riepilogo 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
42Lallocazione 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()
43Lallocazione dinamica della memoria ? 2
- 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)