Sei sulla pagina 1di 101

Il

linguaggio
C
1
Sommario
Introduzione .................................................................................................1
1. Prima di iniziare pag.5
2. Programma compilato e interpretato pag.6
3. Le peculiarit del C pag.7
4. Storia del linguaggio C pag.9
Software .......................................................................................................2
5. Softare da u!are" #indo! pag.11
Il primo programma in C ...............................................................................3
6. Scri$iamo il primo programma in C pag.13
7. %lementi fondamentali di un programma in C pag.15
&. La compilazione pag.16
Elementi fondamentali del C ...........................................................................4
9. Co!a !ono le $aria'ili pag.1&
1(. Le $aria'ili in C pag.2(
11. )li *peratori" introduzione pag.23
12. *peratori aritmetici pag.24
13. *peratori di confronto e logici pag.26
14. Propriet degli operatori pag.27
15. Prime operazioni di +nput,*utput pag.29
2
Controlli .......................................................................................................5
16. Controlli condizionali" +f-%l!e pag.34
17. Controlli condizionali" Sitc. e operatori ternari pag.37
1&. Controlli +terati$i" .ile/ for/ 'rea0 pag.4(
19. Co!a !ono gli 1rra2 pag.46
2(. )li arra2 e i cicli 3or pag.4&
21. 1rra2 4ultidimen!ionali pag.5(
Strutture avanzate .........................................................................................6
24. Ca!ting/ enumerazioni e $aria'ili !tatic.e pag.52
23. Struct/ t2pedef e union pag.56
22. Le funzioni pag.59
I puntatori ....................................................................................................7
25. + Puntatori pag.62
26. Puntatori e 3unzioni pag.64
27. Puntatori ed 1rra2 pag.65
2&. Puntatori e Strutture pag.66
La gestione della memoria ..............................................................................8
29. 1llocazione dinamica della 4emoria pag.67
3(. 1llocazione dinamica della memoria" funzione realloc56 pag.69
Le liste .........................................................................................................9
31. +ntroduzione alle Li!te pag.72
32. )e!tione di una li!ta - + pag.74
33. )e!tione di una li!ta - ++ pag.77
Input output su file ......................................................................................10
3
34. +ntroduzione +nput e *utput !u file pag.&1
35. La funzione fopen pag.&3
36. Le funzioni fprintf e f!canf pag.&4
37. Le funzioni fflu!. e fclo!e pag.&6
3&. +nput,*utput !u !tring.e pag.&7
39. 4e!!aggi di %rrore ed e!empi pratici pag.&&
Pre-processore e Definizioni ..........................................................................11
42. Le 7iretti$e condizionali pag.9(
41. Le 7iretti$e di definizione pag.91
4(. +l Pre-proce!!ore C e le 7iretti$e di inclu!ione pag.93
Progetti di grandi dimensioni ........................................................................12
43. %rrori comuni e regole di !tile in C pag.96
44. 4oduli/ prototipi e .eader file pag.99
45. L8utilit2 ma0e ed i ma0efile pag.1(1
1-Prima di iniziare
4
+n 9ue!ta guida ci proponiamo come o'ietti$o 9uello di imparare a programmare in uno dei linguaggi
pi: famo!i ed utilizzati al mondo/ il C.;no dei moti$i per cui/ ad oggi/ < utile !tudiare il C < il fatto c.e
e!i!tono gi migliaia di rig.e di codice !critte c.e permettono di ri!ol$ere 9ua!i tutti i pro'lemi legati
alla programmazione 5algoritmi/ !trutture/ ecc.6. +l C < un linguaggio c.e/ come il Pa!cal ed il 3ortran
5c.e !ono !uoi predece!!ori6/ permette di !al$are i $alori in $aria'ili/ di !trutturare il codice/ di
con$ogliare il flu!!o del programma utilizzando i!truzioni di ciclo/ i!truzioni condizionali e funzioni/ di
e!eguire operazioni di input,output a $ideo o !u file/ di !al$are dati in arra2 o !trutture= ma
di$er!amente da 9ue!ti linguaggi 5e 9ui i !uoi maggiori punti di forza6 permette di controllare in modo
pi: preci!o le operazioni di input,output/ inoltre il C < un linguaggio pi: !intetico e permette di !cri$ere
programmi piccoli e di facile compren!ione.
Per c.i !i !te!!e c.iedendo quali siano le applicazioni reali del linguaggio C/ 'a!ti pen!are c.e con il
C !i po!!ono !$iluppare programmi di 9ual!ia!i genere/ compre!i i $ideogioc.i= inoltre praticamente
tutti i !i!temi operati$i !ono !$iluppati per la maggior parte in 1!!em'l2 ed in C 5uno !u tutti il >ernel
Linu?6/ anc.e !e negli ultimi anni $iene inclu!o !empre pi: codice !critto in C@@ 5nda" legge!i C plu!
plu!6.
;n neo-programmatore potrebbe essere impaurito dal linguaggio C/ credendolo poco a$anzato e
meno utile di linguaggi pi: moderni come Ai!ual Ba!ic/ CC/ P2t.on o Da$a= tutto ciE non < $ero/ il C
in!egna a programmare/ a pen!are a come impo!tare il codice/ a ri!ol$ere i pro'lemi c.e ci $engono
me!!i di fronte/ e 9ue!to 'agaglio culturale !er$ir !icuramente in futuro= infatti una $olta imparato il C
tro$erete molto pi: facile imparare un altro linguaggio di programmazione e/ addirittura/ le 'a!i
in!egnate $erranno ritro$ate in linguaggi come il C@@/ il Da$a/ il PFP/ il Da$aScript/ etc.
1 coloro c.e !tanno leggendo 9ue!ta guida e non .anno la minima e!perienza di programmazione/ !i
con!iglia di leggere la )uida di 'a!e alla Programmazione in modo da poter comprendere meglio
9uello c.e diremo nelle pro!!ime lezioni
-Programma compilato e interpretato
5
;n programma $iene !$iluppato scrivendo il codice sorgente in un opportuno linguaggio definito/
appunto/ dalla !inta!!i del linguaggio !te!!o. La differenza tra compilazione ed interpretazione < molto
importante ed influi!ce !ia !ulle pre!tazioni c.e !ulle po!!i'ilit del linguaggio !te!!o.
Linguaggi come il C/ C@@/ 7elp.i/ Ai!ual Ba!ic !ono linguaggi compilati e !eguono 9ue!ti pa!!i" !i
!cri$e il codice in un editor/ al pi: utilizzando un am'iente di !$iluppo +7% c.e ne facilita la creazione/
9ue!to codice $iene poi controllato per $erificare c.e non ci !iano errori e poi $iene compilato/ o$$ero
ogni i!truzione $iene tra!formata nel corri!pondente codice in linguaggio macc.ina c.e puE e!!ere/
co!G/ e!eguito dal proce!!ore= 9ue!ti !ono i linguaggi compilati c.e $engono detti anc.e linguaggi
imperati$i/ ed .anno il $antaggio di pre!tazioni migliori.
+ linguaggi interpretati/ in$ece/ !eguono una !trada di$er!a/ il codice !orgente $iene/ appunto/
interpretato al $olo e $engono/ 9uindi/ e!eguite le i!truzioni co!G come de!critte nel codice !orgente= un
e!empio !u tutti < il PFP il cui codice $iene Hela'oratoH e re!titui!ce una pagina .tml pura. La potenza
di 9ue!to genere di linguaggi </ di fatto/ l8alta porta'ilit e l8immediatezza tra 9uello c.e !cri$iamo e
9uello c.e $iene pre!entato all8e!ecuzione del programma/ ma rimangono dei pro'lemi come la ricerca
di errori nel codice !orgente o il carico di la$oro maggiore per il proce!!ore 5c.e ogni $olta de$e
ela'orare la pagina6.
;n linguaggio c!e " a met# strada tra queste metodologie " $ava c.e < !ia compilato c.e
interpretato= il codice !orgente $iene compilato in un formato intermedio 5c.iamato '2tecode6/ il 9uale
a !ua $olta $iene interpretato dalla Da$a Airtual 4ac.ine 5DA46/ c.e .a il compito di interpretare Hal
$oloH le i!truzioni '2tecode in i!truzioni per il proce!!ore= la DA4 $iene !$iluppata per ogni Si!tema
*perati$o e permette di a!trarre la macc.ina $irtuale creata dal S* ad un li$ello di !tandardizzazione
!uperiore 5data di fatto dalla creazione della $irtual mac.ine !opra un8altra $irtual mac.ine6 c.e rende/
in pratica/ D1A1 altamente porta'ile.
Iue!ta metodologia implica la po!!i'ilit di controllare e$entuali errori del codice !orgente 5grazie alla
compilazione6/ di creare programmi relati$amente leggeri 5il '2tecode < un formato c.e crea file di
dimen!ioni ragione$oli6/ ma .a la pecca di a$ere delle pre!tazioni non proprio !oddi!facenti/ 9ue!to
perc.J il codice $iene interpretato dalla DA4 c.e a !ua $olta de$e delegare l8e!ecuzione $era e propria
al Si!tema *perati$o.
3-Le peculiarit del C
6
Iuali !ono le peculiarit del CK Sono molte e 9ui di !eguito elenc.iamo 9uelle pi: importanti cercando
di c.iarirne il !ignificato.
Dimensioni del codice ridotte - )eneralmente il codice !orgente di un programma in C .a
un pe!o 5in >'6 relati$amente piccolo/ in 9ue!to modo ri!ulta molto age$ole tra!portare il
codice da un PC ad un altro/ anc.e u!ando un !emplice flopp2.
Dimensioni dell%eseguibile ridotte - 1nc.e una $olta compilato/ un programma in C/ ri!ulta
molto piccolo e 9uindi di pi: facile diffu!ione= o$$iamente un programma in C potr e!!ere
e!eguito !olamente !ul mede!imo Si!tema *perati$o per cui < !tato compilato.
Efficienza dei programmi - ;n programma !critto in C/ proprio per la po!!i'ilit me!!a a
di!po!izione dal linguaggio di ge!tire a fondo la memoria/ e per le !ue dimen!ioni ridotte/
ri!ulta particolarmente efficiente.
Pu& essere compilato su una vasta gamma di computer - *gni computer puE differire
dagli altri per almeno due co!e/ l8arc.itettura ed il !i!tema operati$o= ad e!empio un
computer con proce!!ore ?&6 e #indo! .a delle i!truzioni 5inte!e come i!truzioni del
proce!!ore6 ed una ge!tione della memoria di$er!e da uno Sparc con Linu?/ perE un
programma !critto in C puE e!!ere compilato !u am'edue le macc.ine/ data l8alta
di!poni'ilit di compilatori per di$er!e piattaforme. Certo non < Hporta'ileH come Da$a/ perE
il fatto di e!!ere !ulla !cena da molti anni e la !ua enorme diffu!ione ne fanno/ di fatto/ uno
!trumento altamente porta'ile.
" un linguaggio di alto livello - ;n linguaggio di programmazione $iene definito di alto
li$ello tanto pi: !i a$$icina alla terminologia umana/ in$er!amente !i dice c.e un linguaggio
< di 'a!!o li$ello !e il !uo codice !i a$$icina al linguaggio macc.ina 59uello formato da ( ed
16= tipico e!empio di linguaggio a 'a!!o li$ello < l81!!em'ler/ mentre linguaggi ad alto
li$ello !ono/ oltre al C/ il C@@/ il Da$a e molti altri. La particolarit dei linguaggi ad alto
li$ello < 9uella di a$ere una !emplice !inta!!i in cui !i u!ano parole della lingua ingle!e per
de!cri$ere comandi corri!pondenti a decine di i!truzioni in a!!em'ler o centinaia di
i!truzioni in linguaggio macc.ina.
Pu& maneggiare attivit# di basso livello - +l C < con!iderato il linguaggio di pi: 'a!!o
li$ello tra i linguaggi di alto li$ello. Iue!to < do$uto al fatto c.e .a poc.e i!truzioni/ ge!ti!ce
in maniera efficiente la memoria ed < po!!i'ile in!erire direttamente all8interno di un file in C
del codice 1!!em'ler.
Implementazione dei puntatori - +l C fa un largo u!o di puntatori per le operazioni
riguardanti la memoria/ gli arra2/ le !trutture e le funzioni.
Loose '(ping - +n poc.e parole in C i tipi di dato delle $aria'ili non de$ono
nece!!ariamente e!!ere dic.iarati= contrariamente/ nel Pa!cal/ nel C@@ e nel Da$a i tipi
de$ono e!!ere dic.iarati 5!trong t2ping6= tale differenza ri!iede nelle !celte deci!ionali del
progetti!ta del linguaggio/ c.e puE $olere pi: o meno fle!!i'ilit all8interno dello !te!!o
5compilando un programma Da$a/ la maggior parte delle $olte !i commettono errori di tipo6.
C8< c.i dice c.e il metodo loo!e t2ping permetta al programmatore di commettere errori di
tipo c.e potre''ero compromettere l8e!ecuzione del programma/ ma < anc.e $ero c.e con lo
7
!trong t2ping !iamo co!tretti a !eguire delle regole rigide c.e/ a $olte/ non permettono di
ri!ol$ere H$elocementeH un pro'lema.
Lelle lezioni !eguenti parleremo della !toria del linguaggio C/ procedendo poi $er!o gli !trumenti di
compilazione di!poni'ili per i $ari Si!temi *perati$i ed al primo programmino 5il famo!o Fello #orld6
!critto in C= la parte centrale della guida < tutta incentrata !ulla !inta!!i del linguaggio/ in ordine/ le
$aria'ili/ gli operatori/ le i!truzioni condizionali 5come l8+3-%LS%6/ le i!truzioni iterati$e 53*M e
#F+L%6/ gli arra2/ le funzioni/ i puntatori/ le li!te/ l8allocazione dinamica della memoria/ l8input,output
!u file e l8utilizzo del pre-proce!!ore C= l8ultima parte !piega in dettaglio lo !tile per !cri$ere un
programma/ l8u!o degli .eader e del 4a0e per la creazione di ma0efile 5!otto Linu?6/ l8utilizzo di
funzioni !peciali di!poni'ili !otto Linu?/ le opzioni del compilatore )CC !otto Linu? e le funzioni
di!poni'ili nelle li'rerie !tandard del linguaggio.
Sar/ in$ece/ ome!!a/ $olutamente/ la trattazione dell8i!truzione goto/ 9ue!to perc.J < un8i!truzione
poco utilizzata e puE portare ad imparare uno !tile di programmazione poco c.iaro e facilmente
!oggetto ad errori= tutte le nozioni date in 9ue!te lezioni permettono di ri!ol$ere tutti i pro'lemi
ri!ol$i'ili con un goto in modo pi: elegante e pi: corretto.
Lon mi re!ta c.e augurar$i Buon La$oroN
4-Storia del linguaggio C
8
Per capire le origini del C/ 'i!ogna parlare della !toria del !i!tema operati$o ;L+O in 9uanto < !tato
!$iluppato !u 9ue!to !i!tema operati$o ed/ anzi/ lo !te!!o !i!tema operati$o ed i !uoi programmi !ono
!critti in C.
Lono!tante tutto il linguaggio C non </ perE/ legato !olo alla programmazione dei !i!temi operati$i/ ma
con e!!o po!!ono e!!ere !critti 5e !ono !tati !critti6 gro!!i programmi di calcolo/ ord-proce!!ing e
data'a!e.
)en '!ompson nel 1969 iniziE a la$orare !u un computer di nome PDP-*/ utilizzando il linguaggio
a!!em'ler= l8idea di 'a!e era di !cri$ere un linguaggio ad alto li$ello per l8implementazione di !i!temi
operati$i. P.omp!on pre!e !punto dal CPL 5Com'ined Programming Language6 e dal BCPL 5Ba!ic
CPL - 19676 per creare il linguaggio B c.e ri!ulta$a/ perE/ e!!ere ancora troppo pe!ante per l8.ardare
a di!po!izione.
Lel 1972/ un colla'oratore di P.omp!on/ Dennis +itc!ie ottimizzE ulteriormente il B 5creando una
prima $er!ione c.iamata LB6/ re!tituendogli alcune funzionalit del BCPL ed in$entando 9uello c.e ad
oggi $iene c.iamato Linguaggio C/ c.e permi!e di ri!cri$ere 9ua!i totalmente lo ;L+O di P.omp!on/
9ue!ta $olta per un computer pi: a$anzato/ il P7P-11.
+na!pettatamente il C permi!e di ri!cri$ere lo ;L+O per il P7P-11 in tempi rapidi!!imi e ciE !pin!e
P.omp!on/ Mitc.ie e >ernig.an a !cri$ere il 0ernel anc.e per l8 H+nterdata &,32H ed il H7ec A1O
11,7&(H/ 9ue!t8ultimo/ all8epoca/ particolarmente popolare.
tra il 1973 ed il 19&( il linguaggio C !i diffu!e anc.e !u arc.itetture Fone2ell 635 e +B4 36(,37(/
grazie al la$oro ad opera del ricercatore Do.n!on c.e !$iluppE il compilatore ppc/ alla na!cita delle
prime li'rerie 5un certo Le!0 !$iluppE il Hporta'le +,* pac0ageH/ rinominato H!tandard +,* li'rar2H6 e
alla !crittura di un li'ro di riferimento da parte >ernig.an e Mitc.ie nel 197&/ il HC Programming
LanguageH/ o come $iene comunemente c.iamato HLi'ro 'iancoH.
+n 9ue!ti anni c8era un po8 di confu!ione/ primo perc.J il C non era uguale a 9uello c.e cono!ciamo
oggi/ ma mantene$a una compati'ilit con i linguaggi da cui deri$a$a 5il BCPL ed il B6/ ed il HLi'ro
'iancoH era nato proprio dall8e!igenza di !cri$ere codice porta'ile c.e permette!!e l8e$ol$er!i del
linguaggio.
Legli anni 8&( i compilatori erano 'a!ati principalmente !ul pcc di Do.n!on/ ma nac9uero molti
compilatori indipendenti c.e non erano conformi al pcc/ ma c.e permi!ero la diffu!ione del C
praticamente !u tutte le macc.ine pi: popolari= per 9ue!to il comitato 1LS+ 51merican Standard!
+n!titute6 O3D11/ nel 19&3/ iniziE a !$iluppare uno !tandard per il linguaggio C/ aggiungendo importanti
caratteri!tic.e ed ufficializzando molte caratteri!tic.e pre!enti nei di$er!i compilatori.
Lel 19&9 !i arri$E 9uindi allo !tandard IS,-IEC ./..-1..0 5c.e c.iameremo 1LS+&9 per comodit6
c.e $enne u!ato come 'a!e per tutti i compilatori.
9
Lel mede!imo periodo ci fu un8altra importante !tandardizzazione c.e mira$a a definire l8interfaccia tra
linguaggio e !i!tema operati$o. Prendendo !punto proprio dall81LS+&9/ fu creata la HPorta'le
*perating S2!tem +nterfaceH 5P,SI16 ad opera dell8+%%% 5+n!titute of %lectrical and %lectronic!
%ngeneer!6 c.e defini!ce/ inoltre/ i concetti di t.read/ !oc0et/ e!ten!ioni realtime e molto altro/ in modo
unico e indipendente dall8implementazione.
Lono!tante negli anni il C !ia !tato implementato !ia con lo !tandard 1LS+/ c.e in maniera proprietaria/
grazie a 9ue!ti !trumenti il C < di$entato 5ed < tutt8oggi6 il linguaggio pi: utilizzato al mondo/ almeno
fino all8a$$ento del C@@ 5c.iamato originariamente HC con cla!!iH6 c.e < !tato anc.e la !pinta del
miglioramento nel tempo del C attra$er!o lo !tandard 1LS+/ di cui < !tata rila!ciata un8ultima $er!ione
denominata 1LS+99/ c.e < !upportata dalle ultime $er!ioni del gcc.
+l C ed il !uo ;L+O .anno influenzato tutto il mondo dell8informatica/ con!iderando c.e da e!!o !ono
!caturiti colo!!i come SC* e Sun 4icro!2tem/ e prodotti come Linu? e BS7. 1 parer mio/ 9uindi/ $ale
la pena di !tudiarlo/ perc.J < !icuramente un 'agaglio molto utile nella $ita di un programmatore.
1 c.i $ole!!e approfondire la !toria dei !i!temi operati$i 5e 9uindi dell8informatica in generale6
proponiamo di leggere i primi capitoli della !eguente )uida di Si!temi *perati$i/ mentre per la !toria
dei $ari linguaggi con!igliamo la lezione/ pre!ente 9ui !u Ftml.it/ di Storia della programmazione.
2-Software da usare3 4indows
10
Per sviluppare in C sono necessari solamente due strumenti/
un sistema di compilazione 5un tool di programmi/ come compilatore/ lin0er/ de'ugger/
ecc.6 c.e controlla gli errori e traduce il !orgente in C in un e!egui'ile 5compo!to da
i!truzioni di codice macc.ina6
un 'uon editor di testi
1nc.e !e < po!!i'ile u!are 9ual!ia!i editor di te!ti di!poni'ile !ul proprio !i!tema operati$o/ 9ui
!egnaliamo 9uelli pi: u!ati e diffu!i/ per $enire incontro alle pi: !$ariate e!igenze/ da c.i $uole !cri$ere
il codice direttamente dalla !.ell Linu? a c.i $uole un !i!tema integrato !otto #indo! c.e permetta
anc.e di compilare. 1''iamo deci!o di fare una li!ta dei migliori compilatori ed editor di!poni'ili per i
pi: diffu!i !i!temi operati$i.
5icrosoft 4indows
Compilatori e ambienti di sviluppo
7D)PP - Porting del famo!o 6CC 5compilatore per macc.ine uni?,linu?6/ permette di
compilare programmi !critti in C ed in C@@= for!e ri!ulta un po8 difficile da in!tallare/ ma
una $olta fatto il tutto/ !i puE la$orare tramite l8interfaccia +!ide/ un editor molto !imile
all8Edit del 7o!. D7gpp < completamente gratuito !ia per u!o per!onale c.e commerciale. Q
po!!i'ile u!are D7gpp/ oltre c.e con !i!temi 7o!,#indo!/ anc.e con Caldera 7M-7*S/
3ree7*S ed ,S-.
Lcc-in32 - Iue!to am'iente di !$iluppo .a al !uo interno tutto 9uello di cui c8< 'i!ogno/
compilatore 5a!!em'latore/ lin0er/ ecc.6/ interfaccia $i!uale per !cri$ere il codice/
correggerlo/ ecc./ il manuale utente e documentazione tecnica. +n!omma < un am'iente di
!$iluppo completo per il linguaggio C. L8u!o per !copi per!onali < gratuito/ mentre per !copi
commerciali < nece!!ario comprare la licenza.
7e$C@@ - 1nc.e 9ue!to prodotto < un +7% 5+ntegrated 7e$elopment %n$iroment6 di
!$iluppo e racc.iude al !uo interno un ottimo editor per indo! e un porting del 6CC
come compilatore. Sono di!poni'ili due $er!ioni/ la $er!ione !ta'ile/ la 4/ e la $er!ione 'eta/
la 5.
Borland C@@ - +l compilatore della 'orland < uno dei migliori di!poni'ili !ul mercato/
o$$iamente l8am'iente di !$iluppo completo < a pagamento/ ma $ale la pena di pro$are a
fare il donload della $er!ione 5.5.
4icro!oft Ai!ual C@@ -
L8am'iente di !$iluppo pi: famo!o del mondo < a pagamento/ ma non !i de$e pen!are c.e !ia
il migliore di!poni'ile/ arri$ato alla $er!ione .L%P il compilatore C,C@@ .a raggiunto un
'uon grado di maturit anc.e !e fino alla $er!ione 6 era po!!i'ile fare programmi c.e !eppur
non corretti gira$ano lo !te!!o o c.e anda$ano in conflitto appena e!eguiti. Certamente
l8interfaccia .a tutte le carte in regola per e!!ere al top 5completamento del te!to/ po!!i'ilit
di u!are izard per co!truire parti di codice/ ed o$$iamente integrazione tra le li'rerie per
!$iluppare in am'iente #indo! e lo !te!!o linguaggio di programmazione6. +l mio con!iglio
11
< di comprarlo !e c8< una reale e!igenza nell8am'ito profe!!ionale= ai principianti con!iglio di
a!pettare per due moti$i/ il co!to 5c.e perE puE ri!ultare molto inferiore grazie alle licenze
!tudente6 e la difficolt/ almeno iniziale/ nel !uo utilizzo c.e !are''e 'ene fo!!e
accompagnata da un 'uon manuale.
C8+I,SI'9 - +l nome 7D)PP deri$a dal fatto c.e l8organizzatore ed il principale programmatore di
9ue!to compilatore < tal 7D 7elorie/ il 9uale ricorda come < nata l8idea di un porting del 6CC per
am'ienti 7o!,#indo!" "Il DJGPP nato all'incirca nel 1989 [...], quando Richard Stallan !il "adre
del #ree $o#t%are& $ta'a "arlando ad un eetin( del ')orthern )e% *n(land +ni, +$er Grou"'
!))*++G& alla Data General, do'e la'ora'o. Gli doandai $e la -ree So#t%are -oundation !-S-&
a'e$$e ai "re$o in con$idera.ione il "ortin( del GCC "er /S0D1S [...], e lui a##er2 che ci2 non era
"o$$i3ile "erch4 il GCC era tro""o (rande e l'/S0D1S era un $i$tea o"erati'o a 1503it. 6anciata la
$#ida, io coinciai.
Editor
1!t Page 2((( - ;no dei migliori editor di!poni'ili per #indo!/ < a''a!tanza $eloce/
permette di aprire pi: file contemporaneamente/ inoltre .a l8.ig.lig.ting del te!to/ il
conteggio del numero di rig.e e colonne/ e molto altro= pen!ato !oprattutto come editor .tml/
!i ri$ela uno !trumento utile anc.e per !cri$ere programmi in C/ C@@ e Da$a.
R%dit - *ttimo editor multipiattaforma c.e !er$ire''e per !cri$ere codice in $ava/ ma c.e
puE e!!ere u!ato tran9uillamente per !cri$ere codice in C. La !ua potenza ri!iede/ oltre c.e
nelle funzionalit a$anzate c.e un editor de$e a$ere 5numero di riga/ te!to con .ig.lig.ting/
ecc.6/ anc.e nell8alto li$ello di configura'ilit e nella !icurezza di poter u!are D%dit con 9ua!i
tutti i !i!temi operati$i !enza perdere in termini di pre!tazioni 5tro$andoci !empre lo !te!!o
am'iente di la$oro/ non !iamo co!tretti ad imparare l8u!o di editor di$er!i6 e di re!a del
no!tro codice 5!iamo !icuri c.e un te!to !critto con R%dit per #indo! < totalmente
compati'ile con il R%dit per Linu?6.
4ini LotePa' 5#in 3.?6 - Iue!to < un editor molto $er!atile di!poni'ile per 4indows :;< ed
< pen!ato come !o!tituto per il notepad. Permette di la$orare !u pi: file ed < leggero/ $eloce
ed altamente configura'ile.
Edit del D,S - 1nc.e !e un po8 datato/ l8%dit del 7*S !i pre!enta come un 'uon editor c.e
.a/ oltre alle funzioni 'a!e/ un8ottima $elocit e la $i!ualizzazione delle rig.e e colonne di
la$oro/ molto utile 9uando il compilatore ci !egnaler un errore.
6-Scriia!o il pri!o progra!!a in C
12
Q giunto il momento di addentrarsi nella programmazione vera e propria utilizzando il linguaggio
C.
)ota7 Da que$ta le.ione in$erireo, alla #ine di o(ni le.ione, dei "e..i di codice coentati relati'i al "ro(raa di
e$e"io che ci acco"a(ner8 lun(o tutta la (uida. Gli e$e"i $aranno "ertinenti alla le.ione e $er'iranno al lettore "er
inquadrare (li ar(oenti in un "ro(raa a33a$tan.a a"io. Sono $tati in$eriti dei nueri identi#icati'i "er o(ni ri(a in
odo da "oter indenti#icare #acilente tali "arti di codice nel li$tato co"leto. Si la$cia al lettore la "o$$i3ilit8 di
a""ro#ondire le "arti di codice "re$entate. 6o $tudio del codice di e$e"io #acoltati'o e non "re(iudica la co"re$ione
della (uida.
L8impo!tazione c.e intendiamo !eguire < 9uella di !piegare i concetti Hper e!empiH/ all8inizio alcune
co!e !aranno poco c.iare/ ma do$ete fidar$i e pro!eguire/ perc.J !pe!!o per !piegare un concetto !i
de$e fare ricor!o a co!trutti/ o i!truzioni c.e $erranno !piegate !olo nelle lezioni !ucce!!i$e.
+l primo programma in C/ il pi: !emplice in a!!oluto < il famo!o HFello #orldNH 5Ciao 4ondo6 c.e
.a !oltanto lo !copo di !tampare a $ideo la !critta per !piegare la !inta!!i 'a!ilare del linguaggio.
Fello orld in C
#include <stdio.h>
main ()
{
printf("Hello World!");
}
Iue!to !emplice programma .a delle corri!pondenze anc.e in altri linguaggi.
Fello orld in Pa!cal
program main;
egin
!riteln("Hello World!");
end.
Fello orld in C@@
#include <iostream.h>
main()
{
cout << "Hello World!";
}
Fello orld in Da$a
class #aluto {
pulic static $oid main(#tring args%&) {
#'stem.out.println(()uot;Hello World!()uot;);
13
}
}
1''iamo $olutamente me!!o a confronto 9ue!ti 9uattro linguaggi per far notare un po8 di co!e.
1nzitutto il C < completamente di$er!o dal Pa!cal/ perc.J .a una logica molto pi: pratica/ ad e!empio
non do''iamo dic.iarare ogni $aria'ile fuori dal programma prima di u!arla= nel C@@/ a differenza del
C/ !i .anno a di!po!izione comandi alternati$i e co!trutti di nuo$a concezione/ !ia come nomi c.e come
!inta!!i= a differenza del Da$a/ in C/ non de$o fare una miriade di dic.iarazioni prima di poter !cri$ere il
programma e non !ono co!tretto a !eguire delle regole rigide per !trutturare un programma 5in Da$a c8<
un forte controllo !ui tipi/ lo !i puE e$incere anc.e dal codice propo!to/ in cui la funzione main de$e
e!!ere He!plicitamenteH dic.iarata pu''lica/ !tatica e $oid/ ed inoltre de$ono e!!ere me!!i gli argomenti
della funzione - arg!ST - anc.e !e all8interno del codice 9ue!ti non $engono utilizzati6.
7-"le!enti #onda!entali di un progra!!a
in C
14
*ra c.e a$ete c.iaro tutto ciE $i !tarete giu!tamente c.iedendo a co!a !er$e l8#includeK Co!a < il
main()K 1 co!a !er$ono le graffeK % i punti e $irgolaK Procediamo con ordine riportando il codice
!critto nella lezione precedente"
#include <stdio.h>
main ()
{
printf("Hello World!");
}
=include < una diretti$a del preproce!!ore/ un comando/ c.e permette di ric.iamare le
li'rerie !tandard del C. Senza li'rerie un programma non a$re''e a di!po!izione i comandi
per e!eguire anc.e le operazioni pi: !emplici/ come leggere un file o !tampare a $ideo una
!critta.
La funzione principale in un 9ual!ia!i programma in C < la main>? c.e/ in 9ue!to ca!o/ non
.a parametri/ ma puE rice$ere anc.e degli input da riga di comando. +l main < indi!pen!a'ile
ed unico e de$e e!!erci !empre=
Le parentesi graffe !er$ono/ in$ece/ per delimitare 'locc.i di i!truzioni/ o come $engono
a'itualmente c.iamate H!tatementH/ c.e !onoe!eguite in ordine/ da 9uella pi: in alto/ gi: fino
all8ultima=
+l punto e virgola/ in$ece/ !er$e per Hc.iudereH un8i!truzione/ per far capire c.e dopo 9uel
!im'olo inizia una nuo$a i!truzione.
%ntrando nel dettaglio della !inta!!i del Linguaggio C/ po!!iamo notare c.e la prima funzione c.e
incontriamo e c.e < anc.e una delle pi: u!ate < printf>?/ adi'ita a !tampare a $ideo tutto 9uello c.e gli
$iene pa!!ato come argomento e c.e fa parte della li'reria <stdio.h>/ !enza la cui inclu!ione/ non
a$re''e !en!o.
1ll8interno di un programma C po!!ono e!!ere in!eriti dei commenti/ 'a!ti !apere/ per ade!!o/ c.e
e!i!tono due modi"
,, - Putto 9uello c.e !ta a de!tra !ulla mede!ima riga $iene con!iderato commento e $iene
ignorato 5ai fini dell8interpretazione del linguaggio6 dal compilatore=
,U ... U, - Putto 9uello c.e < compre!o tra i due a!teri!c.i $iene con!iderato commento=
9ue!ta forma $iene utilizzata per commenti !u pi: rig.e.
15
8-La co!pila$ione di un progra!!a C
Come gi detto un programma in C puE e!!ere !critto anc.e con un !emplice editor di te!ti come il
Blocco note di #indo! 5o !imile6. Per poter $edere il ri!ultato del codice do''iamo !al$are
nece!!ariamente il file con un8e!ten!ione H.cH/ ad e!empio H.ello.cH. 1 9ue!to punto non do''iamo fare
altro c.e compilare il programma.
+n realt la compilazione di un programma in C 5!pe!!o integrata in am'ienti di !$iluppo e 9uindi
apparentemente tra!parente ed uniforme6 !egue $arie fa!i"
+l codice sorgente viene controllato dal preprocessore c.e .a i !eguenti compiti"
o rimuo$ere e$entuali commenti pre!enti nel !orgente=
o interpretare !peciali diretti$e per il preproce!!ore denotate da H#H/ come #include o
#define.
o controllare e$entuali errori del codice
+l risultato del preprocessore !ar un nuo$o codice !orgente HpulitoH ed He!pan!oH c.e
$iene tradotto dal compilatore C in codice a!!em'l2=
L8assembler sar# incaricato di creare il codice oggetto !al$andolo in un file 5.o !otto
;ni?,Linu? e .o'R in 7o!,#indo!6=
Il Lin@ editor !a il compito di collegare tutti i file oggetto ri!ol$endo e$entuali
dipendenze e creando il programma 5c.e non < altro c.e un file e!egui'ile6.
Micordiamo c.e tutte 9ue!te operazioni/ per 9uanto molto a$anzate/ po!!ono indi$iduare facilmente
errori di !inta!!i/ ma mai e poi mai potranno tro$are errori logici 5come ad e!empio un ciclo c.e non
fini!ce6/ anc.e !e !pe!!o $engono !egnalati dei 4arning c.e non co!titui!cono errore/ ma c.e
!egnalano parti di codice !trane e 9uindi !ulle 9uali porre attenzione per e$entuali errori logici. Iui ci
$iene in aiuto il de'ugger c.e .a il compito di aiutare a ge!tire la correzione degli errori con !$ariati
!trumenti come i 'rea0point ed i atc.point.
1$ete ancora il $o!tro file H.ello.cHK !pero di !i/ perc.J < giunto il momento di compilarlo= !e po!!edete
un am'iente di !$iluppo come 7e$-C@@ o Ai!ual C@@ do$ete !olamente cercare il comando HCompilaH
od H%!eguiH/ il programma pro$$eder/ non !olo ad e!eguire tutte le operazioni citate/ ma/ una $olta
compilato/ mander in e!ecuzione il $o!tro programma pre!entando$i il ri!ultato a $ideo.
Per c.i !te!!e u!ando/ in$ece/ compilatori come il D$6PP o 6CC/ la compilazione 5inte!a in tutte le
!ue fa!i6 de$e e!!ere fatta da riga di comando 5dalla !.ell per capir!i6/ e/ !ucce!!i$amente/ !empre da
riga di comando/ !i de$e lanciare il file e!egui'ile ri!ultante 5in linu? con gcc/ di default il file
e!egui'ile !i c.iama a;out/ mentre in am'iente 7o!,#indo! generalmente .a lo !te!!o nome del
!orgente ma con e!ten!ione ;e<e/ in$ece c.e H.cH6.
16
Per compilare 'a!ta po!izionar!i nella !olita cartella do$e ri!iede il file !orgente e !cri$ere"
# gcc hello.c
1de!!o a$ete $i!to un ria!!unto di come !i po!!a !cri$ere un programma e compilarlo/ tanto perc.J non
$i tro$iate di!armati 9uando procederemo con le !piegazioni= molti dei concetti !opra e!po!ti $erranno
approfonditi mano a mano c.e procediamo/ come la !trutturazione del linguaggio/ la compilazione/ le
funzioni di!poni'ili nelle $arie li'rerie.
Esempio pratico
5Ai!ualizza il !orgente completo6
Se''ene il programma di e!empio pre!entato !ia a''a!tanza grande/ !i puE notare c.e ricalca
perfettamente la !emplice !truttura !piegata in 9ue!ta lezione.
** #include <stdio.h>
%...&
+, int main()
+- {
%...&
*./
17
9-Co%a %ono le aria&ili
Mipetiamo la !piegazione della H)uida di Programmazione Ba!eH pre!ente !u 9ue!to !ito"
V1de!!o < fondamentale definire il concetto di $aria'ile/ $i!to c.e nelle pro!!ime lezioni faremo largo
u!o di 9ue!to termine. Pen!iamo/ ad e!empio/ a 9uando !al$iamo un numero di telefono di un no!tro
amico !ul cellulare= !e $ogliamo c.iamare il no!tro amico/ 'a!ter in!erire il !uo nome 5nome della
$aria'ile6 ed il cellulare comporr automaticamente il numero di telefono 5$alore della $aria'ile6. Si
puE $edere 9uindi c.e una $aria'ile e!i!te in funzione del nome e del !uo $alore corri!pondente= la
comodit ri!iede 5come nel cellulare6 nel poter u!are un nome per $alori/ c.e po!!ono e!!ere numeri o
lettere/ di grande entit o difficili da ricordare. ;n altro $antaggio/ non da !otto$alutare/ < la po!!i'ilit
di u!are il nome della $aria'ile al po!to del !uo $alore per e!eguir$i !opra delle operazioni/ con la
po!!i'ilit/ in !eguito/ di modificare il $alore come e 9uante $olte $ogliamo.W
7etto con un gergo pi: tecnico/ le $aria'ili non !ono altro c.e dei contenitori/ identificati da un nome
univoco/ di un 9ual!ia!i $alore/ !ia e!!o un numero o una !tringa. Per poter fare 9ualco!a di concreto
all8interno dei programmi do''iamo utilizzare le $aria'ili in cui il pregio di a$ere un corri!pondente
nome-$alore permette di ge!tire i cam'iamenti di $alore ad e!!e a!!ociati/ fornendo 9uindi 9uella
dinamicit nece!!aria ad e!eguire operazioni comple!!e e,o ripetiti$e con il minimo !forzo.
Le $aria'ili $engono definite da un tipo e da un nome.
+l nome per identificare una $aria'ile 5o una funzione o una co!tante6 $iene comunemente riferito come
identificatore.
;n identificatore < co!tituito da una o pi: lettere/ cifre o caratteri e de$e iniziare con una lettera o il
carattere di !ottolineatura 5under!core HXH 6= la loro lung.ezza ma!!ima dipende dal compilatore/ ma
generalmente non !i po!!ono !uperare i 31 caratteri/ ed inoltre il C < ca!e-!en!iti$e/ 9uindi !i fa
di!tinzione tra lettere maiu!cole e lettere minu!cole. Iue!ta piccola parente!i < do$uta/ $i!to c.e in
!eguito parleremo appunto delle funzioni e delle co!tanti per le 9uali do$ranno e!!ere c.iare le regole
per a!!egnare un nome HformalmenteH corretto.
+l tipo della $aria'ile indica 9uale tipo di $alori puE a!!umere il contenuto della $aria'ile !te!!a/ !i puE
'en capire c.e un tipo intero conter !oltanto dei numeri/ mentre il tipo carattere conterr !olamente
lettere dell8alfa'eto/ numeri e !im'oli= Aa fatto notare c.e l8intero 878 < e!tremamente di$er!o dal
carattere 878/ infatti l8intero $iene trattato come un numero e !u di e!!o !i po!!ono !$olgere le pi:
!$ariate operazioni matematic.e/ mentre il carattere $iene ge!tito come un !im'olo 5!i tratti di una
lettera o di un numero6.
Putto ciE .a una !piegazione logica c.e ri!iede nella rappre!entazione del numero !te!!o= !e l8intero 7
$iene rappre!entato da un '2te 5otto 'it6 come (((((111/ il carattere 7 $iene rappre!entato con un '2te
ma !eguendo 9uella c.e < la codifica 1SC++/ 9uindi appare/ a li$ello di 'it come ((11(111 c.e e9ui$ale
ad una rappre!entazione intera di 55. Le operazioni c.e permettono di con$ertire una $aria'ile da un
18
determinato tipo ad un altro 5ad e!empio da una lettera ad un numero6 prendono il nome di casting/
trattato nel capitolo 12 di 9ue!ta guida.
'utte le variabili/ prima di e!!ere utilizzate/ devono essere dic!iarate/ cio< de$e e!!ere detto al
compilatore il tipo della $aria'ile ed il !uo nome 5e!. int ?6/ 9ue!to per permettergli di allocare la
memoria nece!!aria alla $aria'ile !te!!a= la dic.iarazione generalmente $iene fatta all8inizio del
programma/ ma in programmi di grandi dimen!ioni puE tro$ar!i anc.e in altre po!izioni 5o altri file6/
ma 'i!ogna ricordare c.e comun9ue la dic.iarazione di una $aria'ile puE e!!ere fatta una ed una sola
volta.
Succe!!i$amente la variabile deve essere inizializzata/ cio< le de$e e!!ere a!!egnato un $alore/
operazione c.e generalmente $iene fatta contemporaneamente alla dic.iarazione.
,, !olo dic.iarazione
int ?=
,, inizializzazione
? Y 1(=
,, dic.iarazione ed inizializzazione
int 2 Y 15=
10-Le aria&ili in C
19
+n C e!i!tono di$er!i tipi di $aria'ili/ c.e !er$ono per rappre!entare tipi di dato di$er!i/ dai gro!!i
numeri ai te!ti. 1lcuni linguaggi permettono la dic.iarazione di $aria'ili generic.e/ ma poter a!!egnare
a cia!cun dato il tipo di variabile adeguato/ con!ente anc.e una migliore ge!tione della memoria 5alla
fonte6.
Lella ta'ella !eguente !ono mo!trati i $ari tipi/ la parola c.ia$e C c.e li identifica 5char per carattere/
int per intero/ etc.6/ la tipologia di informazioni c.e rappre!entano ed il numero di '2te nece!!ari per la
loro rappre!entazione in C"
'ipi di dic!iarazione +appresentazione A; di b(te
char
Carattere 1 5& 'it6
int
Lumero intero 2 516 'it6
short
Lumero intero HcortoH 2 516 'it6
long
Lumero intero HlungoH 4 532 'it6
float
Lumero reale 4 532 'it6
doule
Lumero reale HlungoH & 564 'it6
c!ar
+l tipo c!ar puE contenere 9ual!ia!i carattere definito !econdo lo !tandard 1SC++/ 9uindi 9ual!ia!i
lettera 5maiu!cola o minu!cola6/ cifra 5da ( a 96 e !im'olo pre$i!to dalla codifica.
Q molto importante ricordare c.e un char puE contenere uno ed un !olo carattere. Per memorizzare una
!ucce!!ione di caratteri/ alcuni linguaggi adottano un tipo !tringa 5string ad e!empio6/ in C/ in$ece/
utilizziamo un arra( di c!ar. L8arra2 < un contenitore di $aria'ili dello !te!!o tipo e ne
approfondiremo la cono!cenza pi: a$anti.
Per dic!iarare una variabile c!ar/ ad e!empio inizializzandola con la lettera 8r8/ 'a!ta !cri$ere"
char a 0 "r";
int
+l tipo int permette di rappre!entare numeri interi. Po!!iamo dic.iarare un int con due $arianti" s!ort e
long/ anc.e !e in realt un tipo int < gi di per !e8 un tipo short/ mentre il la 0e2ord long permette
di e!tendere 5utilizzando due '2te in pi:6 il range dei $alori c.e il tipo int puE a!!umere/ con!entedoci
di la$orare con grandi numeri.
20
+ numeri interi/ rappre!entati da int/ !ono 9uelli H!enza la $irgolaH o parti frazionate. %!aminiamo un
pezzo di codice in cui dic.iariamo ed inizializziamo $aria'ili intere ed e!eguiamo una di$i!ione 516/
9ue!ta operazione !ui numeri interi ci ricorda c.e 'i!ogna fare attenzione poic.J non po!!iamo
rappre!entare $alori decimali.
nt 2 0 3;
int ' 0 4;
int 5;
5 0 2 1 ';
11 5 $ale 67 cio8 la parte intera della di$isione tra 3 e 4
float e double
+ tipi float e double !ono i co!iddetti numeri in $irgola mo'ile/ c.e rappre!entano l8in!ieme dei numeri
reali" con e!!i po!!iamo rappre!entare numeri molto piccoli o numeri molto grandi/ po!iti$i e negati$i e
naturalmente con e !enza decimali.
La differenza tra i due !ta nel numero di 'it ri!er$ati alla rappre!entazione dei numeri/ c.e !i $a a
riflettere !ul range di numeri e !ul numero di cifre dopo la $irgola c.e po!!iamo memorizzare. Iuindi
!e a''iamo 'i!ogno di particolare accuratezza/ utilizziamo il tipo doule.
Aediamo un !emplice pezzo di codice in cui riproponiamo la di$i!ione utilizzando doule/ per
mo!trare la differenza con il tipo int"
doule 2 0 3./
doule ' 0 6./
doule 5;
5 0 2 1 '
11 5 $ale 4.+
La notazione u!ata per rappre!entare la $irgola < 9uella ingle!e/ in cui !i u!a il punto 5e non una
$irgola6 per di$idere la parte intera da 9uelle frazionaria.
Esempio pratico
5Ai!ualizza il !orgente completo6
1ll8interno del programma di e!empio $engono utilizzate molte $aria'ili= ecco alcune dic.iarazioni per
far capire l8importanza c.e le $aria'ili ricoprono all8interno del programma.
96 int scelta;
%...&
6-9 int suscelta;
21
6-3 int i0*;
6-, int n0*;
%...&
493 int suscelta;
49, int i0*;
49- int n0*;
%...&
.9- int inde20/; 11 ini5iali55a l"indice
%...&
++. int i 0 /;
%...&
+39 char in$io;
Aumeri con segno e senza segno
+n termini di rappre!enta'ilit c8< da far notare c.e l8u!o dei 'it per rappre!entare un determinato tipo
$aria a !econda c.e 9uel tipo !ia signed 5con !egno6 o unsigned 5!enza !egno6.
Per rappre!entare un numero come **./ ad e!empio/ !ono !ufficienti 7 'it/ !e pen!iamo al tipo signed
c!ar/ c.e .a & 'it/ po!!iamo immaginare come l8otta$o 'it 5il pi: !ignificati$o/ 9uello pi: a !ini!tra6
rappre!enti il segno del numero 58@8 !e il 'it $ale ( 8-8 !e il 'it $ale 16.
0***//*/ 11 rappresenta7 in inario7 l"intero 114
1///***/ 11 ecco l"intero -114
Come !i $ede/ oltre a tro$are Hacce!oH il 'it pi: !ignificati$o/ $ediamo c.e la codifica dei numeri
negati$i < in$ertita/ parte dal numero :* 5rappren!etnato con ********6 e arri$a a :*6, 5*///////6.
Iue!ta codifica !i c.iama complemento a due.
La !te!!a codifca con unsigned c!ar/ rappre!enta $alori po!iti$i ma di$er!i tra loro"
0***//*/ 11 rappresenta7 in it7 l"intero 114
1///***/ 11 rappresenta7 in it7 l"intero 142
+n definiti$a/ amme!!o di a$ere n 'it per rappre!entare un numero/ !e < signed/ allora i $alori po!!i'ili
!aranno compre!i tra -2
5n-16
e 2
5n-16
-1/ 9uindi/ nel ca!o di una rappre!entazione ad & 'it !i a$re''ero
$alori compre!i tra -12& e 127.
Lel ca!o di un unsigned/ in$ece i $alori/ come gi detto/ !ono tutti po!iti$i e po!!ono a!!umere $alori
compre!i tra ( e 2
n
- 1/ nel ca!o degli & 'it !i a$re''ero $alori compre!i tra ( e 255.
11-'li (peratori) introdu$ione
1''iamo !piegato come dic.iarare/ inizializzare e manipolare le $aria'ili/ ma non potremo farci niente
di concreto !e non parliamo degli operatori c.e permettono di la$orarci !opra.
22
)li operatori in programmazione permettono di e!trapolare un determinato $alore dal frutto
dell8operazione c.e !i compie !u una o pi: $aria'ili all8interno del programma= co!G come l8operatore
H@H !er$e per !ommare due numeri in matematica/ analogamente !er$e per compiere la !te!!a
operazione in un programma !critto in C.
*$$iamente ci !ono delle do$ute differenze/ innanzitutto le operazioni del C !ono 9uelle 'a!ilari 5per
funzioni pi: a$anzate do''iamo u!are delle li'rerie appo!ite6/ .anno un ri!ultato HfinitoH/
contrariamente a 9uelle matematic.e c.e po!!ono a$ere un ri!ultato !im'olico o infinito e/ infine/
contrariamente a 9uelle matematic.e/ !i po!!ono applicare anc.e a $alori non numerici delle $aria'ili.
)li operatori c.e andremo ad analizzare nelle !eguenti lezioni !i !uddi$idono in"
,peratori aritmetici; Comprendono !omma/ !ottrazione/ moltiplicazione/ di$i!ione intera/
di$i!ione con modulo ecc.
,peratori di confronto; *peratori c.e permettono di $erificare determinate condizioni/
come ad e!empio l8uguaglianza o la di!uguaglianza.
,peratori logici; 7a utilizzare con le i!truzioni condizionali ed iterati$e.
Per comprendere meglio gli operatori di confronto e logici < con!iglia'ile e propedeutico leggere
l8H+ntroduzione alla logica e diagrammi di flu!!oH.
12-(peratori arit!etici
+n realt a''iamo gi $i!to i !emplici operatori di a!!egnamento 5Y6 e di di$i!ione intera 5,6/ ma non
a''iamo !piegato nel dettagli tutte le operazioni c.e !i po!!ono compiere !ulle $aria'ili per mezzo dei
loro operatori. *$$iamente oltre alla di$i!ione intera/ con gli interi/ < po!!i'ile e!eguire la !omma 5@6/
23
la !ottrazione 5-6/ la moltiplicazione 5U6 e la di$i!ione con re!to 5Z6/ di cui pre!entiamo una ta'ella
ria!!unti$a"
*perazioni con gli
int
Sim'olo %!empio
1ddizione @ 4 @ 27 Y 31
Sottrazione - 76 - 23 Y 53
4oltiplicazione U 4 U 7 Y 2&
7i$i!ione intera ,
1( , 3 Y 3
53 < il n di $olte
di$i!i'ili !enza
re!to6
7i$i!ione con
modulo
Z
11 , 6 Y 5
55 < il re!to della
di$i!ione6
Iuando la$oriamo con i numeri reali 5float o dou'le6 l8unica operazione c.e manca < 9uella di
Hdi$i!ione con moduloH c.e o$$iamente non .a ragione di e!i!tere/ in 9uanto le di$i!ioni po!!ono
contenere le parti frazionarie"
*perazioni con i
dou'le
Sim'olo %!empio
1ddizione @ 2.5 @ 14.3 Y 16.&
Sottrazione - 43.& - 12.7 Y 31.1
4oltiplicazione U 7.5 U 3.( Y 22.5
7i$i!ione , 5.( , 2.( Y 2.5
%!i!tono poi degli operatori ai 9uali 'i!ogna porre particolare attenzione/ 9ue!ti !ono l8operatore di
incremento 5@@6 e 9uello di decremento 5--6/ c.e po!!ono e!!ere prepo!ti o po!po!ti alla $aria'ile= !e
!ono prepo!ti il $alore < calcolato prima c.e l8e!pre!!ione !ia $alutata/ altrimenti $iene calcolato dopo=
l8incremento ed il decremento a$$engono !empre nel $alore di una unit !ul $alore della $aria'ile. ;n
po8 di codice !er$ir a far capire meglio come funzionano tali operatori"
int ? Y 2=
int 2 Y 5=
int z Y 9=
int 0 Y 6=
,, accanto/ come commento/ il $alore !tampato a $ideo
printf5HZd nH/ ?@@6= ,, 2
printf5HZd nH/ @@26= ,, 6
24
printf5HZd nH/ z--6= ,, 9
printf5HZd nH/ --06= ,, 5
Come detto 9ue!ti operatori incrementano o decrementano il $alore di una $aria'ile/ 9uindi
?@@
ad e!empio/ e9ui$ale a !cri$ere
? Y ? @ 1=
1nc.e !e la prima forma 59uella di incremento6 ri!ulta e!!ere pi: $eloce.
+noltre e!i!te una forma contratta per e!pre!!ioni del tipo"
e!pre!!ione1 Y e!pre!!ione1 [operatore\ e!pre!!ione2
,, e9ui$alente a
e!pre!!ione1 [operatore\ Y e!pre!!ione2
Iue!ta forma ri!ulta e!!ere pi: conci!a/ e per 9ue!to pi: facile da u!are/ ma 'i!ogna porre attenzione
nel !uo u!o perc.J potre''e indurre in errori do$uti alla poca c.iarezza del codice"
int 2 Y 4=
2 @Y 2= ,, i ade!!o $ale 6
int ? Y 3=
? UY 2 @ 3= ,, ? ade!!o $ale 27
,, 9ue!to perc.J e9ui$ale a ?Y?U52@36 e non ?Y5?U26@3
13-(peratori di con#ronto e logici
,peratori di confronto
25
)li operatori di confronto permettono di $erificare determinate condizioni/ come ad e!empio
l8uguaglianza/ la di!uguaglianza/ o !emplicemente !e un elemento < maggiore di un8altro= la !eguente
ta'ella mo!tra nel dettaglio gli operatori di confronto e la loro funzione"
Simbolo Significato 8tilizzo
00
uguale a
a 00
!0
di$er!o da
a !0
<
minore
a <
>
maggiore
a >
<0
minore o uguale
a <0
>0
maggiore o uguale
a >0
Iue!ti operatori !er$ono 9uando incontreremo le i!truzioni condizionali e 9uelle iterati$e/ perc.J !e la
condizione < $erificata re!titui!cono $ero/ altrimenti re!titui!cono fal!o. )li operatori di confronto !ono
operatori a due argomenti ed .anno !empre po!izione infi!!a 5cio< tra i due argomenti6.
,peratori logici
1nc.e gli operatori logici $engono utilizzati con le i!truzioni condizionali ed iterati$e/ e permettono di
fare l81L7 e l8*M tra due operandi= nella ta'ella mo!triamo i !im'oli u!ati e il loro utilizzo"
Simbolo Significato 8tilizzo
((
1L7 logico
a ((
;;
*M logico
a ;;
Iue!te operazioni re!titui!cono nece!!ariamente 1 9uando !ono $ere e ( 9uando !ono fal!e/ 9uindi
l8e!pre!!ione a ;; a!!ume $alore uno !e e !olo !e a o $algono uno/ mentre $ale zero !e entram'i
gli operandi $algono zero= analogamente a (( a!!ume $alore zero !e a o $algono zero/ uno nel
ca!o entram'i $algano uno.
Lota" i $i3oli && e || $ono di'er$i da & e | che, in'ece, ra""re$entano il "3it%i$e 9)D" ed il
"3it%i$e 1R" !non trattati in que$ta (uida&.
14-*ropriet degli operatori
)li operatori .anno di$er!e caratteri!tic.e e regole c.e permettono a noi di !cri$erli correttamente/ e al
compilatore di capire come utilizzarli. Iue!to accade perc.J !e non fo!!ero !pecificate delle regole
preci!e/ il compilatore c.e agi!ce in modo automatico 5ed automatizzato6 non !apre''e come
interpretare 9uello c.e < !tato !critto.
26
Ai!to c.e non puE Hfare di te!ta !uaH/ do''iamo e!!ere noi a cono!cere le regole !eguite nella !inta!!i
del linguaggio e pre!entare/ 9uindi/ 9uello c.e $ogliamo fare in una forma traduci'ile e !en!ata per il
compilatore.
Le propriet da cono!cere !ono poc.e e non < nemmeno nece!!ario ricordar!ele e!attamente/ 'a!ta
!eguire le con$enzioni e/ con il tempo/ !i $edr c.e di$enter naturale !cri$ere programmi
H!intatticamenteH corretti. %!!e !ono"
Posizione - ;n 9ual!ia!i operatore .a una determinata po!izione ri!petto ad i !uoi operandi.
Si dice c.e un operatore < prefisso !e compare prima degli operandi/ postfisso !e compare
dopo e infisso !e compare tra gli operandi=
Briet# - Iue!ta rappre!enta il numero di argomenti c.e un operatore puE accettare. 1d
e!empio l8operatore @@ .a ariet uguale a uno 51@@6/ il !im'olo @ .a ariet uguale a due 51
@ B6/ mentre l8unico operatore ad a$ere ariet uguale a tre < l8operatore ternario H < = H 51 K
B " C6/ di cui parleremo nella lezione &=
Precedenza >o priorit#? - La precedenza < un $alore c.e identifica gli operatori pi:
importanti e 9uelli meno importanti= maggiore < la priorit minore < il $alore c.e la
identifica" 9ue!ti $alori ri!ultano utili/ ad e!empio/ 9uando !i e!eguono delle operazioni
matematic.e/ per !ta'ilire 9uali operazioni de''ano e!!ere e!eguite per prime/ 9ue!to/
o$$iamente/ in mancanza di parente!i tonde c.e potre''ero modificare l8ordine con cui !i
e!eguono le operazioni !ulle $aria'ili 5in realt ciE accade !emplicemente perc.J le parente!i
tonde .anno una priorit maggiore6=
Bssociativit# - L8a!!ociati$it !ta'ili!ce/ a parit di priorit/ 9uale !ia l8ordine con cui
'i!ogna e!eguire i $ari operatori. Se l8operatore < a!!ociati$o a !ini!tra/ !i !correr da !ini!tra
$er!o de!tra/ mentre !e < a!!ociati$o a de!tra/ !i far l8e!atto contrario.
%!empi tipici in cui inter$engono le propriet degli operatori/ !i .anno nell8interpretazione di formule
matematic.e/ come nell8e!empio !eguente"
a > ? c
1? che $iene interpretato come
? a > ( ? c)7 e non (a > ) ? c
? perch8 la moltiplica5ione ha
? preceden5a maggiore
?1
a : : c
1? che $iene interpretato come
? (a : ) : c 7 perch8 l"associati$it@
27
? della sottra5ione 8 a sinistra
?1
Esempio pratico
5Ai!ualizza il !orgente completo6
)li operatori matematici non $engono u!ati molti!!imo nel programma= $engono/ al contrario/ u!ati
molti operatori di confronto. Iue!to dipende e!clu!i$amente dal fatto c.e il programma la$ora
pre$alentemente con il te!to e non con i numeri. %cco un e!tratto di codice c.e mo!tra $ari confronti"
4-9 if (suscelta < i)
4-3 { 11 AB : CDEF
4-,
4-- 11 #e la lista 8$uota esco
.// if(p 00 FGHH)
./* return;
./6
./4 11 #e la lista ha almeno due elmenti...
./. if(p:>pun !0 FGHH)
15-*ri!e opera$ioni di Input+(utput
Per ade!!o a''iamo po!to le prime 'a!i del linguaggio C= in 9ue!ta lezione $ogliamo fornire gli
!trumenti adatti ad operare !ull8input,output/ inte!o come !emplici operazione a $edio comandate dalla
ta!tiera. Per fare 9ue!to do''iamo includere il file <stdio.h> c.e mette a di!po!izione alcune funzioni
predefinite per e!eguire la lettura da un di!po!iti$o di input 5e!. ta!tiera6 o !crittura !u un di!po!iti$o di
output 5e!. $ideo6= le funzioni di cui parleremo !ono getc!ar>?/ printf>? e scanf>?.
28
La prima funzione c.e incontriamo < la getc!ar/ il cui compito < 9uello di leggere un carattere per
$olta dalla ta!tiera= 9ui di !eguito pre!entiamo un programma c.e conta il numero di $olte c.e !i <
digitato un carattere 5per interrompere il programma premere CtrL@7/ Y %*36.
#include <stdio.h>
main()
{
int ch7 i 0 /;
!hile((ch 0 getchar()) !0 ECB) i>>;
printf("Id Jn"7 i);
}
La funzione immediatamente !eguente 5e complementare6 < la putc!ar>?/ c.e legge un carattere alla
$olta e lo !tampa a $ideo= $iene pre!entata nel !eguente programma c.e con$erte ogni carattere in!erito
nell8e9ui$alente lettera maiu!cola 5grazie alla funzione toupper>?.
#include <ct'pe.h> 1? Der la defini5ione di toupper ?1
#include <stdio.h> 1? Der la defini5ione di getchar7 putchar ed ECB ?1
main()
{
int ch;
!hile((ch 0 getchar()) !0 ECB)
putchar(toupper(ch));
}
L8i!truzione per !tampare a $ideo pi: u!ata < la printf>?/ c.e ci permette di controllare ciE c.e $iene
!tampato/ nel !en!o c.e permette di decidere co!a !tampare ed in 9uale forma. La !truttura di printf < la
!eguente"
int printf(char ?formato7 lista argomenti ...)
Stampa !ullo stdout 5il $ideo o la con!ole in 9ue!to ca!o6 la li!ta di argomenti conformemente alla
!tringa di formato !pecificata. La funzione ritorna il numero di caratteri !tampanti. La !tringa di
formato .a due tipi di argomenti"
caratteri ordinari - 9ue!ti $engono copiati nell8output=
specificazioni di conversione - contraddi!tinte dal carattere percentuale HZH e da un
carattere c.e !pecifica il formato con il 9uale !tampare le $aria'ili pre!enti nella li!ta di
argomenti.
La ta'ella !eguente mo!tra i po!!i'ili formati c.e po!!ono e!!ere u!ati per formattare le $aria'ili= tali
con!iderazioni !i applicano anc.e al comando scanf()=
Stringa di controllo Cosa viene stampato
29
Id7 Ii
+ntero decimale
If
Aalore in $irgola mo'ile
Ic
;n carattere
Is
;na !tringa di caratteri
Io
Lumero ottale
I27 IK
Lumero e!adecimale
Iu
+ntero !enza !egno
If
Lumero reale 5float o dou'le6
Ie7 IE
3ormato !cientifico
II
Stampa il carattere Z
Q po!!i'ile in!erire/ tra il !im'olo Z e l8identificati$o del formato/ una delle !eguenti $oci"
Segno meno 5-6/ e!egue la giu!tificazione a !ini!tra=
;n numero intero/ !pecifica l8ampiezza del campo=
m.d/ do$e m < l8ampiezza del campo e d < la preci!ione del numero= u!ato generalmente per
le !tring.e o per un numero di tipo reale.
Iuindi facciamo degli e!empi per far capire meglio l8u!o di printf()"
int 2 0 */;
printf("Al numero 8 Id"7 2);
1? l"output a $ideo 8 "Al numero 8 */" ?1
print("I:.6.4f Jn"7 6..4-634.);
1? l"output a $ideo 8 6..4-4 ?1
printf("ALM 0 6/II Jn");
1? l"output a $ideo 87 "ALM 0 6/I" ?1
1ltri linguaggi c.e u!ano printf()/ oltre al C/ !ono il CCC/ per il 9uale/ perE e!i!te anc.e il comando
nati$o cout/ ed il PDP/ nel 9uale !i comporta in modo analogo a 9uello del C.
30
1ll8intero di 9uello c.e $err !tampato notiamo !pe!!o il !im'olo HJnH c.e/ come a$rete intuito !er$e
per andare a capo= tale !im'olo $iene c.iamato sequenza di escape. Le !e9uenze di e!cape !er$ono per
rappre!entare 9uei caratteri H!pecialiH pre!enti nella codifica 1SC++ e c.e non !tampano nulla a $ideo/
ma permetto di introdurre all8interno di ciE c.e $err !tampato e$entuali !paziature. Le !e9uenze di
e!cape iniziano con il carattere 'ac0!la!. 5]6 e !ono interpretate come un !ingolo carattere.
'ipo di opzione Descrizione
Jn
Mitorno a capo
Jt
Pa'ulazione orizzontale
J
Pa'ulazione $erticale
Ja
Porna indietro di uno !pazio
Jf
Salto pagina
La funzione scanf>? !er$e per leggere dallo stdin 5generalmente la ta!tiera6 una !e9uenza di caratteri
5lettere o cifre6 c.e $erranno memorizzate all8interno di opportune $aria'ili. Scanf </ 9uindi/ definita
come !egue"
int scanf(char ?formato7 lista argomenti ...)
7a far notare c.e scanf()/ oltre a poter leggere !tring.e di te!to/ e non un !olo carattere alla $olta
come getchar()/ permette di leggere pi: $aria'ili contemporaneamente/ !e 9ue!te !ono !pecificate
nella li!ta degli argomenti.
1 differenza di printf()/ perE la $aria'ile de$e e!!ere me!!a preceduta dal !im'olo (/ perc.J in realt
tra gli argomenti non do''iamo pa!!are il nome della $aria'ile/ ma il !uo indirizzo/ co!a c.e puE e!!ere
fatta tran9uillamente utilizzando un puntatore 5ed ecco il perc.J del (/ !im'olo c.e !er$e ad ottenere
l8indirizzo del puntatore= tratteremo i puntatori nel capitolo 136.
#include <stdio.h>
int main()
{
int i;
scanf("Id Jn"7 (i);
printf("Id Jn"7 i);
}
31
Iue!to !emplice programma !opra e!po!to !er$e !olamente per leggere un numero da ta!tiera e
ri!tamparlo a $ideo= a$rete notato c.e < po!!i'ile u!are gli !pecificatori di con$er!ione anc.e per
scanf()/ c.e/ 9uindi/ !i comporta in modo molto !imile a printf().
;na piccola particolarit limitatamente all8u!o delle !tring.e e degli arra2 con la funzione scanf()/ < la
!eguente"
char stringa%*//&;
scanf("Is"7 stringa);
+n 9ue!to ca!o < po!!i'ile omettere il !im'olo ( c.e ric.iama l8indirizzo del puntatore/ ed u!are/ in$ece/
il nome della $aria'ile/ perc.J il nome di un arra2 corri!ponde all8indirizzo di partenza dell8arra2 !te!!o.
Esempio Pratico
5Ai!ualizza il !orgente completo6
Le funzioni di 'a!e di input,output !ono ampiamente utilizzate all8interno del programma. 1d e!empio/
il menu iniziale $iene !tampato u!ando printf() e all8utente < perme!!o !cegliere l8operazione c.e
de!idera utilizzando scanf().
3* printf(" #######################Jn");
36 printf(" # NGONAPM EM#Q $*./ #Jn");
34 printf(" #######################JnJn");
3. printf(" *) LA#GMHARRM PCFSMSSCJnJn");
3+ printf(" 6) MTTAGFTA PCFSMSSCJnJn");
39 printf(" 4) UCVABAPM PCFSMSSCJnJn");
33 printf(" .) NAUGCLA PCFSMSSCJnJn");
3, printf(" +) HETTA PCFSMSSA VM BAHEJnJn");
3- printf(" 9) #MHLM PCFSMSSA #G BAHEJnJn");
,/ printf(" /) E#PAJnJnJnJn");
32
,* printf(" la tua scelta > ");
,6
,4 11 Mspetto scelta dell"utente
,. scanf ("Ii"7 (scelta);
,+ scelta 0 (int)scelta;
16-Controlli condi$ionali) I#-"l%e
Lella programmazione/ come gi detto/ le i!truzioni $engono e!eguite dalla prima fino all8ultima. Per
de$iare il flu!!o delle !celte 5ad e!empio per !cegliere tra l8opzione 1 e l8opzione B6 'a!ta porre delle
condizioni c.e/ !e $erificate/ e!eguono un pezzo di codice o altrimenti ne e!eguono un altro= 9ue!te
i!truzioni particolari c.e permettono di incanalare il flu!!o !i c.iamano !trutture di controllo
condizionale o/ pi: genericamente/ i!truzioni condizionali. %!i!tono due tipi di !trutture di controllo
condizionale/ l8if-el!e e lo !itc.. L8if-el!e e lo !itc. .anno/ !o!tanzialmente/ comportamenti !imili/
ed anc.e !e il primo < largamente il pi: u!ato/ .anno delle differenze per 9uanto riguarda il tipo di
operazione c.e $ogliamo !$olgere= ma $ediamo nel dettaglio come funzionano.
Lota" in C/ a differenza del C@@ e del Da$a/ non e!i!te il tipo 'ooleano 5c.e puE a!!umere $alore $ero
-true- o fal!o -fal!e-6/ per 9ue!to 9uando de$e e!!ere 'eri#icata una condi.ione e!!a ri!ulta fal!a !e $ale
zero e $era altrimenti.
33
If-Else
L8i!truzione if permette di $erificare determinate condizioni ed .a la !eguente !inta!!i"
[... altre i$tru.ioni ...]
if 5e!pre!!ione6
i!truzione
[... altre i$tru.ioni ...]
+n 9ue!to ca!o !e l8e!pre!!ione ri!ulta $era/ fa e!eguire l8i!truzione immediatamente !ucce!!i$a/
altrimenti 5!e la condizione < fal!a6 !i !alta l8i!truzione 5od il 'locco di i!truzioni6 facenti parti dell8if e
!i procede nell8e!ecuzione delle i!truzioni !ucce!!i$e/ c.e po!!ono e!!ere la pro!ecuzione del
programma o un !emplice else/ ad indicare la po!!i'ile alternati$a all8if"
if 5e!pre!!ione6
i!truzione1
el!e
i!truzione2
o un else if c.e permette di $erificare una o pi: condizioni"
if 5e!pre!!ione6
i!truzione1
el!e if 5e!pre!!ione6
i!truzione2
el!e
i!truzione3
Co!G !i puE comandare il flu!!o del programma decidendo di e!eguire una parte di codice oppure no
5nel ca!o del !olo if6/ di fare una !celta tra due parti di codice 5nel ca!o if - else6 o di fare una !celta tra
pi: parti di codice 5nel ca!o if - else if - else6.
3acciamo un e!empio pratico nel codice !otto!tante/ a!!umendo c.e !ia !tato definito/ nel codice
!opra!tante all8if/ il $alore della $aria'ile intera Hri!ultatoXe!ameH/ c.e puE a!!umere un $alore
compre!o tra ( e 3("
if 5ri!ultatoXe!ame \Y1&6
printf 5HComplimenti .ai !uperato l8e!ameH6=
el!e if 5ri!ultatoXe!ame \Y156
printf 5H7e$i !o!tenere l8orale per 9ue!to e!ameH6=
el!e
printf 5HLon .ai !uperato l8e!ameH6=
34
)eneralmente dopo un if o un el!e $iene e!eguita solo la prima i!truzione pi: $icina/ regola c.e puE
creare dei pro'lemi 9uando ci !ono due o pi: i!truzioni/ ma alla 9uale !i puE porre rimedio ponendo
tutte le i!truzioni tra due parente!i graffe/ la graffa di apertura 5 ^ 6 andr !otto all8if/ allineata con la
prima lettera/ mentre la graffa di c.iu!ura 5 _ 6 andr po!ta dopo l8ultima i!truzione/ !u una nuo$a riga
ed allineata con 9uella di apertura. Per c.iarire meglio/ ecco un if-el!e a''a!tanza !emplice c.e !piega
come utilizzare le parente!i graffe per raccogliere i!truzioni"
if 5ri!ultatoXe!ame \Y1&6
^
printf 5HComplimenti .ai !uperato l8e!ameH6=
int pa!!ato Y 1=
_ el!e ^
printf 5HLon .ai !uperato l8e!ameH6=
int pa!!ato Y (=
_
7o''iamo fare particolare attenzione all8u!o dei 'locc.i if annidati/ come 9uello dell8e!empio"
if 5ri!ultatoXe!ame [ 1&6
if 5ri!ultatoXe!ame [ 156 printf 5HLon .ai !uperato l8e!ameH6=
el!e printf 5HSei !tato amme!!o all8oraleH6=
+n 9ue!to ca!o ri!ulta difficile capire e!attamente 9uale !ia il !ignificato reale di 9ue!to el!e/ e
!oprattutto ci !i potre''e domandare !e realmente il programmatore a''ia $oluto porre determinate
condizioni o !e a''ia !emplicemente !'agliato a !trutturare il co!trutto if. Se non capiamo e!attamente
il codice/ con$iene ricordar!i la regola !econdo la 9uale "l'el$e $i ri#eri$ce $e"re all'i# "i: 'icino, a
eno che non $ia di'er$aente $"eci#icato da e'entuali "arente$i (ra##e"/ ma < comun9ue 'uona
norma u!are !empre le parente!i graffe anc.e 9uando !i tratta di e!eguire una !ola i!truzione/ magari
indentando 5mettendo opportune !paziature6 correttamente il codice. L8e!empio precedente ri!ulta
!icuramente pi: c.iaro !e !trutturato in 9ue!to modo"
if 5ri!ultatoXe!ame [ 1&6
^
if 5ri!ultatoXe!ame [ 156
^
printf 5HLon .ai !uperato l8e!ameH6=
_ el!e ^
printf 5HSei !tato amme!!o all8oraleH6=
_
_
35
17-Controlli condi$ionali) S,itc- e operatori
ternari
,peratore 'ernario
L8operatore ternario H< =H < una forma !intetica dell8i!truzione if-el!e/ e per 9ue!to $iene u!ata per
ragioni di comodit e !inteticit del codice. L8operatore H< =H < l8unico operatore ternario del C/ infatti
opera !u tre parametri a differenza degli altri operatori c.e !pe!!o operano !u uno o due parametri.
7i !eguito pre!entiamo la !inta!!i dell8operatore e la corri!pondente !inta!!i di un 'locco if-el!e"
11 Cperatore ternario <
espressione
*
< espressione
6
= espressione
4
11 Porrispondente locco if:else
if (espressione
*
)
36
{
espressione
6
;
} else {
espressione
4
;
}
Iuindi !e l8e!pre!!ione1 ri!ulta $era/ !i e!egue l8e!pre!!ione2/ altrimenti !i e!egue l8e!pre!!ione3. Per
e!empio il !eguente codice a!!egna/ nelle due forme e9ui$alenti/ alla $aria'ile Hma?H il ma!!imo tra
HalfaH e H'etaH"
if (alfa > eta)
ma2 0 alfa;
else
ma2 0 eta;
11 che corrisponde a...
ma2 0 (alfa > eta) < alfa = eta;
Switc!
Come annunciato/ l8i!truzione !itc. .a delle differenze dall8if-el!e/ infatti puE e!!ere u!ata !olo in
alcuni ca!i do$e"
Aiene $alutata !olamente una $aria'ile/ tutte le !celte dipenderanno/ infatti/ da 9ue!ta
$aria'ile. La $aria'ile de$e e!!ere un tipo int/ !.or/ long o c.ar=
*gni !ingolo $alore della $aria'ile puE controllare !olo una !celta. ;na !celta finale/
c.iamata default < incaricata di catturare tutti i $alori dei ca!i non !pecificati=
L8i!truzione !itc. .a la !eguente !truttura"
s!itch (espressione) {
case elem
*
=
istru5ione
*
;
reaW;
opt
case elem
6
=
istru5ione
6
;
reaW;
opt
...
case elem
n
=
istru5ione
n
;
reaW;
opt
default=
istru5ione;
reaW;
opt
}
Lotiamo c.e lo !itc. .a/ inoltre/ una !truttura a''a!tanza particolare/ < a ca!cata/ cio< !e e!eguo il
primo ca!o 5a$endo !otto degli altri6 e non metto un reaW per u!cire/ continua ad e!eguire anc.e le
37
i!truzioni !ucce!!i$e c.e fanno parte di altre ca!i!tic.e= 9ue!ta !truttura ricorda molto 9uella adottata
nei file 'atc. 5.'at6 utilizzati con il 7*S e permette di ottenere effetti intere!!anti !ulla !elezione del
codice/ ri!parmiandone 9uando < comune a pi: ca!i!tic.e. 4a $ediamo l8e!empio pratico/ a!!umendo
di a$ere la $aria'ile intera HnumeroH c.e puE a!!umere $alori maggiori od uguali a zero.
s!itch (numero) {
case /=
printf("Fessuno");
reaW;
case *=
printf("Gno");
reaW;
case 6=
printf("Vue");
reaW;
case 4=
case .=
case +=
printf("Lalore positi$o piccolo");
reaW;
default=
printf("Lalore positi$o grande");
reaW;
}
Esempio Pratico
5Ai!ualizza il !orgente completo6
L8+3/ all8interno del programma/ $iene u!ato in larga mi!ura= ad e!empio/ per a$$iare le !celte adeguate
del menu !i utilizza una !erie di +3-%LS%"
*/* else if (scelta 00 *) 11 Lisuali55o i contatti presenti
*/6 { 11 EH#EAB * : CDEF
*/4
*/. $isuali55aPontatto(lista);
*/+
*/9 } 11 EH#EAB * : PHC#E
*/3 else if (scelta 00 6) 11 Mggiungo un nuo$o contatto
*/, { 11 EH#EAB 6 : CDEF
*/-
**/ lista 0 aggiungiPontatto(lista);
***
**6 } 11 EH#EAB 6 : PHC#E
38
18-Controlli Iteratii) ,-ile. #or. &rea/
Pre!entiamo dei co!trutti c.e permettono di e!eguire ciclicamente delle i!truzioni fino al $erificar!i di
alcune condizioni. Iue!ti co!trutti prendono il nome di !trutture di controllo iterati$e o i!truzioni di
ciclo.
Le i!truzioni di ciclo !ono una delle componenti fondamentali della programmazione e permettono di
ri!parmiare la 9uantit di codice !critta rendendo 9uindi il programma pi: leggero e pi: facile da
comprendere. Le i!truzioni di ciclo/ come le i!truzioni condizionali/ .anno 'i!ogno c.e alcune
condizioni $engano $erificate affinc.J il ciclo continui nella !ua opera o !i interrompa.
Le i!truzioni di ciclo del C !ono tre"
il w!ile/ c.e continua il !uo ciclo fino a 9uando l8e!pre!!ione a!!ociata non ri!ulta fal!a
il do-w!ile/ c.e agi!ce come il .ile/ ma a!!icura l8e!ecuzione delle i!truzioni a!!ociate
almeno una $olta
39
il for/ c.e < il co!trutto pi: u!ato/ $er!atile e potente tra i tre/ ma c.e proprio per 9ue!to <
9uello a cui 'i!ogna pre!tare un po8 pi: di attenzione.
Come per le i!truzioni condizionali/ 9uando parliamo di Hi!truzioneH ci riferiamo ad una o pi: i!truzioni
a!!ociate/ ricordando c.e !e le i!truzioni !ono due o pi: 'i!ogna u!are le parente!i graffe per
delimitarle/ mentre una !ingola i!truzione non ne .a nece!!ariamente 'i!ogno.
4!ile
La !truttura del .ile < la !eguente"
.ile 5condizione6
i!truzione,i
)eneralmente l8i!truzione o le i!truzioni all8interno del .ile agi!cono !ulla condizione c.e il .ile
a!petta e!!ere fal!a per poter u!cire dal ciclo/ 9ue!to perc.J altrimenti il ciclo non terminere''e. 1d
e!empio per !tampare a $ideo una !ucce!!ione di cifre da ( a 99/ proponiamo il codice !eguente"
int i Y (=
.ile 5i NY 1((6
^
printf5HZd nH/ i6=
i@@=
_
1ffinc.J il .ile po!!a $erificare la condizione a!!ociata/ < nece!!ario a$er dic.iarato la $aria'ile
prima del .ile/ 9ue!to/ come nell8e!empio/ puE e!!ere fatto nella riga !opra!tante o in un altra parte
del programma.
Do - 4!ile
4olto !imile al w!ile < il do-w!ile c.e .a la !eguente !truttura"
do
i!truzione,i
.ile 5condizione6
Penendo $alide tutte le con!iderazioni fatte per il .ile/ $a notato c.e in 9ue!to modo !i e!egue
l8i!truzione all8interno del do-.ile almeno una $olta/ indipendentemente dal fatto c.e la condizione
a!!ociata al .ile ri!ulti $era o fal!a. L8e!empio !eguente mo!tra come !ia po!!i'ile utilizzare il do-
40
.ile/ ad e!empio/ per porre una domanda all8utente e continuare nell8e!ecuzione !olo !e l8utente
ri!ponde correttamente/ oppure ripetere la domanda"
do ^
printf5HPremere 1 per continuare " H6=
!canf5HZdH/ ` $alore6=
printf5HnH6=
_ .ile 5$alore NY16
Eor
Prima di !piegare le caratteri!tic.e del for/ ne proponiamo la !truttura generale"
for 5inizializzazione = condizione = incremento6
i!truzione,i
c.e e9ui$ale alla rappre!entazione con un .ile con la !eguente !truttura"
inizializzazione
.ile 5condizione6
i!truzione,i
incremento
+l for/ 9uindi/ potre''e tran9uillamente e!!ere !o!tituito da un .ile/ !e non fo!!e c.e < pi: conci!o ed <
concettualmente u!ato 9uando !appiamo a priori il numero di iterazioni c.e $ogliamo fare. + parametri
all8interno del for .anno di$er!i compiti/ e !ono !eparati da un punto e $irgola"
+l primo $iene e!eguito prima di entrare nel ciclo/ ed inizializza una $aria'ile/ generalmente
la $aria'ile < u!ata come $aria'ile di controllo del ciclo/ in poc.e parole !er$ir per tenere
traccia del numero di iterazioni del ciclo= a differenza del C@@/ do$e la dic.iarazione puE
e!!ere fatta contemporaneamente all8inizializzazione/ nel C/ in 9ue!to co!trutto/ la $aria'ile
de$e e!!ere dic!iarata fuori/ prima del for=
+l !econdo < la condizione 5c.e coin$olge anc.e la $aria'ile di controllo6/ c.e !e ri!ulta fal!a
interrompe l8e!ecuzione del ciclo=
+l terzo parametro < l8i!truzione di incremento/ c.e $iene e!eguita dopo ogni ciclo del for=
9ue!ta i!truzione agi!ce generalmente !ulla $aria'ile di controllo incrementandone 5o
decrementandone6 il $alore.
Per c.iarire meglio l8u!o del for pre!entiamo un !emplice codice c.e conta da zero a cento/ !tampando
a $ideo la $aria'ile di controllo"
41
int i=
for 5iY(= i[Y1((= i@@6
printf5HZd nH/ i6=
*gnuna delle tre i!truzioni all8interno del for puE e!!ere ome!!a/ con il ri!ultato di condizionare il ciclo/
o non modificando la $aria'ile/ o facendo e!!ere !empre $era la HcondizioneH del for= in 9ue!to am'ito
'i!ogna citare un u!o particolare del ciclo for/ c.e < 9uello del co!iddetto Hciclo for infinitoH. ;n ciclo
c.e non termina/ a''iamo detto precedentemente/ < da con!iderar!i errore/ ma e!i!te una !ituazione in
cui $ogliamo/ in$ece/ ciclare all8infinito fino a 9uando l8utente non decide di interrompere
$olontariamente il programma/ ad e!empio a$endo un menu generale c.e ogni $olta de$e pre!entar!i
!ullo !c.ermo. +l for utilizzato in 9ue!to ca!o .a una !truttura particolari!!ima/ o$$ero non .a ne!!uno
dei tre parametri !opra e!po!ti/ ma contiene !olamente due caratteri punto e $irgola"
main 56
^
for 5 = = 6
^
printf 5Hpremi CtrL@a per interromperenH6=
_
_
< anc.e po!!i'ile utilizzare all8interno delle tre i!truzioni/ pi: di una $aria'ile di controllo/ in modo da
a$ere un ciclo dinamico= un e!empio puE e!!ere 9uello di due $aria'ili/ H.ig.H e HloH c.e con$ergono"
int .ig.=
int lo=
for 5.ig.Y1((/ loY(= .ig. \Y lo= .ig.--/ lo@@6
printf5HFYZd - LYZd nH/ .ig./ lo6=
Istruzione Frea@ e Continue
1''iamo gi u!ato l8i!truzione 'rea0 9uando !ta$amo parlando dello !itc./ !enza addentrarci nel
dettaglio/ ade!!o/ in$ece/ con$iene !piegare le caratteri!tic.e del brea@ e di un8altra i!truzione/
continue"
'rea0 - e!ce dal ciclo o dallo !itc.=
continue - !alta una iterazione del ciclo !enza interromperlo=
42
Per capire la !ottile/ 9uanto importante/ differenza tra le due i!truzioni/ pre!entiamo un !emplice codice
in cui !i legge un numero da ta!tiera c.e $olgiamo !ia compre!o tra ( e 1((/ !e tale $alore ri!ulta e!!ere
negati$o/ !i e!ce dal ciclo/ mentre !e < maggiore di cento !i ric.iede di in!erire un $alore $alido= !e il
$alore < tra 1 e 1((/ !i !tampa a $ideo il !uo 9uadrato/ !e < zero !i e!ce"
int $alore=
.ile 5!canf5HZdH/ `$alore6 YY 1 `` $alore NY (6
^
if 5$alore [ (6
^
printf5HAalore non con!entitonH6=
'rea0=
,U e!ce dal ciclo U,
_
if 5$alore \ 1((6
^
printf5HAalore non con!entitonH6=
continue=
_
int 9uadrato Y $alore U $alore=
printf5HZd nH/ 9uadrato6=
_
ESE5PI, P+B'IC,
5Ai!ualizza il !orgente completo6
1nc.e i cicli 3*M ed i cicli #F+L% $engono u!ati largamente all8interno del programma. Ser$ono
!oprattutto per !correre gli elementi/ ad e!empio/ per !al$arli o !tamparli a $ideo. 4o!triamo di !eguito
due e!empi"
SLegge una !erie di elementi e li !tampa a $ideoT
1&6 .ile 5p NY L;LL6
1&7 ^ ,, #F+L% - *P%L
1&&
1&9 ,U
19( U Stampo gli altri contatti
191 U,
192 !2!tem5puli!ci6= ,, P;L+SC% L* SCF%M4*
193 printf 5H CCCCCCCCCCCCCCCCCCCCCCCnH6=
194 printf 5H C M;BM+C1 %1Sb $1.( CnH6=
195 printf 5H CCCCCCCCCCCCCCCCCCCCCCCnH6=
196 printf 5H C A+S;1L+aa1 C*LP1PP* CnH6=
197 printf 5H CCCCCCCCCCCCCCCCCCCCCCCnnH6=
43
19& printf 5H L*4% \ Z!nH/ p-\inf.nome6=
199 printf 5H C*)L*4% \ Z!nH/ p-\inf.cognome6=
2(( printf 5H P%L%3*L* \ Z!nH/ p-\inf.telefono6=
2(1 printf 5H %41+L \ Z!nH/ p-\inf.email6=
2(2 printf 5H S+P*#%B \ Z!nH/ p-\inf.!itoe'6=
2(3 pau!a56=
2(4 ,, Leggo l8elemento !ucce!!i$o
2(5 p Y p-\pun=
2(6
2(7 _ ,, #F+L% - CL*S%
S...T
S...T
S4odifica una !erie di elementiT
326 for 5nY1= n[i= n@@6
327 ^ ,, 3*M - *P%L
32&
329 ,U
33( U tro$ato l8elemento modifico l8informazione dentro di e!!o
331 U,
332 if 5!u'!celta YY n6
333 ^ ,, +3 - *P%L
334
335 ,, Popolo la $aria'ile da+n!erire
336 printf 5H L*4% SZ!T \ H/ p-\inf.nome6=
337 !canf 5HZ!H/ p-\inf.nome6=
33& printf 5H C*)L*4% SZ!T \ H/ p-\inf.cognome6=
339 !canf 5HZ!H/ p-\inf.cognome6=
34( printf 5H P%L%3*L* SZ!T \ H/ p-\inf.telefono6=
341 !canf 5HZ!H/ p-\inf.telefono6=
342 printf 5H %41+L SZ!T \ H/ p-\inf.email6=
343 !canf 5HZ!H/ p-\inf.email6=
344 printf 5H S+P*#%B SZ!T \ H/ p-\inf.!itoe'6=
345 !canf 5HZ!H/ p-\inf.!itoe'6=
346
347 _ ,, +3 - CL*S%
34&
349 p Y p-\pun=
35(
351 _ ,, 3*M - CL*S%
44
19-Co%a %ono gli 0rra1
;n arra2 puE e!!ere definito come una Hcollezione organizzata di oggettiH. 1nalizziamo la definizione e
capiremo molte co!e/ innanzitutto il concetto di GcollezioneG implica c.e tali oggetti !iano dello !te!!o
tipo/ co!G/ prendendo !punto dal mondo reale/ potremmo definire un arra2 di mele/ c.e/ 9uindi non puE
contenere ne!!un Hoggetto peraH= un arra2 in C < una collezione di $aria'ili dello !te!!o tipo.
G,rganizzataG implica c.e !ia po!!i'ile identificare uni$ocamente tutti gli oggeti dell8arra2 in modo
!i!tematico= 9ue!to in C $iene fatto tramite l8u!o di indici numerici c.e/ in un arra2 di dimen!ione L/
$anno da ( ad L-1.
Miprendendo l8e!empio della ru'rica del cellulare/ u!ato per !piegare le $aria'ili nella lezione 11/ !i puE
pen!are a 9uando creiamo un Hgruppo !uonerieH/ ad e!empio di nome Hamici !cuolaH= tale gruppo puE
contenere a tutti gli effetti un certo numero di nomi,numeri dei no!tri compagni di cla!!e/ ecco 9ue!to
HgruppoH < un arra2/ perc.< formato da oggetti dello !te!!o tipo 5nomi,numeri6 ed indentificato da un
nome 5amici !cuola6 c.e li accomuna.
4a $ediamo nel dettaglio come < po!!i'ile dic.iarare un arra2"
int m2arra2S1(T=
45
Come !i puE notare un arra2 $iene dic.iarato mettendo il nome della $aria'ile 5m2arra26/ e /tra
parente!i 9uadre/ la cifra c.e identifica il numero di elementi dello !te!!o tipo 5int6 e 9uindi la
dimen!ione dell8arra2.
Lell8e!empio/ ognuno dei dieci interi $iene c.iamato elemento dell8arra2 e dieci < la dimen!ione
dell8arra2. +n C/ come gi detto/ ogni elemento $iene identificato da un numero/ contando da ( 5in$ece
c.e da 16 ed arri$ando ad L 5la dimen!ione/ nel no!tro e!empio uguale a 1(6 - 1 59uindi arri$iamo a 96=
per far comprendere meglio il concetto a''iamo creato la !eguente immagine c.e ci riporta ad un
paragone con il mondo reale=
+n 9ue!ta immagine l8arra2 $iene paragonato ad un palazzo. Pen!ateci 'ene/ 9uando diciamo c.e un
palazzo .a 5 piani/ in realt .a !ei li$elli= cio< il piano terra < il primo li$ello/ il primo piano il !econdo/
e co!G $ia= analogamente !uccede nell8arra2/ !e a''iamo un arra2 di dimen!ione 6/ i !uoi indici
andranno da ( a 5 e un elemento ric.iamato/ ad e!empio/ tramite l8indice 3/ < il 9uarto elemento/ 9ue!to
perc.J !i inizia a contare da (.
L8analogia a!!ume maggiore importanza/ anc.e per far capire c.e le $aria'ili dell8arra2 !ono dello
!te!!o tipo/ co!G come un arra2 di int puE contenere !olo int 5e non c.ar o float6/ un palazzo c.e
contiene uffici/ in 9ue!to e!empio/ puE contenere !olo uffici 5e non a'itazioni6.
Porniamo al linguaggio C/ e $ediamo come < po!!i'ile dic.iarare arra2 di float o di c.ar"
float floatXarra2S12T=
c.ar c.arXarra2S7T=
;na $olta dic.iarato un arra2 < po!!i'ile a!!egnare il $alore alla po!izione corri!pondente/
ric.iamandola tramite l8indice/ ad e!empio !e $ole!!i in!erire il $alore &7.43 nell8arra2 di float alla
9uinta po!izione/ 'a!ta !cri$ere"
46
floatXarra2S4T Y &7.43
4entre !e $ole!!i utilizzare il $alore contenuto nella terza po!izione dell8arra2 e memorizzarlo in
un8altra $aria'ile/ do$rei fare"
float m2$ar Y floatXarra2S2T=
20-'li arra1 e i cicli 2or
%!i!te una forte relazione tra l8u!o degli arra2 e di cicli 3or/ per il fatto c.e un ciclo permette di contare
per un certo numero di $olte. +n 9ue!to modo utilizzando una $aria'ile c.e incrementi 5o decrementi6 il
!uo $alore ad ogni ciclo/ !i po!!ono !correre le po!izioni dell8arra2 in maniera !emplice/ con un
note$ole ri!parmio di codice !critto.
Per fare un e!empio/ a!!umiamo di a$ere un arra2 di int di 1(( elementi e di $oler !tampare a $ideo il
contenuto di tutte le po!izioni dell8arra2= $i!ta la particolare natura dell8arra2 non inizieremo a contare
da 1/ ma da (/ fino ad arri$are a no$antano$e 59uindi cento elementi effetti$i6. ;tilizzeremo il comando
di !tampa !ull8arra2 con l8indice/ incrementato ogni $olta/ pre!o dal ciclo for.
+n codice"
int intXarra2S1((T=
int i=
for 5iY(= i[1((= i@@6
^
printf 5HZdH/ intXarra2SiT6=
_
+n 9ue!to ca!o la $aria'ile di controllo HiH del ciclo for $iene u!ata come indice per l8arra2= da far notare
c.e/ a li$ello $i!i$o/ !i capi!ce !u'ito c.e !i cicla di cento elementi/ perc.J la condizione po!ta < 9uella
di a$ere Hi[1((H/ iniziando a contare da zero/ 9uindi/ !i e!egue il ciclo fino al no$antano$e!imo
elemento/ c.e < minore di cento= alla !ucce!!i$a iterazione/ prima di e!eguire il corpo del ciclo/ HiH
$iene incrementata di uno e 9uindi $ale cento/ $alore c.e non $erifica pi: la condizione 51(( non <
minore di 1((/ !emmai < uguale6 e c.e fa terminare il ciclo for= l8inter$allo contato 5da ( a 996 < utile
per rappre!entare tutti e cento gli elementi dell8arra2/ $i!to c.e/ come !piegato prima/ in un arra2 !i
contano gli elementi partendo dallo zero.
+n 9ue!to modo potre''e e!!ere a''a!tanza !emplice anc.e inizializzare tutti i $alori dell8arra2=
!upponiamo di $oler dare ad ogni elemento dell8arra2 il $alore uguale alla !ua po!izione/ con la
!eguente !oluzione !i ri!parmia un !acco di codice"
47
int intXarra2S1((T=
int i=
for 5iY(= i[1((= i@@6
^
intXarra2SiT Y i=
_
Laturalmente un arra2 puE e!!ere inizializzato anc.e pa!!ando direttamente i $alori/ ad e!empio/ come
in 9ue!to e!empio"
int numeriST Y ^ 7/ 23/ 4/ 94/ 12( _=
in cui !i crea un arra2 di 5 elementi/ ed < per 9ue!to c.e tra parente!i 9uadre non !i mette la
dimen!ione/ in 9uanto rica$ata dal numero di elementi compre!i tra le parente!i graffe.
Prendiamo come altro e!empio gli arra2 di caratteri/ c.e .anno una particolarit/ po!!ono e!!ere
inizializzati/ !enza e!!ere di$i!i da $irgole= ora proponiamo due forme e9ui$alenti di inizializzazione/ di
cui la prima !icuramente pi: pratica"
c.ar caratteriST Y HFello #orldNH=
c.ar caratteriST Y ^ 8F8/ 8e8/ 8l8/ 8l8/ 8o8/ 8 8/ 8#8/ 8o8/ 8r8/ 8l8/ 8d8/ 8N8 _=
;na particolari c.a riguarda il linguaggio C/ < c.e non e!i!te un $ero e proprio Htipo !tringaH/ 9uello
c.e in altri linguaggi $iene c.iamato HStringH 5!i pen!i al C@@ o al Da$a6. +n C le !tring.e $engono
rappre!entate tramite arra2 di caratteri/ 9uindi 'i!ogna !tare attenti alle operazioni c.e $i !i compiono e
ricordar!i c.e .anno comun9ue il $antaggio di godere di tutti pregi degli arra2/ tra cui 9uello di poter
!correre a piacimento nella po!izione della !tringa !te!!a. *gni arra2 di caratteri termina con la
!e9uenza di e!cape H
48
21-0rra1 3ultidi!en%ionali
*$$iamente la potenza degli arra2 ri!iede anc.e nel fatto c.e !i po!!ono u!are degli arra2
multidimen!ionali. ComeK in pratica ogni elemento contenuto da un arra2 < a !ua $olta un arra2= in
9ue!to modo !i po!!ono rappre!entare facilmente ta'elle e matrici/ o 9ualun9ue altra co!a c.e ric.ieda
un rappre!entazione anc.e !uperiore/ !i pen!i a programmi di grafica tridimen!ionale/ do$e un arra2
cu'ico puE e!!ere u!ato per di!egnare i punti all8interno dello !pazio tridimen!ionale creato/ o ad un
arra2 a 9uattro dimen!ioni/ c.e puE !er$ire per regi!trare anc.e la $aria'ile tempo.
Con gli arra2 multidimen!ionali !i po!!ono rappre!entare in!omma co!e c.e .anno pi: di una
dimen!ione in maniera facile ed intuiti$a. L8e!empio !otto propo!to u!a un arra2 'idimen!ionale per
definire una matrice di L rig.e ed 4 colonne"
int matri?SnTSmT=
i cui elementi po!!ono e!!ere/ ad e!empio/ !tampati/ utilizzando !olo due cicli for/ come mo!trato 9ui
!otto"
int n Y 1(=
int m Y 12=
int matri?SnTSmT=
int i=
int R=
for 5iY(= i[m= i@@6
^
for 5RY(= R[n= R@@6
^
printf5HZdH/ matri?SiTSRT6=
_
printf5HnH6=
_
ESE5PI, P+B'IC,
5Ai!ualizza il !orgente completo6
49
)li arra2 !ono alla 'a!e delle !tring.e nel linguaggio C. %cco come !ono !tate utilizzate all8interno del
programma. Senza gli arra2 !are''e !tato molto difficile operare !ul te!to.
31 c.ar nomeS5(T=
32 c.ar cognomeS5(T=
33 c.ar telefonoS3(T=
34 c.ar emailS1((T=
35 c.ar !itoe'S2((T=
50
22-Le #un$ioni
Le funzioni !ono uno degli !trumenti pi: potenti del C= e!!e infatti permettono un note$ole ri!parmio e
riu!o del codice/ con o$$ii $antaggi del programmatore. Le funzioni e!i!tono pi: o meno in tutti i
linguaggi e $engono c.iamate anc.e procedure o subroutine.
1lcuni linguaggi fanno di!tinzione tra funzioni c.e ritornano un $alore e 9uelle c.e/ in$ece/ non
ritornano $alori= il C a!!ume c.e ogni funzione ritorni un $alore/ 9ue!to accade utilizzando l8i!truzione
return !eguita/ e$entualmente/ da un $alore= !e non !i mette l8i!truzione return/ ne!!un parametro de$e
e!!ere pa!!ato 9uando !i c.iama la funzione. Prendiamo ad e!empio/ la definizione di una funzione c.e
prende un dou'le ed un int e fa un ele$amento a potenza/ re!tituendo il ri!ultato"
doule ele$amentoXpoten5a(doule $alore7 int poten5a)
{
doule $aloreXritorno 0 *./;
int i;
for(i0/; i<poten5a; i>>)
{
$aloreXritorno ?0 $alore;
}
return($aloreXritorno);
}
1nalizzando 9ue!ta funzione po!!iamo innanzitutto far notare c.e il calcolo e!eguito/ per 9uanto
comple!!o e poco ortodo!!o/ re!titui!ce il $alore corretto anc.e 9uando la potenza $ale zero= iniziamo/
dun9ue/ a !tudiare il codice nel dettaglio"
doule ele$amentoXpoten5a(doule $alore7 int poten5a)
Iue!ta < la definizione della funzione/ c.e ci dice il tipo del $alore di ritorno 5doule6/ il nome della
funzione 5ele$amentoXpoten5a()6 e la li!ta di argomenti u!ati dalla funzione con il tipo 5doule e
int6 ed il nome 5$alore e potenza6 corri!pondente=
return($aloreXritorno);
Iuando !i raggiunge un8i!truzione HreturnH/ il controllo del programma ritorna a c.i .a c.iamato la
funzione. +l $alore ritornato < 9uello po!to dopo la parola return=!e !i c.iude la funzione prima di
mettere un8i!truzione HreturnH/ la funzione ritorna automaticamente/ ed il $alore ritornato potre''e
non a$ere un !ignificato $alido.
+l $alore ritornato puE e!!ere manipolato a piacimento/ infatti !e una funzione re!titui!ce un ri!ultato/
po!!iamo a!!egnarlo/ ad e!empio/ ad una $aria'ile c.e poi potremmo u!are all8interno del programma
come 9ual!ia!i altra $aria'ile=
51
doule $al 0 *//./;
int pot 0 4;
doule risultato 0 ele$amentoXpoten5a($al7 pot);
%!i!tono anc.e funzioni c.e non ritornano alcun $alore/ in 9ue!to ca!o !i parla di funzioni $oid/ come
mo!trato di !eguito"
$oid stampaXerrore(int linea)
{
fprintf(stderr7 "Errore= linea IdJn"7 linea);
}
;na funzione $oid non de$e contenere nece!!ariamente un8i!truzione return/ anc.e !e e!!a puE e!!ere
u!ata per u!cire dalla funzione in maniera opportuna/ un po8 come l8u!o del H'rea0H all8interno dei cicli.
+n 9ue!to ca!o a''iamo pre!entato anc.e l8u!o dell8i!truzione fprintf()/ una $ariante della printf()/
c.e !pieg.eremo in dettaglio nella lezione 16= 'a!ti !apere c.e in 9ue!to ca!o a''iamo !tampato il
me!!aggio di errore !ullo HstderrH c.e puE e!!ere un file o un me!!aggio a $ideo 5generalmente
9ue!t8ultimo6.
Per ric.iamare la funzione/ 'a!ta/ o$$iamente/ !cri$ere il nome con/ tra gli argomenti/ il numero di
linea in cui !i < $erificato l8errore=
int lineaXerr 0 *.;
stampaXerrore(lineaXerr);
Aa fatta una piccola nota riguardante le funzioni/ in merito alla prototipazione delle funzioni/ o$$ero
la creazione di prototipi. ;n prototipo di una funzione non < altro c.e la !ua dic.iarazione/ !enza
!pecificare il corpo della funzione !te!!a= !i !cri$e/ 9uindi/ !olo la dic.iarazione iniziale comprendente
il nome ed il tipo re!tituito dalla funzione/ e gli argomenti pa!!ati come parametro= 9ue!to a$$iene
perc.J ogni funzione < utilizza'ile !olamente 9uanto < !tata dic.iarata/ 9uindi !e in un pezzo di codice/
prima di dic.iarare la funzione/ $oglio u!are tale funzione/ non po!!o farlo/ perc.J Hfi!icamenteH non <
ancora !tata creata. Creando dei prototipi !i o$$ia a 9ue!to pro'lema e !i .anno dei $antaggi anc.e in
termini di funzionalit ed organizzazione del codice !te!!o. %cco due e!empi/ il primo errato/ il !econdo
corretto"
11 )uesto non fun5iona
#include <stdio.h>
int main()
{
int $ar 0 +;
stampaXdoppio($ar);
}
$oid stampaXdoppio(int $ariaile)
{
printf("Al doppio di Id 8 Id "7 $ariaile7 6?$ariaile);
}
52
1? :::::::::::::::::::::::::::::::::::::::::::::::::::::::: ?1
11 )uesto fun5iona
#include <stdio.h>
$oid stampaXdoppio(int $ariaile); 11 prototipo della fun5ione
int main()
{
int $ar 0 +;
stampaXdoppio($ar);
}
$oid stampaXdoppio(int $ariaile)
{
printf("Al doppio di Id 8 Id "7 $ariaile7 6?$ariaile);
}
+n C/ 9uando !i pa!!ano gli argomenti 5$aria'ili6 alle funzioni/ 'i!ogna pre!tare attenzione al pa!!aggio
di arra2 ad una o pi: dimen!ioni= la regola dice c.e la prima dimen!ione dell8arra2 puE non e!!ere
!pecificata/ mentre la !econda e le altre de$ono e!!erlo. ;n e!empio c.iarir meglio il concetto"
$oid stampaXarra'Xuni(int dim7 int arra'Xuni%&)
{
int i;
for(i0/; i < dim; i>>)
{
printf("Id "7 arra'Xuni%i&);
}
}
$oid stampaXarra'Xid(ind dim27 int dim'7 int arra'Xid%&%9&);
{
int i7 Y;
for(i0/; i < dim2; i>>)
{
for(Y0/; Y < dim'; Y>>)
{
printf("Id "7 arra'Xuni%i&%Y&);
}
printf("n");
}
}
53
Esempio Pratico
5Ai!ualizza il !orgente completo6
1ll8interno del programma $engono u!ate !$ariate funzioni. 1lcune e!clu!i$amente create per
in!erire,modificare,eliminare i contatti della ru'rica/ altre/ come nel ca!o della funzione !u'!tring/ per
una funzione di utilit non di!poni'ile in C.
7i !eguito mo!triamo la dic.iarazione dei prototipi delle funzioni all8inizio del programma e la
funzione sustring().
.+ 11 Drototipi delle fun5ioni
.9 $oid $isuali55aPontatto(struct elemento? p);
.3 struct elemento ?aggiungiPontatto(struct elemento ?p);
., struct elemento ?modificaPontatto(struct elemento ?p);
.- struct elemento ?rimuo$iPontatto(struct elemento ?p);
+/ struct elemento ?leggiVaBile(struct elemento ?p);
+* int sal$a#uBile(struct elemento ?p);
+6 $oid sustring(char ?dest7 char ?source7 int iXase7 int iXdim);
+4 $oid pausa();
%...&
.3 1?
+., ? Bun5ione che prende una sottostringa partendo da un"indice
+.- ? ase per un numero di caratteri pari a dimensione
++/ ?1
++* $oid sustring(char? dest7 char ?source7 int iXase7 int iXdim)
++6 { 11 sustring() : CDEF
++4
++. int i 0 /;
+++
++9 for (i0iXase; i<iXdim>*; i>>)
++3 { 11 BCN : CDEF
++,
++- dest%i:iXase& 0 source%i&;
+9/
+9* } 11 BCN : PHC#E
+96
+94 dest%i&0"J/";
+9.
+9+ return;
+99
+93 } 11 sustring() : PHC#E
54
23-Struct. t1pede# e union
;na $olta pre!a dime!tic.ezza con le principali caratteri!tic.e del C !i po!!ono utilizzare dei tipi di
Dati strutturati. +niziamo ad e!aminare in dettaglio le strutture e unioni.
Struct
Le !trutture del C !o!tanzialmente permettono l8aggregazione di pi: $aria'ili/ in modo !imile a 9uella
degli arra2/ ma a differenza di 9ue!ti non ordinata e non omogenea 5una !truttura puE contenere
$aria'ili di tipo di$er!o6. Per denotare una !truttura !i u!a la parola c.ia$e struct !eguita dal nome
identificati$o della !truttura/ c.e < opzionale. Lell8e!empio !otto!tante !i defini!ce una !truttura liro
e !i crea un8i!tanza di e!!a c.iamata ilio"
11 dichiara5ione della struct
struct liro
{
char titolo%*//&;
char autore%+/&;
int annoXpulica5ione;
float pre55o;
};
11dichiara5ione dell"istan5a ilio
struct liro ilio;
La $aria'ile ilio puE e!!ere dic.iarata anc.e mettendo il nome !te!!o dopo la parente!i graffa"
11 dichiara5ione della struct e della $ariaile ilio
struct liro
{
char titolo%*//&;
char autore%+/&;
int annoXpulica5ione;
float pre55o;
} ilio;

Q anc.e po!!i'ile inizializzare i valori alla dic!iarazione/ mettendo i $alori 5giu!ti nel tipo6 compre!i
tra parente!i graffe"
struct liro ilio 0 {"Tuida al P"7 "Bari5io Piacchi"7 6//47 .+.6};
Per accedere alle variabili interne della !truttura !i u!a l8operatore punto 8.8. ;na $aria'ile interna puE
e!!ere poi manipolata come 9ual!ia!i altra $aria'ile"
55
11 assegna un $alore al pre55o del liro
ilio.pre55o 0 93.46;
11 assegna ad una $ariaile int l"anno di pulica5ione del liro
int anno 0 ilio.annoXpulica5ione;
11 stampa il titolo del liro
printf ("Is n"7 ilio.titolo);
Creare nuovi tipi di dato con t(pedef
Per definire nuo$i tipi di dato $iene utilizzata la funzione t(pedef. L8u!o di t'pedef/ com'inato con
struct ci permette di creare tipi di dato molto comple!!i/ come mo!trato nell8e!empio !eguente"
t'pedef struct liro
{
char titolo%*//&;
char autore%+/&;
int annoXpulica5ione;
float pre55o;
} tXliro;
tXliro guida 0 {"Tuida al P"7 "Bari5io Piacchi"7 6//47 .+.6};
+n 9ue!to modo a''iamo definito un nuo$o tipo di nome tXliro/ c.e non < altro c.e una !truttura=
guida < la $aria'ile creata di tipo tXliro. *ra po!!iamo utilizzare il nuo$o tipo come ogni altro/ ad
e!empio po!!iamo creare un arra2 di elementi di tipo tXliro.
tXliro raccolta%+///&;
Per accedere agli elementi dell8arra2/ o per inizializzare i $alori/ < !ufficiente utilizzare l8indice per
identificare l8elemento dell8arra2 ed il punto 5.6 per accedere alle $aria'ili interne del tipo tXliro.
11 assegna un $alore al pre55o del 4.*mo liro
raccolta%4./&.pre55o 0 93.46;
11 assegna ad una $ariaile int l"anno di pulica5ione del 9+-mo liro
int anno 0 raccolta%9+,&.annoXpulica5ione;
11 stampa il titolo del 64mo liro
printf ("Is n"7 raccolta%66&.titolo);
8nion
+l tipo di dato union !er$e per memorizzare 5in i!tanti di$er!i6 oggetti di differenti dimen!ioni e tipo/
con/ in comune/ il ruolo all8interno del programma. Si alloca la memoria per la pi: grande delle
$aria'ili/ $i!to c.e e!!e non po!!ono mai e!!ere utilizzate contemporaneamente 5la !celta di una
e!clude automaticamente le altre6/ condi$idendo il mede!imo !pazio di memoria. +n C una unione $iene
definita tramite la parola c.ia$e union/ come mo!trato di !eguito"
union numero
{
short numeroXpiccolo;
long numeroXlungo;
doule numeroXgrande;
} numeri;
La definizione di un8unione < molto !imile a 9uella di una !truttura/ ed < mede!imo il modo di
acceder$i. +noltre/ u!ata in com'inazione con una !truttura/ !i po!!ono ottenere grade$oli effetti in cui
$iene !elezionato automaticamente il tipo giu!to della union"
56
t'pedef struct
{
int ma2Xpasseggeri;
} Yet;
t'pedef struct
{
int ma2Xalte55a;
} elicottero;
t'pedef struct
{
int ma2Xcarico;
} aereocargo;
t'pedef union
{
Yet unXYet;
elicottero unXelicottero;
aereocargo unXaereocargo;
} $eli$olo;
t'pedef struct
{
tipoX$eli$olo tipo;
int $elocita;
$eli$olo descri5ione;
} unX$eli$olo;
+n 9ue!to e!empio $iene definita un8unione di nome $eli$olo c.e puE e!!ere un Yet/ un elicottero o
un aereocargo. Lella !truttura unX$eli$olo c8< un oggetto c.e identifica il tipo e c.e permette di
!elezionare la !truttura giu!ta al momento giu!to.
24-Ca%ting. enu!era$ioni e aria&ili
%tatic-e
+n 9ue!ta lezione $ediamo come effettuare con$er!ioni tra i tipi di dati/ come creare collegare
enumerazioni a nomi mnemonici e come u!are le $aria'ili !tatic.e.
57
Il Casting
Iuando !i la$ora con tipi di dati di$er!i tra loro/ c.e !iano primiti$i 5int/ char/ float/ etc.6 o a$anzati/
puE e!!ere nece!!ario con$ertire $alori da un tipo ad un altro. Iue!ta operazione !i c.iama casting/ ad
a!!ume il nome di coercizione >coercion? 9uando !i forza la con$er!ione e!plicita di un tipo ad un altro
tipo/ con$er!ione magari non pre$i!ta automaticamente.
+n C/ per con$ertire e!plicitamente un tipo ad un altro tipo/ !i u!a l8operatore > ?/ 9ue!te parente!i tonde
prendono il nome di operatore di cast= all8interno delle parente!i 'i!ogna mettere il nuo$o tipo al 9uale
$ogliamo pa!!are/ e fuori il $alore c.e !i $uole modificare.
11 Pasting da float ad int
int numero;
float reale;
reale 0 .3.*-;
numero 0 (int)reale; 11 $ale .3
1d e!empio < po!!i'ile forzare la con$er!ione di tipo dal tipo float al tipo int/ o dal tipo char al tipo
int.
11 Pasting da int a float
11 ::::::::::::::::::::::
int numero;
float reale;
numero 0 *,;
reale 0 (float)numero;
11 Pasting da char ad int
11 ::::::::::::::::::::::
int numero;
char lettera;
lettera 0 "M";
numero 0 (int)lettera; 11 $ale 9+7 il $alore M#PAA di M
alcune con$er!ioni di tipo $engono e!eguite automaticamente 5casting implicito6/ generalmente
9uando !i utilizzano tipi di altro tipo come int. Q po!!i'ile/ e con!iglia'ile/ utilizzare l8operatore di
ca!ting anc.e 9uando !i compiono operazioni !ui $alori come/ ad e!empio/ la di$i!ione"
int primo;
int secondo;
float risXdi$;
risXdi$ 0 (float)primo 1 (float)secondo;
Comun9ue la regola dice c.e !e !i < nel du''io 'i!ogna !empre mettere l8operatore di ca!t/ o$$ero
'i!ogna !empre con$ertire e!plicitamente i tipi. +l ca!ting < e rimane un8operazione potente c.e/ !e 'en
utilizzata/ puE apportare note$oli 'enefici ad un programma.
58
Le enumerazioni
+l tipo enumerazione < a''a!tanza particolare/ perc.J permette di a!!ociare a delle co!tanti letterali/ un
$alore intero= in 9ue!to modo po!!iamo utilizzare tali nomi per identificare il loro $alore= facciamo un
e!empio utilizzando i giorni della !ettimana"
enum giorni { lun7 mar7 mer7 gio7 $en7 sa7 dom } settimana;
+n 9ue!to ca!o a''iamo definito una nuo$a $aria'ile di nome settimana e di tipo enumerazione
giorni= l8identificatore lun a!!ume il $alore // mar a!!ume il $alore */ e co!G $ia= in poc.e parole !i .a
un indice iniziale / e gli altri a!!umono una numerazione progre!!i$a. Iue!to ci puE e!!ere molto utile
!e do''iamo !cri$ere un programma c.e operi !ui giorni della !ettimana 5come un calendario6= !e non
e!i!te!!e il tipo enumerazione il programma non potre''e a!!egnare alcun H$aloreH ad un determinato
giorno e 9uindi !are''e molto pi: difficile 5e di!pendio!o in termini di codice6 la$orare in tal !en!o.
Q po!!i'ile/ perE/ a!!egnare alle co!tanti anc.e $alori iniziali di$er!i da (/ o $alori non numerici/ come
!piegato nei due e!empi"
11 $alori non numerici
enum se)Xescape { suono 0 "a"7 cancella 0 ""7 ta 0 "t"7 in$io 0 "r" };
11 indice ini5iale di$erso da /
enum mesi { gen 0 *7 fe7 mar7 apr7 mag7 giu7 lug7 ago7 set7 ott7 no$7 dic };
c.e implica fe uguale a 6/ mar uguale a 4/ e co!G $ia.
Hariabili static!e
La $aria'ili .anno la po!!i'ilit di e!!ere $i!i'ili !olo in una funzione 5$aria'ili locali6 o in tutto il
programma 5$aria'ili glo'ali6. Le $aria'ili locali po!!ono a$ere un8altra caratteri!tica/ po!!ono e!!ere
static!e/ o$$ero/ e!!ere definite una $olta/ ed a$ere $ita propria all8interno di una funzione/ con il
$antaggio di mantenere il loro $alore intatto/ cio< il $alore c.e una $aria'ile !tatica .a all8u!cita delle
funzione < il mede!imo 9uando !i rientra 5ric.iamandola6 nella funzione !te!!a. La parola c.ia$e c.e
identifica le $aria'ili !tatic.e < static e de$e e!!ere me!!a prima del tipo della $aria'ile. Come mo!trato
nell8e!empio/ $engono definite due $aria'ili in una funzione/ una !tatica ed una non"
#include
11 prototipo della fun5ione
$oid stampa();
int main()
{
int i;
for(i0/; i<+; i>>) stampa();
}
$oid stampa()
{
int alfa 0 /;
static int eta 0 /;
printf("(int) alfa 0 Id7 (static int) eta 0 Id Jn"7 alfa7 eta);
>>alfa;
59
>>eta;
}
L8e!ecuzione del programma genere il !eguente output a $ideo"
(int) alfa 0 /7 (static int) eta 0 /
(int) alfa 0 /7 (static int) eta 0 *
(int) alfa 0 /7 (static int) eta 0 6
(int) alfa 0 /7 (static int) eta 0 4
(int) alfa 0 /7 (static int) eta 0 .
Esempio pratico
5Ai!ualizza il !orgente completo6
1ll8interno del programma a''iamo do$uto creare un nuo$o tipo/ di nome HtXcontattoH/ c.e contene!!e
i dati !en!i'ili 5nome/ cognome/ telefono/ email/ sito!e6= 9ue!to < !tato po!!i'ile grazie all8u!o
congiunto di t2pedef e di una !truttura.
Le $aria'ili all8interno !ono tutte !tring.e 5arra2 di caratteri6/ ma pote$ano e!!erci tran9uillamente int/
float ed altritipi di dato.
6, 11 Preo la struttura per contenere i contatti
6- t'pedef struct
4/ {
4* char nome%+/&;
46 char cognome%+/&;
44 char telefono%4/&;
4. char email%*//&;
4+ char sito!e%6//&;
49 } tXcontatto;
25-I *untatori
+l concetto di HpuntatoreH < molto importante nella programmazione in C/ poic.J ci permette !ia di
la$orare Ha 'a!!o li$elloH 5con gli indirizzi fi!ici della macc.ina6/ !ia di a!trarre !trutture di dati
comple!!e/ il tutto mantenendo certa !emplicit.
60
Cosa " un puntatoreI
8n puntatore " una variabile c!e contiene l%indirizzo di memoria di un%altra variabile.
Iuando dic.iariamo una $aria'ile/ a 9ue!ta $err ri!er$ato un indirizzo di memoria/ ad e!empio la
po!izione *///. ;n puntatore contiene/ appunto/ l8indirizzo di tale $aria'ile 59uindi il $alore *///6.
L8importanza ri!iede nel fatto c.e !i po!!ono manipolare !ia il puntatore c.e la $aria'ile puntata 5cio<
la $aria'ile memorizzata a 9uell8indirizzo di memoria6.
Per definire un puntatore < nece!!ario anteporre al nome della $aria'ile un a!teri!co 5?6/ e!aminiamo la
differenza tra la dic.iarazione di una $aria'ile e 9uella di un puntatore"
11 $ariaile intera
int $ariaile;
11 puntatore ad un intero
int ?puntatore;
L8a!teri!co 5J6 $iene c.iamato operatore di indirezione o deferenziazione e re!titui!ce il contenuto
dell8oggetto puntato dal puntatore= mentre l8operatore He commercialeH 5K6 re!titui!ce l8indirizzo della
$aria'ile e $a u!ato nella !eguente forma"
11 assegno al puntatore l"indiri55o di $ariaile
puntatore 0 ($ariaile;
8n esempio
Per fare un e!empio pratico/ a!!umiamo di a$ere due $aria'ili/ alfa e beta ed un puntatore di nome
pointer= a!!umiamo anc.e c.e alfa ri!ieda alla locazione di memoria */// eta alla locazione 6// e
pointer alla locazione */// e $ediamo/ e!eguendo il codice !otto propo!to/ il ri!ultato ottenuto"
#include <stdio.h>
int main()
{
int alfa 0 .;
int eta 0 3;
int ?pointer;

pointer 0 (alfa;
printf("alfa :> Id7 eta :> Id7 pointer :> Idn"7 alfa7 eta7 pointer);

eta 0 ?pointer;
printf("alfa :> Id7 eta :> Id7 pointer :> Idn"7 alfa7 eta7 pointer);

alfa 0 pointer;
printf("alfa :> Id7 eta :> Id7 pointer :> Idn"7 alfa7 eta7 pointer);

?pointer 0 +;
printf("alfa :> Id7 eta :> Id7 pointer :> Idn"7 alfa7 eta7 pointer);
}
61
Iue!to !tamper a $ideo i $alori corretti di alfa e eta 5. e 36 e l8indirizzo di alfa memorizzato nel
puntatore 5*//6"
alfa :> .7 eta :> 37 pointer :> *//
poi a!!egniamo a eta il $alore dell8oggetto puntato da pointer 5alfa6/ e 9uindi il $alore ."
alfa :> .7 eta :> .7 pointer :> *//
!ucce!!i$amente a!!egniamo ad alfa il $alore memorizzato in pointer e 9uindi l8indirizzo di memoria
di alfa !te!!o"
alfa :> *//7 eta :> .7 pointer :> *//
continuiamo memorizzando in alfa 5l8oggetto puntato da pointer6 il $alore +"
alfa :> +7 eta :> .7 pointer :> *//
%!i!te anc.e un aritmetica 'a!e dei puntatori ai 9uali < po!!i'ile aggiungere o togliere dei $alori/ c.e
generalmente $engono rappre!entati come 'locc.i di memoria. Per intender!i/ un puntatore e!i!te
!empre in funzione del tipo di oggetto puntato/ !e creo un puntatore ad int/ il 'locco di memoria $ale 4
'2te/ un puntatore a char/ in$ece/ u!a 'locc.i di 1 '2te. +n 9ue!to modo !e utilizzo l8operatore CC/
incremento del 'locco a !econda del tipo di $aria'ile puntata.
Come mo!treremo di !eguito i puntatori po!!ono e!!ere u!ati con !ucce!!o in com'inazione con
funzioni/ arra( e strutture.
26-*untatori e 2un$ioni
+ puntatori ri!ultano molto utili anc.e u!ati con le funzioni. )eneralmente $engono pa!!ati alle funzioni
gli argomenti 5le $aria'ili6 per valore 5utilizzando return6. 4a 9ue!to modo di pa!!are gli argomenti/
non modifica gli argomenti !te!!i e 9uindi potre''e ri!ultare limitati$o 9uando/ in$ece/ $ogliamo c.e
$engano modificate le $aria'ili c.e pa!!iamo alle funzioni.
62
Pen!iamo ad un ca!o e!emplare/ uno !u tutti/ l8u!o della funzione swap >alfaL beta? c.e !cam'ia il
$alore di alfa con 'eta e $ice$er!a= in 9ue!to ca!o il $alore re!tituito dalla funzione 5con return6 non $a
minimamente ad intaccare i $alori delle $aria'ili alfa e 'eta/ co!a c.e $ogliamo/ in$ece/ accada per
poter effetti$amente fare lo !cam'io. +n 9ue!to ca!o !i pa!!ano alla funzione/ non i $alori delle
$aria'ili/ ma il loro indirizzo/ tro$andoci/ 9uindi/ ad operare con i puntatori a tali $alori. 3acciamo un
e!empio pratico per c.iarire"
#include <stdio.h>
$oid s!ap(int ?apt7 int ?pt);
int main()
{
int alfa 0 +;
int eta 0 *4;
printf("alfa :> Id7 eta :> Idn"7 alfa7 eta);
s!ap((alfa7 (eta);
printf("alfa :> Id7 eta :> Idn"7 alfa7 eta);
}
$oid s!ap(int ?apt7 int ?pt)
{
int temp;
temp 0 ?apt;
?apt 0 ?pt;
?pt 0 temp;
}
27-*untatori ed 0rra1
;na digre!!ione !u arra2 e puntatori potre''e portare $ia molti!!imo tempo= in 9ue!to am'ito ci
limitiamo ad accennare alla correlazione tra i due !trumenti a di!po!izione nel linguaggio C.
L8a!petto c.e accomuna i puntatori e gli arra2 < !o!tanzialmente il fatto c.e entrambi sono
memorizzati in locazioni di memoria sequenziali/ ed < 9uindi po!!i'ile agire !u un arra2 5!e lo !i
63
$ede come una !erie di 'locc.i ad indirizzi di memoria !e9uenziali6 come !e !i !te!!e agendo !u un
puntatore 5e $ice$er!a6= ad e!empio !e dic.iariamo un arra2 HalfaH ed un puntatore HpointerH"
11 definisco un arra' ed una $ariaile intera
int alfa%6/&7 2;
11 creo il puntatore
int ?pointer;
11 puntatore all"indiri55o di alfa%/&
pointer 0 ( alfa%/&;
11 2 prende il $alore di pointer7 cio8 di alfa%/&
2 0 ?pointer;
Se $ole!!i !correre/ ad e!empio/ alla po!izione i:ma dell8arra2/ 'a!tere''e incrementare il puntatore di
i= cio<
pointer > i "8 e)ui$alente a " alfa%i&
)raficamente 9ue!to $iene rappre!entato come"
/ * 6 4 . ... n
XX XX XX XX XX XX XX
alfa ;XX;XX;XX;XX;XX;XX;XX;
pointer >* >6 .. >i
Comun9ue tra arra2 e puntatori ci !ono !o!tanziali differenze"
;n puntatore < una $aria'ile/ !ulla 9uale po!!iamo e!eguire le pi: !$ariate operazioni 5come
l8a!!egnamento6.
;n arra2 non < una $aria'ile con$enzionale 5< un contenitore di $aria'ili6 ed alcune operazioni
da arra2 a puntatore potre''ero non e!!ere perme!!e.
28-*untatori e Strutture
Lell8u!o congiunto di !trutture e puntatori/ come mo!trato nell8e!empio !eguente"
!truct P+PP* ^ int ?/ 2/ z= _ elemento=
!truct P+PP* Upuntatore=
puntatore Y `elemento=
puntatore-\? Y 6=
64
puntatore-\2 Y &=
puntatore-\z Y 5=
!i puE notare c.e a''iamo creato una !truttura di tipo P+PP* e di nome HelementoH/ ed un puntatore ad
una !truttura di tipo P+PP*. Per accedere ai mem'ri interni della !truttura HelementoH a''iamo u!ato
l8operatore -M !ul puntatore alla !truttura. +noltre < po!!i'ile utilizzare i puntatori anc.e per/ ad e!empio/
le li!te !emplici 5tratteremo le li!te nella lezione 156/ in cui per collegare due elementi/ 'a!ta !cri$ere"
t2pedef !truct ^ int inf= %L%4%LP* Upun= _ %L%4%LP*=
%L%4%LP* ele1/ ele2=
,, in 9ue!to modo faccio puntare il primo elemento al !econdo
ele1.pun Y `ele2=
ESE5PI, P+B'IC,
5Ai!ualizza il !orgente completo6
+l largo u!o fatto di puntatori fa capire 9uanto !iano importanti 9ue!ti !trumenti per !cri$ere codice
potente 5in termini di capacit6/ ma allo !te!!o tempo e!tremamente ridotto 5ri!petto ad una $er!ione
!enza puntatori6. 1d e!empio < po!!i'ile modificare gli elementi di una li!ta 5!piegato !ucce!!i$amente6
!emplicemente HgiocandoH con i puntatori.
415 ,, tro$ato l8elemento gli faccio puntare l8oggetto puntato dal !uo
416 ,, puntatore/ in poc.e parole H!altoH l8elemento da eliminare
417 if5!u'!celta YY n6
41& ^ ,, +3 - *P%L
419
42( au!-\punYau!-\pun-\pun=
421
422 _ el!e ^ ,, %LS%
423
424 ,, Lel ca!o in cui il puntatore fo!!e L;LL/ per non creare ca!ini
425 ,, glielo a!!egniamo direttamente
426 au!Yau!-\pun=
427
42& _ ,, +3 c CL*S%
29-0lloca$ione dina!ica della 3e!oria
+l C </ per natura/ un linguaggio molto fle!!i'ile/ e la !ua ge!tione della memoria contri'ui!ce a
renderlo ancora pi: fle!!i'ile. 1 differenza di altri linguaggi 5come il C@@ o il Da$a6/ il C permette di
a!!egnare la giu!ta 9uantit di memoria 5!olo e !olamente 9uella nece!!aria6 alle $aria'ili del
programma. +n particolare l8u!o della memoria allocata dinamicamente ri!ulta utile con gli arra2.
;tilizzare 9ue!te caratteri!tic.e del C permette di creare programmi altamente porta'ili/ in 9uanto
utilizzano di $olta in $olta i $alori giu!ti per la piattaforma.
65
;na piccola nota !u come " organizzata la memoria < do$ero!a" la memoria < di$i!a !o!tanzialmente
in due parti/ una !tatica/ c.e contiene tutto 9uello c.e !appiamo $err allocato 5come una $aria'ile int6
e c.e !i c.iama Stac@/ ed una dinamica/ cio< in cui la dimen!ione di memoria per rappre!entare
9ualc.e elemento del programma puE cam'iare durante l8e!ecuzione del programma/ c.e !i c.iama
Deap.
Le funzioni utilizzate per ge!tire la memoria dinamica !ono principalmente malloc>? e calloc>? 5calloc56
< !tata rinominata dall81LS+6/ adi'ite all8allocazione della memoria/ free>? c.e/ come !i intui!ce/ !er$e
per li'erare la memoria allocata/ e realloc>? la cui funzione < 9uella di permettere la modifica di uno
!pazio di memoria precedentemente allocato. ;n comando particolarmente utile ri!ulta e!!ere sizeof/
c.e re!titui!ce la dimen!ione del tipo di dato da allocare.
Per far funzionare il programma do''iamo includere la li'reria malloc;!/ !enza la 9uale 9ue!te
funzioni non potre''ero fare il loro do$ere. Pre!entiamo un e!empio per c.iarire meglio l8u!o di 9ue!te
funzioni/ in particolare alloc.eremo la memoria per un arra2 con malloc56/ la$oreremo !ull8arra2 !te!!o
ed/ infine/ li'ereremo la memoria con free56.
Cinclude [!tdio..\
Cinclude [!tdli'..\
Cinclude [malloc..\
int main56
^
int numero/ Uarra2/ i=
c.ar 'ufferS15T=
int allocati=
numero Y 1((=
printf5HLumero di elementi dell8arra2" ZdH/ numero6=
arra2 Y 5int U6malloc5!izeof5int6 U numero6=
if5arra2 YY L;LL6
^
printf5H4emoria e!auritanH6=
e?it516=
_
allocati Y !izeof5int6 U numero=
for5iY(= i[numero= i@@6
^
arra2SiT Y i=
_
printf5HnAalori degli elementinH6=
66
for5iY(= i[numero= i@@6
^
printf5HZ6dZcH/ arra2SiT/ iZ1( YY 9 K 8n8 " 8 86=
_
printf5HnnLumero elementi ZdnH/ numero6=
printf5H7imen!ione elemento ZdnH/ !izeof5int66=
printf5HB2te! allocati ZdnH/ allocati6=
free5arra26=
printf5Hn4emoria Li'eratanH6=
return (=
_
+n 9ue!to programma po!!iamo notare l8u!o della funzione malloc>? c.e ritorna un puntatore a
carattere/ corri!pondente al punto di inizio/ in memoria/ della porzione ri!er$ata della dimen!ione
HinteraH pa!!ata come argomento= !e la memoria ric.ie!ta non puE e!!ere allocata/ ritorna un puntatore
nullo.
Lel ca!o citato !i puE notare c.e < !tato u!ata la funzione sizeof per !pecificare il numero e!atto di '2te/
mentre < !tata u!ata la coercizione per con$ertire il tipo di dato Hpuntatore a carattereH a Hpuntatore ad
intH/ 9ue!to per garantire c.e i puntatori aritmetici $engano rappre!entati correttamente. %!i!te/ inoltre/
un legame molto forte tra puntatori ed arra2 per trattare la memoria ri!er$ata come un arra2/ ed < per
9ue!to c.e in realt la $aria'ile Harra2H non < !tata definita inizialmente come arra2/ ma come puntatore
ad int 5$edere lezione 136.
30-0lloca$ione dina!ica della !e!oria)
#un$ione realloc45
1de!!o proporremo l8u!o della funzione realloc>? per definire un arra( flessibile/ o$$ero un arra2 cui
$iene ri!er$ata della memoria !uddi$i!a in 'locc.i di dimen!ione ar'itraria. ;na $olta H!aturatoH il
primo 'locco/ utilizziamo realloc>? per allocare il 'locco !ucce!!i$o. La !uddi$i!ione in 'locc.i
a$$iene durante la fa!e di lettura/ c.e e!!endo/ appunto/ dinamica/ permette di minimizzare le c.iamate
a realloc>? e di a$ere un dimen!ionamento a''a!tanza preci!o.
67
Cinclude [!tdio..\
Cinclude [!tdli'..\
Cinclude [malloc..\
int main56
^
c.ar 'ufferS2(T=
int iY(/ nY(/ ?/ Uarra2/ n'=
,U '2te allocati U,
int allocati=
,U '2te in un 'locco U,
int dim'loc=
,U '2te in un intero U,
int dimint=
,U '2te contenenti interi U,
int u!ati=
n' Y 1=
printf5H%lementi in un 'locco" ZdnH/ n'6=
dimint Y !izeof5int6=
dim'loc Y n' U dimint=
u!ati Y (=
arra2 Y 5int U6malloc5dim'loc6=
if5arra2 YY L;LL6
^
printf5H4emoria in!ufficientenH6=
e?it516=
_
allocati Y dim'loc=
printf5H1llocati" Zd '2te!nH/ allocati6=
printf5H+nput di interi terminati da C "nH6=
.ile5!canf5HZdH/ ` ?66
^
u!ati @Y dimint=
if5u!ati\allocati6
^
allocati @Y dim'loc=
arra2 Y 5int U6realloc5arra2/ allocati6=
if5arra2 YY L;LL6
^
printf5H4emoria in!ufficientenH6=
68
e?it516=
_
i@@=
_
,U in 9ue!to modo $engono letti n interi U,
arra2Sn@@T Y ?=
_
printf5HnH6=
printf5H1llocati" Zd '2te!nH/ allocati6=
printf5H7im. 'locc.i" Zd '2te!nH/ dim'loc6=
printf5H7im. intero" Zd '2te!nH/ dimint6=
printf5H;!ati" Zd '2te!nH/ u!ati6=
printf5HC.iamate realloc" ZdnH/ i6=
printf5HLumeri" ZdnH/ n6=
printf5Hn%cco i numerinH6=
for5iY(= i[n= i@@6
^
printf5HZ5dZcH/ arra2SiT/ iZ1( YY 9 K 8n8 " 8 86=
_
printf5HnH6=
return (=
_
La !inta!!i della funzione realloc>? .a due argomenti/ il primo riguarda l8indirizzo di memoria/ il
!econdo !pecifica la nuo$a dimen!ione del 'locco= il tipo re!tituito < un tipo puntatore a $oid/ il 9uale
nel programma < !tato ca!tato a puntatore ad intero/ per $erificare c.e il !uo $alore fo!!e L;LL.
ESE5PI, P+B'IC,
5Ai!ualizza il !orgente completo6
3acciamo notare come/ all8interno del programma/ $enga u!ata la diretti$a HmallocH per allocare la
giu!ta memoria al puntatore. Pale comando permette/ nel !uo u!o !emplificato/ di ottimizzare
note$olmente il programma e di rendere pi: $eloce l8e!ecuzione. +noltre/ allocando prima la memoria/ il
puntatore < gi pronto per contenere le informazioni/ in poc.e parole < !tato inizializzato nel migliore
dei modi.
265 ,U creazione primo elemento U,
266 ,, 1lloco la memoria nece!!aria
267 p Y 5!truct elemento U6malloc5!izeof5!truct elemento66=
26& ,, 4etto da+n!erire nell8informazione del puntatore
269 p-\inf Y da+n!erire=
69
27( ,, p punta a L;LL/ o$$ero il marcatore di fine li!ta
271 p-\pun Y L;LL=
:1-Introdu$ione alle Li%te
Le li!te !ono uno degli argomenti pi: delicati da trattare/ per il !emplice fatto c.e !ono uno !trumento
potente e $er!atile/ ma anc.e molto fragile. Ba!ti pen!are c.e l8u!o delle li!te permette di impo!tare
programmi di ordinamento in modo molto efficiente 5un e!empio !u tutti l8algoritmo 5ergeSort6/ ed
offre 9uella dinamicit/ tra l8altro tipica del C/ di cui !i puE a$ere 'i!ogno durante lo !$iluppo di un
programma.
;na li!ta non < altro c.e una collezione di elementi omogenei/ ma/ a differenza dell%arra(/ occupa in
memoria una po!izione 9ual!ia!i/ c.e tra l8altro puE cam'iare dinamicamente durante l8utilizzo della
li!ta !te!!a= inoltre la !ua dimen!ione non < nota a priori e puE $ariare nel tempo 5l8oppo!to dell8arra2/ in
70
cui la dimen!ione < 'en nota e non < modifica'ile6. ;na li!ta puE contenere uno o pi: campi contenenti
informazioni/ e/ nece!!ariamente/ de$e contenere un puntatore per mezzo del 9uale < legato
all8elemento !ucce!!i$o.
La li!ta 'a!e .a un !olo campo informazione ed un puntatore/ come mo!trato di !eguito"
%lemento Y informazione @ puntatore
c.e/ tradotto in codice/ ri!ulta e!!ere"
!truct elemento ^
int inf=
!truct elemento Upun=
_
;na particolarit delle li!te 5a differenza/ ad e!empio/ degli arra26 < c.e !ono co!tituite da due funzioni
del C/ le !trutture ed i puntatori/ 9uindi non !ono un tipo di dato nuo$o/ 'a!ato !u implementazioni
particolari/ ma !ono il ri!ultato di un u!o !apiente di tali co!trutti.
Come !i < detto prima/ una li!ta puE contenere uno o pi: campi di informazione/ c.e po!!ono e!!ere di
tipo int 5come nell8e!empio6/ c.ar/ float/ ecc.= mentre de$e e!!erci !empre un campo c.e punta ad un
altro elemento della li!ta/ c.e < L;LL !e non ci !ono altri elementi/ mentre ri!ulta e!!ere una !truttura
elemento nel ca!o $i !ia un !ucce!!ore. Per dic.iarare una li!ta/ 'a!ta !cri$ere 5riferendo!i alla !truttura
dic.iarata precedentemente6"
!truct elemento Uli!ta=
c.e altro non < c.e un puntatore ad una !truttura elemento/ e come tale potre''e e!!ere inizializzata
anc.e ad un $alore L;LL/ c.e identific.ere''e una li!ta $uota. +n 9ue!to modo definiamo/ 9uindi/ una
lista lineare/ o$$ero una li!ta c.e de$e e!!ere $i!itata 5o !candita6 in ordine/ cio< dal primo elemento
fino all8ultimo/ c.e $iene identificato perc.J punta a L;LL. 7a ricordare c.e/ anc.e !e nella !ua
rappre!entazione/ una li!ta ri!ulta e!!ere !e9uenziale/ in realt l8allocazione di memoria relati$amente
agli elementi < li'era/ cio< ogni $olta c.e de$o aggiungere un elemento alla li!ta/ de$o allocare la
memoria relati$a/ connetterlo all8ultimo elemento ed in!erir$i l8informazione. La rappre!entazione
grafica di un elemento della li!ta < la !eguente"
mentre 9uella di una li!ta ri!ulta e!!ere come !egue"
71
32-'e%tione di una li%ta 6 I
1de!!o a''iamo intenzione di pre!entare un programma c.e permetta di memorizzare e !tampare una
li!ta compo!ta da un determinato numero di interi. Se''ene il programma po!!a !em'rare !emplice/ in
realt`agra$e= la !ua !te!ura/ ed il ragionamento po!to alla 'a!e di e!!a/ < particolarmente accatti$ante/
anc.e perc.`eacute= non !i po!!ono commettere errori/ ne !intattici/ ne logici.
+nnanzitutto do''iamo partire con l8inclu!ione delle li'rerie/ in 9ue!to ca!o includiamo !olamente
stdio;!/ per le pi`ugra$e= comuni operazioni di input,output/ e malloc;! per l8allocazione dinamica
della memoria= ne!!una li'reria particolare de$e e!!ere inclu!a/ in 9uanto/ come gi`agra$e= detto
prima/ una li!ta < compo!ta da elementi pree!i!tenti nel linguaggio C.
72
Cinclude `lt=!tdio..`gt=
Cinclude `lt=malloc..`gt=
Succe!!i$amente creiamo il tipo elemento/ alla 'a!e della li!ta/ c.e contiene un campo intero di nome
HinfH ed un campo puntatore al tipo elemento di nome HpunH"
,U !truttura elementi della li!ta U,
!truct elemento ^
int inf=
!truct elemento Upun=
_
Si do$ranno 9uindi creare i prototipi delle due funzioni adi'ite alla !oluzione del no!tro pro'lema= la
prima funzione .a il compito di creare la li!ta/ c.iedendo i dati di input all8utente tramite ta!tiera/ c.e
poi $err`agra$e= re!tituita dalla funzione !te!!a= la !econda/ in$ece/ re!titui!ce un $oid e prende in
input la li!ta da !tampare.
,U prototipi delle funzioni U,
!truct elemento UcreaXli!ta56=
$oid $i!ualizzaXli!ta5!truct elemento U6=
+l codice pro!egue con l8o$$ia creazione del main/ la dic.iarazione della una $aria'ile li!ta di tipo
puntatore ad elemento/ l8e!ecuzione della funzione creaNlista>?/ c.e .a il compito di HriempireH di
$alori la li!ta/ e l8e!ecuzione della funzione visualizzaNlista>? c.e !tamper`agra$e= a $ideo tutti gli
elementi della li!ta=
int main56
^
!truct elemento Uli!ta= ,, puntatore della li!ta
li!ta Y creaXli!ta56= ,, crea la li!ta
$i!ualizzaXli!ta5li!ta6= ,, !tampa la li!ta
_
73
Procediamo con la definizione del corpo della funzione creaNlista>?/ la 9uale crea due puntatori ad
elemento/ uno di nome p e l8altro di nome punt= 9ue!te due $aria'ili !er$iranno per !correre la li!ta/
infatti p < il puntatore al primo elemento della li!ta/ mentre punt < un puntatore au!iliario c.e permette
di !correre la li!ta= la $aria'ile i < l8indice del ciclo/ mentre n !er$e a memorizzare il numero degli
elementi c.e !i intende in!erire.
!truct elemento UcreaXli!ta56
^
!truct elemento Up/ Upunt=
int i/ n=
La $aria'ile n $iene in!erita tramite ta!tiera dall8utente/
printf5Hn Specificare il numero di elementi... H6=
!canf5HZdH/ ` n6=
Se n $ale (/ $iene ric.ie!to di creare una li!ta $uota/ 9uindi !i a!!egna a p il $alore null/
if5nYY(6
^
p Y L;LL= ,, li!ta $uota
altrimenti !i co!trui!ce il primo elemento della li!ta/ c.iedendo il !uo $alore da ta!tiera"
_ el!e ^
,U creazione primo elemento U,
p Y 5!truct elemento U6malloc5!izeof5!truct elemento66=
printf5Hn+n!eri!ci il primo $alore" H6=
!canf5HZdH/ ` p-\inf6=
punt Y p=
74
33-'e%tione di una li%ta 6 II
Aediamo c.e < !tata u!ata la funzione malloc>? in!ieme a sizeof per allocare dinamicamente la memoria
nece!!aria ad un elemento della li!ta 5$edere lezione 146= il $alore ritornato $iene ca!tato ad un
puntatore allo !pazio allocato/ c.e $iene a!!egnato a p.
1!!umendo c.e !ia !tato in!erito un $alore di n 5il numero di elementi della li!ta6 uguale a 3= nella
prima iterazione/ $iene creato il primo elemento della li!ta con il codice !opra e!po!to e $iene
a!!egnato 5tramite ta!tiera6/ ad e!empio/ il $alore 5=
75
Succe!!i$amente $iene creato un altro puntatore alla prima po!izione/ di nome HpuntH/ tale puntatore
au!iliario/ !er$ir per !correre gli elementi della li!ta e mantenere il collegamento all8ultimo elemento
in!erito.
Pro!eguendo con l8e!ecuzione del codice/ arri$iamo ad in!erire il !econdo ed il terzo elemento 5grazie
al ciclo for6"
,U creazione elementi !ucce!!i$i U,
for5iY2= i[Yn= i@@6
^
punt-\pun Y 5!truct elemento U6malloc5!izeof5!truct elemento66=
punt Y punt-\pun=
printf5Hn+n!eri!ci il Zd elemento" H/ i6=
!canf5HZdH/ ` punt-\inf6=
_ ,, c.iudo il for
punt-\pun Y L;LL= ,, marcatore fine li!ta
_ ,, c.iudo l8if-el!e
return5p6=
_ ,, c.iudo la funzione
Per prima co!a $iene creato un altro oggetto della li!ta/ identificato con punt-\pun/
76
poi HpuntH/ il puntatore au!iliario/ $iene fatto puntare/ non pi: al primo elemento/ 'en!G al !econdo/
all8atto pratico HpuntH di$enta il puntatore dell8oggetto da lui puntato 5punt Y punt-\pun=6.
Iuindi $iene in!erito il campo informazione dell8elemento tramite l8input da ta!tiera dell8utente= in
9ue!to ca!o $iene in!erito il $alore 2(=
La procedura/ o$$iamente/ !i ripete per il terzo elemento/ e/ !e $i fo!!ero !tati altri elementi da
aggiungere/ !i !are''e ripetuta fino all8in!erimento dell8ultimo elemento=
1ll8ultimo elemento/ alla fine del ciclo/ $iene fatto puntare il $alore L;LL c.e !er$e come marcatore di
fine li!ta.
77
La funzione visualizza Nlista>? ri!ulta e!!ere molto pi: !emplice di 9uanto !i pen!i= e!!a prende in input
la li!ta da !correre/ $iene con!iderato il primo oggetto puntato da p 5c.e < il primo elemento6 e $iene
!tampata la !ua informazione= l8iterazione inizia e !i a!!egna a p il !uo oggetto puntato/ o$$ero il
!econdo elemento/ di cui $err !tampata l8informazione relati$a= il ciclo continua fino a 9uando il
puntatore p non $ale L;LL/ cio< non coincide con il marcatore di fine li!ta/ momento in cui !i e!ce dal
ciclo e la funzione $i!ualizzaXli!ta56 termina il !uo compito.
$oid $i!ualizzaXli!ta5!truct elemento Up6
^
printf5Hnli!ta ---\ H6=
,U ciclo di !can!ione U,
.ile5p NY L;LL6
^
printf5HZdH/ p-\inf6= ,, $i!ualizza l8informazione
printf5H ---\ H6=
p Y p-\pun= ,, !corre di un elemento
_
printf5HL;LLnnH6=
_
ESE5PI, P+B'IC,
5Ai!ualizza il !orgente completo6
Le li!te $engono u!ate ampiamente all8interno del programma/ perc.J permettono una lung.ezza
dinamica per il numero di contatti pre!enti. Iui !otto proponiamo le parti di codice principali per la
creazione e l8u!o di tale li!ta"
3& ,, Creo la !truttura per creare la li!ta
39 !truct elemento
4( ^
41 tXcontatto inf=
42 !truct elemento Upun=
43 _=
S...T
S7ic.iaro la li!ta $uotaT
63 !truct elemento Uli!ta Y L;LL=
S...T
S;tilizziamo delle funzioni per modificare la li!taT
78
11( li!ta Y aggiungiContatto5li!ta6=
S...T
SParte di codice c.e in!eri!ce i nuo$i elementiT
255 ,U creazione elementi !ucce!!i$i U,
256 ,, 1lloco la memoria nece!!aria
257 punt Y 5!truct elemento U6malloc5!izeof5!truct elemento66=
25& ,, 4etto da+n!erire nell8informazione del puntatore
259 punt-\inf Y da+n!erire=
26( ,, 4etto il puntatore in te!ta alla li!ta
261 punt-\pun Y p=
34-Introdu$ione Input e (utput %u 7le
Scri$ere !u file < for!e la parte pi: importante di 9ue!to cor!o/ perc.J !i pongono le 'a!i per !al$are i
propri la$ori e 9uindi iniziare a !trutturare programmi di una certa comple!!it. 1''iamo gi accennato
alle operazioni di input,output limitandoci a 9uelle c.e coin$olge$ano la ta!tiera come di!po!iti$o di
input e lo !c.ermo come di!po!iti$o di output. Per poter operare correttamente < nece!!ario includere
l8.eader file Ostdio;!M c.e contiene tutte funzioni per l8input,output/ compre!e 9uelle c.e operano !ui
file.
+n C le operazioni di +,* $engono !emplificate attra$er!o l8u!o degli stream/ altro non !ono c.e delle
a!trazioni rappre!entati$e di un file o di un di!po!iti$o fi!ico/ c.e $engono manipolate attra$er!o l8u!o
di puntatori. L8enorme $antaggio di u!are gli !tream < 9uello di poter!i riferire ad un identificatore
!enza preoccupar!i di come 9ue!to $enga implementato= generalmente le operazioni c.e !i compiono
!u uno !tream !ono tre/ lo !i apre/ $i !i accede 5nel !en!o di operazioni di lettura e !crittura6 e lo !i
c!iude. L8altra importante caratteri!tica < c.e lo !tream < bufferizzato/ o$$ero $iene ri!er$ato un
'uffer per e$itare ritardi o interruzioni nella fa!e di lettura e !crittura/ infatti il contenuto del 'uffer non
$iene mandato al di!po!iti$o 5c.e !i tratti di un di!po!iti$o fi!ico o di un file non .a importanza6 fino a
9uando non $iene !$uotato o c.iu!o.
79
)li stream predefiniti nel linguaggio C 5c.e $engono me!!i a di!po!izione includendo la [!tdio..\6
!ono"
!tdin/ !tdout/ !tderr
Iue!ti !tream utilizzano principalmente il te!to come metodo di comunicazione +,*/ anc.e !e i primi
due po!!ono e!!ere u!ati con i file/ con i programmi/ con la ta!tiera/ con la con!olle e lo !c.ermo/ lo
stderr puE !cri$ere !oltanto !u con!ole o !ullo !c.ermo. La con!ole < il di!po!iti$o di default per
stdout e stderr/ mentre per stdin il di!po!iti$o di default < la ta!tiera.
Linu< e l%I-,
Linu? 5e ;ni?6 permette una !erie di operazioni c.e non fanno parte del linguaggio C/ ma del !i!tema
operati$o !te!!o= 9ue!te operazioni permettono di ge!tire l8input o l8output di un programma e di
redirigerlo do$e meglio !i crede.
M
redirige lo stdout/ generalmente !tampato a $ideo/ in un file= ammettiamo di a$ere un
programma di nome HprogH/ per redirigere il ri!ultato in un file 'a!ta fare/ da con!ole"
C prog \ ri!ultato.t?t
O
redirige il contenuto del file allo stdin= ammettiamo di a$ere un file di nome Hinput.t?tH e di
$olerlo pa!!are come input al programma HprogH/ 'a!ta digitare/ da con!ole"
C prog [ input.t?t
P 5pipe6
9ue!to !im'olo !peciale permette di redirigere lo stdout di un programma allo stdin di un
altro programma= !upponiamo di a$ere Hprog1H c.e de$e mandare il proprio output a Hprog2H/
da con!ole !cri$eremo"
C prog1 d prog2due e!empi pratici in linu? !ono"C prog d lpr
,, manda l8output di HprogH alla !tampante C l! -l d more
,, $i!ualizza le director2
,, una !c.ermata per $olta
80
35-La #un$ione #open
+ file !ono la parte pi: importante degli !tream perc.J/ come gi detto/ !ono un elemento e!!enziale per
permettere al programmatore di fare applicazioni interatti$e. Come menzionato prima/ la prima co!a da
fare < aprire un file= per fare ciE !i u!a la funzione fopen/ !trutturata nel !eguente modo"
3+L% Ufopen5c.ar Unome/ c.ar Umodo6=
c.e prende come parametri di input il nome del file al 9uale !i intende accedere ed il modo in cui !i
$uole aprirlo/ conforme al !eguente !c.ema"
GrG - lettura=
GwG - !crittura=
GaG - !crittura in fondo al file 5append6.
re!tituendo un puntatore all8oggetto EILE c.e !er$ir/ dopo l8apertura/ per poter accedere correttamente
allo !tream= !e non !i puE accedere al file/ $iene re!tituito un puntatore a L;LL. Iui di !eguito
proponiamo un !emplice programma per poter leggere un file/ ad e!empio/ di nome miofile;t<t=
Cinclude [!tdio..\
int main56
81
^
,U dic.iara lo !tream e il prototipo della funzione fopen U,
3+L% U!tream/ Ufopen56=
,U apre lo !tream del file U,
!tream Y fopen5Hmiofile.t?tH/ HrH6=
,U controlla !e il file $iene aperto U,
if 55!tream Y fopen5Hmiofile.t?tH/ HrH66 YY L;LL6
^
printf5HLon po!!o aprire il file Z!nH/ Hmiofile.t?tH6=
e?it516=
_
S...T
,U Codice c.e la$ora !ul file U,
S...T
_
36-Le #un$ioni #print# e #%can#
;na $olta aperto un file con la funzione fopen/ po!!iamo u!are due funzioni per acceder$i" la fprintf e
la fscanf c.e/ per 9uanto !imili printf e scanf/ operano !ullo !tream del file aperto da fopen()= la
forma con la 9uale !i pre!entano le due funzioni < la !eguente"
int fprintf(BAHE ?stream7 char ?formato7 argomenti ...);
int fscanf(BAHE ?stream7 char ?formato7 argomenti ...);
La fprintf/ come !i puE intuire/ !cri$e !ullo !tream/ mentre la fscanf legge dallo !tream= entram'e
!eguono per i parametri/ tranne il primo/ 9uello c.e < gi !tato detto per printf e !canf e c.e riportiamo
!inteticamente 9ui !otto per comodit di con!ultazione.
Eormato e argomenti
La !tringa formato .a due tipi di argomenti/ i caratteri ordinari c.e $engono copiati nello !tream di
output/ e le specific!e di conversione/ contraddi!tinte dal !im'olo percentuale 5I6 e da un carattere/
c.e illu!triamo di !eguito e c.e !pecifica il formato con il 9uale !tampare le variabili pre!enti nella
li!ta di argomenti"
Stringa di controllo Cosa viene stampato
Id7 Ii
+ntero decimale
82
If
Aalore in $irgola mo'ile
Ic
;n carattere
Is
;na !tringa di caratteri
Io
Lumero ottale
I27 IK
Lumero e!adecimale
Iu
+ntero !enza !egno
If
Lumero reale 5float o dou'le6
Ie7 IE
3ormato !cientifico
II
Stampa il carattere Z
Laturalmente fprintf e fscanf po!!ono !cri$ere negli !tream predefiniti/ stdout - stderr e stdin
ri!petti$amente/ come mo!trato dall8e!empio !eguente"
1? stampa un messaggio di errore ?1
fprintf(stderr7 "Ampossiile continuare!n");
1? scri$e a $ideo un messaggio ?1
fprintf(stdout7 "Cpera5ione completata!n");
1? rice$e da tastiera una stringa e la
? sal$a nella $ariaile "miastringa" ?1
fscanf(stdin7 "Is"7 miastringa);
%!i!tono/ inoltre altre 9uattro funzioni c.e operano !u file !cri$endo un carattere per $olta/ e!attamente
come fanno la getc!ar e la putc!ar per gli !tream predefiniti= 9ue!te 9uattro funzioni !ono"
int getc(BAHE ?stream);
int fgetc(BAHE ?stream);
int putc(char ch7 BAHE ?stream);
int fputc(char ch7 BAHE ?stream);
;na curio!it ri!iede nel fatto c.e getc < una macro del preproce!!ore/ mentre fgetc < una funzione di
li'reria/ ma fanno e!attamente la !te!!a co!a.
83
37-Le #un$ioni 8u%- e #clo%e
+nfine gli !tream/ 9ualun9ue u!o ne !ia !tato fatto/ de$ono e!!ere prima HpulitiH e poi c.iu!i/ 9ue!to !i
puE fare comodamente con le funzioni fflus! e fclose/ formalizzate come !egue"
fflu!.53+L% U!tream6=
fclo!e53+L% U!tream6=
+l !eguente programma c.iarir meglio l8u!o delle funzioni !piegate per operare !u file= infatti
!imuleremo un input da ta!tiera c.e $err !critto !u un file in!ieme ad un te!to predefinito e c.e $err
appe!o al te!to gi pre!ente nel file"
Cinclude [!tdio..\
int main56
^
c.ar mia!tringaS4(T=
3+L% U!tream Y fopen5Hmiofile.t?tH/HaH6=
printf5H+n!eri!ci meno di 4( caratteri -\ H6=
f!canf5!tdin/ HZ!H/ mia!tringa6=
fprintf5!tream/ HLa mia !tringa e8 " Z!nH/ mia!tringa6=
fflu!.5!tream6=
fclo!e5!tream6=
_
84
Le ultime funzioni c.e operano !u file !er$ono principalmente per e!eguire operazioni di de'ug/ le
9uali !are''ero difficili da implementare in maniera proprietaria"
int feof53+L% U!tream6=
int ferror53+L% U!tream6=
$oid clearerr53+L% U!tream6=
int fileno53+L% U!tream6=
il cui u!o $iene c.iarito 9ui !otto"
feof>? - Mitorna un $alore $ero 5true6 !e lo !tream raggiunge la fine del file=
ferror>? - Miporta uno !tato di errore dello !tream e ritorna $ero 5true6 !e ne incontra uno=
clearerr>? - Cancella le indicazioni di errore per un dato !tream=
fileno>? - Mitorna il de!crittore di file intero a!!ociato con lo !tream.
38-Input+(utput %u %tring-e
%!i!tono due funzioni molto !imili alla fprintf ed alla f!canf/ c.e perE prendono come input una !tringa
e non uno !tream= 9ue!te funzioni ri!ultano molto utili perc.J in C una !tringa < un arra2 di caratteri/ e
potre''e e!!ere difficile ge!tirla con gli !trumenti pre!entati fino ad ora. + due prototipi di funzione
!ono"
int !printf5c.ar U!tringa/ c.ar Uformato/ argomenti ...6=
int !!canf5c.ar U!tringa/ c.ar Uformato/ argomenti ...6=
Le modalit di utilizzo !ono analog.e a 9uelle !piegate in 9ue!ta lezione 5o nella lezione 76/ ma
proponiamo comun9ue un !emplice pezzo di codice per far capire meglio come operano 9ue!te due
funzioni"
Cinclude [!tdio..\
int main56
^
c.ar mia!tringaS&(T=
int di!tanza=
int tempo=
float $elocita=
printf5HUUU Calcolo della $elocita8 UUUH6=
printf5Hn+n!eri!ci la di!tanza -\ H6=
85
!canf5HZdH/ ` di!tanza6=
printf5H+n!eri!ci il tempo -\ H6=
!canf5HZdH/ ` tempo6=
$elocita Y 5float6di!tanza,5float6tempo=
!printf5mia!tringa/HAelocita8 -\ Z2.3fnH/ $elocita6=
printf5HZ!H/ mia!tringa6=
_
39-3e%%aggi di "rrore ed e%e!pi pratici
;n8altra importante caratteri!tica del C/ < c.e di!pone di una !erie di !trumenti per riportare/ al
programmatore/ gli errori comme!!i durante lo !$iluppo. Iuando prenderete dime!tic.ezza con la
programmazione capirete 9uanto !ia importante a$ere degli !trumenti per il de'ug/ $i!to c.e 'uona
parte dello !$iluppo di un programma ri!iede proprio nella correzione degli errori= per poter utilizzare
9ue!te funzione < 'ene includere/ oltre alla Ostdio;!M/ anc.e le li'rerie Ostdlib;!M e Oerrno;!M.
;na delle funzioni maggiormente utilizzate per 9ue!to !copo < la perror56/ u!ata in!ieme alla errno= la
!truttura della funzione < la !eguente"
$oid perror5con!t c.ar Ume!!aggio6=
La perror>? produce un me!!aggio a $ideo de!cri$endo l8ultimo errore ri!contrato e ritorna ad errno
durante una c.iamata ad una funzione di !i!tema o di li'reria.
Errno < una $aria'ile di !i!tema !peciale c.e $iene !ettata !e una c.iamata di !i!tema non e!egue
correttamente i propri compiti= per e!!ere u!ata in un programma de$e e!!ere dic.iarata come e?tern int
errno=/ a 9uel punto puE e!!ere manipolata attra$er!o gli !trumenti me!!i a di!po!izione dal C/
altrimenti ritorna l8ultimo $alore ritornato da una funzione di !i!tema o di li'reria. La funzione e<it>?/
in$ece/ !i pre!enta con la !eguente !truttura"
$oid e?it5int !tato6=
e !er$e e!!enzialmente per terminare l8e!ecuzione di un programma e ritornare il $alore H!tatoH al
!i!tema operati$o/ c.e puE a!!umere e!!enzialmente 9ue!ti due $alori"
%O+PXS;CC%SS - nel ca!o in cui il programma termini !enza pro'lemi=
86
%O+PX31+L;M% - nel ca!o in cui il programma termini con errori.
ESE5PI, P+B'IC,
5Ai!ualizza il !orgente completo6
+l programma utilizza le funzioni di lettura e !crittura !u file per leggere e !al$are il file Hru'rica.t?tH.
La particolarit del programma < c.e !al$a in formato CSA 5Comma Separated Aalue6/ formato c.e
permette a programmi di po!ta come *utloo0 o 4ozilla di importare i dati !enza pro'lemi.
LE''8+B
472 3+L% U!tream Y fopen5Hru'rica.t?tH/HrtH6=
S...T
475 .ile5fget!5linea/ 5((/ !tream6 NY L;LL6
S...T
51( fflu!.5!tream6=
511 fclo!e5!tream6=
SC+I''8+B
525 3+L% U!tream Y fopen5Hru'rica.t?tH/HH6=
S...T
532 fprintf5!tream/ HZ!/Z!/Z!/Z!/Z!nH/ p-\inf.nome/ p-\inf.cognome/ p-\inf.telefono/ p-\inf.email/
p-\inf.!itoe'6=
S...T
539 fflu!.5!tream6=
54( fclo!e5!tream6=
Lota particolare $a a Hgetc.arH/ utilizzata per !cri$ere una funzioncina c.e permette all8utente di
leggere i dati una !c.ermata per $olta= grazie a getc.ar !i puE continuare l8e!ecuzione premendo in$io.
573 $oid pau!a56
574 ^ ,, pau!a56 - *P%L
575
576 c.ar in$io=
577 printf5Hnn - premi +LA+* per continuare -nH6=
57& in$io Y getc.ar56=
579 return=
5&(
5&1 _ ,, pau!a56 - CL*S%
87
40-Il *re-proce%%ore C e le 9irettie di
inclu%ione
+n 9ue!ta lezione do''iamo parlare di un elemento importante nella programmazione in C/ il pre-
processore. Iue!to !trano elemento .a un ruolo apparentemente tra!parente/ ma allo !te!!o tempo
importanti!!imo. +l pre-proce!!ore < incaricato/ fondamentalmente/ di tro$are delle direttive all8interno
di un file !orgente e di e!eguirle= do$e !ta l8arcanoK c.e il pre-proce!!ore opera !u un file !orgente e
Hre!titui!ce un file !orgenteH 5c.e poi/ a 9ue!to punto/ $iene pa!!ato al compilatore6/ perc.J le diretti$e
c.e lui interpreta !ono principalmente di inclusione/ di definizione e condizionali.
;na direttiva inizia !empre con il carattere cancelletto = ed occupa una !ola riga/ !u tale riga po!!ono
e!!ere me!!i dei commenti 5 ,, o ,U 6 o il !im'olo di continuazione alla riga !ucce!!i$a 5 6.
+l file !orgente contenente le diretti$e/ $iene tradotto dal pre-proce!!ore in 9uella c.e $iene c.iamata la
translation unit 5anc.8e!!a formata !olamente da codice !orgente6/ la 9uale $iene poi compilata in
codice 'inario/ dando origine al corri!pondente file oggetto= tutti i file oggetto/ infine/ $engono
collegati dal lin@er/ generando un unico programma e!egui'ile.
Direttive di Inclusione
Le diretti$e di inclu!ione !ono 9uelle u!ate maggiormente/ !emplicemente perc.J $engono u!ate per
in!erire le li'rerie !tandard del linguaggio= la forma !intattica corretta della diretti$a/ c.e peraltro
cono!ciamo 'eni!!imo/ per includere i file < la !eguente/
Cinclude [file\
88
mettendo il nome del file da includere tra il !im'olo di minore 5[6 e 9uello di maggiore 5\6= in 9ue!ta
forma il compilatore andr a cercare i file pre!enti nelle director2 di include pre!celta= generalmente
9ue!ta director2 < predefinita/ ed < 9uella c.e contiene i file delle li'rerie !tandard/ come ad e!empio
!tdio../ !tdli'../ mat.../ !tring../ time.. e co!G $ia.
4a !e $ole!!imo includere un file pre!ente/ generalmente/ nella !te!!a cartella del no!tro programma/
do$remmo u!are una forma alternati$a/ come !egue/
Cinclude HfileH
< po!!i'ile nidificare la diretti$a =include/ infatti un file inclu!o puE contenere a !ua $olta 9ue!ta
diretti$a/ ma poic.J il li$ello di nidificazione dipende !pe!!o dal !i!tema/ < meglio cercare di non
annidare l8include degli !te!!i file 5e per 9ue!to proporremo una !oluzione pi: a$anti6.
41-Le 9irettie di de7ni$ione
Le diretti$e di definizione !ono !o!tanzialmente due/ =define e =undef/ c.e/ come $edremo !otto/
po!!ono e!!ere u!ate congiuntamente per definire o meno 9ualco!a in modo condizionale.
4a pa!!iamo a !piegare l8utilizzo di =define= 9ue!ta diretti$a/ 9uando !er$e per definire una co$tante .a
la !eguente !inta!!i/
Cdefine identificatore e!pre!!ione
in cui !o!tanzialmente il pre-proce!!ore !o!titui!ce tutte le occorrenze di HidentificatoreH con
l8e!pre!!ione corri!pondente 5c.e puE contenere anc.e !pazi o $irgolette6= generalmente il nome di una
co!tante definita con tale diretti$a/ oltre ad e!!ere tutto maiu!colo/ $iene preceduto dal carattere
under!core 5 X 6. Iuando la diretti$a !er$e per definire una macro .a una !inta!!i leggermente di$er!a/
Cdefine identificatore5argomenti6 e!pre!!ione
in 9ue!to ca!o/ in$ece/ !i !uppone c.e l8e!pre!!ione contenga gli argomenti come $aria'ili !ulle 9uali
operare/ il pre-proce!!ore non fa altro c.e !o!tituire il codice di e!pre!!ione/ modificando gli argomenti
definiti nella macro con 9uelli attuali/ ad ogni occorrenza dell8identificatore.
89
+l $antaggio c.e !i .a ad u!are le diretti$e di definizione < 9uello di non appe!antire il codice con
c.iamate o allocazioni di memoria/ poic.J !i !o!titui!ce il codice della macro con le occorrenze
dell8identificatore nel codice sorgente e !olo dopo lo !i pa!!a la compilatore. Iualcuno potre''e
contro'attere c.e al po!to delle !opraccitate diretti$e !i potre''ero u!are le parole c.ia$e del C/ const
per le co!tanti e inline per le macro 5c.e poi !ono delle piccole funzioni6= < $ero/ !i puE fare/ anzi <
opportuno non eccedere troppo con l8u!o delle diretti$e c.e/ in$ece/ de$ono e!!ere u!ate in forma
al9uanto limitata e !olamente in 9uei ca!i in cui la !o!tituzione apporti un 'eneficio reale al programma
ed alla leggi'ilit del !orgente. *$$iamente =undef !er$e !olo per annullare il compito di ciE c.e
a''iamo definito con l8e$entuale =define.
Per fare un e!empio pre!entiamo un pezzo di codice c.e fa u!o delle diretti$e di definizione"
Cinclude [!tdio..\
Cdefine L;4%M* 5
Cdefine I;17M1P*5a6 5a6U5a6
int main56
^
int ?=
printf5HLumero " Zd nH/ L;4%M*6=
? Y I;17M1P*5L;4%M*6=
printf5HIuadrato" Zd nH/ ?6=
Cundef L;4%M*
Cdefine L;4%M* 7
printf5HLumero " Zd nH/ L;4%M*6=
? Y I;17M1P*5L;4%M*6=
printf5HIuadrato" Zd nH/ ?6=
return (=
_
Iue!to !emplice programma !tamper a $ideo/
90
Lumero " 5
Iuadrato " 25
Lumero " 7
Iuadrato " 49
42-Le 9irettie condi$ionali
Le diretti$e condizionali permettono di definire una !erie di i!truzioni c.e $erranno compilate in
determinate condizioni/ 9ue!to tipo di diretti$e $iene u!ato !pe!!o per compilare il mede!imo !orgente
!u di$er!i !i!temi operati$i 5cam'iando dei parametri c.e in Linu? funzionano ed in #indo! no/ e
$ice$er!a6= le diretti$e condizionali !ono !ei/ ma non !ono difficili da ricordare"
Cif
- Se il $alore di ciE c.e !ta a de!tra < zero 59uindi 31LS*6 allora l8if non far niente= !e il
$alore < di$er!o da zero 5tr;%6/ allora !i e!eguir il codice !otto l8if fino a c.e non !i incontra
un elif/ un el!e o un endif.
Cifdef
- Miferendo!i all8identificatore pa!!ato come parametro/ !e < gi !tato definito 5tr;%6 !i
continua nell8e!ecuzione del codice !otto!tante/ altrimenti 531LS%6 !i cerca un elif/ un el!e o
un endif.
Cifndef
- Complementare al precedente= infatti in 9ue!to ca!o !i e!egue l8if !olo !e l8identificatore
pa!!ato non < !tato definito.
Celif
91
- Corri!ponde al co!trutto del %LS% +3/ e 9uindi $erifica la propria condizione ed agi!ce di
con!eguenza= puE e!!ere u!ato per definire !celte multiple 5tranne l8ultima6.
Cel!e
- Lell8ultima $oce delle !celte condizionali 'i!ogna mettere l8el!e c.e copre la ca!i!tica non
ricoperta dall8if e dagli elif precedenti. Putto il codice c.e !ta dopo l8el!e $err e!eguito fino a
9uando non !i incontra un endif.
Cendif
- C.iude la diretti$a Cif e/ corri!ponde/ nel linguaggio/ alle famo!e parente!i graffe.
7i !eguito facciamo un !emplice e!empio !u come po!!iamo u!are 9ue!te diretti$e per !elezionare
9uale codice e!eguire/ co!a molto utile/ lo ripetiamo/ 9uando $ogliamo compilare il mede!imo
programma !u !i!temi operati$i di$er!i.
Cinclude [!tdio..\
Cinclude Hmiofile..H
Cifndef S+SP%41
Cdefine S+SP%41 1
Cendif
,, S+SP%41 Y 1 -\ Si!tema Linu?=
,, S+SP%41 Y ( -\ Si!tema #indo!=
main 56
^
Cif S+SP%41YY1
printf5HSi!tema operati$o" Linu?nH6=
Celif S+SP%41YY(
printf5HSi!tema operati$o" #indo!nH6=
Cel!e
printf5HSi!tema operati$o" !cono!ciutonH6=
Cendif
return (=
_
+n 9ue!to !emplice pezzo di codice a''iamo due !cenari/ o l8identificatore S+SP%41 < gi !tato
definito/ ad e!empio/ in miofile../ con un $alore c.e puE a!!umere ( 5#indo!6/ 1 5Linu?6/ 2
5!cono!ciuto6/ oppure $iene definito all8interno del codice con $alore di default pari ad 1. 1 9ue!to
punto gli !trumenti fino ad ora !piegati !er$ono per !tampare uno dei tre te!ti a !econda del $alore
92
a!!unto dall8identificatore S+SP%41. +l codice < $olutamente un po8 HforzatoH per mo!trare tutte le
dic.iarazioni condizionali citate. Si la!cia al lettore il compito di fare ulteriori te!t per !coprire la
potenza di 9ue!to !trumento.
ESE5PI, P+B'IC,
5Ai!ualizza il !orgente completo6
Micalcando l8e!empio !opra propo!to/ !i puE $edere come il pre-proce!!ore po!!a $enir u!ato per
impo!tare la !te!!a funzione c.e .a un nome di$er!o in Linu? e in #indo!. +l comando < 9uello per
Hpulire lo !c.ermoH/ con il pre-proce!!ore a!!egniamo ad una $aria'ile il $alore giu!to a !econda del
!i!tema operati$o in u!o. La pulizia dello !c.ermo a$$err con il comando H!2!tem5puli!ci6=H.
15 ,, S+SP%41 Y 1 -\ Si!tema Linu?=
16 ,, S+SP%41 Y ( -\ Si!tema #indo!=
17 Cifndef S+SP%41
1& Cdefine S+SP%41 1
19 Cendif
2(
21 ,, Scelgo la funzione di !i!tema per pulire lo !c.ermo
22 Cif S+SP%41YY(
23 c.arU puli!ci Y Hcl!H=
24 Celif S+SP%41YY1
25 c.arU puli!ci Y HclearH=
26 Cendif
S...T
7( !2!tem5puli!ci6=
93
43-"rrori co!uni e regole di %tile in C
%cco alcuni degli errori in cui !i incappa pi: fre9uentemente 9uando !i programma in C. Q utile
elencare 9ue!te co!e perc.J tipicamente !ono 9uelle c.e fanno !cer$ellare i programmatori per ore
perc.J !ono imperfezioni del codice a $olte in!idio!e e mimetic.e.
Bssegnazione >Q? al posto del confronto >QQ? - Bi!ogna porre attenzione/ 9uando/ utilizzando
una !truttura condizionale come IE-ELSE/ !cri$iamo l8operazione di confronto 5YY6/ poic.J
e!!a puE/ per un errore di 'attitura/ di$entare un a!!egnamento 5Y6= !e ciE do$e!!e accadere/ ad
e!empio/ cercando di confrontare !e due numeri !ono uguali/ potremmo tro$arci nella
!piace$ole !ituazione in cui/ in$ece di controllare !e a 00 / c.e re!titui!ce true 5in C un
numero di$er!o da (6 !olamente 9uando le due $aria'ili .anno lo !te!!o $alore/ poniamo a 0
/ c.e < true praticamente !empre a meno c.e non !i a!!egni a uno // il c.e di$enta
mimetico al ma!!imo.
5ancanza di parentesi > ? per una funzione - +l programmatore ine!perto tende a credere c.e
una funzione alla 9uale non !i pa!!ano parametri non de''a a$ere le parente!i tonde= ciE <
errato/ le parente!i tonde/ anc.e !enza parametri/ de$ono e!!ere !empre me!!e.
Indici di Brra( - Iuando !i inizializzano o !i u!ano gli arra2/ 'i!ogna porre attenzione agli
indici utilizzati 5e 9uindi alla 9uantit di elementi6 poic.J !e !i inizializza un arra2 con L
elementi/ il !uo indice de$e a$ere un inter$allo tra ( 5c.e < il primo elemento6 ed L-1 5c.e <
l8n-mo elemento6.
Il C " Case Sensitive - +l linguaggio C 5come C@@ e Da$a6 fa di!tinzione tra lettere maiu!cole e
minu!cole/ interpretandole come due caratteri di$er!i= 'i!ogna 9uindi !tare attenti/ !oprattutto
9uando !i utilizzano le $aria'ili.
Il GRG c!iude ogni istruzione - Q un errore tanto comune c.e non puE non e!!ere citato/ ogni
i!truzione de$e e!!ere c.iu!a con un punto e $irgola= 9ue!ta facile dimenticanza 5Lda" c.e
colpi!ce anc.e i pi: e!perti "6 6/ !egnalata dal compilatore/ puE far perdere del tempo prezio!o
ed appe!anti!ce inutilmente il la$oro del programmatore.
94
I nomi delle variabiliL struttureL costanti e funzioni devono essere significativi - poic.J le
parole c.ia$e del linguaggio !ono in ingle!e/ !i con!iglia di utilizzare nomi/ per le $aria'ili e le
funzioni/ in lingua italiana/ in modo da poter capire/ dal nome !te!!o/ !e 9uello c.e !tiamo
u!ando < effetti$amente una parola c.ia$e del linguaggio o un co!trutto creato all8interno del
no!tro programma. +noltre !are''e 'uona norma/ !e il nome < compo!to da pi: parole/
e$idenziare con iniziali maiu!cole le parole !eguenti la prima= 9ue!ta regola non $ale/ in$ece/
per le co!tanti/ c.e de$ono e!!ere !critte tutte in maiu!colo e !eparate/ !e formate da pi: di una
parola/ dal carattere under!core HXH.
8soL funzione e posizione dei commenti - + commenti de$ono accompagnare 9ua!i tutte le
i!truzioni/ per !piegare il !ignificato di ciE c.e !tiamo facendo/ inoltre de$ono e!!ere !intetici
e de$ono e!!ere aggiornati appena modific.iamo un8i!truzione. + commenti de$ono e!!ere pi:
e!te!i/ in$ece/ !e de$ono !piegare un determinato algoritmo o !e accompagnano una funzione.
Espressione ternaria - L8e!pre!!ione ternaria <cond> ? <$al> : <$al> </ generalmente/
!o!tituti$a di un co!trutto if:else e re!titui!ce il primo $alore !e l8e!pre!!ione < $era 5true6 o
il !econdo !e/ in$ece/ < fal!a 5fal!e6. L8e!pre!!ione ternaria $a me!!a/ !e po!!i'ile/ !ulla !olita
riga e/ per e$itare pro'lemi/ < con!iglia'ile racc.iudere tra parente!i tonde !ia l8e!pre!!ione !ia
i $alori.
*gni sorgente do$re''e contenere/ nell8ordine"
1. Commento iniziale 5con nome del file/ nome dell8autore/ data/ te!to del pro'lema ed
e$entuali algoritmi u!ati6=
2. +!truzioni #include per tutti i file da includere 5'i!ogna includere !olo i file nece!!ari6=
3. 7ic.iarazioni di con!tanti/ !trutture e tipi enumerati$i=
4. 7efinizione di $aria'ili=
5. Prototipi delle funzioni=
6. 7efinizione delle funzioni 5con la funzione main me!!a come prima funzione6.
8so delle parentesi graffe S T - Lelle dic.iarazioni di tipi 5Str;CP/ ;L+*L/ %L;46 o nelle
inizializzazioni di $aria'ili all8interno delle definizioni la S c.e apre il 'locco $a po!ta di
!eguito al nome del tipo/ $icino all8uguale dell8inizializzazione/ !ulla !te!!a riga= la graffa di
c.iu!ura andr allineata con l8inizio della dic.iarazione/ !u di una riga a !J !tante.
Lelle funzioni o nei co!trutti +3,%LS%/ 3*M/ #F+L%/ S#+PCF la S di apertura del 'locco $a
allineata !otto la prima lettera del co!trutto/ mentre nel co!trutto do:!hile la S $a !ulla
mede!ima riga del 7*. La T di c.iu!ura del 'locco $a allineata e!attamente !otto la S di
apertura/ tranne nel do do$e la T di c.iu!ura $a allineata !otto la 7 di do/ !eguita dal !hile.
Putte le i!truzioni contenute in un 'locco $anno indentate ri!petto all8allineamento del 'locco
!te!!o 5c.e !ia la S di apertura o il do6/ tranne per le dic.iarazione di $aria'ili locali c.e $anno
allineate !otto la S 5o il do6. Per e$itare di a$ere !orgenti c.e eccedano la larg.ezza dello
!c.ermo < preferi'ile indentare di un paio di !pazi/ in$ece c.e di un ta'.
95
8so e commento delle funzioni - ;na funzione de$e e!eguire un compito e non <
!emanticamente corretto !cri$ere funzioni c.e contengano il codice per fare molte co!e
a!!ieme. Q/ piutto!to/ con$eniente !cri$ere le funzioni per i !ingoli compiti ed una ulteriore
funzione c.e !$olga il compito comple!!o/ ric.iamando le funzioni precedenti.
Prima di ogni funzione/ eccetto c.e per il main/ < nece!!ario fare un commento c.e contenga"
o Scopo della funzione=
o Significato e $alori leciti per ognuno dei parametri=
o Aalori di ritorno nei $ari ca!i=
o %$entuali parametri pa!!ati per riferimento modificati all8interno della funzione=
o %$entuali effetti collaterali !ulle $aria'ili glo'ali.
Esempio Pratico
5Ai!ualizza il !orgente completo6
Prendendo !punto dai contenuti di 9ue!ta lezione/ !i puE notare c.e il codice di e!empio contiene
molti!!imi commenti/ !ia per de!cri$ere le azioni od il ruolo di un determinato oggeto 5co!a rappre!enta
una $aria'ile o co!a fa una funzione6/ !ia per !egnare l8inizio o la fine di alcune parti di codice
5delimitazioni di apertura e c.iu!ura delle funzioni/ degli +3 e dei cicli 3*M6.
%Antesta5ione Ani5iale che descri$e il programma&
/ 1?
* ? Fome del file= rurica.c
6 ? Mutore : Bari5io Piacchi
4 ? Vicemre 6//4
. ? Nurica dimostrati$a per Html.it
+ ? Al programma genere un file rurica.t2t in formato P#L7 Pomma
9 ? #eparated Lalue7 e )uindi permette ad CutlooW o Uo5illa di
3 ? importare i contatti.
, ?1
%...&
%#piega5ione e commento di apertura di una fun5ione&
6*4 1?
6*. ? Mggiungo un nuo$o contatto
96
6*+ ?1
6*9 struct elemento ?aggiungiPontatto(struct elemento ?p)
6*3 { 11 aggiungiPontatto() : CDEF
%...&
%Pommento di apertura e chiusura di un AB&
..* if(suscelta 00 *)
..6 { 11 AB : CDEF
%...&
..9 } 11 AB : PHC#E
44-3oduli. prototipi e -eader 7le
1''iamo !piegato le 'a!i della programmazione in C/ ma !empre limitandoci a programmi di
dimen!ioni medio,piccole= < utile/ 9uindi/ affrontare gli a!petti teorici e pratici dello !$iluppo di
programmi di una certa dimen!ione/ 9ue!to perc.J un progetto con applicazioni reali u!ualmente
raggiunge grandi dimen!ioni.
+n 9ue!ti ca!i < con!iglia'ile dividere i programmi in moduli/ c.e do$re''ero !tare in file !orgenti
!eparati 59uindi ogni file conterr uno o pi: funzioni6/ mentre l8i!truzione main do$r e!!ere in un !olo
file 5generalmente main.c6. 1lla fine 9ue!ti moduli interagiranno tra loro !emplicemente includendoli in
fa!e di compilazione/ con l8o$$io $antaggio anc.e di riu!a'ilit per altri programmi.
Putto ciE $iene fatto/ con gli !trumenti adeguati/ per o$$ie ragioni"
+ moduli $erranno di$i!i in gruppi di funzioni comuni
< po!!i'ile compilare !eparatamente ogni modulo e poi lin0arlo nei moduli compilati
97
;!ando utilit2 come ma@e/ !i po!!ono mantenere a''a!tanza facilmente gro!!i !i!temi
8tilizzo dei file !eader
;tilizzando un approccio modulare/ do$remo includere in ogni modulo la definizione delle $aria'ili/ i
prototipi di funzioni ed i comandi per il preproce!!ore C/ etc. Iue!to potre''e cau!are pro'lemi di
mantenimento del !oftare/ co!G < con!iglia'ile centralizzare 9ue!te definizioni all8interno di un file 5o
pi: di uno6 e condi$idere/ poi/ le informazioni con gli altri file. Pali file $engono generalmente definiti
H.eader fileH 5file di inte!tazione6 e de$ono a$ere e!ten!ione 5un !uffi!o6 .h.
)eneralmente includiamo i file .eader delle librerie standard/ come ad e!empio <stdio.h> o
<stdli.h>/ mettendoli/ appunto tra il !im'olo di minore 5<6 e di maggiore 5>6/ 9ue!ta < la
con$enzione u!ata per includere gli .eader di !i!tema 5di cui il compilatore cono!ce il percor!o
completo6=
+ncludere .eader file di !i!tema
#include
Per includere in$ece/ all8interno di un file .c/ un file .eader c.e ri!iede nella mede!ima director2/
do''iamo u!are le $irgolette 5""6. 1d e!empio/ per includere un file di nome miaXintesta5ione.h/
'a!ta !cri$ere all8interno del file"
#include "miaXintesta5ione.h"
Per programmi di moderate dimen!ioni < meglio a$ere due o pi: file .eader c.e condi$idono le
definizioni di pi: di un modulo cia!cuno. +l pro'lema !orge 9uando a''iamo delle variabili globali in
un modulo e $ogliamo c.e $engano ricono!ciute anc.e negli altri.
)eneralmente le $aria'ili e!terne e le funzioni de$ono a$ere $i!i'ilit glo'ale. Iuindi per le funzioni
$engono u!ati i prototipi di funzioni/ mentre po!!iamo u!are il prefisso Ge<ternG per le $aria'ili
glo'ali c.e/ in 9ue!to modo/ $engono dic.iarate ma non definite 5cio< non $iene allocata memoria per
la $aria'ile6/ !aranno definite/ poi/ una ed una !ola $olta all8interno di un modulo c.e comporr il
programma= per 9ue!to po!!iamo a$ere tanti!!ime dic.iarazioni e!terne/ ma una !ola definizione della
$aria'ile.
98
45-L:utilit1 !a/e ed i !a/e7le
L8utilit2 maWe < un programma c.e di per !e non fa parte del famo!o )CC/ perc.J non < altro c.e un
program manager molto u!ato/ !oprattutto in +ngegneria del Softare/ per ge!tire un gruppo di moduli
di un programma/ una raccolta di programmi o un !i!tema completo. S$iluppata originariamente per
;L+O/ 9ue!ta utilit2 per la programmazione/ .a !u'ito il porting !u altre piattaforme/ tra cui/ appunto/
Linu? e #indo!.
Se do$e!!imo mantenere molti file !orgenti/ come ad e!empio"
main.c fun5ione*.c fun5ione6.c ... fun5ionen.c
potremmo compilare 9ue!ti file utilizzando il gcc/ ma rimane comun9ue un pro'lema di fondo anc.e
9uando a''iamo gi creato 9ualc.e file oggetto 5.o6 c.e $ogliamo lin0are durante la compilazione
glo'ale del programma"
< tempo !precato ricompilare un modulo per il 9uale a''iamo gi il file oggetto/ do$remmo
compilare !olamente 9uei file modificati dopo una determinata data/ e facendo degli errori
5co!a c.e aumenta con l8aumentare delle dimen!ioni del progetto6 potremmo a$ere il no!tro
programma finale !o!tanzialmente errato o non funzionante.
Per lin0are un oggetto/ !pe!!o/ < nece!!ario !cri$ere gro!!i comandi da riga di comando.
Scri$ere tanti comandi lung.i e di$er!i per !$ariati file puE indurre facilmente all8errore.
99
L8utilit2 ma0e $iene in aiuto in 9ue!ti !cenari/ fornendo automaticamente gli !trumenti per fare 9ue!ti
controlli e 9uindi/ garanti!ce una compilazione e!ente da errori e !olo di 9uei moduli di cui non e!i!te
gi il file oggetto aggiornato.
L8utilit2 ma0e utilizza/ a tal fine un !emplice file di te!to di nome Hma0efileH/ con all8interno regole di
dipendenza e regole di interpretazione.
;na regola di dipendenza .a due parti/ una !ini!tra ed una de!tra/ !eparate dai due punti 5"6.
latoXsinistro = latoXdestro
La parte sinistra contiene il nome di un target 5nome del programma o del file di !i!tema6 c.e de$e
e!!ere creato/ mentre quella destra defini!ce i nomi dei file da cui dipende il file target 5file !orgenti/
.eader o dati6= !e il file target 5de!tinatario6 ri!ulta non aggiornato ri!petto ai file c.e lo compongono/
allora !i de$ono !eguire le regole di interpretazione c.e !eguono 9uelle di dipendenza/ infatti 9uando !i
e!egue un ma0efile $engono !eguite 9ue!te regole"
1. Aiene letto il ma0efile e !i e!trapola 9uali file .anno 'i!ogno di e!!ere !olamente lin0ati e 9uali/
in$ece/ .anno 'i!ogno di e!!ere ricompilati
2. Come detto prima/ !i controlla la data e l8ora di un file oggetto e !e e!!o ri!ulta HantecedenteH
ri!petto ai file c.e lo compongono/ !i ricompila il file/ altrimenti !i lin0a !olamente
3. Lella fa!e finale !i controlla data e ora di tutti i file oggetto e !e anc.e uno !olo ri!ulta pi:
recente del file e!egui'ile/ allora !i ricompilano tutti i file oggetto
Laturalmente po!!iamo e!tendere l8utilit2 di ma0e a 9ual!ia!i am'ito/ perc.J po!!iamo u!are 9ual!ia!i
comando dalla riga di comando/ in 9ue!to modo ri!ulter intuiti$a 9ual!ia!i operazione di
manutenzione/ come fare il 'ac0up.
Creare un ma@efile
1mmettiamo di a$ere i file !imili all8e!empio precedente"
programma.c fun5ione*.c fun5ione6.c header.h
e di $oler far !i c.e ci !iano delle regole c.e impongano di ricompilare !e cam'ia 9ualc.e file/ ecco
come/ ad e!empio/ potre''e e!!ere !trutturato un ma0efile 5modifica'ile con un 9ual!ia!i editor di
te!to6"
programma = programma.o fun5ione*.o fun5ione6.o fun5ione4.o
gcc programma.o fun5ione*.o fun5ione6.o fun5ione4.o
programma.o = header.h programma.c
gcc :c programma.c
fun5ione*.o = fun5ione*.c
gcc :c fun5ione*.c
fun5ione6.o = fun5ione6.c.
gcc :c fun5ione6.c
100
fun5ione4.o = fun5ione4.c.
gcc :c fun5ione4.c
Iue!to programma puE e!!ere interpretato in 9ue!to modo"
HprogrammaH dipende da tre file oggetto/ Hprogramma.oH/ Hfunzione1.oH e Hfunzione2.oH= !e
anc.e uno !olo di 9ue!ti tre file ri!ulta cam'iato/ i file de$ono e!!ere lin0ati nuo$amente
Hprogramma.oH dipende da due file/ H.eader..H e Hprogramma.cH/ !e uno di 9ue!ti due file <
!tato modificato/ allora 'i!ogna ricompilare il file oggeto. Iue!to $ale anc.e per ultimi due
comandi
)li ultimi tre comandi $engono c.iamati regole esplicite perc.J !i u!ano i nomi dei file in modo
e!plicito/ mentre $olendo !i po!!ono u!are regole implicite come la !eguente"
.c.o = gcc :c Z<
c.e puE !em'rare apparentemente incompren!i'ile/ ma c.e !i traduce facilmente in Hprendi tutti i file
.c e tra!formali in file con e!ten!ione .o e!eguendo il comando gcc !u tutti i file .c 5e!pre!!o con il
!im'olo Z<6.
Per 9uanto riguarda i commenti/ !i u!a il carattere cancelletto 5#6/ co!G tutto ciE c.e < !ulla mede!ima
riga $iene ignorato= 9ue!to tipo di commento < lo !te!!o di!poni'ile in p2t.on ed in perl.
Per eseguire un ma@efile < !ufficiente digitare dalla linea di comando/ il comando maWe/ il 9uale andr
automaticamente a cercare un file di nome maWefile da e!eguire. Se perE a''iamo utilizzato un nome
di$er!o ad e!empio acWupXall 5a''iamo creato un ma0efile per fare il 'ac0up6/ po!!iamo dire a maWe
di interpretare 9uello come ma0efile corrente/ digitando"
# maWe :f acWupXall
*$$iamente e!i!tono altre opzioni per il comando maWe/ c.e po!!ono e!!ere !coperte digitando da
con!ole/ il comando"
# maWe ::help
# man maWe
1''iamo dato un8idea dell8u!o del maWe e dei ma0efile/ 9ue!to per farne comprendere le po!!i'ilit/
!enza addentrarci troppo nella programmazione di un ma0efile comple!!o/ compren!i$o di comandi pi:
a$anzati o dell8u!o delle macro. Putto ciE !pero po!!a !er$ire come punto di partenza per uno !tudio pi:
approfondito di tale !trumento c.e/ comun9ue/ $iene utilizzato 9uando !i inizia a la$orare !u progetti di
una certa dimen!ione e c.e/ 9uindi/ non < utile trattare ulteriormente in 9ue!to am'ito.
101