Sei sulla pagina 1di 297

Sommario

P REFAZIONE .. ......... ............ .... .......... ..... .. ... ........... . ............ ..... .. Xl

e
Corso completo di programmazione
Titolo originale:

C How to Program, Second Edition


Autori:

Harvey M. Deitel, Paul J. Deitel


Published by arrangement with the or.igioal publisher, PRENTICE HALL, INC.,
a Pearson Education Company
Copyright 1994 - PRENTICE HALL, INC.

Lo scopo di questo libro ............................ .................................................................... xi


La metodologia di insegnamento .................................................................................. xii
Lapprendimenro attraverso il codice ................................ ......... ...................... xii
Laccesso al Wodd W ide Web .......................................................................... xii
Obiettivi ............................ ..................................... ...... ................................... xi i

~i;:c: ~~a~i:~~~.:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:
Consigli e suggerimen ........................... ... ...................................... ....... ....... xiii
Esercizi di autovalutazione ............................................................................... xiv
Esercizi ........... .. ..... ....................................... ... ........................................ ........ xiv
Indice analitico ...................................................... .......................................... xiv
Panoramica sul libro .. .......... ......... ............................. ............................................ ....... xiv
C APITOLO I : N OZIONI SULLA ELABORAZIONE ELETTRONICA .... ... . .... .. .... .. .... I

1.1

Inn:oduzione ...................................................................................................... 1
Che cosa un computer? ................................................................................... 3
1.3
L'organizzazione del compucer ........................................................................... 3
1.4
L'elaborazione batch, la multiprogrammazione e il timesharing ........................ 4
1.5
L'elaborazione personale, distribuita e dient/server .......................................... 5
1.6
I linguaggi macchina, assemb.ly e di alto livello ....................... .. ...................... .. 6
1.7
La sroria del
7
1.8
La libreria standard del
8
1.9
Gli altri linguaggi di alto livello .......................................................................... 8
1.1 O La programmazione strutturata .................................................................. ........ 9
1.1 1
Le basi dell'ambiente c ................................................................................... 10
1.1 2
Note generali sul Ce su questo libro .... ................... ... ..................................... 12
1.13 Il Concurrenr C ................ .................. .. ... .... .................. ....... ..................... ...... 13
1.1 4 La programmazione orientata agli oggetti e il C++ .............................. ... ......... 13
Esercizi di autovalutazione .............. .................................... .......................................... 14
Risposte agli esercizi di autovalutazione ............... .................. ...................................... 14
Esercizi ..................................... .................................................................................... 15
Letture consigliare ....... ... ................... ........................................................................... 16
1.2

Copyright per l'edizione italiana 2000 - APOGEO stl


Viale Papiniano 38 - 20123 Milano (ltaly)
Telefono: 02-461920 (5 linee r.a.) - Fax: 02-4815382
Email
U.R.L.

educati on@apogeonline.com
www. apogeonline. com

ISBN 88-7303-669-4
Traduzione cli Michele Trulli
Revisione di Ivan Scagnetto
Impaginazione di Guido e Gianfranco Giuseppini
Realizzazione editoriale di Spock s.a.s. di Augusto Vico e c.
Editor: Alberto Kratter Thaler
Copertina e pcogetto grafico: Enrico Marcandalli
Responsabile di produzione: Vitiano Zaini

Tutti i di.ritti sono riservati a norma di legge e a norma


delle convenzioni intrnazionali. Nessuna parte di questo ]jbro
pu essere riprodotta con sistemi elettronici, meccanici
o altri, senza l'autorizzazione scritta dell'Editore.
Nomi e marchi citati nel testo sono generalmente depositati o registraci
dalle rispettive case produttrici.

c ...................................................................................................
c ..................................................................................

CAPITOLO

2:

INTRODUZIONE ALLA PROGRAMMAZIONE IN C .... .... ....... . . ...

I9

2. 1
2.2

lnuoduzione ................... ......................................................................... ........ 19


Un semplice programma C: v.isualizzareuna riga di tesro .. .............................. 19
2.3
Un altro semplice programma C: sommare due interi .... ................................ 23
Nozioni sulla memoria .. .................................................................................. 28
2.4
2.5
L'arianetica del C ............................................................................................ 29
2.6
Prendere delle decisioni: gli operatori di uguaglianza e relazionali .................. 33
Esercizi di autovalutazione ..... .. ............. ........................ ... ............. ................................ 37

Sommario
P REFAZIONE ........ ... ........ ... .... ... ... .. ............. ..... .. Xl

e
Corso completo di programmazione
Titolo originale:

C How to Program, Second Edition


Autori:
Harvey M . D eitel, P aul J. D ei tel
Published by arraogcmenr with the origiaal publisher, PRENTICE HALL, lNC.,
a Pearson Educacion Company
Coprnght 1994 - PRENTICE HA.LL, INC.
Copyright per l'edizione italiana 2000 -APOGE O srl
Valc Paptniano 38 - 20123 Milano (h aly)
Telefono: 02-461920 (5 linee r.a.) - Fax: 02-4815382

Email education@apogeonline .com


U.R.L. www . apogeonline. com
ISBN 88-7303-669-4
Tmduzione di Michele Trulli
Revisione di l van Scagncu o
l mp aginazione di Guido e Gianfranco Giusppini
RcaJizzazlone eclito ria le di Spock s.a.s. cli Augus to Vico e c.
Editor: Alberto K.rnttcr Tbitler
Copertina e progetto g rafi co: Eru:ico M arcandalli
.Responsabile dJ proclnrionc: 'Vitiano Zaini

Tuto i diritti sono riservaci u norma di le~ e a no.an,1


delle convenzioni intc:roaz1on:i. Nessuna pane di questo libro
pu esi.erc ciprodoua con s1stcmj elettronici, mcccaruct
o aJm, senza l'aucorizzaz1one senna dell'Edito!e.
N omi e mardu citati nel resto sono generl}lmente depos1cat o ccgistraa
dalle rispettive case produrtnct.

Lo scopo di questo libro ................................................. ........................................... .... xi


la metodologia di insegnamento .................................................................................. xi i
I.:apprendimcmo aa:raverso il codice ............................................................. xii
t.:accesso al Wotld Wide Web .................... .. .................................................... xii
Obic:n.ivi .......................................................................................................... xii
Il codice e gli esempi ................. .. .................................................................... xii

.
.
. .
..
Ftgur~ : 11nmag~ 1 : ............................... ...................................... ............... ~ '.'.

Consigli e suggenmentt .... ........... ........~ ..... ................. .. ................................. x 111


E..~e rci1.i di autovalucazione ............ .......... ........ .............. .. ........ ................. ... .. ... xiv
Esercizi .............. ............................... ...... .. ..... ................ .................................. xiv
1n<licc: analitico ........ ................................. .................. ................................. .... xiv
Panoramica sul libro .................................................................................................. ... xiv
C APITOLO I : N OZIONI SULLA ELABORAZIONE ELETTRONICA ... . . . I

1.1
1.2
1.3
l.4

Inrrod uzione .................................................. ............... ............................... ...... 1


C he cosa un computer?................................................................................... 3

L'organizza:Lione del computer ........................................................................... 3


L'elabor.nione bacch , la multiprogrammazione e il timesharing ........................ 4
l.5
L'elaborazione personale. dimihuita e dient/server .......................................... 5
1.6
I linguaggi macchina, asscmbly e di aJro liveliQ................................................. 6
1.7
La scoria del
7
1.8
La l.ibrcna scand..ard del e .................................................................................. 8
1.9
Gli altri linguaggi di alto livello .......................................................................... 8
LIO
La programmazione scrucrurara .......... ............................................... ................. 9
L.11
Le basi dell'ambic:n cc: e ................................................................................... 1o
1. U
Note generali sul C e su qucst0 lib ro ............................................................... 12
I .1 3
li Concurrent
13
1. L4
La programmaz:ione orientata agli oggetti e il C++ ......... ................................. 13
Esercizi d.i aurovaJurazi<;> ne ........ .............. .............. ..................................... ................... 14
R:isposcc agli esercizi di aucovalurnziMc .................... .. .......... ............ ........................... 14
Tuercizi ............ ......................... ............ ............ ,.. .. .. ... .. .. .. . .. .. .. .. .. .. .. . .. .. ... . .. .. . .. . .. .. .. . ... .. 15
Letture consigliate ................................................................ ........................................ 16

e ...................................................................................................

e ...............................................................................................

C APITOLO

2.1
2 .2
2.3
2 .4

2: INTRO DUZIONE ALLA PROGRAMMAZIO N E IN C

.... ... ..........

19

fn rroduriooc: .................................................................................................... 19
Un semplice programma C: visualizzareuna riga di resco ................................ 19
Un altro semplice programma C: sommare due interi .................................... 23
Norion.i sulla memoria ....................................- .............................................. 28
1.5
L'arirmetica dcl C ....... ............................................. ........................................ 29
2.6
Prendere delle decisioni: gli operatori di uguaglianza e relazionali .................. 33
Esercizi di aucovalut:u.ionc ............................................................................................ 37

SOMMARIO

IV

Risposcc agli esercizi di aurovalutazione ....................................................................... 39


Esercizi ................................................................. ........................................... ............. 40
CAPITOLO

3: Lo SVILUPPO DI PROGRAMMI STRUTTURATI . .............. . . ....... 45

3.1
3.2
3.3

Introduzione .................................................................................................... 45
Gli algoriuni ................................. ................................. ................................. . 45
Lo pseudocodicc .............................................................................................. 46
~.4
Le strutture di conaollo ................................................................................... 47
3.5
L;i scrui:o.u:a di selezione lf ................................. .............................................. 49
3. 6
La suutcura di selezione lf/El~e ............................ ,..............................,,.......... 51
3.7
La scrucrura <.li iterazione wbile ............... ......... ........ ........ ................................ 55
3.8
Formulazione degli aJgoani: srudio di un caso 1
(icerazione Gontrollaca da un concarore) ........................................................... 56
3.9
Formulazione degli algoritmi con processo top-down
per raffinamenri successivi: srudio di un caso 2
(irer.Wene controllata da un valore sentineUa) ................................................. 58
3.1 o rormulazine degli algocm.i con processo rop-down
per raffi n;unemi successivi: studio di un caso 3
(suurrure di conrroUo nidificare) ...................................................................... 65
3.11 Gli ope.rarori di assegnament ......................................................................... 69
3.12
Gli opcrarori di incremento e di decremento .................................................. 70
Esercizi di aucovalucazione ............................................................................................ 73
.Risposte agli esercizi di aurovalutazione ............................................................ ........... 74
Esercizi ................................................... ...................................................... ,............... 76
CAPITOLO

4: IL CONTROLLO DEL PROGRAMMA ........... ..................... ......... 85

4.1
4.2
4.3
4.4
4_5

lnuoduzione .................................................................................................... 85
Gli elemem:i della iterazione ............................................................................ 85
Jcei;azioBe cntrollara da un contatore ..............................................."" 86
La strurcura di icera7one for ..... ............................ ................ ..... ... ........... ........ 88
La struttura for: noce e osservazioni ................................................................ 91
4,.6
Esempi di utilizzo della srrurrura tor ................................................................ 92
4.7
La sm:rrrura di selezione mulcipla swicch - 95
4.8
la struinl.Ea di iterai.ione do/while ................................................................. 101
4.9
Le isrn1zi0ni break e concioue ............................................................... .. .. .... 103
4. 10 Gli operatori logid .................................. ..............".. 105
4.1 1 Confondere gli operacori di uguaglianza (:=) e di assegnamento C=.) .... I08
4.12 Riassumo ddla programmazione sr:rurturaca .................................................. 110
Esercizi di aurovalurazione. .................... .. ..... ...... .... ................. ............ .. .. ........... .... . ... I 15
Risposte agli eserizi di autovaJuraz.ioqe ..................................................................... 117
Esercizi ................................................................................................. ...................... J 18
'C APITOLO

5.1

5.i
5.3
s.4

--~-

5: LE: FUNZIONI . . . . . ... . . . . .. .. . . . . . .. . . . .. .. . .. . . . . . . . . . .. . . . . . . . . . .. . .. . . . I25

lnrroduzione .................................................................................................. 125


1 moduli di programma jn_ e ......................................................................... 125
Le funzioni della libreria maremacica ................................. ......................... ... 126
te funzioru .................................................................................................... 127

-=-- -_

SOMMARIO

Le definizioni di funzione ................................. ... ................................. ......... 129


I prototipi di funz.lone ............. ...................................................................... 133
I file di inresrazione ....................................................................................... 136
Invoca.re le funi.ioni: chiamata per valore e per dferimento .......................... 137
Generazione di numeri casuali ...................................................................... 138
Esempio: un gioco d'azzardo ................................. ................................. ....... 142
Le classi di memoria .................................................................. ................... 145
Le J:egole di visibilit ...................................... ,.............................................. 1.48
La ricor~ione ................................................................................................. 151
Esempio di ut:ilizzo della ticorsione: la serie di Fibonacci ............................. 155
Ricorsione e iterazione .................................................................................. 158
di autovalucazione .......................................................................................... 161
Risposte agli esercizi di autovalucazione ..................................................................... 163
Eserci?.i ............................................................................................... ........................ 165
5.5

5.6
5.7
5.8
5.9
5.10
5.11
5.12
).13
5.14
5.15
.Esercizi

C APITOLO

6.1

6:

I vEnoR1 ...... .... . ...... ........... ........... ... ... .. .. ................. ................

175

6.2

lnrroduzione ................................. ................................. ................................ 175


I vettori ................................. .............................................. ........................... 175

6.3

La dichiarai.ione dei ven:qri ........................................................................... 177

6.4

Esempi di ucili220 dei vecroci ......................................................................... 178


Passare i vertori alle funzioni .................................................................. ....... 190
6.6
L'ordinam.coco dei verto.ri ................ .......................................... ,................... 195
6.7
Srudio di un caso: calcolate la media, la mediana e la moda usando i vettori 197
6.8
La ricerca nei vettori .................................................................... ,................ 201
6.9
I vercori mulcidimensionali ............................................................................ 206
Esercizi di autovalutazione .......................................................................................... 212
Risposte agli es~rcizi di aurovalurazione .................................................... ._............... 2 14
Eserci2i ................. ............................................................................................... ,...... 215
Esc::,rcizi sulla rieorsione ..................................... .. ...................................... ................. 225

6.5

CAPITOLO

7.1

7: I PUNTATORI ................. ........................ ................... ...... ... .......... 227

Introduzione ........................................................................................... _...... 227


7.2
Dichiarazione e iniziaJjzzazione dci puntarori ................................................ 227
7.3
Gli operatori sui puntatori ............................................................................. 228
7.4
la chiamara per riferimento delle fun?.ioni .................................................... 231
7:5
Ucilizz.are il qualifcarox:e const con i punratol'i ................................. ............. 235
7.6
L'ordina.mento a bolle utilizzando una chiamata per riferimento ................... 241
7.7
Le espressioni con i puntatori e l'atmetica dci puntatori ............................ 246
7.8
La relazione tra i puntatoci e i verrori ............................................................ 249
7.9
l vettori di puntatori ................................. ..................................................... 253
7.10
Srudio di un caso: simulazione di un mescolacore e discribucore cli carte ...... 254
7.11
I puntatori a fun1,ionj ................................................... .. ,............................... 259
Esercizi di aurov-aluta.7.ione ........................................... ,.............................................. 264
Risposce agli esercizi cli aucovalutrione ...................... ., ............................................. 266
-Esercizi ....................................................................................................................... 267
Sezione speciale: cosrruire il vostro computer ............................................ - 270

SOMMARIO

Vl

8: I CARATTERI E LE STRINGHE ............................. ............................. . 281


lnrrod:uzione ........................................................ ,......................................... 281
8.2
1 concerti fondamenrali deUe stringhe e dei ca.racreri ..................................... 281
8.3
La libreria per la gestione dei carartcri ................................. ......................... 283
8.4
Le fu.m.ior per la conversione deUe srringhe ................................................. 289
8.5
Le funzioni deUa libreria per l'iopuc/oucpur standard .................................... 293
8.6
Le funzioni per la manipolazione delle stringhe incluse neUa libreria
per la gcscione delle so:inghc;: .......................................................................... 297
8.7
Le fi;m~ioni di confromo.in:cluse nella libreria per la gestione delle so.inghe .. 299
8.8
Le fu.rrzion i d i ricerca incluse nella libre.ria pcr ta -gestione delle stringhe ...... 302
8.9
Le funzioni per la maniplai.iorn: della mc.moria incluse nella libreria
per la gestione dcl le stringhe .......................................................................... 308
8. 1O L alrre fu.oz.ioni della libreria per La gestione delle stringhe .......................... 312
Esercizi di aurovalurazione .......................................................................................... 3 L3
Risposte agli esercizi di autovalutazione ................................. .................................... 3 14
Eserciz.i .... - ...... .. .................................................................. ............................. . 315
Sezione speciale: esercizi di manipolazione avanzata: dclle stringhe ............... ;............ 31 8
Un progetto impegnativo per la manipolazione delle stringhe ..................................... 322
CAPIT OLO

8.1

CAPITOLO

9: lA FORMATTAZJONE DELL'INPUT/OUTPUT . .......... ................. .... ........ 323

SOMMl\RJO

10.1 1 Le cascanti d i enumerazione ................. ............. ...... ................................. ..... 371


Esercizi di autovalutazione .... ........................... ...... .. ................................. ........... .. ..... 373
Risposte agli esercizi di aucovalucazi.on e .... ........................................ ............ .. ........... 375
Esercizi ........................ ........... ......................................................... ........................... 375
CAPITOLO

11. I
11.2
11.3

C APITOLO

12.1

I 0: LE STRUTTURE,

LE UNIONl1 L GESTIONE DEI BIT E LE EN UMERAZIONI

349

ln rrod~one

10.1
10.2

................................ .... ......................................... ..................... 349


La definizione delle srrurrure .. ................................... .................................... 349

10.3

Inizializzare le srrurrure .......... ..................................... ................................. .. 352


Accedere ai membri delle suunure ................................................................ 352
Usare le suurrure con Le fun~ioni ................................. .................................. 354

L ElABORAZIONE DEJ FILE ........................ ........ . .......... .. . . ......... ...

379

] 1.4
Creare un file ad accesso sequenrt.iale ............ ................................................ 382
11.5
Leggere i dari da un file ad a-ccesso sequenziale ............................................. 387
11.6
I file ad accesso casuale ................................................................................. 392
11.7
Creare un fe ad accesso casuaJe ........................ ........................................... 393
11.8
Scrivere i dari in modo casuale in. un file ad ac::esso casuale ................_........ 395
11.9
Leggere i dari in modo casuale da un fle ad accesso casuale ......................... 398
11.10 Studio di un caso: un progratllJilll pe.r l'elaborazione delle mll1s;I2oui .......... 399
Esercizi di aurovaluraz.ionc .................. ........................................................................ 404
Risposte agli esercizi di autovalutazione .................................................................. ... 405
'Esercizi ................................................................... ..................................................... 406

9.1

CAPITOLO

11 :

Introduzione .......................................... .. ............ .......................................... 379


La ger.arGh ia dei dari ...............-...................................................................... 379
I fil.e e g.li Strea.in .... .................. ................................. ........... ............. ... ........ .. 38 1

9.2

lnrroduzione .................. ........ ........................ ..................... ........................... 323


Gli srrearn ...... .. .... ......................... ...... .......... ...... ....................... ............. ....... 32.3
9.3
f oanattit'e l'output con priurf ........... ............................................................ 324
9.4
Visua.lizz.are gl.i interi .......... ........................................................................... 324
9.5
Visualizzare i owneri in virgola mobile ......................................................... 326
9.6
Visualizzare le stringhe e i caratteri ............................................................... 328
9.7
Gli altri indicatori di conversione ...................., ............................................. 329
9.8
Visualizzare co11 le d imensioni di campo e le p .recisioni ................................ 330
9..9
Utiliz1..are j H.ag nella srri:oga.di coum'>.llo del fo.anato ................................. ... 333
9.1 O Visualizzare i ~lerterali e le s.e.que112e di escape: ................................................ 336
9.1 l
Pormarciire l'input con scanf. .. ....................................................................... 336
Esercizi di aurovaJutazione ........................................... ............................................... 342
Risposte agli esercizi di aucovalucazione ................................. .................................... 344
..Esercizi ....................................................................................................................... 345

Vll

I 2:

L E STRUTTURE D I DATI ..................... . ................. ........................

41 I

U.2
12.3

lorroduzion!! ............................................... .. ,................................................ 4 11


Le srrumrr ricorsive .................. ........................... .. ................................. ..... 412
Allocazione dinamica della memoria ............................................................. 412

12.4
12.5
12.6

Le liste concarenace ..... .......................................................................... ........ 414


Le pile ............................. ..................................... ............................... ........... 422
Le code ........................................................................................................ .. 428

12.7
Gli alberi .............................. .......... ................................................................ 434
Esei:cizi di :turqvalut:az.ione .................................................................. ........................ 439
-a
.. di aurovaluEaZione
. .
t,rspoSte agli eserClZJ
..................................................................... 4"11
Esercizi .............................................................. ............... ......... ... ............................ .. 442
Sezione speciale: costruite il voStro compilatore .... .................................................... 449
Primo passaggio ............................................................................................. 452
Secondo passaggio ........................................................... ........................... ... 454
Un esempio completo .................... .............. ........ .... ......................... ............. 454
Un ~e passo per passo del processo di compilazione ............................... 456
C APITOLO

13:

I L PREPROCESSORE .......... ......... .............. ..... ........... . .. .... .............

463

Typedef.......................................................................................................... 354
Esempio: simulazione di un. mescolatore e distributore di carre

13.5

ad alt.a. efficienza .......................................................................................... .. 355

13.6

L0.8
Le un.ioni .. ..................................................................................................... 3 57
L0.9
Gli operatori bicwise ...................................................................................... 360
10.10 l campi dj bit: ................................................................................................ 368

Tnrroduz.ione ................................. ................................................. ,............... 463


La ~rriva del preprocessore # include ...................................... ................... 463
La diretva del preprocessore #defne: le cosran simboliche ....................... 464
La diren:iva del preproces.soce #define: lt: macro ..... ...................................... 464
La compilazione c0ndizi0nale .................. ....................... ,.............. ................. 466
l e direttive del prcprocc,:ssorc #errar e #pragma .........................- ......... ....... 468

13.7
1 3.8

Cli operatori# e ## ............. .......................................... ................................ 468


I numeri di riga ................................. ............................................................ 469

13.9

Le cosranci simboliche predefinite ........................................................... .. .... 469

10.4
10.5
1.0.6
L0 .7

13.1
13.2
13.3
13.4

./ . , ......).,. .
~'f~1, :~
~~-

Vili

SOMMARJO

13. J O Le asserzioni .......................... -....................................................................... 469


~erciz.i di autovalutazione .......... ................................................ .......................... ...... 470
R1spo~t~ agli esercizi di aurov-.tlutazi.one ..................................................................... 471
Eserc1z1................................................................................................................... .... 472
UPITOLO

14: ARGOMENTI AVANZATI . .............................................................. 473

Introduzione .................................................................................................. 473


Re~rezioo.are l~in~~t:/?utpuc sa sistemi UNIX e DOS .................................. 473
GL1 elcn~hi variabili di a:rgomenci .................................................................. 474
Usare gli argomemi della riga di comando .................................................... 477
1 .I
14.5 Noce sulla compilazione cl.i programmi fqrmari da vari file sorgente ............. 478
Chius~a dei pr~g~ c:pn Exit: e Acexir .................................................... 480
1!.6
Il qua116carore di npo Volatile ........................................................ ............... 481
1 .7
J:8 l Sllffissi per le costanti ~n(r e in virgola mobile ..... .................................... 4 82
1 .9 Ancora sai file .. ,............................................................................................ 482
14.10 La ges'l!ione dei segnali ................................................................................... 484
14.11 Allocaz.ione dinamica della memoria: le funzioni calloc e rea11oc ................... 4.85
.14. l~ . IJ salto iacondzi()nacq: goto ............. ............................................................. 486
Eserc1z.1 di aucpvaluraiione ................................................ .................. .. ...................... 489
Rispo~t~ agli esercizi di aurovalur;u.iqne ........................ ............................................. 489

14.1
1!2
\;.

Eserc1z1 ....................................................................................................................... 490

lA SINTASSI DEL C ............. ............... ......................................... 49 1


Sommario della sin cassi del linguaggio ....................................................................... 491
A PPENDICE A :

A. l
A.2
A.3

Grammacica lessicale ..................................................................................... 491


Grammatica della suunura della frase ........................................................... 495
Oircrcive del preprocessore ........................................................................... . 501

APPENDICE

B. l
~.2
B~
.~
8B ~
B:7

818
B.9

B.10
B.l l
B.12
B.13
B.14

B: LA LIBRERIA STANDARD ........ ........................................................ 503

Erroci <erroo1h> ............................................................................................ 503


Oefinizini comuni <srdde.f.h> ...................................................................... 503
Diagnostica <asserr.h> .................................... ............................................... 504
Gestione dei caratteri <crype.h> ............................... ................... .................. 504
Localizz.~one <loci.le.h> ....................................... ........................................ 505
~r~e:~~~~c~~srher.~m> ~_..................................................... ..................... ..... 509
) P.JV> ................. .. ...... ..................................... 51 I
Gesrione dei segnali <signalh> ...................................................................... 512
.Argomenti v.ariabili <stdarg.h> ...................................................................... 513
lnpur/Oucpur <stdio.h> .................................................................... .. ........... 514
Urilir generiche <srdlib.h> ............................................................................ 525
Gestione delle stringhe <suiog.li> .................................................................. 532
Data e ora <time.h> ...................................................................................... 536
Lim.ici dell'imp1e.mencazione .......................................................................... 539

:~:[~:.::::::::::::::::::::::::~::::::::::::::::::::::'.::::::::::::::::::::::::::::::::::::::::'.::'.:'.:::::::: ;!~

APPENDICE C: PRIORIT E ASSOCIATIVIT DEGLI OPERATORI ........... .......................

543

SOMMARIO

. ~ }iH
.\;'.:~~'
. . . . .~~ID,
,~ .... ,
"i'. .
'.Cj l;~,\>'

A PPENDICE

D: LINSIEME DEI CARATTERI ASCI I ................................................... 545'~

A PPENDICE

E: I SISTEMI NUMERICI ................................ ..................................... 547

lncrodu.zione .............................................................. .................................... 547


L'abbreviazione dci numeri binari in oaali ed esadecimali ........................... 550
La conversione dei numeri oaali ed esadecimali in binari ............................ 551
La conversione da binario, orcale o esadecimale in decimale ........................ 552
La conversione da decimale a binario, ocrale o esadecimale ........ .................. 553
E.5
I numeri binari negativi: la notazione con rnmplernenco a due ..................... 554
E.6
Esercizi di aurovaluraz.ione .......................................................................................... 555
Risposte agli esercizi di aucovalurazione ..................................................................... 556
Esercii.i ................................ .. .......... ............................. ..... .................................. ..... .. 557

E. I
E.2
E.3
E.4

INDICE ANALITICO ....................................... .. . ......... ..... ... ...............................

559

Prefazione

Benveouci nel mondo del C. Q uesco libro scaro scrirro da un padre, l:larvey M. Deitel, e
da. suo figlio, Paulj. Deicel. JI padre ha programmaco e/o insegnaco la programmazione per
38 anni, menrre il figlio h:1programmato e/o insegnar.o la programmazione per 18. Il padre
programma e insegna grazie all'esperienza maturam; il figlio, invece, programma e insegna
gazie a un'inesa.uribile riserva di energia. Il padre pwita alla chiarezza, U figlio alle presta"!li.oni. H padre cerca l'eleganza e I.a bellezza, iJ figlio vuole soprammo risultati eone.reti.
lnsieme hann0 cercaco di rcafu.zarc un libro che speriam0 possiate trovare mi.le, complero
e diverre.nce.

Lo scopo di questo libro


Il Professor Harvey M. Deird ha cenuco corsi universirari. inrrodurrivi sulla programmaz.ione pe!r 20 anni, punrando soprarruno a insegnare come sia possibile sviluppare programmi
ben scrirri e ben srrurcuraci. Mol dci suoi inscgnamen riguardano i concetti fondamentali della programmazione, con particolare ~i suU'ucilizzo efficace deile strutture d i
q>nrrollo e sulla funzionalit. Questi argomenti vengono presentati all'interno di quesro
libro esanamente nel modo in cuj il Professor Deicd li ba sempre proposti ai propri
.srudeori universirari.
t

In base aila noma esperienza, gli srudenti affronranp i temi presentaci io questi capitoli
n~llo sresso modo in cuiaffrontaoo i corsi di Pascal. G, comunque, un'importante differnza:: gli srudemi sono escre.mame.nre motivaci dal farro che sranno imparando un linguag-

gio che porranno ucilizzare immediacameme quando lascer.lDilo l'universit e a.ffromeran-

.110 il mondo del lavoro. Turro quesro aumenta notevolmente il I.oro entusiasmo nei confronci del

e, nonostante ci siil moltissimo da impatare.

U l10StEO obiettivo er.a. chiaro: offrire un testo .sul C d6L.naco ai corsi W'liversirari a
livilo inrroi:lurrivo, per quegli studenti che non bruino -ak:una esperienza nell'ambito del.la
programmazione, pur fornendo, allo sresso rempo, la ~omplerezza rcorica e pratica ricb ie
sra ai tradizionali corsi avanzati di C.

11 resro segue lo srandard ANSl C; rene(e presence d1e moire funzionalit dell'ANSI C
.nn sono implementate nell.e versioni pre-ANSI deJ C. Per avere informazioni pi derca:gliate sul linguaggio vi conviene consultare il manuale di riferimemo dd vostro sisrcma o
pn;>curarvi una copia dd documento ANSiflSO 9899: l 990, "Amecican National Scandar9 for lnformaon Sysccms-Programming Language C", clell'AmericanNationaJ Standards
1nsrure, 11 Wcsc 42od Streec, New York, New York 10036.

Xl!

PREFAZrONE

La metodologia di insegnamento
Questo libro contiene un'ampia varier cfj esempi, esercizi e progerri che prendono spunto
da moire situazioni e che offi:ono agli smdenri la possibilit di risolvere problemi reali. Il
libro prende in esame i principi dclla progena:iione dd software, insistendo sulfimponanza della chiarezza dei programmi ed evicando J'uso cfj cerminologfa complessa a favore cfj
esempi chiari e cLretti, il cui cocLce sia scaco collaudato sulle piaccaforme C pi diffuse.

l:apprendimento attraverso il codice


D libro presenta una grande quantit di esempi basaci sul cocLce. Ogni argomento viene
presencaco neU'ambico di un programma C completo e funzionante, seguito sempre da una
o pi finestre che mostrano l'oarput del p rogramma in questione. Viene quindi usato il
Llriguaggio per insegnare il Llnguaggio, e la lettura di questi programmi offre un'esperienza
molto simile alla loro eseuzione reale su di un omputer.

L:accesso al World Wide Web


Tu ero il codice presente nel lhro si m;>va .anche in lnrerner, nel booksite abbinato a quesco
libro, all'indirizzo http: I /www. apogeonline. com . education . booksite. Il nostro consiglio quello di scaricare turro il c>dice, eseguendo poi ogni singolo programma via via
che appare nd resto. Potere anche modificare iJ codice degli esempi e vedere cosa succede,
imparando cosl a programmare prograiimando. Tutto questo marcriaJe protetto da dirirci d 'aucore, quindi urilizzatelo liberamente per studiare il e, ma noo pubblicatene alcuna
parre senza l'esplicito permesso da pane degli aurori e ddla casa editrice.

Obiettivi
Ogni capirolo inizia con la presenrazione degli Obiativi. Gli srudenci possono cos} sapere
in anticipo ci che andranne ad apprendere e, alla fine della l.errura del capitolo, porranno

verificare se hanno raggiunro o meno questi obiettivi.

PREFAZIONE

Xlii

Consigli e suggerimenti

d . 1 roo-rammazione per amcare glt srudenr1 a


. .
nguar ~udlla p 0iluppo di pr~grammi. Questi consigli
Il libro offre mola sugge:iro.en~1mporcann
J
e o sv
pi
r
e
Coilaua()
tip1c(),
En()re
Buo na abitudine
. . _L.
concenrrarst sug I asperu le sez10111
.
'

cn1amare
6 miti acrraverso
,,n;r 'enza, Qb,ettivo p()rtabilit, lngegnma del software.
. "JJ"''
Ob.u:mvo
o
vengono
a punto,
messa
.

ali"

B uona abitudine

interto!!Iammare e la.chiarezza, e
hi . . .
d li cniche er la scrittura
U concerro pi imporranre per c mma a p 0
P '
no delle sezioni Buona abitudine vengono pre_s~tare e e ~il'
di programmi chiari, comprensibili e pi. facilmente ges

I.

.
ono a
cen
linguaggio
nuovo
un
volta
rinia
r la
affr .
.
se:ion i Errore ti.pico ai urano gli
Le
Tucci gli sn1d;nt1 che
_.
. .,
com me ere re rrequencemen
stu.denri a evirare di commettere I Plll comun i.

Errore tipico

o~caeng~i ps~essi ~rrori.

Collaudo e messa a punto

Quesce seiioni forniscono consig~ circa le attivit di tese e debuggrng dei programmi C, anche a livello prevenavo.

b~e

Obienivo efficienza

c~rso

nosrr~b~pdC:~ti~U:~ l'obi~civo
.

nare

li studenri come scnvere programmi

pi imporrante di qualsiasi
alla
Jn.
, vogliono normalmenre im parare a scnve.
.
ch1an e compre.nst
h ti.l.izzino poca memoria,
l
di programmauone. Gli swdenu'. p~o, d.
. h
0 esegum i.n mo o ve oce~ c e u
. di comandi e che offrano presrazioni eccelre programrru
auntma quanut
. hi d c e ven?~
cb
. offion. o suggerimenti su come migliorare le
. . effic1enui
~o ~na
e neLe esezioni
Obiettl/Jo
lenti.
prestazioni dci propri programmi.

Il codice e gli esempi


Le funzionalit del C vengono preseruare nelJ'ambiro di programmi completi e funzionanti.
Ogni programma scguiro dalle immagini degli ourpuc che vengono prodotti, cosl che gli
studenti possano assicurarsi della corrc:rcezla _d ei risultati. I programmi presencati vanno da
poche linee di codke a esempi compo~ti da varie centinaia di righe. Gli studenti doVIebWeb http: \\ www. apogeonl1ne. com/ education I
bero scaricare cucco il codke dal
booksi te, eseguendo poi ogni progtnma via via che questo viene preseararo all'incemo
del resto.

~i.co

Obiettivo ponabilit

Al
un'applicazione e, questa
plementando
grammaron. pensano ehe,
di
cl' mente porta)I ile .su rurrn" ,,,.... p1'attfiorme' sforcunacamente, oon
1 pro
cun
b'L' , .: ... 0 gU sruden ti t scrivere: co ce
.
sta 11nme 1ara
di
do
1
sempre cost Le se-l.oni Obiettivo port4 .t..it:a a1u:3. .
tm:'

realmente portabile, fornendo inoltre i nfo~aztom su come


raggiungere quesco elevato livelJo di portabilit.

C .. ,

sia tn gra

Ingegneria del software

Figure e immagini
11 libro offre un'ampia variet di grafcj, immagini e outpuc di programmi. Nelle sezioni
dedicare alle srrua.ure di contrqllo_, per ciempio, appaiono vari diagrammi di flusso molto
ucili. [N()ta: l diagrammi di Busso non vengono presenrati come uno srrumenro di sviluppo, ma ricorriamo a- una breve presenra:iione basara su questi diagrammi per specificare le
singole: operazioni di ogni struttura di conrrolJo C.]

Llnguaggt~

efficacenell'ambiro della progerrazione del sofrware, e


.
.
d 0 in esame gli asper[i architetturali e
molto
Il C un
di sisremi software, specialmenre
le sezioni Ingegneria .del sofrwarulJ.ae pr~n o~
.
..
rea izzaz 1one
ali eh 1. flwscono s
e ~ su vasta scala Molce di quesre informazioni saranno unli agli
progerru
caso d1. s1.stem1
nel
studenri nei corsi pi avanzaci, olcre che nel mondo dd lavoro.

XJV

PREFAZIONE

Esercizi di autovalutazione

Capitolo 4 - I l controUo del programma: raffina le nozioni di programmazione smmuram

gr

.
d
~ Jibro propone moJci esercizi corredati di. risposte cos che
J sru ~ntJ po~~o prepararsi alle esercicaz.ioni vere e proprie. Gli sruden:ri d~ bb
vre ero essere incoraggiati a svolgere
turti questi esercizi di aucovalutazione.

.e .inrroduce altre srrurcwe di controllo; esamina in dettaglio l'icerazione e paragona i cidi


_conrrollaci da un contatore con quelli conrrollati da tm valore seminclla. La Struttura for
pres'enraca come uno strumento adatto a implementare i cicli conrroUati da un concarore.
Sono inrrodocre anche la scrumua di sele'Lione swi tch e quella di irerazione do /while. Il

Esercizi

spicola termina con una discussione sugli operatori. logici.

eh
. .
Ogni capirolo si conclude coo uo insieme di eserciz1 d.1
e permettono agli
vano tipo,
1 L . .
insegnanti di dart
..
ai:e e propne ez1onJ alle esigenze pa.rricolari di ogru' classe Cli
, a
esercm
.
. . ., .
verifica no I apprendimenro dei concett: d .
denri di scrivere singole istr . . . . . i el e1 re~mu:i1 ~JU imponanci, chiedono agli sruuz1oru> ptcco e porzioni di funzio . fun . .
z1oni e programmi
n1,
.
. .
.
ali

compled fino ad
arnvare a cos.i:ru21one di rnten progeru.

Indice analitico
al'
di
Alla Boe del Llbco possibile trov-ar
legge questo libro per la prima ~oJ~ ~~:t"'procgre~ttco. cchompl leco, molto ur~e s~a a chi
aron e o usa.no come nFenmento.

Panoramica sul libro


.
Capitolo i - Nozioni sulla elaborazione elettronica s .
. p1:ga cosa sono J compurer, come
funzionano e in che modo possono
essere programmaa. Questo capicolo introduce la
.
proo-rarnrru.zi
rivoiuzione n::e~~:;:u:~~:;';~t perch qu:sro insi~me di tecniche abbia favorito una
p~og~.rru:1 1 : TI capscolo offre una breve storia dello
sviluppo dei lingu di
.
cchin . r
programmazione, dai linguaggi
aggi
. a, ~J inguaggs assembly,
ai linguaggi di alco livello. ~ dis~ussa anche l'o . . d 1 rma
Il capicolo indude uo'inrrodl17.ione alI' b' agd1~e e mgu~o d1 programmazione C.
am ienre 1 programmazione del C.
fc .
.- .
Capitolo 2 - Introduzione alla P rogrammaz1one
.
d
m orrusce
un Lntro UZJOne Stnterica ai
.
programmi di SCrrtura. C e offie
aritmetiche del C Dopo ave . d'-:1 ((aeramento. derragltaro delle operazioni decisionali e
. r sltu . taro questo cap1mlo, lo scudcnce avr imparato a scrivere
rogrammi se 1" .
P
mp 1c1 ma comp ea.

::-:::ttu.rau:

.
. ,
.
Capitolo 3 - Lo sviluppo di pro
e pro~a?tlrnence_il capiro.lo pi impq.rtnte del testo, specialtnerrce
nozione di algoritmi (proced:e) p: 1 ? I te. srud<len.re di rnfo.rmaaca. Esso introduce la_
d il
r anso uz1one e1 problemi spiega 1"
unponam;a e .a
.'
.
d .
programmazione s1trurturara et I
1
abbt pro . ,llZto~ ~-pr~~tm-"! comprensibiJi, che siano
t ollaudabili e modifkaci e
~nz~onare c~rrettame.nte sin dal
primo tentcivd. Lotroduce anche 1::~~:;:r~ ~~~t
tro o on amenral1 della programma.
zione Strutrw:ata . ' l
(while). U capi;o%o~pj::a~ttmpr~ d1seque~za, seleud'one (ife if/else) e di iterazione
.
gramm.auone rop- own a raffinarne
t>

rm success1v1, una
.
ii
tecruca unporrance per produrre in.
mo o c:orrerro _programmi srrurrurari. Esso presenta u:n
popolare strumento di . - al1
. I
aiuto a progettazione dei programm
1, ov:ero~~ O pseudocodice
Strutturato. f metodi e gli approcci usaci nd C . j
aptto o 3 sooo applicab1l1 alla programma.
.
zione struttttrata in o . lin
capirolo aiuta lo scud~ce a ~~19 di pr.ogrammaz.ion~ n~~ s~lo a quella in C. Questo
programmazione che lo
prepareranno ad affrontare gli . ppa:~ ~elle buone ab1_rudin1
programmazione p1u consisten ti del resro dd
eserC1Z1
libro.

eh:

1/

.?1

---

xv

PaEEAZIONE

::e

--

Capitolo 5 - Le fum.io.ni: trarra della progettazione e co.scruzione dci moduli del programma. Il linguaggio include funzioni d i libreria sraodard., funzioni dclnice dal prograrnmarore, la ricorsione e la possibilit di effeccuare delle hiamace per valore. Le tecniche presentare sono essenziali per la produzione e la comprensione di programmi strutmrar.i,
specialmente di queUi pi.1 grandi, e del software elle i progmmmarori di sistemi e di
applieazioni svilupperanno pi probabilmente nelle app1icazioni del mondo reale. La srrategii\ "dividi e conquisr' presentata come un mezzo efficace per risolvere i problemi pi
mplessi; le fi.111?..ioni aiutano il programmatore a suddivide.re i programmi complessi in
compnenci pl.1 semplici d1e inceragiscono rra di.1Qru, Agli studenti piae avere a che fare
con i numeri tasuali e le simulazioni e apprez.zan.o la rrag;iz!one del gioco di dadi craps che
fu un uso eleganre d elle munure di conrrollo. il eap:irnlo offre una soHda inrroduzione alla
.r:ieorsione e include una tabella che riassume i 31 sropi ed esercizi s ulla ricorsione
distribuici nel resro del libro. Alcuni libri affrontano la ricorsione solo verso la loro fme,
.ma noi pensiamo che sia meglio trattare l'argomento in modo graduale Ilei corso di rutto il
lib.ro. I.:esceso gruppo di 39 esercizi p resenraco alla fine del Capitolo include vari proble.mi
clissici sulla ricorsione come le Torre d i Hanoi.

Capitolo 6 - L venoci: discure la srrurrurazione dei dari in vettor, cio gruppi di d ati
corrdaci dello stesso tipo. U capitolo presenra numerosi esempi sia sw verrori con un solo
indice che su quelli con indice doppio. .Limportanza della smmurazione dei dati ampramenre riconosciura al pari dell'utilizzo delle srmrrur~ di controllo nello sviluppo di programmi srrurruraci. Alcuni esempi del capimlo appr-ofondiscono varie tipiche elaborazioni
dei vettori, la scampa degli isrogrammi, la classificizlone dei dari, il passaggio dei verrori
alle funz ioni e UJn troduzione all'analisi dei sondaggi di opinione. Un pumo cararrerisrico
di questo capitolo un'accurata presentazione della ricerca binaria, un enorme miglioramemo di quella lineare. Gli esercizi alla fine del capitolo l.ocludono una vasca selezione di
probleini inreressanri e sti molanri , Questi includonQ t~niche di ordina.memo migliorare,
la progercaiione di un sis.cema di prenotaz.ion per linee aeree, W'l'incroduzione al concerto
d-efla Turtle Graphlc (resa famosa dal linguaggio LOGO) 'e i problemi del giro dd cavallo e
dlle otto regine che !rmoducono la nozione d i prog.rani.miliorle euristica, molto urilizzata
'
'
nel<::ampo deU'inrelligenza artificiale.

Capitlo 7 ~ T puntatori: prcsenra una delle caratteri_stich pi parenti del linguaggio C. U


capirolo fornisce spiegazioni dertagHace sugli operatori dej puncacori, sulla chiamata per
rifetimento, sulle espressioni con puntatori, sull'arirmerica d ei pumarori, sulla relazione
u:a. puntatori e vettori, sui venori d i puntarori e sui punracori a funzioni. GH esercizi del
capitolo includono una simulazione della classica gara tra.. la rarraruga e la lepre e vari
algoritmi per il mescolamento e la distribuzione delle cane. inclusa anche una speciale
s~one in.ncolara "Cosrruice il vostro computer", che spiega la programmazione in linguaggio macchina e prosegue con un progerto che ompreide-Ja progertazione e l'implemencazone di un simulatore che permerta al lecrore di sciivere e far funzionare i p rogrammi
sviluppati in linguaggio macchina. Questa caratteristica unica del libro sar ucile soprarruc-

XVI

PREFAZI01.~R

al I.errore che vorr ca~e i.l reale fuazio namc:nro dei compu
ter._Ai nostri srud~nci piace
questo progetto e spesso implementano sostanziali
mi<>li,oramenfr molri di questi sono
pJop0sci alJ'inrnrno degli eserci7.i. Nel Capitolo 12,
~'alua scri~ne spedale ~ider il
lerror; attraverso la_ cosrr~z.ione d_i un ompilamre;
il linguaggio macchina prodoa:o dal
compilator_e sar poi esegruto con il sirnularor di lingua
ggio macchina prodocco nel Capi~~

XVII

1:0

Capitolo g - l caratteri e le stringhe: mma dei prin.cipj


fondamenrali dell'elaborazione dei
da~i non n_umerid..n capitolo include una panoramica comp
leta delle funziohi per l'elabo r-az1one dei canlttcri e delle scrifilghe disponibili neUa libreri
a del C. Le tecnide discusse in
~uesro contesto sono ampiamnre utilizzate nello
sviluppo dj woi:d processor, software di
u;np~~~on~ e applicazin i per l'daboriiz.one del tesco.
Allo scudence piaceranno gli serC12J. sw luner1ck, sul~a gen~razione ~suale di
poesie, sulla o.nversione dall'inglese al pig
Launo, s~a. generazione d1 parole d1 sette lettere che
equivalgono a un numero telefonico
dato, sull allineamcnro dd test, sulla protez.ione dgLi
assegni, sulla scrirtura della cifra di
un assegno in lettere, sulla generazione del Codice Morse
, sulle co1wersioni metriche e
sulle lettere di sollecito. L'ultimo esercizio invirn lo stude
nte acl utilizzare un dizionacio
compute~aro per creare un generatore di
cruciverba!
Capitolo .9 - U, fo.rmattaz.ione ~ell'Input/Output:
presenta rurce le potenti capaci~ di
forma:n:az,1one di pnruf e scanf. D1scureremo ddle capac
it di formattaz.ione del I' oucpur ru
ftrintf, come l'<!.llorondamenm dci valori in virgola
mobile a un dato numero cli cifre
decimali, l'incolonnamemo dei numeri, l'allineamen
to a destra e a sinistra, l'inser.memo
di in.fi>rnurz,io~i letterali, la forzarura.del seg110 positivo,
la stampa degli zeri iniziili, l'uso
ddla .num.ra210ll esponenziale, !'a.So dei numeri oro
ed esadecimali e il controllo delle
dn~nsion~ di campo e dclla precisione. Dscureremo
tutte le scqunze di es~pe di princf
per 11 movtmeru:o del cursare, per la $rampa dei cararr
eri speciali e per la produzione di un
allarme acuscico. Esamineremo curce le possibilit di
formacta7.one dcll'inpm: di scanf incluso l'in?~t di spe~ifci tipi di dari e come ignorare
dei catatceri spedfci presenti sullo
scream. ~1 1:Pu:. D1s~uterern~ ru:r~ le :~pecifcbe di
conversione dj scanf per leggere i
n~e l.eamah, ottali, esdecJrnalt, in Vtrgola mobile,
i caratteri ed i valori di una srrin:ga.
D1scureremo della scansione dell' input in modo che
corrisponda (o meno) ai caratteri
udusi in un gruppo d:i stansione. Gli esercizi del capito
lo verificano virtualmenre rune le
eapacir di inpur/ourpur foananato.

C:apitoio 10 - ~ .stru~~' le ~on.i, le elaborazione de.i


bit: e Penumernzione: prcsenca
diverse caratterist1ch~ 1mporrana. Le srrucrure sono
come i record del Pascal e di alrri
linguaggi: esse raggruppano dati di ti.pi diversi. Le scrutt
ure sono usace rrcl Capi.colo 11 per
formare file composti da record di infonnazioru. Nel
Capitolo J 2 le srrurrure sono Wate
in~ieme ~ p~tacoci e ~H'allocazione dinamica d~lla memo
ria, per formare strutture dinamiche ru daa come le lisce concarenace, le code, Le pile
e gli alberi . Le union i consentno
~i utliiizare un'area di memoria per diversi cipi di daro
in tempi differenti; que.sra condiviSJ(>ne
ridurre. la ~uan~t di memoria principale o s~c::ndacia
richiesra da un prgramlllll'. Le. enumerazioru forlllScono un
modo conveniente per definire delle costanci simbolic:J:e u.rili; ci ai':11'4 a rendere i programmi pi amoesplica:r
ivi. te porenci capacit di manipola2~one dd b1c ~el C Consentono ai programmacori di
scrivere programmi thc USaD(1> Je
cap~c~t: a basso livilo dell'harclwate. Ci aiuca i progr
ammi ad elaborate ming he di bic,
ad .lmposcare a on o a off i singoli bit e ad immaga?:l.n
'are le informaz,ioui in modo pi
l':Ornparro. Tali capacit, spesso disponibili solo ne.i
linguaggi assembly di basso livello,

eu

sone parcicolarmence appr~te d~ programmar~~ ne.li.a


scrirrura ~i sofcware per i si.st_e~i
. elativi e per la gestione delle rea. Una caratte.nst1ca
cli questo captrolo la nuova vers10ope ad alra efficienza della
simulazione del me.scoIacore e dism'bmore di
n.
'
~ccellente opportunit per l'insegnante per porre L'nccento sulla qualit carre. '<-uesra e una
degli algorrrmi.
Ca:p1colo l1 - L'eJ.aborazione dei file: disc~re d~e. ~ecnic
he ~~are per .elaborare i file ~
st ad accesso se~uenz.ialc e casual e. Il
captto
lo
1111z1a
con
un 1D.rroduz1one alJa gerarchi.a
te
dei .dati: dai bic ai'-i byre, ai campi, ai recor d, aJ"f1le. S

' presenta~
ucccsswam
emc e.
una
semplice panoramica sui. file e sugli scream del C. I file
ad acces~o seql).e!1z1ale s~no discus:...
usando una serie dj ere programmi che mostrano
come aprue e h1udere 1 file, come
SJ
immagawinare i dari in modo sequenziale in un file e
.I .
come legge~~ i~ mo do sequeDZJa
e '.
dari da un file. Si discnre dei file ad ace.esso casuale usand
o una serie di quarrro pr.ogrammt
che mostrano come creare un file ad accesso ca5uale,
come leggere e se.rivere i dati con
acc~o q1.5uaJe, e c9me lcgge.i:e J daci in modo sequenziale
cl.a ~m file ad ~c~esso casual~. _li
quarto programma combina molce ce~ic he. ~ accesso.
ai .file, ~1a seque~7.1~ che ~asual.1, 1~
un programma completo per Felaboraz1one ~1 tr3:saz1on!.
Gli s~udenu ~ei nosa;i semm aa
indllscriali ci hanno detto che dopo aver studiato _il mater
iale suU elaboraz.1one dei file, sono
mci capaci di produrre programmi corposi per l'~abo
razione dati che sono stati immedi:i-iamente utili all'imerno delle loro aziende.
Capitolo 12 - Le strutt ure di dati: discute le ;ecnic
he usate P,er ~reare del!e scru~rure
dinamiche di dari. U capitolo inizia di.scurendo dc.Ile
strutture ncors1ve e deU aJ1ocaz.1o~e
din11IDica deUa memoria e pi:osegue con um discussione
su come_ creru:e e conserva:e van~
struuure dinamiche di dati come le lisce concareriace,
le code (o Ime di arcesa), le pile e gli
alberi. Per ogni tipo di struttura di dati presentiamo dei.
prgrammi funzion.anti e com~leti
e mosrciamo degli esempi di ourpuc. li Capirolo 12 c?nse
nce .aJl? s:'~enre di f.ad~on~ggiare
eff:ttivamence i punrarori. li capitolo include molu
esempi di ut1lnzo dell m,dirC'Z.lone e
della doppia indirei.ione (un concetto parcicolarrnenre
difficile). Uno dei problemi ~ega~
alJ'mifu.zo dei pumatori che gli studenti hanno difficolr a
visual iz~c le _srnmur~ ~ d:ia
e i1 modo in cw i loro nodi sone colJegaci, cos abbia
mo incluso delle illusrr:moru che
mostr:ll1> i collegamemi e la sequenza in cui essi sono
~reat:i. eesernpio d~'al~ero b~ari?
una stupenda pi~rra miliare per lo_scu~o d~i puncatn
e de.I.le ~rr~n~e ~che~ d~t1.
~qwo esempio crea un al~ero .bmano,' s1 pr~ccup.a
dell ~~mmaz_ione ~1 d~pl1ca~ e
mr.r-0duce l'attravcrsarnenco n comvo dell albero ID ordm
e anacrpaco, 1.0 ordine e m ordine
pOStjcipaco. Gli scudenri rirengono realmente esaustivo
lo sturuo e Fimplenient~ii.one . di
que5ro esempio e apprezzano in modo particolare il veder
e che l'~crrav~rsamemo ID ordine
dell' aJbero stampa i valori dei nudl nll'ordine stabil
ito. li tap1colo 11iclude un gruppo
consistente di esercizi. Rilevance la sezione specia
le "Cosrruite
Gli. eserci7.i ;iccompagnano lo studente nello sviluppo di un progril vosuo oompilacor:".
amma ~i con~ersiane
<4Jl;i notazione infissa a quella polacca i1wersa e di un progr
amma di valutazione di espressioni in norazione polacca inversa. Abbiamo qwndi modif
icatq l'algoritmo di v~u~zio.ne
di espressioni in notazione polacca inversa_ i~ m~do da poteI
g~ner~re un codice lll linguaggio macchina. 11 compilatore immagazzinCi 11 s.ud~
~no c~dic_e 1~ un f~ (usand~ Le
teenich.e del capitolo 11). Gli studenti ~ono qw.nd
1 il co~ce 1n ~ngua~o macch_ina
prodotto dai loro compilatori suJ simulatore di sofcware
cosrru1co negli esercm del Capi colo 71
Capit olo 13 - 11 preprocessore: offre una ruscussion
e denagLla:a ~elle direa ive del
pteprocssore. TI e,ipicolo inqud e informazionj pi comp
iere sulla duert1va #inc lude che

XVIII
I

PREFAZIONE

I
induce l'inclusione d.i una copia di un file specificato in sosciruzione della direrriva, prima
che il 6le sia compilarn, e sulla direttiva #defil"le che definisce deUe cosrant! simboliche e
delle macro. Il capitolo spiega la c9mp1azione condiziona~a per conscnd.re aJ progran1matore di concrollare l'esecU7.ione delle dirercive del preprocessore e la compilazione dcl codice del pr0gramma. Si parla dell'operacore # che converreil suo operando io unasrringa e
dell'operatore ## che concarena due token. Sono presentate le cinque coscanri simboliche
LLINE_. _FILE_. _DATE_, _TIME_ e_STDC_J. AJla fine rracma la macro
assert del fle d.i incesrazione assert. h. Ac;sert preziosa nel collaudo, la messa a puDto,
la verif:ca e la convalida del programma.
Capitolo 14 - Argomenti avanzati: prescnca vari argomenti avanzaci che di solito non sono
.affrontaci nei <:orsi introduttivi. La sezione 14.2 mosrra come redireiionare l'input di un
programma in modo che provenga da un file, come redirezionare I'ourpuc i.o .modo che sia
immagaz.z.inaco in un file, come redirezionare l'oucpuc di un programmain modo che vada
a costitu ire l'iopm di un alrro programma (piping) e come accodare l'ourput di un programma ad un file gi esistente. La sezione 14.3 discute di come sviluppa.re funi.ioni che
usano elenchi va.ria.bili di ai:gomenri. La .sezione 14.4 tnostra in che modo gli irgomend
della riga di comando possano essere passati alla funzione main e come urilizzali all'interno
di w1 programma. La sezione 14.5 craaa della compilazione di programmi i cui componenti possono es5ere discribuici in vari file. la sc:z.ione 14.6 discute della registrazione delle
funzioni con acexit io modo che possano essere eseguite al teanine dell'~euziooe di un
programma e come terminare l'esecuzione di un programma con la funzione. exir. La
se~i~ne 14.7 discute dci qualifcaroci di tip0 consce vola:cile. La sezione 14..8 moma come
speclfiare il tipo di tU1a costante 11l1Illerica, usando dei suffissi per gli inreri e i numeri in
virgola mobile. L;i sezione L4.9 crarca dei file binaci dell'uso dei file remporaoei. La
sezione 14.10 mostra come usare la libreria per Ja gestione dei segnali per inrercerrare degli
eventi inamsi. La sezione 14.11 discute della creazione e dell'uso dei veccori dinamici con
le funzioni calloc e realloc.
Moire Appe:Cidit;i forniscono un -valldo materiak di riferimento. In parricolare, ndrAppen.dice A fomiam~ la sinrassi del Lin.gu.aggi0 C; nell'Appendice B un cle.oco commeJltai:o di turce le-funzioni della libreria standard dcl C; nell'Appendice Cuna cabeUa compleca
della priorit e dell'associarivit degli operacori; ndl'Appendice D l'insieme dei codici dei
cararrc ASCII e. nell'Appendice E, una discussione sui sistemi numerici binari, ottali,
decimali ed esadecimali. CAppeod.ice J3 scara escratta dal documento deU'ANSI standard
con l'esplicito permesso scritto dell'American Narional Srandards Insrirure; la suddccra
appendice fornisce un riferimenro-vfili4o e dertagliam per l'esercitazione del programmatore C. tAppendit E una spiegazione compleca dei sistemi numerici, che include molti
esercizi di auro-valutazione e le relarive risposte.
Vi preghiamo di inviarci i vostri coilllilenti, suggerimenti, critiche e correzioni, al f ne
di migliorare ulteriormente questo libro. e indirizzo a cui scriverci il segueme:
deitel~deitel.com

Bene, pet ota rutto. Vi rinnovi;imo il benvenuto nel mondo del C e dcllo sviluppo
delle applicazioni clel futuro. Buona fortuna e buon lavoro!
Harvcy M. Deitel - Paul

J. Dcirel

CAPITOLO

Nozioni sulla elaboraz ione


elettron ica
Obiettivi
Comprendere le nozioni elementruirelative ai computer.
Familiarizzare con i diversi tipi di linguaggi di programmazione.
Conoscere la sroria del.linguaggio di programmazione C.
Venire a conoscenza.della libreria standard delC.
ComprendereJ'ambienredisviluppo dei programmi C.

1.1

Apprezzare le ragioni per le quali appropriato apprendere il C in un primo corso di


program.maz.ionc.
Apprezzare le ragioni pe.r le guaii il C fornisce lehasi fondamentafj per i succ:essivi scudi
sulla p.r<ignim mazione, lii generale, e sul C++ .in particolare.

Introduzione

Benvenuti n.d mondo del C! Abbiamo lavorato dmamente per creare quella che, speriamo
sinceramente, sar per voi una esperienza inform::rdva_ e divertente. Il e un linguaggio
difficile che nMmalmeme insegnato soltanto ai pr9gram.matori esper, perci questo
libro unko ua quelli sul C:

adacco a chi ha u11a conoscenza tecnica, ma ha poea o nessuna esperienza di programmazi0ne.


adatto aiprogrammacor esperti che desidera.no una rran:u.ione rigorosa e approfondita
del linguaggio.
Come pu un libro piacere a entrambi i gruppi? La cisposca che il libro cofucizza il
raggiungimento della chiarezza del programma, actraverso le provare tecniche di "programmazione srrurruraca". QueUi che non sono ancora dei programmacori impareranno sin
dal.l'inizio il modo "giusco". Abbiamo ce:ncaco d i scrivere in un modo chiaro e diretto. Il
libro abbondanremente illuscrato. Cosa p robabilmente anche pi imponame, il libro
presenta U!l enorme numero d.i programmi
nm7..i:nanci e mosrra gli output (risultaci)
prodotci, quando quesci programmi sono esegui.ti su un computer.

l primi quattro capitoli introducono i principi della elaborazione elemooica, la programmazione dei computer e il linguaggio C. Le discussioni sono corredare da una incroduz.ione alla pm~rarnmazione dei c0mputer, usando fapproccio srruccurato. I prindpian

CAPITOLO l

che hnno st;guiti i no:m:i <;mj ci haum:> a_ssicumo eh.e il materiale di questi c:apitoli
:fumjs_e una silid;i b_a.se per l'approfo-i:+!imerrro del C svilupp.ato nei Capiqll dal 5 al 14..
Di solito, l prog1:ammatri esp~rci leggeratu10 vclCenJf'.ne i primi quattrc:i cmpicoli e scoprii::ann0 in seguiti'.> che il e tnttCato nci Capitoli dl 5 al l'4 fil rilo.d.l r~goroso e~ a.!Je
stesso remp, in:.rSsarrce. &si apprez.?..eranno in modb parri~.l.3.r~ i cipir6li avanzati, con
la 101:0 ttatr-.izio ne dercagliata dei . puntateri, delle striflghe; dei. fil.e e delle s.rruttDX:e di dati.
.Molri pi:ogra.ril.rti:tori speru ci h:an:uo riferito Il loro a.pp:rez.zaniemo i;er la nqstra
di:scu-&sione. sulla progra.tll.Iili4ione stturrurarn. Per quanto ave~cr-0~.togratlJ.Ula.t;o sp~s in
un linguaggi@ strunuraro come il Pa.Sc.I, non erano ili gradg di sciivre il miglior mdice
possibile (?rch non avevano .mai conosciuto in modo formale la programmat.ione srrutturara. Ora, d9p9 a:vr .imparam il C da quesrq libro, hanno la possibilka di mLgliofare il
p~opriq stile d.l pr.gr.ammazio_
ne. Per oli, che siate dei prinjpianti e;> dei pr9grammaT<,ffi
esperti, in qu~o libro ci serio .niolre q:se cl1e potran.IlQ inf9nu:arvi, diverciwi e sti:milarv:i.
,Molti hanno familia:rir con le cose interflSsanti che i compurer sono in grado di fare.
In q.Uesto ors_Q, imparerete a: Goma.nda.rn i ompur.e:c P,erch !facciano quelle cose. il
so_frtP,41e (Q'vveJ:Q~~a, le istrn,7. tOni eh~ vgl stiv~re rei: qrdinare al C.Omp.uter dJ ~seguJ re delle
~eo.:i e ptend~re ddle deci$-ioni) ~be GoQtr{')IJa i o;\U_p.l.[cer. (dettispess_p, hartl;ti.1,4r~) . e il C'
oggigiomo urro dei.:-lingua_ggi dJ f?Ie&faill.maz.in,e pi pop9la.ci. Qu,es-i;o testo fo.rp.istte un.a
i.iirioduzione alla _progmtnazioe dell'ANSI C, la .versione sfand.ard.iizata. nel 198.9 Ji,egll
StatiUhici dall'lstituto N'azionale Americano per gli Standard (AN.SI). e-, nl re.Sto deLriion~~ claJJfO.rganizzazi_one [ncemazionale per gli St~dard (ISO) .

Emilino dei computer sca crescendo in q_urud rutti i cam_pl delle arrivic W.n;til. In
un'.crn:,di. cosri cosfamememe in cre5Cita, quelli della elaborafilone lettionicasono. dimnuici verrlgin osamG11te, a ca~sa degli impress.fonanri sviluppi deUa cecnologia hardware e
sqF.twa:rG. Qu~i c-Q:mp.u~ el:!, 5~0 25 anni fa, po-i:evll.!10 riemi;>ire grandi stanze e costavano
ntiUol di dQllar4 Qggi pq~.On() ..essere pi;odott su lamine qi silici<:.> (hip) pi pl~le Q.i
Un'unghia, eh~ Gpsrape.fors'e.. pochi doll;ui Itonicamen~e, il siUci.o uno dei mare.ciali pi
ahB.ortdand ~uH teri:-at un i..ngtedi~~.nte dcl.la. s~bbi_a c.rtH1ne. b :rec-nol9gia dl ch.ie j.i
silicici ha -res0 l'dab0:razion'e demonica cosl econo.miGi. cli~. 1P rutto il Jttndo, sorr9 iJl Liso
cenci~aia di milioni di, com.pucer general ~purpse (per stopi generjci), .a.itttando la gente
negli affari, ndl'indusrria, nel goveino e nelie loro virn personali, che potrebbero facilmenre .ra_M9ppiars.:i io una ;manciac.a c4_
anni.

PuO'..il Q esse.te ..illiegnam in 1Jil pmno <::O.tS0 di programmaiionc~ ovve.r.sia adart;o al.
pubblGo; a cui si riv.olge questo libro? Noi c1.:ediamo di sl. Qwilne arino fa. :?])oifuho
accertato questa sfida, q_ua.ndo il lingaggi0 affermaco nei primi corsi di informarica era il
P,ascal. ~biamo se.ritto C Boli! To Pr_ogram~ k prima: edizine d i que.to esco, e 0eminaia
li up.iyr.si~~ in ;tuq-q. iJ m.onc;lo lo haf.1.no LJtiliZ?<aro. [ cQr.si b<!-:saci ~u quel libro hatu;l-p
d.i:mqs'tr-are di esser~ lC::af"i tanto qu.;tn,ta i, lo.re predeces59ci ba~ari suLPas.oal. N!!>.n $pno
smre sse~are 'cl:ifferenze: significmiv~ eccettO d1i.gli l!l'Ud~ti ~<;i.no m<:gli~ ~'ociyari, perch S'ilino rle .nei 10.ro fusi di livello superiore e nelle proJJ.tie aa.rrie.re;. use.ranno. con
maggior probabil i.e~ iJ C die non il Pascal. m i studenti Ghe appiendon il C sann anhe
ehe sarannomegHo preparaci ad apprendere velocemente-il C++.Il C+.+ una sevrascruuura
dl. 'G, ci'VOlt<} ai prGgr.arn.Qlatqri che vogUono s~vc;re pr<;>grammi q_ri~rati agLi oggerri.
"Oil"e~O quaJ~QSci Jn pi.t sul C+t neU~ S.ezfon~ l.1 4,
1

N~NISUilA ELABOR,AZJONE ELE:ITRON.LCt\

!fn funomeno imeressame, che ~i $J:a: veritc_ando .nel mrcaco dei linguaggi di programmaz.iq_.ne, t che molti dei fornitoci prineipali, piuttli)Sto che offrire .~~ prodorti s,e pa.raci,

b ve-nd.n: semplicemente. un CYC++, eo.qibinate. Ci d. al)..'uf:.nc(!, se lo desi.de(a, , la


posiibill~'&. ~mitn.rare a prqgta)1i1.n.;i.re in Ce di n:iigrare 15radualme.n~e al C++, quando .lo
.ii teu op.poi;:i:u.Qp,
S~.J;e" 4!mque per intraprender un p.erQrso i.ntel'~S!lftre e, s~riamo~ ~munerac:ivo.
proi;:eder~~. se :v.orrece;c::omuuicit'e tron noi, inviateci una email su Tritemer

"M:ai:l rifa:ti' cbe

>allhdi'rim'o d.eitel~(le.i.tel . com. F:remo rutro i l possibile per rispondrv.i vd0cememe.


Buona fO.l'run.a!

l.2

Che cosa un computer?

tJ'.n (fPPJJu'tgr un d.isp0,si~ivq in ,gradQ di ~egw.re. dei ca.leali e di p-repdere dcl) decisiQn.i,
logj;~.Q.~, jJ cuct0 a una veloeit~ superiote cl.i .milioni e a nch~ .nii.liai:-di d..i -voke a quella degli
~~ti umani. Oggi per ese:oipi:o, ril.olti persona! computer possono eseguire decine di
:mili0'fi'.i ili ~rd d.izion:i per sec.nd.6. Una persona che operi a una calcolarrice- da tav:olo
;p&tEebbe. av.er Disogho di deGenni 1 per COIDj>le-tare lo Stesso llWttero di ~q:>lj cil.e un
p~onal computer pu e.seguire in un secqnd.o. (Punto li illlessione: ~ome potres.te sap~re
'S,'e.:G ,pers~maJ1a.sommato correra,mente..i numeci? Com pocr~'t~.sapre se il oropure'r ha
s<:>ftllillir/ ~Q.cr~tQliileme i nurner.Ln . [ superconputer pi~1 vdoci oggi possono ~guire ceu~tta:U. di rnilia1:di di addiziori'i pi' seCt'.fodo: aJJ'in<;:i.r<::a quanto i alcoli che nrinaia di
llllgliaia :i p~due -pottebbero eseguire in un anno! E nei lbraror1 di ricera stanno gi
filn'iionanlo computer i n grado l.i segufre migliaiadi miliardi di, iscruzioui per secondo.

:r

'CQJUpute.x ~labo.ran.o i dati serto il co.ilrrollo di i.risiemi tli ism.izion.i c.h.ia:mati


pfefl!l!,.mtn.'iper'coiftpz;ter. Tali programmi guidano il cc>mpurer per mezzo di insiemi ordinaci dkai'i.on1. specific:;ati da persone. chiamare prof!t11hrhatiJ1i di computer..
I va.ci disposici:'ti che t:P.mp,_ongt>no. un sisc~tn di cpmpurer (m'e la rastiers., lo sdierJn~, i.~~. lameii;loria, e l'uniT di da.b.e r_
azione)-sono chiamaci co-mplssiyanience.hardware.
1 Ift~i che p0.$Sono ~sete ~e-gu.i.ti su ll'.ll C.Om.puter s.6ne. ch.ia.n'lati >'oftware. Il costo
n;ll'Jia.fdware diminuite >T&riginosamn-te negli ukimi anni, al punto che il personal
l>o.fu~ucer diventato un oggerro di uso comune. Sforrunata.meme, i cosci di ~ilupp<;> del
skw<,U;e.sono andati aurmmcando costan~em:e .mah ma.np che i pr~grarn.maroti hanno
svil~gpat([l iip,plii_qni sempr.e' pi potenti e omplesse, SltIIZ:1. peraltro. esser:~ capaci d i
Qctea.ere un .II)..glioramento orrispo.nd!!nre .nella tecnok~gia di sviluppo del softww. In
SJ,~t<:l libro, iinparerer metodi di Sviluppo cl,el sl)frw.are the ne ciduc;on0 sesr.anz,ialme.nte
i'*1S:d e ac~lerano iJ processo di SYiluppo d:i applicazioni softwar:e porn e di alta qualit.
.Q._l!.lesti merodj ..i.nclodono -la priJgratnrtJ.azio.ne StrUftt.f,rata, la pro.grarn.mazione top4!J.wnj n!f. r.affinamenfi suGcessivi; la progr:ammttzione modulzzre.

1.3' L'organizzazione del computer


fu'dtpe,nden:cem.!5nt dalle diffeteil.ri ;appal'eiize foi~he, ogni rompueer pu e.sser.e virtualm~i:e (;nepito .come s.ttddivi.so in sei unit. logiche o seZioni. Qusre sono:
1.

CFnit di irtp1J.t (ingresso t/i dati). Qu~ra la sezi.Qne ~'cev:enre" d~ ~ompu.cer. Es.~a c:tiene
in~r~oni (dari e.progi:a.mmi per il c0mputeJ) da y.r.i t/ispositivi di i'!:ipu.te. mene .queste
Jofomiai.i.on~ a dispqsi2iane delle altre unit, in modo che possano essere el.abrare. La

WlfOLO l

maggior pane delle infoanazion.i o~gigiomo '.mmessa nei computer arrravcrso una
tasriera simile a quella di una ma:ccbina per scnvere.
2. Unit di output (uscita di doti). Quesra la sezione di "spc~io~e" d~I co.m~ute~..~~~
tende l'informa2ione che stara_el;i.borata dal computer e lauw1aa diversi dtspo~i~tn a:t
Offtpiit. lll modo da render.la disponi.bile per r utilit.'ZO all'escemo del c9mpurer, Ogg1g1or.o
la m~gg!or parte delle informazi0ni invi.ara all'escerno dei mmpu.rer amavcl'so la visualizzazione sullo schermo o la srampa su carta.
3. Unit di memoria. Questa l"3. scz1one di "magazzino" coo aecesso rapido e ~apaci r
cdvamenre bassa dd computer. Essa conserva Le informazion.i che sono state immesse
arn'averso l'unit di inpur, in m<:>do che possano essere rese irnmediai:a.mente ~is~oni
bili quando saranno necessarie. "Lunir_di memoria consei:va ~nch~ l~ 1nf~r;n:iz1.oni che
sono gi srare elaborare, Enran t che; possano ancora essere mvi~te :u dispos10v1 di ouc_pm
dalla corrispondente unit. L'unit di memoria spesso chiamata anche memorut o

memori prima.ria.
4. Unit aritmetica e /.Qgictt (ALU). Ques!"l la sezione di "produzi~ne'.' d.el con~p ucer..

resp~nsabile dell'esecU'iione dei calcoli c~m~ I~ sori:n:e, le som3.Z.10nt, le molnp kaz10ni e le divisioni. Essa conciene i me.cdill1Sm1 di decisione cbe con~enrono al compucer,
per esempio, di confrontare due demenci p relevaci dalla un.i~ cli memoria, per determinare se sono uguali oppure no.
5. Unit di elaborazione centrale (CPU). Questa la se:Vone "amminisu:aciv' del compu~
tee. E il coordinatore del computer ed responsabile della supe.rvis.ione ?er ~e ope~on~
delle altre sezioni. La CPU indig alla unit di input il momemo m cru Le 1nformauon1
dovnnno essere lerre nella uni(3 di ~emoria, indica alla ALU. il momento in cui le
ia.formazinl della memoria dovr:i.n9 essere uriliz.zate per i cakli, e indica alla UJ1ir
diomput jJ momento in cilldovr inviare le informazioni dalla unit cl.i memoria a certi
di.sposiv:i di output.
6. Unim di memoria second(lria: Questa la sezione di "magamino" a lungo termine e.con
alu capacit de.I cqmpurer. l programmi e i dati, ~e in ~n certo ~on~e~iro o.on sono
utiliztari dalle altre unir, saranno normalmenre s1sceman su un d1sposiuvo d1 .memoria secondaria (come i dischi), finch non saranno nuovamem:e necessari; probabilmenre
ore, ?iorni, mesj o anche anni pi tardi.

1.4

l!elaborazione batch, la multiprogrammazione


e il timesharing

I primi ompucer erano in grado di ese;guire sciltai;ico un Jo.b (processo) e un. task (lavoro) alla
volta. Questo modo di operare dei computer spesso chiamato tlaboraztone batch (e.labo~

razione a l/Jtti) .mOnOUCCnte. U compurer esegue. un solo progra.nula_per volt.a,, menc::e I da~
sono laboc-ati in gruppi ossia batch. [n questi p~imi ~istern.i, .g~eralmenre, gli ucenc~
sottoponevano i loro processi al centto di elab?raz~one. Ln mazz~ di sche_dc perforare: ~~
ucemi dovevano spesso aspettare ore, o anche g1orru, puma che i tabulau fossero resmum
alle loro scrivanie.
Man roano che i compurer son9_diveucaci pi potenti, si reso evidente cbe l'elabora~
zione barch mn<:>utence ucilizw.v_a r;rrameme in modo efficiente le risorse del computer. S1
p~ guiudi dj fare i.n mode che molti processi o lavofi .pc;>ressern conJ_ividere (share) le
risorse del eoroputcr per ottenerne un miglior utilizzo.. Questo modo di operare decro

N OZIONI SULLA EJ..ABORAZ.lONEELErTRONlCA

mtdtiprogrammnzione. La mulciprogrammaz.ione richiede l'elaborazione "simultanea" dimolci


processi sul computer: questo, in altre parole, condivid,_e le proprie risorse tra i vari processi che comperano per la sua actenzione.. Con i primi sistemi in multiprogrammazione
perii gli urn,ri dovevano ancora sorroporu i processi su mazzi d sched.e perforate e
attendere ore o giorni per i risultati.
Negli anni '60, 1110ki gruppi indusrriali e le u nivenfrm esplorarono il concrro di tirne.shari1zg
(co,tdiJJisione del tempo). JI rimesharing un caso speciale di mulprogrammazione per
mezzo del quale gli urenti accedono al compurer arrraverso dispositivi di input/ourpur o

terminali. In un tipico sistema di compucer in rimesharing, pocrcbbero esserci dozzine o


anche centinaia di ucenci che condividono conremp<;>raneamenre il computer. In realr, il
compurer non serve rnrci gli urenti in modo simulra:n~o. Esso esegue piurrosto una piccola
p.o.rz.iooe del processo di un utente e in seguire prese-a il proprio servizio all'urence successlvo, Il compurer fa rutto ci cos) velocemente che, in un secondo, in grado di fornire
moire volre il proprio SCJVZO a ogni u rente. In questo modo gli urenti s,mb1ano essr
serv.iti si111 uItaneam.enrn.

1.5

l!elaborazione personale, distribuita e client/server

Nel 1977, la Appie Computer rese popolare il fenomeno della elaborazione pmonale. Al
principio, questa era il sogno di ogni hobbisra. l computer divennero abbastanza ecinomiei perch la genre potesse comprarli per il proprio uso personale o per i propr1 affari. Nel
1981 , la TBM, il maggior fornico re di comp urer nel mondo, imrodusse il
Persona! Compmer IBM. L'elaborazione personale, lerreralmenre nel giro di una -nme,
divent legirtima negli affari, nell'indumia e nelle 01:gani:a.azioni governative.
Questi computer ~ralio per delle unir "indipn.d.emi": la gente eseguiva il propri0
sulla propria maccltlna e quindi rraspo.n:ava avami ediecro dei disch i, per condividere lt: ioformabioni. Per quanro i primi personal compmer non fossero abbastanza potenti
da gestire molti urenti in timeshacing, quesre macchine potevano per essere collegate
insieme in reri di compurer; a volte su linee telefoniche e a volte in re locali all'imenio di
una organizzazione. Ci ha portaco al fenomeno della dnborazione distribuita, in cui il
Garico di daborazione di una organ.iu.azione, invece di essere eseguito necessariamente in
qualche insrallazione centrale di compurer, distribuito attraverso le reci alle varie posrazioni
in cui vjcne svolto effertivmeme il lavoro. I personal compurer erano sufficientemente
potenti da gesrire Le richieste di elaborazione di urenti individuali e le fondamentali atti_vir
della comunicazione: passare avami e indietro le infonnazioni in forma c:leruonica.
b~0to

Oggigiorno, i persona! compucer pii1 poremi lo sono tanto quanto le macchine da un


milione di dollari di solo dieci anni fu. Le macchine desktop (da cavolo) pi porenci_ (dette
workstation) forniscono ai singoli ucenci delle capacit enorrn.i. I.;informazione . facilmente
condivisa artraversole rr:i dicomputer, nelle quali alcunt.macchine, derrefile server (fornitori
di servizi. per i file). offrono un magazzino comune di programmi e dati che pu essere
utilizzato da macchine client (clienti) d isrribuire in runa la rece; da cu i il rennine
elaborazione cliem/server. Il e e il C++ sono divem:aci i limmaggi di programmazione scelti
_pe,r scrivere il software dei siscem.i operacivi, delle reti c;mpmer e deUe applicazioni
distribuire in ambiemi cliem/serv.er.

dl

CAPITOLO

1.6

I linguaggi maccbjna, assembly e di alto livello.

I programmatori scrivono le iscruzi0 niin vari linguaggi <li programma2iooe, alcuni <liretta:
mente comprensibili dal compucer e alrriche richiedono dei passi inrermedi di traduzione.
Oggigiorno si utilizzano centinaia di linguaggi ptt i computer. Questi possono essere sud
divisi in rre categorie generali:
1. Linguaggi macchina

2. Linguaggi assembly
3. Linguaggi di alro livello
Ogni computer pu comprendere direttamente s0 ltanco il proprio linguaggio macchina.
Il linguaggio macchina la "lingua naturale" di un particolare computer. Esso stretta.mente correlaro con la p.rogertazione deUtli.ardware del computer. I Linguaggi macchina cons1stono generalmenre di sequenze di numeri (riducibili in defniciva a successfoni di l e )
che ordinano ai compurer di eseguire, una per volta, le loro operazioni pi elemen~ari. I
L~nguaggi macchina dipe1~d-0no dalla ma:cchin4: in altre parole, un parrkolare linguaggio
macchina pu essere ucillzuuo solrantQ..su un tipo cli compm:er. l linguaggi macchina sono
scomodi per gli esseri wnani, com.e si pu vedert: dal seguente frammento di programma
in linguaggio macchina, che aggiunge la paga degli st:raordina.ri a quella base e immagazzina il risuJraco nella paga lorda.

+1300042774
+1400593419
+1200274027

Man mano che i compurer sono diventaci pi popolari, e divenuto evidente che la
programmazione in linguaggio macchina era semplicememe troppo lenca e noiosa per Ja
maggior pane dei programmatori. Invece di us.are le sequenze di numeri che i computer
potevano capire di.rettameme, i programmatori cominciarono a usare delle abbreviazioni
simili all' inglese, per rappresenrare le oper:az:ioni elementari del compurer. Tali abbreviazioni formarono le basi per> i linguaggi assembly. Furono sviluppa dei programmi traduttor,
chiamaci assembler (assemblatori), per convenire in linguaggio macchina, alla velocit del
computer, i programmi sericei in linguaggio assembly. Anche il seguente frammento di
programma i.o !Jnguaggio assembly ~ggiunge la paga degli straordinari a quella base e immagazzina il risultato nella paga lorda, .ma in modo pi chiaro del suo equivalente in
linguaggio macchina:

LOAD
ADD
STORE

BASEPAY
OVERPAY
GROSSPAY

I:utilizzo dei computer aumen rapjdamentecon l'avvento de.i linguaggi assembly, ma


questi richiedevano ancora molte iscruzrni per eseguire anche il pi semplice dei compiri.
Per accelerare il processo di pmgramm.a:zione, furono sviluppaci dei Linguaggi di 11/UJ Li'l!e!Jo
in cui si poteva scrivere una singqla istruzione per eseguire un compico essenziale. I programmi cradurtori, che convertono in linguaggio macchina il codice scritto io quello di alto
livello, sono cb.iama compilatori. l linguaggi di alro Livello consentono ai programmatori
di scrivere delle istruzioni, che sembr:i.no quas.i simili all'inglese di ogni giorno e contengono le notazioni matematiche urilizzare comunememe. Un programma per la busca paga
scrirto in un linguaggio di alto livello porrebbe conrenere una isrruzione come:

..

N QZt!ONl Sl!J[l.,/\ EIA130RJ\ZIONE BLETI'RONlCA

grossPay = basePay

overTirnePay

Ovviamente dal punto di vista dei programrnamci, i lingaggi di alto livello sono molro
pi desiderabili, in confronco ai linguaggi macchina o a quelli assembly. li C e il C++ sono
rra j pi potenti e pi diffusamente utilizzati lingua!W di alto livello.

1.7

La storia del

Il C si evoluto da due precedenti linguaggi: il BCPL e il B. li BCPL fu sviluppato da

Martin Richards, nd 1967, come un linguaggio per srive.re il sofrware de.i sistemi operativi e dei compilatori. Kcn Thompson prese a modello il -SCPL, per moire cararce.cistiche
el suo Jinguaggio B, e us B per creare le prime vrsieni del sistema operacivo UNlX nei
Beli Laboracories, nel 1970, su un computer DEC PDP-7. 11 BCPL e il B erano linguaggi
"non tipizzati": ogni unit di .informazione occupava una "word" (parola) nella memoria e,
per esempio, l'onere di considerare un dato come un numero imero o come uno reale
dt!deva sulle spalle del programmarore.
TI Linguaggio C fu 1.ma.evoluzione del B sviluppara da Dennis Ricchi.e, .nei Be.LI Laboratorics,
-e tii implemenraro originariamente su un computer DEC PDP-11, nel 1972. li C ini'~al
menre divenne famoso come il linguaggio in cui era ~t:ato sviluppato il sistema operacvo
l.il$llX. Oggi, sono scritti in Ce/o in C++ quasi rurri i principa!J sistemi operavi dell'ultima. generazione. Negli ultimi vent'anni, il C divenrato disponibile sulla maggior parre
dei compurer.11 C indipendence dall'hardware. Con una progcrra.zione arrenca, possibile scrive.re in dei programmi che siano portabili sulla maggfor parre de.i computer. "
utilizza molti imporrami conceni del BCPL e del B, mentre aggiunge la cipizzazione dei
dari e altre potenci caratteristiche.

Dagli ulrimi anni '70, il C si evoluro io quello che oggi chiamato "C tradizionale".
La pubblicazione, nel l 978, del libro di Kernighan e Rirdiie,1/ linguaggio di programmazione C,
ha arraro moire artenzioni su questo linguaggio. Quesra pubblicazione diventata, in
cam,po informacico, uno dci libri di maggior successo di cucci i rempi.

La rapida espansione dd C sui diversi cipi di computer (detci, a voi ce, piattaforme hardware)
ha prodotto molte varlanci. Queste erano simili, ma spesso incompatibili. Ci rappresentava un problema serio per i programmarori, che avevano bisogno di sviluppare un codice

-che potesse girare su piarcaforme diverse. Divenne allora evideme che era necessaria una
'!~fS.ione standard del C. Nel J983, per "fornire una de.fi.n.i.zione dd Linguaggjo che non

tli>sse ambigua, e die fosse indipendente dalle machine", si cre U com.itaro tecnico X3J 11 ,
lle'Clif:'>eni:lenze del Com itato Nazionale Ame.tic(!.no pef gli Scan<:lard dei Compurer e l'Ela-

bofazfone della lnformazione (X3). Lo standard fu a.pprcivaro nel 1989. Il documento si


chiama ANSI/ISO 9899: l 990. Copie di qtLesto docum.mb possono essere richieste al~
L'lstituco Nazionale Americano per gli Standard, il cui indirizzo riporcam nella. Prefazione
di quesro cesto. La seconda edizione del libro d i Kernighan e Ritchie, pubbUcaca nel 1988,
:riflecre questa versione, chiamara ANSI C. usata ancora oggi in cucco il mondo (Ke88).

Obiettit10 porrabiLit I. I
Dato che il C un linguaggio indipendente dagli hardware ed largammte diffuso. le
applicazioni scritte in C possono essere ese~ite, ccn poche o nessuna modifica, .m una
vasta gamrna di sistemi di computer differenti.

CAPl'l'OLO 1

N @ZIONI SULLA ELADOtMZ IONE cLEn"RNtcA

~=-\:] \: .'] ~
lf>;,911't+t. ~

1,;f ;i. ~'lo )(',)

..~,; ,t.

r>..}1

1.8

La libreria standard del

1 programmi scricti in e, come apprenderete nel Cai;>itolo 5, consisrooo di moduli o peni


chiamati funzioni. Voi porrcce programmar~ tu.ree le funzioni di cui avrere bisogno per
scrivere un programma c. ma la maggior: pane dei programmatori
traggono vantaggio
da una ricca collezione di funzioni gi esisremi, chiamata libreria standard del C. Di conseguem.a, ci sono in realt due asperri del "mondo" del e da jmparare. li primo imparare
il linguaggio C in s, menrre il secondo imparare a utilizzare Je funzioni dclla libreria
standard del C. Nel corso di questo libro, parleremo di molte dj quelle funzioni. l.:Appenruce B
(condensara e adartata a partire dallo stesso documenro dello srandard ANSI C) elenca
runele funz.ioni disponibili nella libreria standard del C. il libro di Plauger (Pl 92) dovrebbe essere letto dai programmatori d1e abbiano bisogno di una profonda conoscenza delle
funzioni incl.use nella libreria, di come implementarle e di come usarle per scrivere un
codice porrabi1e.

ln questo corso, sarece intoraggiari a utilizzare un approcci di costruzione a blocchi


per creare i programmi. Evirate di invenrare nuov;.uneme la ruoca e urili1!t.ate i pezzi gi
esistenti: questa si chiama riusabilit.dal software. Quando programmerete in e, L!S~rete
tipicanrcnce i seguenti blocchi:

Le funzioni della librea srandard


Le fum.ioni create da voi stessi
Le funzioni cbe sono state sviluppare da alrre persone e che vi sono state messe a dispo-

siz.ione
Il vantaggio ru creare le vosrre funzioni che saprete esarr.uTiente in che modo funzionino.
Sarete io grado di esaminare i1 codice C. Lo svanraggio dato dal dispendio di rempo
richiesto dallo sforto per progernrre e sviluppare delle nuove funzioni.
Usare le funzioni gi esisccnci vi evirer di invenrare nuovamente la ruota. Nel caso
deUe funzioni dello srandard ANSt saprere che sono state scritte con molta cura e che i
vosrri progra.mmj avranno un'alta probabilit di essere portabile, poich stace miliZ7.ando
delle funzioni ch sono virrlialmenre disponibili su mere le implemenr-azioni ANSI C.

Obiettivo efficienza 1.1'


Utilizzare le fim.zioni della Libre_ria standard ANSI, invece di srri.vere le uortre corris-pondenti versioni~ potr migliorare l'efficienza del progmmma, perch quelle funzioni
sono state scri'tte con ~ura per wria e,ser:uzione efficiente.
Obiettivo portabilit 1.2
Utiliz.zare le funzioni de//4 libreria [tandard ANSI, invece di scrivere le vostre corrispondenti vmi()ni, porr migL/oratt:c la portahilit del programma, perch quelle fimzioni
sono state incluse in qu@ tutt<: le versioni del C.

1.9

Gli altri linguaggi di alto livello

Sono stati sviluppati ceocinaiaru linguaggi di alco livello, ma solcanto alcuni hanno orrenuro
un largo consenso. 11 FORTRAN(FORmuh -ptANslacor, Traduttore di formula) fu sviluppato dalla IBM, rra il 1954 e il 1957, p~r essere ut:ili'l.Zaco nelle applicazioni scientifiche e

>\ t

r'

;k'. .r~.~ .i.'5


\,,/;>('........,

di ingegneria che richiedono complessi calcoli matematici. 11 FORTRAN urili~"-~''A .?-~~~~


..1:a::..
.
11.1r..
QJ.U.=ameote ancora oggi.

Il COBOL (COmmon Business Orienced language, Linguaggio orienraro alle comuni


attvit commerciali) fu sviluppato nel 1959 da un gruppo di produrcori di computer e di
urenti gove.mavi e industriali. li COBOL milizzam principalmente per le applicazioni
commerciali che richiedono una precisa ed efficiemc manipolazione di granili quancir di
dati. Ancora oggi, pi della mer di nmo i1 sofrware commerciale programmato in COBOL.
pj di un_milione ili persone sono impiega.ce come programmacori COBOL.

lJ Pascal fu progettaro circa nelJo stesso periodo del C. Esso era desrinaro a un uso
aecademico. Diremo qualcosa di pi a proposiro del Pascal nclla prossima sei.ione.

1.1 O

La programmazione strutturata

JJw;ante gli anni '60, molti grandi progcrti dj sviluEpO di software inconrrarono delle serie
dlffkelr. Si er,:i tipicamente in rirardo risperro ai piani di sviluppo del softw<ue, i cosci
et;edevano notv0lmenre i budger e i prodorri finiti non. erano affidabiu. La geore comin:lliiQ .a eomprendere che lo sviluppa del sofcware era una .;mi:vit pi complessa di quanto
>3Ve5;5~ immaginato. I.:arcivic di ricerca degli annj '6!) ebbe C(lme risultato lo sviluppo della
prop:amm.11.Zionc Strtttt'Jlnltll: UJl apprOCCO rusciplinato alla scrirrura di programmi chiari,
'.fililla correttezza dimostrabile e semplici da modi.6rue, Il Capitolo 3 e il Capitolo 4 presenteranno llOa panoramiet generale sw principi della. programmaz.ione scrurrurara. Il re:sm del cesco affronrer lo sviluppo di programmi suurruraci in C.
_ Vno de~ risultati pi tngibili prodocci da questa rit':erca fu lo sviluppo, da parte dcl
.Professor N1cklaus Wtrrh nel 1971, del linguaggio ru programmazione Pascal. 11 Pascal,
me prese il suo nome dal matemarico e 61osofo dd d.iciassecresimo secolo Blaise Pascal, fu
p.rogectato per insegnare la programmazione srrua:uraca negli ambienti accademici e divenee rapidamcnce il linguaggio di inrroduz.ionc alla programmazione preferico nella maggior
parre delle w1iversir. Sforrunatamence, il linguaggio mancava di moire delle srrua:u.re oec::c;ssarie per reoderl.o utile nelle appHca.zioni commerciali, .indusrriali e governacive, perci
nen fu accenaco dilfusamence in quesci ambienri. La stri pu ben ricordare che la sua
selezione come base del unguaggio di programmaziruie Ada stara la reale imporranza del
~cal.

:L.Ada fu sviluppato sorto iI panocinio del Diparrimenro della Djfesa, degli Sraci Unici
'80. Per produrre gli imponenri siscemi
t~frw~e di comando e di co~rrol~o del ~OD, ern.no s.rati a.~za.ci cemtinaia di ling~1aggi
d,tvers1. Il DOD voleva un lUll.CO lmguaggw che potesse andare mcontto alle proprie nece.ss~t'. ll Pascal fu scclc~ come. base m~ Ada, i1 linguaggio finale, risult completamente
diverso dal Pascal. Il l111guagg10 prese i1 suo nome da Lady Ada Lovdacc, figlia dcl poeta
Eord Byron. A Lady Lovelace genera.Imenee amibuito i1 merito. di avere seri reo, all'inizio
del 1800, il primo programma per computer del mondo. Una imporrante caraccescica
dcli' Ada il multitasking. questo consente ai progra.mmacori di specificare che molte arrivit dovranno verificarsi io parallelo. Gli al cri linguaggi dj alto livello ucilizzaci diffusamente
di cw abbiamo discusso (inclusi il Ce il C++), ~onsentono di scrivere programmi eh~
eseguono soltanto una activic per volca. Resta da vedere ~e l 'Ada abbia raggiunco U suo
obiecvo: ovverosia, produrre un software affidabiJe e ridurre soscanz.ialmence i cosci di
~iluppo e manucenziooe dd sofcware.
~IJ>QD.)., durante gli anni '70 e alJ' inizio degli

CAPITOLO l

10

1.11 Le basi dell'ambiente C


Tutti i sistemi C consisrono generalmeme di ue parti: l'ambience, il linguaggio e la Libreria
scandard del C. La discussione seguente spiegh.r il tipico ambiente di sviluppo C, mostrato nella Figura 1.1.

Fase 1:

Fase 2:

Fase 3:

Fase 4:

L...--~}

'---Edi-tor----'

~ -~}
Preprocessore!Complatore

..

..,..

Disk

)}

0Gk)}

Llnker

nprogramma scaco
crearo con l'editor ed
immagaz.inaco nell'hard
disk

11 programma
preprocessore esegue il
codice
li programma
compilatore crea il codke
oggetco e lo immagazioa
nell'hard dlsk

Il linker colleg iJ
codice oggerco con le
librerie, crea a. out e lo
memorizz.a sul disco

Memoria
Primaria

Fase 5:

Loader

,.

Memoria
Primaria

Fse 6:

Figura I . I

CPU

Un tipico ambiente C.

N0ZIONT ~HL.LA f.'.IA~ORAZlONEELETIRONJCA

Jl

r programmi scritti in e passano tipicamente attraverso 6 fasi , prima di essere eseguiti


(Figura 1.1). Queste sono: editrm:, p1eelaborar.e, compi-fare,, linknre (cotlegnre), caricare ed
-estJguire. In questo contcsco ci concentreremo su un tipico sistema C basaro su UNIX.
Qualora non sciare utiliz1.ando un sistema UNIX, fue riferimento ai manuali del vostro
sjsrema, o chiedete al vosrro insegnanre di eseguire queste attivit nel vostro ambience.
La prima fase consisre nella scrittura del codice (editing) in un file: quest'a si esegue
con un programma chiamato editor. Il programmacore scriv~ un programma in C con I'edicor
~. se necessario, eseguir delle correzioni. 11 programma sar quindi i.m.magazzinaro in Wl
dis_posivo di memoria secondaria, come un disco. Il nome del .file del programma C
dovr terminare con l'estensione . c. 11 vi e l'emacs sono due ediror largameme ucilizzaci
sill sistemi UNIX. 1 pacchetti software de! C/C++, come il Borland C++ per i PC lBM e
compadbili e il Symancec C++ per l'Apple Macinrosh, dispongono di ediror incorporati
che sono agevolmence integrati nell'ambiente di programmazione. Supponiamo che il letw re sappia come editare un progranlina.

1n seguico, il programmacore immccrcr iJ comando di compilazione dcl programma. ll


nel codice in linguaggio macchina (detto anche
ompilatore tradurr il programma
f:<Jdice oggetto). I n un sistema C, prima che incominci la fuse. di r:ra.duz.ione, sa.r es~uico
~u~omati'camenre li programma preprocessore: 11 preprocessore del e obbedisce a comandi
speiaJi, chiamati diretti11e del pre:processore, con le quali si indi.ca che sLLI programma doVl'no esse.re e.~eguice determinare manipolazioni, prima della compilazione vera e propria. Tali manipolazioni consistono generalmente nella inclusione di alrri file in quello da
crompilare, e nella sosciruzionc di simboli special i con un tesro del programma. Nei primi
mpiroli, saranno discusse le dirercive pi comuni dcl preproeessore; nd Capitolo 13 pre~enreremo una crarcazione dettagliata di tutte le cararreristiche dd preprocessore. Questo
sar invocato auromaticamenre dal compilatore, prima che il programma sia converro io
linguaggio macchina.

Il linker carica in
memoria il
programma

La qwirra fase chiamaca linking (collegamenta). I programmi se.cirri in C conrcngono


tipicamente dei ciferimenc.i a fu.nz..ioni definire alrr0ve, per esempio nelle librerie standard
0 in quelle di un gruppo di programmatori che lavorano su Wl particolfe progetto. Di
c~mseguenza, il codice oggerco prodotto dal. compilatore oncerr tip'icamenrc dei "buchi"
fl.ovmi a queste parti mancami. Il link" collega il cdite oggecro con quello delle funzioni
mancinci per produrre una immagine eseguibile (senza pezzi mancami). In un tipico sisccma
basam su UNIX, iJ comando per compilare e collegare j pezzi di un programma cc. Per
~~empio, per cempilare e collegare i pe-;;:.d di un programma: cliiamaco welcome . e scdverece

La CPU esegue
un' iscruziorlc per
volta
immagazinando i
nuovi dari oa:en.uci
dall'esecuzione del
programma

(f(;

welcome . e

al prompt di UNIX e premerete il tasto invio. Ne.I c~o il programma sia staro compilaco

e collegato corrcrramencc, sar prodotto u.n file c:h.iamaro a . out. Quesro sar l'immagine
eseguibile dd nstro programma weloome.c.
La ~uinta fase d1iamara ctJt:amento. Prima eh.e possa essere eseguiro, un programnella memoria. Questa operazione 5ar~eseguiradal !.oader (caricatore)
che prender l'immagine eseguibile. dal disco e la trasferir ne.Ila memoria.

ma dovr essere caricato

FinaJmenre, soLTo iJ controllo della swi CPU, il compmer eseguir il programma, una
istruzione per volta. Per caricare ed eseguire il programma in un sistema UNIX, scriveremo a. out al prompr di UN1X e premeremo il casco invio.

12

I
I

I
I

CAPITOLO 1

La maggior parte dei programmi scritti in


ricevono e/o produco no dei dari. Certe
funzioni scritte in
prendono il propri<;> inp ut (i dari in ingresso) dalle stdin (il
t;/.ispcti.#vo standardperI'input), che assegnato normalmente alla cascic:.ra, ma lo stdin
porrbbe :tnche essere eonnesso a un alrro clispositivo. .Loutpltr {i dari io uscita) inviato
allo stdout (il dispositivo standard per /'outpuJ, che normalmenre lo schermo del compurer, ma che potrebb anch e e.ssere connesso a un altro dispositivo. Q uando affermiamo
che w1 programma scampa un risuharo, normalmente, imencliamo affermare che quello
vis~zzaro sullo scherm. I dati possono essere inviati ad altri dispositivi, come i<eischi e
le stampanti (scampa su cana:). C' anche un dispositivo sttmdardper L!Torecb.iamaro stderr.
Udisposit"ivo dello stderr (normalmente cotl.lil$SO allo schermo) utilizzare per visualizzare
i messaggi di errore. uso comune dirigerei dari dell'output regolare, ovverosia lo stdout,
vers un dispositivo diverso dallo schermo, mentre si mantiene I stderr assegnato allo
schermo, cos che l'urente possa immediacamenre essere informato degli errori.

1.12

NOZlON l SUUA ELABORAZIONE El.EJTRONICA

Noi abbiamo preferito Umica.re la nostra discll5sione all'ANSl C. Moire tt.u:attcrisciche


incluse nel,l 'ANSI C non sono corn.pa bili con. le altre implementa'l.ioni d el C~ perci porreste verifarre ch alcuni dei programmi di questo testo non funrionano sw compilarod
pi darari.

Buona abitudine 1.2


leggete i manuali della vers;one det C che state usando. Consultate frequentemente qu.esti
manu.dli per essere sicuri di conoscere la ru:ca colfe.Uone di caratteristich-e dei e e Jj 11.sarle
in modo conetto.

Buona abitudine 1.3


Il vostro computer e il vostro compilawre sono dei buoni in.segnanti. Qua/ara non s111te
siciui di come fanzioni una caratteristica dcl C, scrivete un programma di esempio con
quella caratteristi.ca, compilatela ed eseguitelo e osservate quei/o che succede.

Note generali sul C e su questo libro

Il uu lingt1aggio difficile. A volte, i p rogrammacori es~eni S"OUO org<>gliosi d i essere


capaci di creare u cilizzi bizzarri, conrorri e c_omplicaci del Unguaggi. Quesra una cartiva
abim.d ine di programmazione. Essa rende i programmi difficili da leggere, maggiormcme
soggetti a comporramemi suani e pi difficili da collaudare e correggere. Questo lihio
ade~ro ai programmatori principiami, p erci ci sjamo sforzaci di scrivere prpgrammj
chiari e ben srrurcurari. Uno dei nostri o biettivi principall, in q uesto libro, q uello di
P~.~ui.re la chir.zrezza dei program m i, am a.ver.s o le comp rovare re.c;niche di programma:z.in s trumtrara e le molte correlate buone :abirudini di p rog4\Iiullazione.

Buona abitudine 1.1


Scrivete i vostri programmi C in u1za maniera semplice e diretta. Qu.emt 1egola tktta
volte KIS ("keepit simpLe '~ mamienilo semplice). Non 'forzate" il linguaggio, tef:J,tando d.elLe "stranezze''.
4

l'otrei;te ave.r sentiro dire che il C un linguaggio portabile e che i programmi sccitti in

C possono essere eseguiti su molti computer differenti. La pqrtabiifr un obiettivo sfuggente; Il documento deUo standard ANSI (An90}annovera ben J 1 pagine di insidiosi probiemi
rigtiardanti la pon:abilic. Sono srari scritti libri interi sull'argomento della porrabilii: nel
(fa89) (Ra90).

Obiettivo por.tabilit 1.3


Per quanto sia possibile scrivere programmi portabili., ci sono molti problemi tra 'le tan-

te implemenrawmi de.I Ce i vari com_puter, che rendono laportabi/~ un obiettivo difficile

da raggiungere.. Scrivere semplicemente dei programmi in C non ne gara11ti.sce In portt1bi/it.


Abbiamo eseguiro una attenta vedfca del docwnenco deUo srandard ANSI Ce ahbiamo onfronraro con q ueij9 la nostra presentazione per complerez.za e accuratezza. Turravia
1
il C un l i.nguaggio molto ricco e ci sono akWJe sortigliezze nel liguaggio e cerci argomenti avanzati d Je non abbiamo uartaco. Vi suggeriamo di leggere lo stesso docum.en te d eUo
Standard ANSI
o il manuale di riferimento di Kcrnighan e Ritchie (Kc88), D~ caso
dovCre aver b isogno di ulteriori dercagli recn.ici sull'ANSI C.

13

1.13

Il Concurrent C

Altre version.i del C sono State sviluppate per mezzo degli sforzi continui della ricerca nei
Bel! Laboratories. Gehani (Ge89) ha svilupparo il Concurrenr C: un superinsieme del C
che include delle primitive per specifiearc delle anivitl...multiple che porranno essere eseguite in parallelo. E n rro i prossimi dicci anni, con l'aumento dell't1cilizzo dei multiprocessori
(ovverosia, dei romputer con pi. di u na CPU), i linguaggi come i.I Con~urtcn t C e le
caratteristiche de.i sistemi operativi che supporcano il parallelismo ne.Ile applicai.ioni dell'utente, divenrecanno sempre pi popolari. Per quanco riguarda questo testo, il Concurrent C
ancora principalmente un linguaggio di ricerca. I corsi e i libri ili testo sui sistemi
operativi (De90) includono solirameme rratta.iioni corpose sulla programmazione concorrente.

1.14

La programmazione orientata agli oggetti e il

e+ +

Un alcro supecinsieme del C, oss,ia il C++, fu sviluppato da Srrousrrup (Sc86) nei


BelJ Laboratories. Il C++ fornisce diverse cararceristiche che migliorano il linguaggio C.
Ma, cosa pi imporrante, fornisce delle primitive per fare una programmqzume orimtt1.to

agli oggetti.
Gli o.ggetti sono essenz.ialmenre dei componenti sofrware riusabili che mo dellano glj
d ementi del mondo reale. C' u na rivoluzione in preparazione nella comnnic del sefcware.
Costruire il software velocemenre, corretcameme e io m0do economico cimane un obiettivo sfuggenre e questo in un perioqo in cui aumeman o vertiginosamente le richieste per
un software nuovo e pi porenre.
Gli svilupparori di software stanno scoprendo che, utilinando un approccio modulare
e orienram agli oggetti per la progenaz.iooe e l'implementazione, si porrebbe. fare in modo
che i gruppi d i sviluppo siano dal Oa 100 volce p i p!7Ciduttivi di qua nro fosse. possibile con
le tecn iche di p rogrammazione convenzionali.
Sono stari sviluppaci molti linguaggi di programmazione oriemari agli oggerri. Molti
docenti sono convinri che la migH<'.lr suacegia educativa oggigiorno sia cli imparare a fondo
il C e di studiare, io seguito, il C++.

L4

,,

CAPITOLO

N oz1.0NJi SULLA F.l.ABORAZIONE ,Ebc'JTRONICA

Esercizi di autovalutazione

Esercizi

1.1

J .3

Riempire gli spazi in ognuna delle segue.nei frasi;


a) r:azienda che ha scacenaw il fenomeno della elaborazione personale nel mondo sr.ira la
b) li compuccr che h.1 legirtimaro l'elaoor-azione personale nel commercio e ncll'indumia

staro il _____

e) l computer elaborano i dari sonoilcormoUo dj insiemi di imuzioni chiamati _ _ _ __


per computer.
d) Le sci principaLi unit logiche del compurer sono - - - - - - - -- e----e) U
~ un caso speciale deU:i. multiprogrammazione in cui gli urend accedono
al compurer ama verso dispositivi ch..itria ceoninaJi.
f) Le rre classi di linguaggi discusse in qusro capitolo sono _ _ _ __, ____ _ e

r programmi che Lr;tducono in lingu<lggio mai:;china quelli scritti in linguaggio dj alro


livello sono chiamali
.
h) TI C largamenre c;onosciuto corire il linguaggio di sviluppo dl sistema operaiivo
g)

Quc$tO libro prescnra .la versione del G <iliianiara


C. che stata sc;utdardiizaca recentemente dalJ'!sruro Nazi_on.aleAmei:ici010 per gli Standard.
j) li linguaggio
fu sviluppato da Wirth per insegnare la programmazione
strutturata nelle universir.
k) tl Dipartimento della P .ifesa sviluep il linguaggio Ada con una caraneriscica dena
_ _ _ __, che c_onscnce ai progr;unmacor{ di specificare che moire acrivic possono
procedere in paraUelo.
Riempire gli spazi in ognuna delle seguencifrasl riguardanti l'ambiente C.
a) J ptogrammi C S(JDO normalmente mniCSS in un computer usando UD programma
i)

1.2

b) 1n un sisrema C, prima che incominci la fase .di rrad1J2ione, sar eseguito auromacicamenre
un programma _ _ __ _
c) l due i:ipi pi comuru c:U direrrive del prprocessore sono
e _ _ __ _
d) TI programma
/
c;pmhiua l'output del compilarore con le varie funzioni di
libreria, per produrre una immagine esguihile:
e) li programma
crasferisq: l'i1lllilagine eseguibile dal disco alla memoria.
f) Per caricare cd eseguire iJ programma c9mpila:ro pi recenrcmeme su un sisremaUNIX,
digirace
-

Risposte agli esercizi di autovalutazione


1.1
a) Appie. b) PersonaI Compurcr della JBM. c)' programmi. d) unit di i npur, unir di oucpuL,
unit di memoria, uoitll aritmeriea e logica (ALU); unit. di dabo.raztone centrale (CPU), unit di
~emoria secondaria. e) rimeshacing. f) linguaggi macchina, linguaggi assembly, linguaggi <li alco
liveUo. g) compilarorl. h) UNIX i) ANSI. j) P.asc:al. k) muJcixasking.
1.2
a) ediror. b) preprocessore. e) includere altri 1le in quello da compilare, sosciruire i simboli
speciali con il tesro del programma. d) linker. e) loader. f) a . out.

15

Classificate ognuno dei seguenti elementi come hardware o software:


a) CPU

b) c:ompilatorc e
e) ALU
<l) preprocessore
e) unit di input
I) un programma dj elaborazione di resti.
1.4
Perch dovresce preferire scrivere un programma in unlinguaggio indipendente dalla macchina, invece che in un linguaggio dipendcme dalia macchina? Perch un linguaggio dipendcnre dalla
macchina potrebbe essere pi appropriato per scrivere cerci tipi di programmi?
1.?
I programmi cradunori, come gli assemblatori e i compilatoci, convertono i programmi da un
lil).guaggio (detto sorgente) In un al ero (demo oggctco). Oeterminace quali delle seguenti affesmaz.ioni
sono vere e quali sono fulse:
a) Un compilatore traduce in linguaggio oggeno i progr-;unmi $crini in un lngua.ggio di alro
livello.
b) Un asse.mblarore converte in programmi in linguaggi rnacd n:i quelli scritti in linguaggio sorgente.
e) Un compilatore converte in pC0grammi in linguaggio oggetro quelli scritti in linguaggio
socge.nre.
d) I linguaggi di alto livello sono genecalmerue indipendenti dalla macchina.
e) Un progr::imma in linguaggio macchina richiede una rradurione, prima che il programma
possa essere eseguito su un computer.
1.6
Riempite gli spa bianchi delle seguenti fusi:
a) I disposir.iv attraverso i quali gli urenri accedono ai sistemi di computer in cimesharing
sono chiamaci di solito _ _ _ __
b ) Un programma per computer che converte in programmi in linguaggio macchina quelli
scritti in linguaggio assembly chiamato _ _ _ __
c} i:unir logica dd computer, che riceve daU'esterno le informai.ioni affinch il calcolacort le
possa uciliu:are, si chiama _ _ _ __
d) Il processo di istruzione del computer per risolvere problemi specifici chiamaro _ _ __
e) Quale tipo di linguaggio per computer urilizza dclle abbreviazioni simili all'inglese per le
ismwoni in li11guaggio macchina? _ _ _ __
f) Quali sono le sei unir logiche del compucer? _ __ _ _
g) Quale unir logica del computer invia ai vari dispositivi le informazioni che sono gi srate
elabe rate dallo stesso, in modo che queste poss.ano essere utilizzate all'esterno del compute r ? - - - - h) li nome generico di un programma, che c;onverte in linguaggio macchna 1 programmi
scritti in un cerco linguaggio per computer, _ _ _ _ _
i) Q uale unit logica del computer conserva le infor01az0Qi? _ _ _ __
j) Qual.e unit logica del computer esegue i calcoli? _ __ _ _
k) Quale unit logica del computer prende le decisioni logiche? _ _ _ __
I) l:abbreviazione comunememe utilizzata per l'unir di conrrollo del compuler _ _ _ __
m) 11 livello del linguaggio per compucer pi conveniente per il programmacore, per scrivere
i programmi pi velocemente e facilmence, _ _ _ __
n) TI linguaggio oriencaro alle comuni applicazioni cornmerciaJj usaco pi diffusamente oggigiorno il _____
o) runico linguaggio che un compucer pu comprendere dfrettamente il
del
computer.

16

CAPLTOLO I

p,) Qu.a.le unit .logica dcl comp uter coordina


le atrivid\ di nme le ahre unc logiche?

1.,7

Deren ninai:e se ognuna delle segue nti affermazioni


sia vera o falsa. Spiegare le vsrre risposce.
a) I linguaggi macchina dpend onQ generalmen
te dalla macchina.
b)' ll dmdh aring consente realm enre a molci utenci
di usare simul~eameme un computer.
) Come gli alrri linguaggi di allo ljvello, il C
generalm.enre considerato indipendenrc dalla
m.acchhia.
1.8
Discutete il significaro dj ognuno dei seguenti norr
in ambieme ONIX:
~) stdin
b) stdou t
e) stder r
1.9
Quale caratteristica cbfave fornita cW Conc urren
t C che non sia disponibile in ANSI C?
1. 10 Perch oggigiorno c' cosl c:anca armu.ione
conemrarn sulla progr am=. ione orienrara agli
oggecci, in generale, e sul
m particolare?

e-

Let ture consigliate


(An90) ANSI, Amerim11 Natioru1LSr.a1ulardfor_l1rfarmnt
~o11 Sysr.emr-Rrogrammi11g language C (ANS
I .Dommcn r ANSJ //S() 9899: 1990), New York,
NY: Arnecican Nacio nal Standards lnstitutc, 1990.
Qucs~o ll qocuruem che de.finisce i'ANS
I C. Il documen to ilispouibile in vend.ira prc:~so l'Amc
rican Narional Srandard. lns1 imce, 1430 Broadway,
New York, New York I 0018.
(De90) Dci rei, H. M. , Opmifing .S)rmns (Second
Edltiqn), Redlng, MA: Addison-Weslcy Publlshing
Company, 1990.
un manuale.: per JI midizionalc rso dj informatica
U sistemi operativi. J capitoli 4 e 5 presen
tano
una approfondita discussione sulla prgramma:r.iom:
conco.mmcc.
{Ge89) Gchani. N. , and W. D. Room c, The Conmrrmt
C Programmmg 1..m1gu11ge, Summir, NJ: Silicon
P.ress, L989.
~uesro il libro

.ru _defin_iuonc del Conc~m:m C: u.n


pro.grammacorr ili specificare un:a esecoz1one pralldaSl1pcri~ieme d~l linguaggio ~ che cons~nre
di attivit multiple. f. anche mduso un compenwo del Concurrcm C++.
Oa89) Jaeschke, R. Portabiiity ond the e Language. Jndian
apol.i$. fN: Hayden Books. 1989.
Questo 1ib.ro discute la sori.rmr:i in 4i progrruruni
porwbili. Jacscbke ha pancdp:iro ai coniitaci
ANSI e ISO pergli srandard del C.
(Ke88) r<.ernigh:m, B. W:, :md D. M!.Ricchie, Tht
C Pmgmmmi11g l011g11age (Second Edicion), Englewood
Cliffs, NJ: Pr.cncrce Hall, 19.88,
Qucsco libr un classico nd settore. Il libri'! ampia
mente ucilin.'lro, nei corsi di C e nei seminari
p i Rrogrammatori di ruolo, e iriclude un eccellcnce
manuale di i:iferifncnro. Riccrue L'aucore de.I
linguaggio C e uno dci progettisa dcl sistema operar
ivo ONIX.
Wl 92) .I'.lauger, P. ]., '!11e Srmul11rd C Libmry, Engle
wood Cliffs, NJ: Prentic<lfall, 1992.
Definisce edimo ma l'utiliri..o delle funzioni incluse 11c:lla
libruria sc:a:nda rd del C. Pla.gcr. nell'ambito
del comicaro che ha sviluppaco lo st:anchud ANSl C.
staro il capo del sonocomitato pr la libreria
ed anche Slato <:<;>Jui il quale ha convotlato. il COiJJj
l3CO [$Q per l'evoluzione dcl C.
(Ra90) Rabinowicz, H., aod C. Scha3p, Portab/.c C,..En
gbvood Cliffs, N); Prencice Hall, l990.
Quesro libro stato svUppaco per u.n corso sulla porrnb
ilic tenuto neglLAT&T Beil L!borawries.
Rabinowirz..hvora presso il Laboratorio ili lncelligenz.a
An:l6ciak della NlN.EX Corpor-Jcion, mentre
Scbaap un.Jirigent dc.Ila Ddfi Consulting Corpo
ration.
(Ri78) Ritchie, D. M.; S. C. Jobnson; M. E. Lesk; and
B. W. Ketnghan, "UNL,'{Tune-Sha:riog Syscem: The
C Programmlng Language", Th11.Btll Systn11 Tech11ical
Joumal, Voi. 57, No. ~. Pan 2, July-Augusr
1978, pp. 199!-20.19.
ai.

Questo uno degli arri.coli classici di inrroduz.ione al


linguaggio C.Apparve..in un num~ro spec;iale!
deUa rivisr;i Bei~ Systm1 1iodmk11l foumiil dedicar.a al
"Sistema dJ funcsharing jo UNIX".

Nozr oN1sulli \ Fl.ABORAZIO NE ELETrRGNIC


A

17

(lli84;) Rir.chie. D. ~I. . "The UNlX $ysccm: The Evolu


on of the UN rx Time-Sh:uing Sys~m~. AT&T &Il
Labor;nrpries 111:hnicn,ljournn.J.Vol. 63, No. 8. P.ort 2,
Oc;tobcr 1984, pp. 1577-1593.
Un articol o classico sul siscema operativo UNIX. Quest
o anicoJo apparve in una edizione :;peciale
della rivistn Bd./ .'>)stem Tedmkttlfoltrnal complecame
nre dedicata al "Sisrema UNIX".
(Ro84) Roslc.r, L., "Thc UNIX Sysrcrn: Thc F.voluc
.ion ofC- Past ;md Future", A116-T BellLnborniories
Technical. jo1m10/, Voi. 63, No. 8, P:m 2. Ocrober 1984.
pp. l 685-L699.
t w 1 cccdlenn: artico lo, da far seguire ~dRi78) , per il !errore interes
sato a craciare In scoria del C
e le radici dello sforz0 per srandardizzare i'ANSI C. App3r
vc in una edi:t.Jone speciale della rlv1sra B,l/
System 7echnical jonrnal dedicira al "Sistarna UN IX".
(Sc84) Srrouscrup, B., "The UNlXSysU!fT1: Data.Ahsrrac
tion in C,Ar &T BellLnb.o.mtorit:s Tcchnic11ljoumal,
Voi. 63. No. S, Pan 2. Octoher l984. pp. 1701- 1732.
t:arcicolo classico di introdLLiione al C++.Comparve in
una edizioni; speciale ddl:t r.ivi.sra Bcl!Syswrn
Tethnicoljoumol dcdk ara al "Sisrema UNlX ".
~St9J.) Srrousuup. B. The c.~+ Progmmming Lmti11
1ge (Sccon d Edition), Reading, MA: Addison-Wesley
Serics in Computer Science, l 991 .
Qoesc olihro 'il riferimenro per la definii.ione del
C++: un supecinsieme dd C, che apporca vari mi
glioramemi al e, specialmente le car:arrerisciche per l<t
progr3mrnaiione orientata agli oggctri. Srrousrrup ha sviluppato il C++ negli AT&T Be.li Laboc
:uories.
(To89) Tondo, C. L. and S. E. Gimpel. The C.A1isw
er 'Bo(Jk, Englewood Cliffs. NJ: Prentlce Hall, 1989.
Qacsro libro unico fornisce le risposte agli eserciti nel
Kernighan e Ricchie (Ke88). GJi autori mo
strano w10 ,m ie di progro.mm:azione esemplare, merur
e fumlscono spiegazioni sui loro approcci alla
soluzione dei problemi e sulle scelte di progemiiione.
Tondo 111.vora presso la l&M Corporation e la
Nova Ullivcrsicy in Fr. Lauderdalc, Florida. Giinpl
un consuliinre.

CAPITO LO

Intro duzi one


alla prog ramm azio ne in

Obietti vi

Esserdngr ado discrivere semplici programmj per computer in C.


Essere in grado cli usare semplici istruzioni cli input e cli outpuL

Familiarizzare con.i tipi cli dato fundarnent:ali.


Comprende re il funzionamem:o della memoria del computer.

Essere in grado cli usare gli operarori aritmetici.

Comprengere le regole cli pcioric degli op.eracor.i ari:rm.etici.

Essere in grado cli saivere semplici istruzioni decisionali.

2.1

Introduzione
11 linguaggio e fac.ilira u.n a(>ptocci.O scrurturato e discipLlnat o alla

progenazio ne ru un
pr ogramma per computer. In questo ca.pi.tolo introducia mo la programm aziqne in
e
presentiam o molci esempi che illusrrano varie importami cararrccistiche del linguaggio .
Ogni esempio .aualiz:1.aco aaencamem e, una isrru1.iooc per volca. Nd Capitolo 3 e od
Capi cole 4, prescmiam o una inc:roduzione alla programmazione stnetturata in C. lo seguim,
useremo l'approccio srrumirato in rutta la parre rirnanenre del libro.

)'

2.2

Un semplice programma C: visualizzare una riga di testo

u.rilizz.a alcune notazioni che possono apparire strane a eh.i non ha mai programm ato
un computer. Comincere mo consideran do un semplice program.m.a C. ll .nosrro pcimo
esempio visualizza una riga ru cesto. Il programm a e la schermata dell'ou rput risultante
sono mosc:raci nella figura 2.1.
Il

Per quanto questo programm a sia- semplice, iJlusrra mqlce cararrerisciche importa:a.ri
del linguaggio C. Consideria mo ora nel dettaglio ogni riga del programma . La. ciga
1

Un primo programma e */

incomincia coh /*e termina con ""/ per indicare che la riga un commentc. l progra.mmacori inseriscono dei commenri per documentare i programmi e migliorare la leggibilil
degU stess.i. [ conimnci non. p rovocano l'esernzion e di nessuna azione da pnrte del computer, quando il prof,rrn.mma viene eseguito. l commenti sono ignorati dal compilator e
e

20

CAPITOLO 2

non inducono la generazione di alcun codice oggerro in linguaggio macchina. ncomme1no


Un primo programma C descrive semplicemence gli scopi del programma. I commenri

aiunuio anche le alcre persone a leggere e comprendere iJ vostro programma, ma rroppi


commenti potrebbero rendere diffiile la lettura dello stesso.
Un primo programma C */

/*

ma i n()
{

l NTilOOtr.llON E ALU\ PROGRA.W.IAZIONE IN C

21

c::ararcere backslash (\) den:o carattere di escope (fuga). fusq indica alla printf clie dovr
fare qualcosa fuori dell'ordinario. Nel momcnco in cui avr i.nconcraro un backslash, l'istruzione printf guarder il c:arnttere successivo e lo unir con il backslash per foi;mare una
se_qu.enztJ di escape. La sequenza di escape \ n significa iu:wline (nuova rig--~) e prvoca il
posia.ionamento de.I cursore nella pusizione iniziale della riga successiva dello schermo.
Nella Figura 2.2, sono elencare alrre sequenze di escape tipiche. Lisrruzione printt ~una
delle rance funzioni fornite dalla Libreria standard del C (ed dencate nella Appendke B).
Sequenza

printf('Wel come to

C!\n ~) i

di escape

Descrizione

\n

Newline (nuova riga). Posiziona il cursore all'inizio della riga successiva.


Tabulazione orizzontai~. Muove il cursore alla tabulazione successiva.

Welcome to Cl

\t
\r

Ritorno carrello. Posiziona il curS-Ore all'inillo dclla riga crreme; non lo fa


av3.Jl7..a.re a quella successiva.

Errore tipico 2.1

\a

AUarme. Fa suonare il cicali no dd sistema.

Dimtmicare di urmzare un commento co11 "/.

\\

13ackslash. Visualizz.a un cararrere backslash in una isrrLI2ione printf.


Apice singolo. Visual izza un carattere apice sin?olo in una istruz.ioue p-rintf.

Figura 2. 1

Un programma che visualizza del testo.

\'

Errore tipico 2.2

, ~

Jncominciare Ull COmmenJo (()Il caratteri

''/O temlllllTW C01l /"'.

La riga

Figura 2.2 Alcune sequenze di escape tipiche_

Le ultim'e tre sequenze di escape nella Figw'a 2.2 pou.ebbero semhrare srrane. Dato
che il backsl:ish ha un significato speciale per l'isrruzione primf, ovverosia essa lo ricono-

ma i n()
una parre presente io rutti i programmi C, Le parentesi dopo main indica.no che main
un blocco di costruzione del programma. hiamaco fimzione. r programmi e com:eogono
una o pi funzioni., fina delle quali deve :essere main. Ogni p1ogramma C comincia eseguendo la funzione main.
1

Virgolette. Visualizza un cararre.re virgolen:e. in una istruzione printf.

Buona abitudine 2.1

l(2J

Ogni fitnzione do!lrehbe 'ssere preceduta da un cotnmento che ne descrivag/ scopl.


La parentesi graffa aperta, {, deve aprire il corpo di ogni funzione. Una corrispondente
parmtesi graffe chiusa deve chiudere ogni funzione. Q uesra coppia di parenresi graffe e la
porzione di programma racchio_sa in esse sono and1e cl.erre blocco. Il blocco w1a importante unir dei prog(ammi C.
La riga

printf( "Welcome to C!\n');


ordina a1 computer di eseguire una azione. visualizzare sullo schermo la stringa di caratteri
indicata era le virgolette. Una stringa a voi ce detta stringa di c11.mtteri, messaggi-O o letterale.
L'intera ciga, incluso printf, i suoi argomemi all'inrerno delle parencesi tonde e il
prmto evitgoltt (.; ), . derm istruzione. Ognuna di queste deve cermU:i.a.re coo un punto e
virgola (detto anche. te.nninatore di istruzione). Nel mo~ento in cui sar e.seguira, risrruzione printf precedente visualizzer sullo sch~rmo il mes~o Welcome to e I Normalmente, i caraneri sono visualizzati nello sresso modo in ct appaiono m le virgoierre della
i ~'Ull2One printf. 0$~ervate che i ~cararlcri \n non sono srati vis1:1alira.ad sullo schermo. TI

sce come un carartere di e.scape, piurrosto che come un qualcosa da visu.a.liu.are, utilizzeremo un do ppio backslash (\\) per indicare che oe dovr essere visu.alizzaro uno singolo.
An.che scampare le virgolette presenca un problema per l'istruzione prinrf, p0ich essa
normalmente presume. che queste ultime indichino i limi di una stringa e che le stesse
non debbano essere effetrivamence visualizzate. Usando la sequen7.a di <:Satpe \", informeremo prinrf che dovr stampare le virgolette.
La parentesi graff chiu;a, }, indica che stata raggiunta

la fine

dcl main .

j~ Errore tipico 2.3

~ hn.mettere in un programma il norne.detl:afunzi.one di output pr-intf

comeprint.

Abbiamo affermato che l'istruzione printf spinge il computer a seguire una azione.
Nel momento in cui in esecuzione un programma qualsiasi, il computer svolge una serie
di azioni memre il programma prende delle decigoni. Alla fine di quesro capicolo, aatreremo delle. isauzion.i de<':isi0nali. N'el Capirnlo 3, spiegheremo ulceriotmence questo
modello di azione/decisione della pr9grammazione.

impo-rtanre osservare che le funzioni della libreria srandard, come printf e scanf,
non faru10 parte del linguaggio di programmazione C. Di conseguenr.a, il ompilamre non
potr trovare, per esempio, un errore di batcinua in printf e scanf . Nd momenro in cui
l'istruzione. printf sar compilara, iJ compilaro.r:e fornir semplicemente uno spazio, nel
progr:tmma_ oggerto, per una "chiamata" a quella. funzione della libreria. U compilatore

22

!NIRODUZION Al.l.J\ Pl~UGRAMMAZION!! IN

non sa dove sir.rovino le funzioni ddla libreria a differem.a del linker che, quando sar cseguico, individuer le funzioni della libreria e inserir od programma oggerco le ch.iamace appropriare
a queste funzioni. A questo pumo il programma o&,aerro "completo" e promo per essere
eseguito. Il programma prodorro dal linker, infarr.i, spesso chiamato eseguibile. Nel caso
dovesse esserci un errore di digicazione nel nome della funzione, quesco sar individuato dal
linker, perch, per quel nome nel programma C, esso non sar in grado di trovare una corri~
spoudenza era i nomi di rune le fumjoni noce delle librerie.

23

/* Visualizzare righe multiple con una singola printf */


main {)
-{

printf('Welcome\nto\nCl\n');
}

Buona abitudine 2.2


L'ultimo carattere stampato da u114 fanzione che Megue qualsiasi visualizzazione dovrebbe
essere un newline (\ n). Ci assictmt che la fon.zione /,asci il cursore dello schermo nella
posizione iniziale di una nuova rig4, Li> un.ve,n.g;ioni di questo genere incoraggiano la
riusabilit dci sofiware: un obkttiv forrdo.ment.ale negli ambienti di sviluppo.

Welcome
to

e1

Figura 2.4

Visualizzare righe multiple con una singola printf.

Buona abitudine 2.3

2.3

Fate rientrare l'intero corp" di ogtd fu:n.2iivnt: qi un Livello (tre spfl.7-i), all'interno deile
parem:esi gr1iffe che definiscono il corpo de(iafimzione. Ci enfatizza ltt strutturtt fimziotude del programma e aiuta tt renderlo pi leggibile.

TI nostro prossimo programma milizza la funzione scant della libreria standard per leggere due
interi digirat:i alla rascic:ra daJl'ureme, calcolare la somma ~ei due valori e visualizzare il risulrato
U;Saodo la funzione printf . Il programma e I'oucpur d i esetnpiq son0 mostraci neUa Figura 2.5.

Buonn abitudine 2.4

/* Programma di addizione */
#include <stdio.h>

5'-egliete una convenzione pr la dimnsione del rientro che preferite e qwndi appiicateiA uniformemente. Potrebb essere utilizzato il tasto di tabulazione per cretlre i rientri, ma tenete pres-ente che i punti di 4rrestv delle tabulazioni potrebbero variare.
Rm:comttndiamo di usare delle tabulazioni da 114 di pollice (6,35mm) oppure di contare manualmente tre spazi per ogni livello di rientro.

main()
{

La fum.ione printf pu visualizzare Welcome to e I in molci modi differenci. Per


esempio, il programma della Figura 2.3 produce lo stesso ourput dcl programma in Figura 2.1. Ci accade perch ogni printf riprende la visualirtaz.ione dal punto io cui s.i era
fermata quella della printf p'recedeme. La prima printf visuaHua Welcome seguito da
un.o spazio, meoc:re la seconda printf inmmincia a scampare immediarameme dopo lo
spazio.
Usando il cruartere newline come nella figura 2.4, uua sing0la funzione printf porr
visualizzare diverse ~ighe. Ognl volta che inconcrer la sequenza di escape \n (newline), la
funzione printf si posizioner all'ini~io d~ll~ riga successiva.

Un altro semplice programma C: sommare due interi

i nt integer1, integer2, sum;

/ * dichiaraiJ.oni */

prifltf('Enter first integer\n ") ;


scanf( "%d", &integer1);
printf( "Enter second integer \n');
scanf("%d", &integer2);
sum ; integer1 t integer2;
printf("Sum is \d\n'', sum);

/"
/*
I*
/*

return 0;

/* i ndica c he il prog r amma t erminato con successo

EntFer f irst

inte~er

45

ma in()

Enter second integer


7.2.
suin is 117

printf("We lcome ");


printf("to Cl\n");

Figura 2 .5

Wel oome to Cl

Figura 2.3

Visualizzare su una riga con iscruzioni printf distinte.

~1

/*. Visualizzare su una riga e<on due i struZioni printf *l


{

prompt */
l egge un intero */
prmpt */
legge un intero */
1~ a~seBnamento della somma 'I
t visualiz.z.a la somma t

'

Un programma per la somma.

Il comrru:nro / * Programma di addizione * I dichiara lo scopo del programma. L'l riga


#incl!Jde <stdio.h>

uoa direrriva per il preprocessore del C J..e righe che LnCOlflncianO COD /I SOUO eJabocace daJ
preproessore, prima che il programma sia compilaro. Questa specifica riga indica al preprocessore

G\PITOLO 2

24

d indudcrenel programma il concenuco del file di intestazione per l'input/output rMndard (stdio. h).
Quesro file di imes.roziQne conriene Le informazioni e le dichiarazioni u.sace dal compilarore
durame la compilazione de.ile funzioni per l'input!ourpur srandard, come printf . Il 61e di
inu:sraz.ione contiene anche infurmaz.ioni che aimano il compilatore a dererminaie se le chiama.re alle funzioni deit Hbrecia sian0 sc:ace scrirte correttam en~e. Nel Capitolo 5 spiegheremo
pi decragliatamenre i conrenuri dci fil dl inresw.ione.

Buonr1 abitudine 25
Per quanto I'inclu.sme di <$tdio. h> sia op~onafe, esst1 dovrebbe essere effettuata in
ogni programma e dh utilizzi u.nn qfl._11'1p1q1-{e delle funzioni di inptf.t!output della libretia standard. Ci aiuter iJ' compilatore tt sempilfico.l'vl l'individuazione-degli e1:rori durante fafr.se di compilazione del vostro progrrzm~ piuttoSJ che durante quei/a
di esecuzione (quando gli errori sono di solito pi onerosi da correggere).
Come abbiamo affermam in prncedem,a, ogni prowam.ma cominc_:ia la propria esecuzione con la fonzione main. la parenresi graffa aperca { marca l' inizio del co~p9 del main
mentre la 9rrispon dcnre parentesi graffa chiusa marca la fnc d.i quesr'ulti mo. La riga
i nt

inte~er1,

integer2 , sum;

una dkhitt1112.ione . .Le voci integer1 . i nteger2 e sum sono i nomi delle 11ari.-dbili. Una
immagazuv~bile una locazione (posjzione) della memoria in cui un valore pu essere
che le
specifica
ione
dichiaraz
,Questa
na:ro perch possa essere utilizzato da un programma.
variabili
queste
cbe
significa
Ci
int.
variabili integer l, integer2 e sum sono di cipo
conrcrranno dei va.lari interi, ovverosfa, dei numeri. inte.ri come 7, - 11, O, 31914 e simili.
Tutce le variabili devono essere dichiarare con un nome e un tipo di dam, i.mmed.iatamence
dopo la parentesi graffa aperta che inizia il corpo del ma in, prima d1c possano essere
urilizzate in w1 programma. In C. ci sono altri tipi di dato oltre a int. In una dichiarazione
possono essere dichiarate molte variabili dello stesso tipo. Avremmo poruco scriver tre
dichiarazioni, una per ogni varfabile, ma la fo rma ~ta prec::edentemence p concisa.
~ Buona abmdine 2.6

25

Buono abitudine 2.7


Scegliere nomi signifiC11.ri11i di variabile n.iute:rlr n rendere ilprogmmma auto esplicativo. ill altre paro/. sara1mo 1tecellrzri meno commenti.
Bi~ona

abiNtdine 2.8

ln prima lettera di un identificatore usato e<mte un semplice nome di variabile M11reb


be essere tttw let:tan. minuscola. Pi avanti, in qu.ette libro, asseg;nerenw 1111 sif!iificato
particolare agii identificatori che incomiiiciano con m1a lettem maiuscolit e a quelli che
usano soltanto lettere maiuscole.

Buona abitudine 2.9


I nomi di vario~ile fonnati da pi parok possono aiutare a rendere il programma pi
leggili.ile. Evitate di tombinme le di11er.se pctroLe r.ome in totalcom mi$Sion s. Sepnmtele piuttosto con carntteri di sottolineatum, come in total_ commiss ions o, se 11olt
re legarle insieme, cominciate ogni parola dapo la prima con una Lettera maiuscol'l, COlnl!
in totalCom missions .
Le dichiarazioni devono essere sisremace dopo la paremesi graffa aperta di una fum.ione e prima di ogni struiione es!guibile. Per esempio, nel programma _della f.igura 2.5 ,
l'inserimento della dichiarazione dopo la prima printf avrebbe causato un errore di sin.cassi. Un errore di sint.'lssi causato quando il compilat0re non in grado di riconoscere
una iStrll'"1.ione. Il cornpilarore normalmence emene un messaggio di errore per aiurare il
programmamre a loelizzare e correggere l'istruzione errata. Gli errori di sincas$i sono
violazioni delle regole del linguaggio. Essi sono anche chiamati errori di cqmpilazione, (}
1
-

errori a tempo di compilazione.


Errore tipico 2.5
Sistemare le dichiarazioni di 11arit:zbile tra le istrt1Pioni eseguibili.
Buona abitudine 2.10

Mettete uno spazio dapo ogni virgola(, ) per rendere il programma pi leggibile.
On nome di variabile in C qualsiasi id.emi.fictltori valido. Un ide.uti:fcacor~ una serie
di caratteri, comprendente lettere, numeri e caratteri di srtoli.Jiearura LJ, che non comincia on un numero. Un idenPfcacore pu avere qualsiasi lungh1=zza, ma soltanto i primi 31
l dell'ANS IC.
c;ua:tterid~0no CS$~{e riconosciuti dal o.mpilaro re C, i.o accordo tou loscandar<
in C,
dlffernci
sono
ninuscole
1
Il e e case sensitive, ovvero, le letrere Jna.iuscole e quelle
perci a 1 e A 1 sono idencificarori discinti.
Errore tipico 2.4

Us.are una lettera maiusco/11 laddope ne dovrebbe essere utilizzata una


est:fnpio, sr.riuent;/Q Min in.v.eue di ma in).

INTRODUZIONE ALl.1\ PROGRAMMAZI ONE. IN

mimtsc~la

(per

Obiettivo portabilit 2.1


Wate identificatori di non pi di 31 caratteri. Ci aiuter ad assicurare I.ti portabillttt
epotr evit{Jre alcuni subdoli errori di programmazione.

Separa.te le dk.hiarazi.oni e le i.stmzioni eseguibili dJ una fimzmc crm una riga vuotn, per
enfatizzare il ptmto in cui finiscono le dichiarazioni e i11cominciano I.e irtmzioni eseguibili..
L'isrruzione
printf( "Enter fi rst integer \n " )i
visualizza il letterale Enter f irst intger sullo schermo e si po~ iziona all'inizio della riga
successiva. Quesco messaggio derro prompr perch chiede all'i:icence di e.$eguire una azione specifica.
L'iscruzone

scanf(" \d", &intege r1);


urllizz.a scanf per ottenere un valore dall'ucenre. 1..a funzione scanf prende i dati in ingresso dallo srandat:d input che di solito la rasriera. Questa scanf ba due aigomenci: '%d " e
&int eger1 . li primo argom.enro, la st11ingadicm:1trollodeljrmato, indica ,il tipo di dato
che dovr essere immesso dall'Uience. La rpecific.a di conversione \d indica che il dato dovr

26

C1\:l'ffOLO

essere un incero (la lettera d sca per "inrero decimale"). Il %, in questo con.resto, consideraro dalla funzione scanf (e come vedremo anche da printf) alla stessa srregua di un
carattere di C!Scape {come \) e la cornbi.naz.ione %d una sequenza di escape (come \ n). li
secondo argomemo della scanf incomin'i'ia con una E commerciale ( &), detta in C
opertttore di indirizzo, seguita dal nome della. variabile. La E com merciaie (o ampersand),
quando combi.nara con il nome deU~ variabile.., indica alla scanf la locazi~t(e di memoria
in cui irnmagazzinani. la variabile i nteger1 . Il cbmputer quindi immagazziner il valore
della variabile integer1 in quella locaiioo.e, I:uso di ampersand (&) confonde spesso i
programmarmi principianri o queUi che hanno gi programmato in alrri linguaggi cbe non
richiedono quesca nocazione. Per ora, ricordare solcanro di far precedere ogni variabile da
un arnpersand in rurre le isrruzioni scanf . Alcune eccezioni a questa regola: saranno discusse nel Capicolo 6 e nel Capirolo 7. li reale significato dell'uso di ampersand diventer
chiaro dopo che avremo srudiato i puntatori nd Capitolo 7.
Nel momento in cui il computer eseguir la precedente scanf, arrender che l'urente
abbia immess9 llI! valore per la variabile integer1 . LLLCente risponder digirando un
incero e premendo il tasto retum (a volte dea;o t(!sto enter o tasto di invio), per inviare il
numero al computer. Quesco assegner allora U suddecro nwnero, o w;lore; alla variabile
integer1 . Ogni sucessvo riferimcnm a integer1 nel programma user Tale valore. Le
funzioni printf e scanf facilitano l'inrerazione tra l'ucente e il compmer. Daro che quesca
incerazione somiglia a un dialogo, spesso chiamata elaborazione interattiva.
Cistruzione

visualizza il m~o Enter second i ntegr sullo schermo e quindi posiiiona il cursore
all'inizio della rig.i.~successiva. Anche questa' printf chiede all'uceme di eseguire una azione.
I.:istnt.:z,iqne

L'istruzione
printf( "Sum i s %d\n " , sum);
usa la funzione printf per visualizzare suUo schermo il len:erale Sum is seguito dal valore
numerico della variabile sum. Quesca printf ha due argemenci, ' Sum is l\id\n" e sum. IJ
primo argomento la ~rringa di conrrollo del formato. Quesca contiene alcuni caratreri
JerreraH che dovranno essere visualizzati e la specifica di conversione l\sd indicante che sar
visualizzato un intero. U secondo ti.rg0 menco spedfa il valore da visualizzare. Osservare
che la specifica di conversione per un incero la stessa sia in printf, sja in scanf. Questo
accade per la maggior parte dei cipi di daco in C.

I calcoli possoo.o anche essere eseguiti all'inreroo della istruzione print f . Avremmo
potuto combinare le due precedenci istruzioni in

printf("Sum is %d \ n " 1 integer1

integer2);

I.:isrruzione

r eturn 0;
resc:ici,1isce il valore 0 all'ambiente del sistema operadv in cui il programma stato eseguito. Questo indica al sistema operativo che il programma stato eseguito con succ~sso.
Consulcace i manuali del vostro specifico sistema operativo, per ottenere informazioni su
come comunicare un parti9>lare ripa di falljmento del programma.

ottiene dall'urente un valore per. la variabile integer2. I.:istmzione di assegnamento


I

Errore tipico 2. 7
Dimenticare una:0 entrambe /,e virgolette che circondano la stringa di contro//,o delfirmuttQ
i"n una printf o in una scanf.
Errore tipico 2. 8

scanf('%d", &lnteger2);

= integer1

27

La parentesi grafl chiusa. }, indica che stata raggiunta la fine della funzione main.

printf( "Enter second integer\n ")i

sum

I NTRODUZIONE ALlA l'ROGRAMMAZlONElN C

integer2;

calcola la somma.delle variabili i nt egr1 e integer2 e assegna il risulcaro alla variabile sum,
usando l'operatore di assegnamento= . .Listruzione lea:a come "sum prende il valore di
i nteger1 + integer2". La maggior pane dei calcoli sono eseguici ncUc istruzioni di assegnamento. I.:operamre = e quello+ sono chiamari '<1p.erat01i binari percb ognuno di qu.esti ha due
operandi. Nel caso, dell'operatore +, i due operandi sono i nteger1 e in1;eger2. Nd e::aso
dell'operqtore =, i due oper3l1di sono sum e il valore deJJa espressione integer1 + integer2.

Buona abitudine 2.11

Dimenticare il % in una specifico di conversionr nello_ minga di controllo del formato


di una printf o tli uno scanf.
Errore tipico 2.9
Inserire untt sequenza. di escape come l n all'estemo della sttinga di controllo de.I.formato di una printf o di uha scanf.
Enore tipico 2.1 O
Dimenticare di includere le espmsioni di cui dovranno mere visualizzati i valori, in
una p rin tf contenente delu specifiche di conversione.
Errore tipico 2.11

Inserite degli spazi su entrambi i "1ti di un operatore binario. Questo mette in risalto
/'operatore e rende pi leggibile il programmo.

Non fornire, nella stringa di controllo del formato di una printf, una specifica di
converrione, qualora sia neces;aria per visualizuire una espre;sione.

Errore tipico 2. 6
Ertore tipico 2.12
Il calco/,o <in una istruzione di assegnamento deve.essere a destra dell'operatore =. un
en-oredi sintrmi sistemare wn: calcolo a sinistra di u.n operatore di as>egnamento.

Inserire, a/L'interno della stringa di controllo delformato, la virgola che dovrebbe separare la stessa dalla eiprcssione da visualizzare.

28

C1\J>!TOLO

Errore tipico 2.13


inteper1

Dimenticare, in una irtruzione scanf, di far precedere da un ampersand una variabile, quando quma dovrebbe, di fotto, esserepreceduia da un ampersand.
Su molti sistemi, questo errore rilevaco nella.fase~ecuva deuo "errore di scgmencaz.ione"
o "violazione di accesso". Un simile errore occorre, quando il programma di w1 utente
cenca cli accedere a una parte della memoria del computer per cui il p rogramma Stsso non
ha clirirti cli accesso. La causa precisa di quesrn errore sar spiegata nel Capitolo 7.

li

Errore tipico 2.14


Far precedere da un ampersrtnd. in una istn1zwne printf, uno vm1hle quando, di
fotto, questa non dovrebbe essere pr.ecedttta d<.1. tm ampersand.

Nd Capitolo 7, srudieremo i pumamri e-vedremo dei ca.si ill cu:i VO(remo far precedere da w1 a,mpersand un nome di variabile, per visualizzare l'indirizzo della scessa. Per molti
dei prossimi capitoli, rurtavia, le istruzioni printf non includeranno tale uso dell 'ampersa.nd.

2.4

29

lNIRODUZIONEALLA PROGRAMMAZIOl'JE IN C

integer2
Figura 2.7

8
8

le locazioni di memoria, dopo che entrambe le variabili sono state ricevute in input.

che esegue !'addii.ione, comporta anch'essa una scrimira disucmiva. Ci accadr quando la
so111Il3. ca1co1:u:a da integer1 + integer2 sar siscem:ara nella locazione sum (dism1ggendo il
-valore he poreva essere gi contenuro io sum). Dopo che sum sar stata calcolata, la memoria
apparir come nella Figura 2.8. Osservate che i valori di integer1 e integer2 appaiono
~menre com'erano prima di essere urilizzaci nel calcql<;> di sum. Questi valori sono ~tari
rrriliz.za.ti, ma non dimurci, quando il computer ha esegu.irn il calcolo. Di <::o1l5egue117..a, quando
un valore lerro da una locazione di memoria, r:a.le processo detto lettura non distrur.tiva.

Nozioni sulla memoria

i ntepe r1

45

i nteger2

72

sum

117

I nomi cli variabile come intege r1 , intege r2 e sum corrispondono in.realt a locazioni (o
posizioni) nella memoria del cmpurer. Ogni ~bil ha un ffome, un tipo e un va/ore.
Ncl programma per la somma della Figura-2.5, quando sar eseguita l'iscruz.ione
Fig ura 2.8

scanf( "%d", &integer1);

il valore digitato dall' utenre sarimmesso nclla._posizione dimemoria alla quale ilnome in t ege r1
stato assegnato. Supponere che l'uccnte i.mmerra comev-alore per integer1 il numero 45. Jl
ompurer sisremc:r il 45 nella locazione integer1 , come mosrrato dalla Figura 2.6.

int~11er1
Figura 2.6

Una locazione di memoria che mostra i1nomee il valore di una variabile.

Ogniqualvolta un valore si.~remaro in una posi1johe di memoria, esso si sostirujsce a1


valore comenuco in precedenza in quella locazione. Dam che quesca informazione precedenre
sar discruna, il processo di scrittu(-a in una l0cazi9ne di memoria detto scrittura distmfitiva.
Supponete che l'urente immerta il valore 72 quando l.'isrruzione
scanf( ~%d " ,

&integer2);

eseguica. Quesro valore sar siStemato neUa locazione integer2 e la memoria apparir
come nella Figura 2.7. Osservare che quesre po!!izioni non saranno necessariameme adiacenti ill memoria.

Una volca che il programma avr orrenuro i valori per integer1 e integer2, esso li
sommer e sistemer il risulcaco nella vari.abile sum. I.:isuu.zione
sum = integer1 + integer2;

Le locazioni di memoria dopo un calcolo.

2 .5 L 'aritmetica del C

la maggior parte dei programmi esegue dci calcoli. Gli operd.t<tri aritmetici del sono
Iiassun nella Figura 2.9. Osservare l'uso cli vari simboli speciali non utili7.zati in algebra.
I:.asterisco ( ") inclica la moltiplicazione, mentre il segno di perwm~ale (%) denota l'operarore modulo che sar inuodotto in seguito. In algebra, se volessimo molciplicarc a per b.
porremmo semplicemenre sistemare quesri nomi di variabili, composti di lettere singole,
l'uno di fianco all'akro come in ab. In C invece, se avessimo scrirro cosl, ab sarebbe stato
interpretato come un singolo nome (o idencifcamrc), composco cli due letrere. Di conseguenza, il e (come gli ali:ri linguaggi di programmaz.i0ne, in generale) richiede che la
moltiplicazione sia espliciram'eme denoraca, lltUizzando l'of?~rar>n~ , come in a * b.
Ope razioni in C

Operator e a rit m e tico

Espressione a lgebrica

Espressione C

Addizione

h7

p -c

p . e
b

* m

I y

Sorrraz.ione
Molciplicazione

bm

Divisione

x/y o

MGdulo

+ 7

Fig ura 2.9

..

Gli operatori aritmetici del C.

r mod s

o x+y

r %s

30

CAPITOLO 2

GLi operatori aritmecici sono rurri operarori b.inari. Per esempio, l'espressione 3 +
7 c.onciene l'opeJatore binario + e gli operandi 3 e 7 .

La divisiom tra interi resciru:isce un risulcato incero. Per esempio, l'espressione 7 I 4


sar_ :valutata 1, menrre il valore di 17 I 5 sar 3. lJ C fornisce l'operatore modulo, lii, che
r~tiruisce il resto cli una divisione rra inceri. Questo un operatore incero che porr essere
ut.i.Uzza.to soltancd ton operandi.-rueci. L:espressione x lii y resr:iruit il resco della divisione
aa x e y. Di conseguenza, 7 lls 4 restitui.r 3 , mencre 17 lls 5 produrr 2 . Discuteremo
melre interessami applicazioni dell'operarore .modulo.

lNTRODUZIONEAllA PROGRAMMAZ.IONEJN C

Le regole di priorit degli operat01i son direrrive che consentono al e cl.i valutare le espressioni
neU'orcline corretto. Nd momento in cui affermiamo che la valutazione procede da sinistra a
desrra, ci sciamo riferendo all' associati.vt degli operatori. Vedremo che alcuni operatori associano da destra a sinistra. LaEigura 2.10 riassume le suddette regole di priorit degli operatori.
Operatore/i Operazione/ i
Ordine di valutazione (priorit)
Parentesi

( )

Sono valucate per prime. Nel caso che le parenresi siano


nidificare, saranno valutare per prime le espressioni nel
la coppia pi interna. Nel caso che ci siano pi coppie
di parencesi "allo stesso livello" (ovve~osia non nidificate),
queste saranno valur.ar da sinistra a. destra.
Sono valutare per seconde. Nel caso che ce ne siano
moire, saranno vaJmare da sinisrra a destra.

Errore tipico 2.15


Un terittivo di divisione per zero di solito indefinito in un computer egeneraimente
causa un errbre fatale, vale a dire, uno di quelli che provqcano la terminazione immediata del programma, se!lZ'A che questo possa compktare con successo il proprio lavoro.
Gli errori non fatali consrotoM ai programmi di continuarefino al wro compktamentb,
producendo spesso per qei risultati non corretti,
Le espressioni aritmetiche in C dovranno essere scritte su una riga per facilitare l'immissione dei programmi nel computer. Di conseguenza, espressioni come "a diviso b "
dovranno essere scritte come a / b, cos che rurri gli opcrarori e gli operancli appaiano su
una stessa riga. La. noraz.iooe algebrica

*, I o

Molciplicari_ooe
Divisione
Modulo

9s

o.

Addizione
Sottrazione

Sono vaJutate per ultime. Nel caso c::he ce ne siario


molce, saranno valutate da stnistra a desaa.

Figura 2.1 O Le priorit degli operatori aritmetici.


Consideriamo ora diverse espressioni a.Ila luce deU regole cli priorit degli operatori .
Ogni esempi0 elenca una eSpressione algebrica e il suo equivalenre in C.

a
b

non generalmence accertabile dai compilatori, sebbene esistano alcuni pacchetti software
sgecializzaci, che supportano una noraz.ione pi naturale per le espressioni macemaciche
c0mplesse.
Le parentesi s,ono urilizzate oeile espressioni C in una maniera molto simile a quella
ucil.izzata nelle espressioni algebriche. Per esempio, per molripli.Care a volre la quancic b +
e , scriveremo:
a

31

(b

e)

Il e valuta l e espressioni a:raneciche in una sequenza precisa, dete.rm.ina1a dalle seguenti regole di priorit degli operatori, che sono generalmeme le scesse adottare in algebra:

l:esempio seguente cfilcola la media aritmetica di cinque termini:


a+b+c+d+e

Algebra:

n1

C:

m = (a

s
+ b + e + d + e) I 5;

Le parentesi sono necessarie perch la divisione ha una priorit maggiore della addizione.
Dovr essere divisa per 5 l'intera quanric. (a + b + e + d + e ). Nel caso le parentesi
dovessero essere erroneamente omesse, ottrremmo a + b + e + d + e / 5 che sareb.be

valutata in modo scorretto come

e
a+b+c+d+ -

l. Le espressioni o parti cli esse, <iomenure all'imemo cli coppie di parentesi, saranno valucare

_per prime. Di conseguenza, le parentesi potranno essere utilizzate per forzare l'ordine di
valutazione, in moda-che quesf.ultima si svolga nella sequenza deside,.ata dal programmatore. Le parentesi hanno il "massimo livello di priorit". N~ caso le parente.si siano nidificau saranno valurare per prime le espressioni della coppia pi inrerna.
2. In seguico saranno valutare le operaz.ioni di molciplicaz.ione, clivisione e modulo. Nel caso
che un'espressione contenga diverse operazioni di moltiplicaz.ione, clivisipne e modulo, la. va.lutazione proceder dasinistta a descra. La molripliCa!rione, la divisione e il modulo
si crovano allo scesso livello di priorit.
3. In ultimo saranno valutare le operazioni di ad.di.i.ione e cli sottrazione. Nel caso che una
espressione contenga diverse operazioni di ad.diz.ione e cli sottraz.iooe, la valutazione proce4er da sWsa:a. a desua ..Ancbe l'addiz.ione e-14 sottra.ione.hnno lo stesso Iivello di priorit.

I.:esempio seguente l'equaiione cli una linea retea:


Algebra.:

y = rnx+b

C:

y = m* X+

bj

In quesro ~ non sono richieste delle parentesi. La moltiplicaz.ione sar valutata per
prima poi:h essa ha una priorit maggiore della addizione.
!:esempio successivo contiene le operazioni di modulo (%), moltiplicaz.ione, divisione,
addizione e soruazione:
Algebra:

C: z

= p

= pr%q+w/x-y

* r lls q + w I x - y;
<D@ G)

'
CAPlTI:0.2

32

I nu)ne.r:i c~chia,ti sotto l':i.sr.ruzigne mdiean9 l;ordin:e ifl cui il C valuter gli operarori. La
mol4pl.k;1rione, il mo.dul0 e la diyi$.i'ofi!! saranno \7alutati per pnirni in ordine dasiuistra a
tle.5tra (ov,v~sa a!\SOCl)..FIO da sinistra a deste~), po~t:h.hantio una priorr~ .rnagg!o~~ della
addjii_ll fol[a so.ttrazione-. ln seguito sarruillo va!utre fal!dizjone e ta s~jne. Anche
queste savanno valmare da.sinisrra a desua.

N:n rurre le espre~sioii eri divers~ coppie di pare,nr<;sl eq11tengo!\.9 dlle parentesi
tridfc.a'te.

eesp r~sslone

(b

e)

+ e

(d + e)

non eontiene patentesi nidificate. Diremo invece

che le parentesi sono "allo stesso livello".

~ ql1~t~ s~ruazign i,. il valuter per prime le espre.<ts:ioni ndu.S rrelie parenresi in ordine

da sin'i'sc:ra a deso:a,
m<;>

Per sviluppare una miglior comprension delle regole di priorir .d,egli opetamri, vediae:Qm.e il C valuta Wl polinomio di secondo gtado.

y:

a* X* X+ b

*X + ,Cj

CD@$
J aumeci erbiati sorto l'isrru7-iene indlcano l'ordine in cill il C eseguir le operazioni. Nqn ~iste n~sun opeFator.e adrmc;tic.9 in
per 1'elevamenro a ptnza, pere
a.bbiamo tapprcsentiJ.to x2 tome X * X . La libreria: st.andard del e include La funzione
pow ("p$;lwr'", porehza) pe.r ~guire 1'.ele.varnento a f>.0tei,a. A caus;i; .~ a!Guni .insidiosi
pteolmi correlati ai tipi di &c .rithiesei da pow, rimandiamo la spiegazione derragiiara di pow fmo al Capitolo 4.

Sup,po.nete the-a = 2, b = 3, e = 7 e x
il precedeme polinomi!) di s<k:orido gra.:do.

= 5. La Figuni 2.11 mosua come sar. valUtaro

.JNrrRQlJU:llON l~ ALLA l'ROGR.<UYIM.PmONE IN C

2.6

33

Prendere delle decisioni: gli operatori


di uguaglianza e relazionali

Le isrruz.ioni ese~1ibili del. e e;:ompiono delle azioni (come dei calcoli o l'input e l'ourpm;
dei d;rti), oppure prendono delle decisioni (vedremo eresrn malti esen'\pi di questo ripq). Jn
un programma; per e.?rupiQ, pq~remm~ ptenqe:r una decisione per d_c:;termb:iawse il voto
di .Ufia persona in un. esame maggio<e o uguale a 60 e, in ral caso, vf$.ualir.tru: .iLme$s:aggie
"Cm1:gratula:z.ionil Aver $1'1peraro l'~am". Questa se-,ione i.1m:0duee mi semplice versi.o.ne dell stmttur di t'ontrollo i f del G, che clisente .a un pr.ogrmrima di prendere delle
dee::isoo basate sull<t verit 0 sulh falsit dl alcun.e esj:>re5siol chiatnare per l'appumo
atmdizioni. Nel cas.o in cui la: condizione sia sraua soddisfatta, oYVerosia nel caso in cui
risulti vera, verr ese:;guira i'istruzione pre~cr1teall'memo del eorpo della srnnrua i f. N el
gaso in :ui la. ;om;liziOD.~Jlon sia soddisfa rea. owerosia nel caso in cui cisl ci falfil, ~srruzio11.e prese);lr~ ;JJl' i qreot~ qel corpo nqn verr e.seguita. Oopq il compler;ne_
.ro dcUa stmttui'~
f, i.ndipendemen)ente dal faqo che l'istnqjone del corpo sia cs~guiI;'!. o noi l'esiuzjone
proceder cn l'istruzine succc:s.sicva alla srrmrura i f.
Le c<:>ndiziqni nelle $trtttture ' f sono formate usando gli vp1qJori di" ugr14glil!''n.Y4 e gli
o-perawri n:ktzi.fin_ttli rip.s.s_unti n,clla F.igru:a2.12. Gli OJJe1'acori re4izon~li h~fi.0 lo sc~so livello
di priocicl.i: e ,assoti:mp da s.iriistr:a a dStra. Gli pratori di uguagliru:iz banno un. livello di
pciorir pi basso degli 'Operatoci r.elazionali e associano da s.illisrm a destra. (Nora: in C, una
ndzi:bne pu e-ssere .in realt una espressiene che generi un valore. ugual (fulso) o diverso
(\tero) da ieEO. VedremG moke applicazioni dl ei nd corso del libr9).

O peratori aJgebr ici


di uguagli.nia
re lazi.o na li standa rd

Operatori
di uguaglianza o Esempio di
relaziona li in e condizio ne e

Significato de lla
condizione e

Op~rori di uguaglian2a

P~s.~1.

I=

f: y

x non ugul a y

>

>

X >

<

<

y
< y

x maggio.i;~ di y
x min0re di y

>=

X >=

:::;:

<=

X <= y

#.

x uguale a y

Operatori .relazionali

Pmso2.'

(l!J:inU.la ni()ltipll~ ne dell'addizione}

Figura 2. 12

Of!!~ratorl

y.

x maggiore o u,guale a y

x tnin.pre o u:iwale a y

di uguaglianza e retazional.

Errore. tipit'f> 2: 1()


(L'ad~ii'o'uc p_i:.uinsrrn)

$4t gentrato tjrt, -e:rron: di sintassi, se si s-epmera?zno '"{{'1 degli spazi i tf.11.'e sirnbii che
~omppngotfo pgi1uno .4.egli qperafjJ.ri --, I= , >= e <=.

Errore tipico 2.17

Figura ;2.11

Va!ut~ione 'd

un polingmie di secondo grado.

SarlJ:gertf!rat 1irz. envre di sintr;ts_si fl:' si :Jvertin;mw i.dite.simboli che com,pongarlQ ognurio
degli operatori I=, >=e <=, rispettivamente in =I, =>e=<.

UPITOLO

34

35

l.Nrn.ODUZIONE Al.I.A PROGRAMMAZIONI:. IN C

~ Error tipico 2.18

int n.uml , num2;

printf(.Enter two ntegers, and I Will ~ell you \ n");


printt { "the relationships they satisfy: );
/ *legge due interi*/
scanf{"\d%d ' , &num1, &num2);

Confondere l'operatore di uguaglianza == con quello di assegnamento =.

Per evirare questa confusione, l'operatore di uguaglianza dovrebbe essere ferro


1mme "doppio uguale?1 mentre l'operarore di assegnamento dovrebbe essere letto come
''prende". Confondere questi operatori, come vedremo presce, non prnvocher uecess.ariamente un errore di sintassi facilroenre riconoscibile, ma potr causare degli errori
logici molto subdoli.

~ Errore tipico 2. 19

ln.rerire un punto e virgo/,a subito dpo La parentest destra della condizione, t una
stmttura i f .
I.:esempio<lella Figura 2.13 uliua sei istruzioni i f per confronrare due.numeri immessi
dall'uceme. Qaaloca la condizione in qualcuna di queste isrruzioni 1f dovesse essere soddisfatta, sarebbe eseguita la funzione printf .SSociara a quell'if. Nella figura sono mostrati
jj -programma e. ere output di esempfo.
Osservate che il programma in Figura 2.13 ufu.z.a scanf per prendere i:n input i due
numeri. Ogni specifica cli COilYersione ha un argomento co_rrispondente io cui dovr essere immagazzinato un valore. U primo ~d convertir un valo.re che sar immagazzinato hella
variabile num1 , mentre il secondo convertir un valore che sar immagazzinato nella yariabjJe num2. Far _rientrare iJ corpo cli ogni isrruziooe i f e inserire delle righe vuote sopra e
sotto ognuna di queste, aumenter la leggibilit del programma. Nora.te anche che ogni i f
della Figura 2.13 ha una singola istrUZione .nel suo corpo. Nel Capi colo 3. mosrreremo
com e specificare delle i f ton corpi composci da pi isrruzioni.

if

<n~~1 == num2)
printf(''%d is equal to %d\n", num1, num2);

if (num1 I= num2)
printf(" \ d is not equal to %d\n', num1, num2);
if (n um1 < num2)
prntf(.%d is less than %d\n , num 1 , num2);

i f (num1 > num2)


pri n-tf( "%d is greater than % \n, num 1 , num2);
if (num1 <~ num2)
printf ("\d is less than or equal to %d\n",
num1 , num2) ;
if ( nurn 1 >= num2)
printf( 0 %d is greater than or equal t
num1, num2);

return 0;

\d\n~,

/1' i n.d ica che i l programma terminato con successo /

Buona abitudine 2 .12


Fare rientrare la/e istruzione/i nel corpo di una srruttura i f .
Buona abitttdine 2. I3
ln.serire.yer I.a lef,gibilit, una riga vuota prima e dopo ogni n:rtttturll. di controllo ih un
programm/J..

a fs

Buona abitudine 2.14

&nter t wo int elJers, and I will t ell ~eu

Non ti do1mbbe essere pi di una istruzione per riga i un programma.

the re l ationships tbey -satisfy: 22 1.2


~ 1s not equal t~ 12

Errore tipico 2.20

Inserire delle virgol.e (qt1ando non sono richieste) tra le specifiche di convmione nella
stringa di corztrolw del formato in una istruzione scanf.
/* Usare le istruzioni if, gli operatori
relazionali e quelli di ug uaglianza t
#include <stdo.h>
man()
{

Ent er two i nte ger s, and ! will tell ye.u


the relationships they s atlsf y : 3 7
3 is not e~ua4. to 7,
3 l s less thn 7
les s tha o o r e qual t o 7

22 is greater than 12

22 is greater than or equal to 12


Enter two integers , ana I Will tell
the relaflonslti~~ the~ s&tisTy : 7 7
7 i s equal to 1
7 is le~s tnan o r equal to 7
7 ~ greater than or equal to 7

yo~

Figura 2.13 Usare gli operatori d i uguaglinza e relai:ronali.

CAPITOL02

36

11 commento nella figura 2.13 spczzaro su due righe. Nei programmi C, i carartcrj

di spazio bianco come le tabulazioni, i newlinc e gli spazi, sono normaJmeme ignoraci. Di
conseguenza, le istrui.ioni e i commenti potranno essere spezzari su pi righe. Non in
ogni caso corretto spezzare gli idencifcamri.

LvrRODUZJONE Al.LA l~J~OG RAMMl\7.ION~. IN

37

stessi da parre dell'urente, l'esecuzione di calcol i le scruz.ioni decisiotiali. Nd prossimo


capitolo, ci baseremo su quesrc tecniche mentre incrodurremo la programmazione rtrurturata.
Lo studente diventer pi familiare con la tecnica ru applicare dei rientri al codice. Srurueremo come specificare l'ordine in c ui le isuuzioni saranno eseguire: il cosiddcuo

fl1tsso di controllo.

Buona abitudine 2.15

Una istruzione lunga potrlt eere distribuita su molte righe. Nel caso che una istmzione possa essere spezzotll su. pi righe, scegliete dei pumi di interruzione che abbiano
un senso (per esempio dopo urw vir,,'(o.fa in un elenco separato da virgole}. Nel caso
che una istrnzione sia stattl spezzata su due o pi righe, fate rientrare tutte quelle
successive alla prima.
L;i. tabella nella Figura 2. ] 4 mostra le priorit degli operatori in""rodorci in guesco
capitolo. Gli ppcracori sono mostrnti dall'alto in. basso, in 9rdine decrescente di priorit.
Osservare che anche il segno ru uguale un op.eraro,i:e: 1rti questi opera.cori, a eccezione
di quello d i assegnamento =, associano da si.illsu:a. a deStra. J...:operatore di assego,:uncnto
(=) associa da desr.ra a si nisrra.

Parole chiave
auto
const
double
float
int
short
struct
unsigned

break
continue
else
fo r
long
signed
switch
void

case
default
enum
goto
register
sizeof
t ypedef
vola1;ile

char
do
extern
if
return
stati e
union
While

Figu_r a 2.15 Le parole chiave riservate del C.

Brtona abitudine 2.16


Ogni volta che scrivete delle espressioni contenenti molti operatori, fate riferimento alla relativa tabella de/le priorit. Assiettratec11i che gli operatori nella espressione
siano eseguiti nell'ordine appropriato. N el caso non siate sicuri di tm ordine di
valutazione in una espressione complessa, usate le parentesi per forzare l'ordine,
esattamente come avreste fatto nelle espressioni algebriche. Assicuratevi di osservare che alcuni operatori del C, carne guello di assegnamento ( =) ,11ssoci11.no da destr11
a sinistra, invece che da sinistra a destra.
Operatori

Associativit

()

da sinistra a desua

<;

da sinistra

<= > >=

da sinis.mt a desrra
da ,sinistra: a destra.
da. si.nisr:a a. desrra

I -=

l. l

di ogni funzione.
c) Ogni isrruzione t~na con un ----~
della libreria standard visuafu.za le infocm:n:ioni sullo schermo.
d) La funzione
che muove: il cursore nella
e) La sequeo2a d'escape \ n rappresenra il cmmere
posizione ini7.ia.lc: dc:Ua riga successiva sullo schermo.
della librera standard utilizzara per leggere i dati dalla
f) La funzione:
r:iscic:ra.
. usara in 1rnastringa di con1rolio del formato di
g) L.'l specifica di conversione
una funzione scanf, per indicare che sar. immesso un incero, menrrc in uoa stringa di
controllo del formato cU una funzione printf, per indicare che sar visua.lizzaco LLD incero.
h) Ogniqualvolta un nuovo valore sar sis.remato in ~1na loc.1zionc di memoria, esso si sosri1uiri\ a.I va.lore conrenuro in preccdenz.1 in quella lueazione. Qucsco processo noto come

da desa:a a sinistra

Quando un valore nr lotAo da una locizione di mcm<iria~ il valore in quella locazione sar
preservato; questo proces.~o detLO _ _ ___.
urili7..Zata per prendere de.Ile decisioni.
j) ' I:istru:t,ione
i)

Figura 2.14 Prio rit e associativit degli operateri discussi finora.

Alcune delle parole che abbiamo usato nei ptogr:mmi C di quesro capitolo, in particolare i nt , retu rn e i f , sono keyword (parole chiave) ovverosia parole riservare del linguaggio. Linsjeme completo delle parole chiave dd C mostrato nella Figura 2. 15. Quesce
hanno un signifcaro speciale per iJ compilamre C, perci il progcammarore dovr3 srare
auenro a non ucili.zzarle come idencifcaroci, per esempio, nei nomi di variabile. In questo
libro, discuteremo di cucre le parole chiave.

ln quesro capirolo, abbiamo introdotto moire caraner:isciche imporcanci dcl linguaggio


di programmazione C, inclusa la visualizzai.ione dci da sullo schermo, l'immissione degli

Riempite gli sp:izi in ognun:i delle seguenri rigne.


a) Ogni programma C incomincia la propria escuzione con la funzione - - - - reanina il corpo
inizia il corpo di ogni funzionemenrre la
b) La

a destra

I %

Esercizi di autovalutazione

2 .2

Srabilire quali delle seguenti affermazioni sono vere e quali fulse. Nel caso siano f.lse, spiegarenc:

il morivo.
a) Quando sar invocata la funzione printf, questa comincer a visuali=re sempre dall'inizio d1 una nuova riga.
b) I commenci inducono computer a vUualizzare sullo sc~ermo il cesro racchiuso era/ e /
dwanre l'esecuzione del programma.
e) La sequenza di escape \ n, quando usaca in una stringa di controllo dcl formaro di una
funzione printf, mduce il cUISorc a posizionarsi all'inizio della riga successiva sullo schermo.

38

CAJ."JTOLO

d) Turce le variabiLi devono essere dichiarare prima di essere utilizzare.


e) A curce le variabili dovr esscre~segnaco un tipo, quando saranno dichiarate.
f) 11 C considera identiche le variabili number e NuMbr.
g) Le dichiarazioni possono a~parire in quals.iasi parre dd corpo di una funzione.
h) Tutti gli argomenti successivi alla srringa di cencroUo dcl formaro in una funzione printf
devono essere preceduti da un ampe.rsand ( &)
i) I:operacorc modulo (l\s) pu esse.re urilizz.am solramo con degli operandi interi.
j) Gli opera cori aricmetici , / , \ , + e - hanno runi lo S(esso livdlo di priorit.
k) Vero o falso: i seguenri nomi di variabili sonoidencici in curci i sistemi ANSJ C.

INTRODUZIONE /\Ll..J\ PROGRAMMAZ!ONE IN

2.3

2. 1

a) main. b) pare?tesi graffii aperu ( {) . e) parentesi graffa chiusa (}) . c) punto e virgola. d)
printf. e) ncwlrne. f) scanf. g) \d. h) scrirrura disrrurciva. i) Jetrura non distruttiva. j) if.

2.2

a) Falso. La funzione princf incomincer sempre a visualizzare laddove sar staro siscem:no U
cursore, e quesro potr essere ovunque su una riga.dello schermo.
b) fulso. 1 commen non causano l'esecuzione di nessuna azione durante l'esecuzione del
programma. Essi sono usaci per documeocare i programmi e migliorare la loro leggibilit.
e) Vero.
d) Vero.
e) Vero.
f) Falso. ue disngue fra maiuscole e mlnusool, perci queste variabili sonc> diverse.
g) Falso. le dicbiarazioni dovranno apparie dopo la pa.rC.ntesi graffa aperta del corpo di una
funzione e prima di ogni istruzione eseguibile.
h) Falso. Gli argomenci in una funzione printf clinoJ l2 non dev.ono e$sere preceduti da un
ampersand. Gli argomend successivi alla stringa p~ controllo del formaro di una funzione scanf dovranno essere preceduti d1 norma da llia ;.mpersand. Discureremo delle eccezioni nei Capi coll 6 e 7.
i) Vero.
j) Falso. Gli operacori " , I e \ hanno lo stesso livello di priorir, menr:re gli operarori +e - sono
a un livello di priorit pi basso.
k) Falso. Alcuni siscemi possono disringuere degli ide.nti:ficatori con pl di 3 J caratteri.
I) Falso. Una istruzione printf con moire sequenze di escape \ n pu visuaLiz.zare canee righe.

2.4

Vero o fulso: un programma C che visualizzi tre righe di output dovr, concenerc ue
istruzioni printf.

Scrivete una singola istmzione C per eseguite 9gmmo dei $eguenti compid:
a) Dichiarate le variabili e, thisVariable, q'78354 e number di ci po int.
b) Richiedete aU'ucence di immettere unlntero. Terminatell vosr.romessagglo di richiesra c-0n
un due punri ( : ) seguito da uno spaziQ e lasciate il cursore posizionato dopo lo spa:iio.
e) Leggere in input un .intero dalla tastiera e immagazzinare il valore immesso nella variabile
intera a.
d) Se La variabile number non uguale a 7, vistlizzare ' The variable number is not
equa! to 1 .
e) Visualizzare il messaggio "This is a e program. su una riga.
f) Visualizzare il messaggio "This is a e program. su due righe, dove la prima termina
eon e .
g) Visualiwue il messaggio "his is a C program . con ogni parola su una riga separata.
h) Visualizzare il messaggio "This is a e program . con ogni parola separata da una
tabulazione.
Scrivere una iscruzione (o un commemo) 11et esguire ognuno dei seguenti compiti:
a) Indicate che un programrha cakolei: il prodrro cli rre inreri.
b) Dichjame le variabili x, y, z e result di po int.
c) Richiedece all'utente di immeu:ere ue-interi.
d) Leggere in input cre iarerl dalla mciera..c immagazzinaceli nelle variabili x, y e z.
e) Calclate il prodocro dei ae inceri ct>ntenuti nelle variabili x, y e z, e assegnare il risulcaro
alla YariabiJe resul t .
f) Visualizzare "The product is seguit d;il valore dlla variahllc re sul t .

.2.3

int e, thisVariable, q76354, number;


printf("Enter an integer: ");
scanf ( .,\d", &a );
if (number I= 7)
printf('The varia.ble number is not equa! t.o. 7. \n);
e) printt ( ' This is a C program. \n ) ;
f) printf( ' This is a C\nprogram.\n ' );
~ printf (' This \nis\ na \ nC \ nprogram.\n ");
h) printf( "This\tis\ta\tC\tprogram . \n);

2.4

a)
b)
e)
d)
e)
f)

2.5

a) /."' Calcola i l prodotto di tre interi


#inlude <stdio. h>

2.5

Usando le iscruzioni che ave ce sericeo aell'Escrdzio 2 .4, scrivete un programma complem che
calcoli il prodocro di ere inceri.

2.6

ldentifcacc e correggere gli errori in ognuna delle seguenti istnttioni:


a) Pl"'intt ( "The value is '!\id\ n, &number );
b) scanf ( "\d\d , &number1 , number2 l;
d)

i f (C < 7);

printf("C is less than 7\n);


d) i.f (e => 7)
printf( e is equa! to or less than 7\n");

39

Risposte agli esercizi di autovalutazione

thisisasuperduperlongname1234567
thisisasuperduperlongname1234568
I)

a)
b)
c)
d)

I* Calcola i l prodotto di tre interi ~ 1


i nt x, y, z, result;
printf ( ''Enter t hree integers: ") j
f
soanf ( "%d%d%d" , &x, &y, &z) ;
tesult = x * y z;
printf("The product is %d\n", result) ;

ma.in()
{

int x, y, z, result;
printf('Enter three integers: ');
scanf( '\d%d\d', &x, &y, &z);
result = x y z;

*/

CAPrro1.o 2

40

rNTRODUZIONE f\IlJ\ PROGRAMMAZIONE IN e

d) Una espressione aricmecica in C valida, cbe non comicne parenresi, sar valurata da
sinistra a cl~stra.
e) Quelli che scgitono sono e.uni nomi di vari:tbilc noh validi1 ~g, 87, 67h2, h22, 2h.

prlntf( "he prodl.lct is \d\n, result);


return 0;

2.6

Errore: &number. Correi.ione: eliminare il carattere &. Pi mrdi nel tesco discuteremo deUe
eccezioni a quesca regola.
b) Errore; number2 non ha un ampcrsand. Corre-tione: number2 deve essere &number2. Pi
avanti nel libro diseiueremo delle eccezioni a quesm regola.
c) Errore: il pumo e yirgola dopo la parcncesi dcsrra della condizione dcll'iscruzione i t .

a)

Correzione: ri muovere il punro e virgola dopo la parentesi destra. Nota: il risultato di


questo er.rorc sar che l' istruzione prntf sar esegrril'l) ind.ipc!lldentcrnemc dal fatro
che la condizione della istruzione 1 f sia>'cra o no. Il punrcl e virgola dopo la parentesi
destra sar consideraco alla scessa stregua di una isa:uzione vuoca: una isrru1.ione che
non fa n.ience.
d) Errore: l'operatore relazionale=>:, dovr essere cambiaro in>=.

2.11

2 .12 Che cosa sar visualizzare (se lo sar), quando ognuna delle seguenti.istruzioni C-verr esegui
ca? Nel caso in cui non venga visualiu-A1co nien.ce, rispandete "niente". Assum~~ che x ~ 2 e y " 3.
a) printt('\d '', x);
b} prntf( ' \d", x + x);
e) pr.i,rrtf ( qc= .. ) ;
q) pritJtf ( X=%d11 1 X) j
e) printf(u%d =%d .. , x + y, y + x);
Z =X + y;
g) scairf( %d%d, &x, &y) ;
h) /W printf(X + Y = %cJ, X+ y); T/
i) prirrtf( \O);

fdencifcarc e correggere gli errori in ognuna delle seguc.-nri istmzioni (Nora: pouebbe esserci
2.7
pi cli un errore per iscru7.ione):

f)
g)

scanf("d", value);
printf( "he product of %d and %d is '.\ld''\ n, x, y);
firstNumbe r + secondNumber = sumOfNumbers
i f (number => largest)
laq:_iest = number;
"I Program to de:termine :the largest of three intgers /
Scanf(.%d" , aninteger) ;
printf( "Remainder of l\sd divided by %d is\n", x, y, x % y);

Ji)

if

i)

printf(\d is equal to %d\n'', x, y);


print ( "The sum is l\sd \n, x + y) ;
Pri ntf('The vaiue you entered is : %d\n, &value);

b)
e)
d)

e)

j)
2.8

2.9

(X:

y);

Riempite gli spai.i in ognun:i'deile seguenci dghe:


sono uciliz.zari per docum.ntare un programma e migliorarne la leggibilit.
a) l
per visu;tlizzarele informazioni sullo schrmo _ _ _ __
utilizz<tra
funzione
b) La.
e)' Una iscruzione C che prenda una decisione um _ _ __ _
d) I calcali sono nonnalmcnrc eseguld dalle istru.iio1 di _ _ _ _ _
prende in input: dilla casciera dei valori.
e) La funzione
Scrivcce una: singola istruzione C o una riga che esegue pgnuno de.i ~egucnci compiri:
a) Visualizzate il messaggio "Enter t wo numllers.
b) A.~scgnare alla variabile a il prodorro di be c.
) Tndia.te che un programma esegue lLD sempio di calcolo dello stipendio (ovverosia,
ucilizz;;tte un resro che aiuti a docurncncare un programmn).
d) Prende.te in inpuc dalla rasciera ue valori inceri e memorizzaceli nelle variabili a.b e c .

2.1 O S"Ci.bilfre quale delle seguenti alfo:mazi<mi vc.ra e quale falsa. Morivace le vome cisposre.
ti) GJj Operacori del C sono V:'lluraci da .'ifl'listra a destra.
b) Quelli die scguon9 sono tun:Lnomi cli variabile validi: _unde r _bar_, m928134, t5. j 7,
her_sales , his_~ccount_total, a, b, c.z,z2 .

e)'1 I.: i ~i.one printf( "a

= 5;. ~ ) i un lipic;o esempio di istruzione di assegnamento.

Riempite gli spa1j bianchi in ognuna delle segucnci righe:


a) Quali operazioni aricnmiche hanno lo sccsso livello di priorit11 della molplica1.ionc?
b) Quando le parentesi sono nidificate, quale gruppo di paremesl sar valutalo per primo in
.
una espressione arirmeci~
e) Una l9c:uione della memoria di un computer che pu conrcnere valori diffcrenci, in vari
momenti della esecuzione di wi programma. rrna - -- - -

Esercizi
~)

41

2. 13

Quale delle seguenri istrniioni C, se ce n' una, contiene delle variabili coinvolte in Ltna lemmi

d.isrrutciv:'I?

a) scanf("%d\d%d%d%d, &b, &e , &d, &e , &f);


b) p = i + J + k + 7;
e) printf(''De structJ.ve readin ");
d) printT("a = 5');

2. 14 Oarn l'equazione y =
per quesca equazione?

a.~

+ 7, quale delle seguemi isrruzion i C, se-ce n' una. quella c:orrerta

a) y = a X * l( X + 7;
b) y = a~ X .. X (X + 7) j
c) y = (a " x) ./,. X (x + 7);
d) y = (a x) .. X X + 7;
e) y = a " (X * X,. X) +7;
f) y=a .. x (X )( + 7);

2. l 5 lnJicate l'ordine cl.i valutazione degli operarori, in ognuna delle segucmi isau7jonj C, e mostme.il valore di x dopo che.ogni iscruzioue sar stara cscguica.
~

X= 7 t

3 ~ 6

I 2 - 1j

=2

% 2 + 2 2 - 2 I 2;
~ X= (3 . 9 ~ (3 + (9 3 I (3))));

b)

2.16 Scrivete un progrnmma che chieda all'urente dj immerrere due nur,ned, ottenga i n.unwri
dru.l'ureme e visualizzi la loro somma. prodorw, differenza, quozienre e niduJo.
2.17 Scrivere un programma che vi.sualizi.i i numeri da I a 4 sulla stessa_riga. Scri~ce il programma
utilizzando i seguenti mctdi:

42

CA.PrroLO 2

lNTROD UZlONE ALLA PROGRA'MMAZfONE l:N

a) Usando una jscrui.ione pri ntf .senza specifiche dj conversione.


b) tJsando una isuuzione printf con quaccro specifiche di conversione.
c) Usand_o quarr;ro istruzioni printf.

A p
p
p

JJ
J
J
J
JJJJJJJ

tdJUhi)
D
O

rniJQt three differen t integers : 13 27 14


SLln is 64

D
D
D
I>
mllO

A'Vrage iw i.e
Product .i8 4914

Slllallest :ts 13
'Laf&est fs:Zl

2.20 Sc.civete un programma cne legga il raggio di un cerchio e visualizzi


il diametro, la circonferenza
e l'area dello stesso. Usare il valore rostame 3,14159 per pi. Eseguite ognuno
di questi calcoli all'interno della/e isrruzione/i printf e usare la specifica di conversione%f. (Nora:
in quesco ca_picolo abbiamo
a:atcato solranto oosronti e variabili ince,re. Nel Capitolo 3 discuteremo
i numeri in virgola mobile,
ovverosia quei valori che possono.cootcneye dei decimali.).
2.21 Scrivete un programma che visualtti una scacola, un qvale, una
freccia e un diamance come i
segucnri

,,*

*
,.*
*

,. .,

il'

llfllt

2.22

il'i-

..

...

!/t

......,..
...

"'

2.27 Visualizzate il disegno di una scacchkra utilizzando ono istruzion


i pri ntf e quindis c:unpare
lo stesso disegno, con il m'inor nu.merq possibile d'isrruz.ioni pri ntf.

** *

.. .. ,.,., .

1*

"*

"* *
...
...

Che cosa visualiz.zecl il codice seguente?


prlntf( 01 \n**\n~ \n ~ \n* \n);

2.23 Scrivere un progt-amma che legga cinqu inceri e quindi determin


i e visualizzi quclli che,
all'interno dd gruppo, sono il maggiore eiJ minore. Usare soltanto le tecniche
di programmai.ione che
ave.te appreso in quesco llpirolo.
2.24 Scrivere un programma che legga un incero e dececmilli e visualizz
i ~e sia pan o dispan.
(SuJ;gerimChto: usare l'oprarore modulo. Un numero pari un multiplo
cli J:l ue. Ogni multiplo di
due d un resto u~ale a zero, quando dlviso per 2.)
2 .25 Visualizzate le vo~.tre iniziali i1ummparef10 in direzione del fo n~o
dellapagirui. Costruire ogni
lene.ca in srampacello ucilizzandolo StC:SS'El caran:ere che essa rapprcsenra,
come segue:

* *

lil"* it

*"'

:jl

.....

2.26 Scrivece un programma che legga due interi e determilli e visualizz


i se il primo sia un multiplo
del secondo. (S,uggccimenco: usace l'operato re modulo.).

*"'*

p
p

Pi'

2.19 Scrivete un programma C che prenda in in pur dalla casera tre diversi
inceri e qujndi visualizzi
la somma, la media, il prqdorro, il minore e il maggioi:e dj quesci numeri.
Usare soltanto la form:i a
selezione singola della isl'.CUzione if che-avete appreso in quesco capitolo .
Lo schermo di dialogo dovr
apparire come il seg_ucnce:

il'

43

PPPPPPPPP

2.18 Scrivete un programma che chieda all'ucenre di imrem:ll due


imeri, orcenga i numeri e
visualizz i quello maggiore seguito daUe parole is larger. . Nd caso
che j numeri siam> uguali,
s~anipate il messagg io rhese numbers are equal. . Usare soltanco
la forma a selezione: sing,ola della
istruzione if che avere appreso in questo capitalo.

~;~ Il*

2.28

Discinguerc era i termini errore fatale ed errore non farale. Perch pouesce
preferire di incorrere

ja un errore fatale, invece che in uno non facale?

2.29 Diamo ora una sbirciataJn avanti. f n quesco capirolo avere appreso
degli imeri e del tipo int.
Il pu rapprese ntare ancheJe lertere maiuscole, quelle minuscc:>le e una
considerevole varier di
simboli speciali. IJ usa incemamcnre degli interi di un hyre per rapprese
ntare ogni singolo caracrere.
Linsieme dci caratteri usati da un c_ompur~r e la <;c:>([ispondence rapprese
acazjone incera per quei
carartcd J'insieme dei caratteri di quel computer. Porrete visualiziare l'intero
equivalente ddla lettern
maiuscola A, per esempio, eseguendo l'immionc:

printf( 9gj, 'A') ;

Scrivete un progrnmma ch.e -visualirn gli inceri equivalenti ad alcww lettere


ml!iusco le, minuscole,
numeri_e simboli spe'c.iali. Decerminare, come nlinimo. l'imero equivaleme_
di: A B C a b e 0 1 2 S
" + I del cararrere spai.io.

2.30 Scrivete un programma che prenda in in pur un numero di cinque cifre,


lo spCZ1.etti nelle sue
Singole cifre e le visualizzi ognuna separata dall'slrra da m: spazi. Per esempio
, se l'utcme digira.sse
42339, il program ma dovrebbe; visualizzare
4

44

CAPITOLO

2.31 Usando solranto le tecniche che avere appreso in quesro c:apirolo. ~crivere un progr:imma che
calcoli i quadraci e i cubi dci numeri da Oa IOe uc$ni le Eabul_azioni pervisual.iu:u:e 1::1 seguente rabclla
ru valori:

nunero

quadrato

G!tlo

0
1

0
1

21

5
6

9
16
25
:Il

8
9

64
81
100

10

6'I
125

CAPITOLO

Lo sviluppo di programmi
strutturati

"216

3113
bl2

Obiettivi

Comprendere le tecniche fondamentali per la risoluzione de.i pcoblemi.

100;0

Essere 11 grado di sviluppare algoritmi, utilizzando il processo rqp-dowo per


raffinrunenci successivi.

ESsere io grado di ufiHzzare le stmmue d.i selezione ife i f I else, per selerioun.re le
azioni.

Essere in grado di utilizzare la smurura di iterazione while, per eseguire


ripetuta.mente delle i.struzioni, io un programma.

Comprendere i cicli concrollati da un contatore, o da un valore sentinelJa.


Comprendere la programmazione scrum.a.rat.a.
Essere in grado di ucilin.are gli opera roridi incremenco, di decremento e di

assegnamento.

3. 1

Introduzione

Prima d i secivere un programma che risolva un particolare problema, essenziale avere una
piena comprensione di qucsr'uhimo e un approccio pianificata con cura per risolverlo. I
p rossimi due cap.iroli rrarrcranno delle rccniche che facilirano lo sviluppo di programmi
si;rurtura per computer. Nella Sezione 4.11, presence.remo un sotn.mario della program.JDazione srrutturara, che merrer insjeme le tecnjche sviluppate in .quesro e ne.I Capirolo 4.

3.2

Gli algoritmi

La risoluzione di ogni problema di elaborazione c0mporta. l'esecuziorre, in un ordine spcuna serie di azioni. Una procedura che risolva un wablema in termini di

cific:o, di

l. azioni che devono essere eseguire e

2. l'ordine in cui rali azioni devono essere eseguire


derra algoritmo . .eesempio seguente dimoscra che impora.nre specificare correrr.amenre
l'ordine in cui le azioni devono essere esegillre.

Considerate l'algoritmo "al7.ari e briUa" adorrato da un giovane dirigeme per alzarsi dal
lerco e andare a lavorare:

46

C APITOLO

Alzarsi. dal letto.


Togliersi il pigjama.
Fare una doccia.
Vestirsi.
Fre colazione.
Prendere l'auto per recarsi al lavoro.
Questa procedura p.ona al lavoro il dirigente, ben preparato ~er
prender~ delle decisioni critiche. Suppc,mete, ttmavia, che quegli stessi passi siano eseguit
i in un ordme Leggermente diverso:
Alzarsi da! letto.
Togliersiil pigiama.
Vestirsi.
Pare una doccia.
Fare colai.ione.
Prendere l'auro per recarsi al lavoro.
In quesro caso, il nomo giovane dirigent~ gi~gerebbc ,al la~or~
con;ipl~tam~tc .inzuppato. 1n un programma per computer, la specificaz..Jon deU erdlne
m cude isr_ruz10111 ~evo
no essere eseguite chiamata controllo del programma. In questo
e nd prosstmo cap1tolo,
esam:ineemo con.cura le possibilit offerte dal per il controllo
del programma.

3.3

Lo pseudocodice

Uno_pseudocodice un linguaggio artificiale e inform ale, che aiuta


i programmac?ri a sviluppare gli algorirmi, Lo pseuciocodice che presenciamo i.o. ~uesto
contes~o parucoLai:mente
utile per 19 sviluppo di algocito~ che sai:n~o c.on.veru~ .m .pro~
~mt .e si;rua:uraa. U~o
pseuliiocodlce un linguaggio si.mile ali'ttal.1ana dt rutti 1 gior~;
e pranco e maneggevole,
scbb:ne non sia realmente un vero linguaggio di pro~ramrna:z.iorte.
furcal r, i pr-0grammi scritti ~ pscudocodice non possono essere
esegui.ci sui comput~r.
Essi, piucrosto, aiutano il prograaimacore a "riflettere" sul pr~gra
mma, ~rima c.h~- provi _a
scriverlo in un linguaggio di prngrammazione, Ome il C. Fornire
mo mol_a ese~~ rn questo
capit):>lo, per mostrare come uno pseudcodlce possa essere efficac
emente urilizzaro flello
sviluppo di programmi C Strutturati.
Uno p.seudocodlce composto semplicemence da cararteri . perci~
~ programm~tori pottanDO immercere in un compu ter i programmi
in pseudocodice~ uri!iz:an~o contorcevo~
menre un edlcO'r di cesto. U computer ptr v.isualiz:iare o scampa
re, a nch1e5ta, una cop!a
aggiornata di un programma in pseudocodice. Questo, se prepa.r<
tto c?n c~ra, po~ facilmente essere convertito in un corrispondente programma C. I.a
moln casi, ruc.co CL .sar
ottenu to ~osruendo semplicemente le istruzioni in pseudoodice
con quelle equNalenn nd
linguaggi C.
Uno pseudocodice consiste unicamente di istruzioni~ azione: oy.ve.co
sia,. qelle che sa:
ranno eseguite, quando il programma sar s~o ~rrv::rn~ ~~
psewiocodice al e e .sara
srac9 eseguito in C. Le dichiarazior non sono JStruz1on1 esegrnb1l1.
Queste sonq messaggi per
il compilarore. Per esempio, la dichiarazione
i.nt i i

LOS\filUl'[IU 111 PROGRAMMI ~TRUTT1JRJ\Tf

47

indica. semplicemente il tipo di daw della variabile i, al. compilarore,


e induce quesr'uJciml>
aJ:iservarc uno sp~io in memoria per la suddet ta variabile. Quesca
dichiarazione, dunque.
non provocher l'esecuzione di nessuna azione (come un iopuL,
u-n ourpm, o LI.Il calcolo),
quando il programma sar eseguito. Alcuni programmatori scelgon
o di elencare ogni variabile e di menzionare brevemente gl i scopi di ognuoa di quesre, all'iui~
io di un programma in
pseudococUce. D'alrroode, uno pscudocodice un aiuto inform
ale allo sviluppo dei progr.untni.

3.4

Le strutture di controllo

Normalmente, le isuuzioni prescnri iu un programma sono eseguir


e, un:a dopo l'alua, nclf'ordine in cui sono srare scrirte. Parleremo perci di esecuzme
sequenzl/e. Varie istruzioni
del C. delle quali discur.eremo presto, consentono al progr:a.mmaro
re di specificare che la
successiva istrll7ione da eseguire possa essere diversa da quella
efforrivameme susseguence
nella sequenza. Quesro cipo di indicaz.ione det{a tmrftrimento
del controllo.
Duram e gli anni '60, divenne evidcnce che l'urili27.o indiscriminat
o dei trasferimenri di
con crollo raJa cau.sa prima di una gran quanc di difficolt sperim
entate nei gruppi_ per 10
sviluppo del sofrwa.re. Cindice deJl'accusafu puntato sulla ~truzio
ne goto, d1e consen va al
programmatore dl specificare w1 rr;isferirneoco di comrollo verso
una di lln v.astissimo raggio di possibili destinazioni all'interno di un programma. La
nozione della cosiddetta
programrnaz10ne strutturato divenne quasi un sinonjmo di ''elimi111
zzione dei goto".
La ricerca di Hohm e J:u:opini (13ohm, C., and G. Jacopini, "Plow
Diagrams. Turiog
Machines, and Languages witb Only Two Formarion Ru.les," Commu
nioatioru of the.ACM,
Voi. 9, No. 5, May J 9Q6, pp. 336-371.) ha dimosrrato che i
programmi possono essere
scritti sem.a usa.re nemmeno una is.truzione goto. La ~fida dell 'epoca,
pr i prgrammamri,
divenne qudla di cambiare il proprio stile in una "programmazione
senza goto". Ma fu solo
nel pieno dt;!gli anni '70 che Ltna gran quanti~ di progr:ai:nmacori
comincio a prendere
ser.iafueme io considerazione la programmazione srrunucata. l
risulraci sono stad davvero
imp(essi.onaoti, dato che i gi:_uppi di svifoppo (}ttenneco: tempi
di produzione ridotti, punrualir pi frequente nd consegnare i sistemi, e una maggior freque.
rua di compleramenri
dei progetti software m.j termini previsti dal budget. La d1i::1ve di
questi ~Lttessi sempJkememe il l'atto che, con l tecniche scnmurare, i programmi prodot
ti sono pi ch:iari, facili da
mettere a punco e modificare e, innanzi turro, con maggiori probab
ilit di esse.re esenti da
errorJ.
U lavoro di B0hm e Jacopini ha climoscrato che cutti i programmi
posson o essere sccirri in
termin i di tre sole strutture di comrolfu: la stn1ttu rn di sequenza,
la sm1ttu rtt di selezione, e la
struttura di iterazione. La struttu ra di sequenza implicita i.11 C. Sempr
e che non gli si ordini
diversameme, il computer esegue automaticamente le isrruzio
ni dd C, una dop() l'altra,
nell'o.rdin.e in cui sono sr-aresccitte. Il segmento illdiagramrnadifluss
o (flowclmrt}' nella l?lgura 3.1 illusrra la srrumu:a di sequeni;i dd C.

Oo digr:unma di flusso una rappresentazione grafica di uo algoria


no o di una porzione cli guesco. I diagrammi di flusso sono disegna usando cerri simbol
i con signil~ speciali, come i re.mmgoli, i rombi, gli ovali t i cerchierli; quesri simbol
i sono connessi tra loro da
frecce chiamare linee di flusso.
1

~1

48

CAPITOLO 3

LOSV14UP.PO DI PROGRAMMI S'IRUlTURATI


due differenci :12i0ni. La struttura swicth detta sti'Uttra
se)eziona una tra v.a.cie d.i.ffeten- qoi.

di felezione?(~'l:lltip/a,

perch

li C forni.sce tre ripidi strutture di iterazione: il wh_ile (Sezione ~.7), iJ d(> / Whi le e il
for (emrambi d:is_cussi nel Capit9l9 4).

aggiun_gl Il voto
al totale
totai = total + grade;
6ountr ~ eountr 1' '1 ;

aggiungi I
al contatore

Figura ~. l

49

Il di~ramma di flus~o ~ella struttura di sequenza del C.

Allo stesso modo dello pseuCl0codice; seblkne qaes:ro sia piefecito da molti programmatori, i diagr.ammi di flusso sono uli per sviluppare e rappresentare gli algoritmi. I
diag_rammi di 'flusso n10scrano con chiarezza il modo in <::ui operano le sb:urrure i conrrol~
1111; in q~m resro li useremo sqlo per tale scQpo.
Cnsiderare il sgmenro di diagramma di flusso per la structuca sque.nzi.al mosrrato
nella figur-a 3.1. Us~mo il sfmbokJ .rattangp/.o, chiamato anche simbolo di aifo11e, per indicare o,gni ripo di artiv.it che iotjuda uo.cralcolo o una ~peraz.ione di inpur/ourpm. Le linee di
fl.sso preseot:LneUa 1igll.CiJ. imijcano liordb;le in ~ui le azimi de:>v,i;anno esse[e eseghe: in
ptimo. ltu).go, grade pp:v:r essere :J.ggiunro .oa tot al, : quindi 1 ~ovr ess~r; spmm.ato -a
ou'nt~r. 11
<::i ~#rte di ave.r-, in Q.na s.truttt.iia di ~e.quer;iza, P!nte azioill q.qai;1.te ne
V:ogli)mo. Come-vedremo p.!i.~(o, porranno e:ssre inserite niolre isrruzio.niiMequ~zaladHove

n pssa ciser~ss'tniata una.

NeJ dis~w.r;rre un..P.iagraj:nnf~ li Auss~ cbrapp.r~enri un alg!:'> riimo co1r_ipi~o, il primo a


essete ucili:iz;uo sart il simbolo ovate cont.enenre la ~parola "Iriizi0";. melitl'e un srmb~IO ovai~,
~oncenenr.1a parola "Fine!' ,sai l'ultimo simb.olo urilizzatb.. Nd dlsegnate sol.o una porzione
ai un algoritmo, come nella Figura 3 .1, i sjmboli ovali saranno omessi, in favore ddfiuiJizzo
di simbolicerchietto decti anche simbolidi connessione.

T1 simb0l pi imporrame dej diigramm,i .di flusso forse il simbofp romb'Q, derro anche
si.rilbo.lo di d.csiinze, .indieanre che dovr, SSre.eseguica ima selta..Disea.trillo .dcl s.iri:.th.lo
romb0 nella prossima sezione.

TI Cfomi.St rre tipi di srrutnire di selz.ion~. La stn.i'ttura d i selezione. i f (Seri9rie 3 .5};


nel Gso 'Gh una "data. condizione sia ver-a, eseguir (selezioner)' una eerta a.Ziorie, m.ntre la
ignrera, nd c::aso che la cndizione sia falsa. La strutrura dj sel.ezione i f /.els (S:Zione 3.6)
e5eguir. una certa az.ione1 nel caso <::he u~<J. data condi.zienesia v.el'<l, mentre ue es~guir una
differente, nd. ~ clic; la S:Jlddeyca. 9ndizon. sia: fal~.a. ~ ~!J'.oa:ura. di Clip}le swi tcb
(dJi.su.<;Sa
eipitolo 4). scgll~r ~d eyguir. una ~tante ~emi ~n.i, s~cn,d.o il valo-

nel

:r_e' as,sun,r(! .da p.na ~.ra, espr.s:sJene.

La struttur"- i f detra strutturadi selezione singola, perch seleziona o ignora una singola azio!le. La $trumir-a i f I else 4etta str/t'tttl.rq di selezione i/.ppia, p.erch'-s~eziona una di

Qu.stotutto.11 Chasolramo sem:srrurrure di conrroilo: la sequenza., ue tipi di.st;Iezion.e e altretranci di iterazione. Ogni programma C fomUJ.to dalla c9mbinaz_ione di 9gnuo11
dlle Sildderie srrua:rae- di controllo; uriliz1.are .in q,ua:.nrit. appropciaJ:e .al pcigramma che
lmplementa l'algoritmo. Vedremo che ogni strurtw'.a di conrtoll0, .Ome quella sequenziale
della Figura :3..1, ba due sin1b0li cetcbiectq, ua nel punto di enrr_ara. e Val.rro in quell0 di
uscita-. Queste-mtUtlffe ef/i i;ontr'o{ln can 1"Jl ingre{fQ. l t+'M uscita singoli sempll:fiduio la cosrmzione dd progt-Mnrni. L:stro:ttute di cont:rllo possn:o essere arratace Funa all'altra, colleg<111do il punfo di uscita di urta di.esse con"'qu.1.16.di entrara della successiva. Tutro i9 .moltt>
simile. al modo in ui i l:5amb.ini lnnesrano i mattoncini delle costruzioni, p~ci cltiamianio
quesro modo di operare ttacatastttmento dellestruttu.re di omrollo. L:npareremQ che c:' solcamo 'Ul1 altro modo in cui l~ ~trurrure di coni:rqllo porranno essere ~~te: QVV'ecos:ia, un.
merodi c_h.ia.maro nidificazjqne .delle sttttur- di tgtrttoll.o. Di q:mseguenza., qualsiasi prgntmma Cl di q.ti'po.rremm0_.y.er bisogno, potr itsser.e cosuuito ucilii,zando solamente serre
cipj di srrurruie di ontrbilo, .c::ombinate in due soli modi.

3.5

La struttura di selezione lf

Bna suutturn. di sdezit<me U$ata per scegliere r.ta per corsidi azi0ne :ilremacivi. Per ~ernpo,
suppgnere cly; la votazione pe:r superare un es:ue s'1<1: 60. l!isti:uzione in pseudomdlce

Se il 11oto dllo studente maggiore o uguale a 60


ViiualiZ2!1l '"Promosso" .
,deremi;na: se l;i.. condizione "vero dello srudente m.ggiore o uguale a 60'" vera o fal~a.
Nd c;aso in ci la c0ndizi-0r sia. v.ra, sar visuali'zzato ''Promosso" ed "eseguita"; l'tstruzione succeS-Siva, nell'online. indicato dallo pseudoeodice (riqirdace che_q.uesto non un vero
linguaggio di pi:ogp.mmazione). Nel. qiso in c;ui la condizione ~ia fab~, la visual.izzzione
sar ignorat:a: e ~ar. eseguita ristruzio'qqutces~iva, nell'ordine i ndka'to c:lallo l'~udo-cod.i.ce.
Osservat.e che h seeonda riga di questa struttul1!; di sdezione cien.a;ara. Tale rienrro
opzinale, ma a:j.rameiit~ ritccomandaro, poith iuta a dare cisako alla scrunura intcia.seqi dei programmi. Applicheremo con mol~ cura l c.nvenzioni dei r.ientri in rutto il libfQ.
Il compilato-re C ignora i caratteri di spazio bianco, come gli spazi, le cabula,zion.i e l~
newliri.e utilizzate per i rientri e la spaziacura verricale.

Buona -abitudine 3.1

/!pp#care le conven.zi0.ni dei rierltii, in modo '<?onsistente e respomabile, miglioro. en,ormemente lti le(tibilit dei programmi. Peti rientri suggeriamo unat{lbuf4zione fissa d.i
114 di pollice (6,3:fmm) o d h'e ~pazi.
L_ precederit istruzione se in.pseudoaJdice pu essere seri.tra in Q; Game
f (grade >~ 60)
p~inif(~Promossa,n");

C,w1TOLO

50

Osservare che il codice C corrisponde sa:eria:rileuce allo pscu<locodice. Questa una


delle propriet deUo pseudocodice che lo rende un utile srrumcmo di sviluppo dei programmi.
~

B11on11 abitudine 3.2

Lo pseudocodice spaso utilizmto per "riflett.ere" S1t 1111 progranm1a, durante la fasi' tli pr<>gettazione dello stesso. Il programma in pseudocodice sar successivamente convertito in C.

Il diagramma di flusso della Figura 3.2 illusrra la struttura di sele~ione singola if.
Queste contiene quello che forse il simbolo pi imporrante dei diagrammi di flusso: il
si;nbo!o rombo, detto anche simbolb di ilccisfone, il quale indica d 1e dovr essere effccruara
una scelta. Il simbolo di decisione conriene una espressione, per esempio una condi:dollc,
che pu essere vera o falsa. li simbolo di decisione ha due li nee di flusso che emergono
da.ilo stesso. Una indica la direzione da seguire quar:ido l'e.spressione all'interno del simbolo
vera; l'altra indica la dirC?.ione da segu ir~ quando l'espressione fa lsa. Nel Capitolo 2,
abbi.amo appreso che le dedsioni possono essere prese secondo delle condi11joni, che conrengno operatori rela'lJionali o di uguaglianza. In realtlt, una $Celta porr essere compiura
bas;1Jldosi su qualsiasi esp~essione: se essa vahu:ara zero, sar cratcaca come falsa, memce
~e il suo valore diverso da zero, sar considerata vera.
Osservate che anche if una srrurmra con un ingresso e una uscica singoli. Apprenderemo presto che:: anche i diagrammi di Elusso per le rimanenti strurrure di concrollo
contengono (a parre i cerch ierri e le lince di 1:1usso) solca.mo dei simboli rerraogolo, per
indicare le azioni da eseguire, e dei simboli rombo, per indicare le decisioni da prendere.
Questo il modello cli programmazione basato su azioni e decisioni che abbiamo evidcnziaco.

lo SVlLUEPO 0 1l'ROGRANL.'vfl STRUTIURATI

51

3.6 La struttura di selezione lf/ Else


La sa:urrura di l'selezione

. .i f esegue l'aziolle indicata solo quando la condl.Zl0 ne vera,. 111


caso conr_rano,. azione e ignorara. 1:-3 s~rrura di.s~lezione i f / else consence al programm~rore ~1 specificare che, nel c~o m cw la condizione sia vera, dovr essere eseguira una
a:1on~. diffe~enre. da quella che St dovr eseguire qualora la condizione sia falsa. Per esempio, I 1Struz10ne rn pseudocodice
Se il voto dello studente maggiore o ugual.e a 60
Visualizza "Promosso"
altrimenti
Visualizzo "Bocc1.to
vsu.alima
Promosso
m:moiort- o uguale a 60 , m e nere vrsu
al'12za
B
iJ
dse la vocazione dc:llo srudence -=
o~ci:;t(1 Se . ~o~? eU? scudcnte _inferiore a 60. la entrambi i casi, dopo la visualizzazione,
sara . esegica 1'.stmz1one succzess1va nella sequenza dello pseudocodice. Osservare cbe anhe il corpo dell altrimenti rienrraro.

~ Buon~ abitudine 3.3


Fate rientrare entrambe le istruzioni del corpo di una stmtmra f / else.
Qualunqu~ conv.ei:z~one di rientri abbiace scdt0 dovr ~scr~ applicara coll cu-ra nei vostri

progra~". i?.. d1fh~ile leggere un programma che non obbedisca in modo uniforme alle
convenzioni di spaz1arura.

Buona abitudine 3.4


Nel c~o ~ovess~ro ess~rci diversi Livelli d1 rientri, per ognutUJ di essi impiegare /o stesso
qwzn.twwvo di spazio.

stampa " Promosso"

La precedeme srrurrura selaltrimenri in pseudocodice pu_ essere scritta in e come


1-f (grade >= 60)
. printf ("Promosso\n");
e1se
pr i ntf("Bocciato\n");

falso
Figura 3.2

vero

Il diagramma di flusso della struttura di selezione singola del C.

Possiamo immaginare sette concenirori, ognuno dei quali contiene solo uno tra i serre
tipi di suutture di conrrollo. Tali srrurrure sono vuoce. Non scritto nicncc nei renangoli e
altrettanto nei rombi. Il compito del progra.rfu:fiarore qu.U1di quello di assemblare un programma, con rance srrutrure di concrollo di ogni cipo quante ne richiede: l'algoriuuo. combinandole in due possibili modi (ovverosia impilandole o nidi6candole) e complecandole, in
un secondo momenro, con le azioni e le decisioni appro_pare all'algoritmo. Discuteremo in
seguico le varier dei modi in cui possono essp-e scrirre le azioni e le decisioni.

stampa "Bocciato"

Figura 3.3

stampa "Promosso''

Il diagramma di flusso della struttura di selezione doppia i f / else del c.

52

CAPITOLO

li diagramma della Figura 3.3 illustra esarramerue il flusso di controllo per la srrutrura
i f I else. Ancora una volra, osserva:ce che, a pane i cerchietti e le frecce, gli unici simboli
presenri nel diagramma di flusso sono i reaangoli (per le azioni) e il rombo (per la decision e). Conrinuiamo a evidenziare iJ modello di elaborazione basaco su a'l.ioni e decisioni.
Immaginare nuovamente un conreniw re cap-ienre, empico con tante srructure vuoce di
selezione doppia quante ne possono servire per cosuuire qualsiasi programma C. li lavoro
deJ programmacoJ'c, ripetiamo, quello di assemblare le suddertc srrurrure di selezione,
accarasrandole e nidificandole, con qualsiasi alrra ~rrura di controllo possa essere richiesta dalJ'algocmo, e complerando i rettangoli e-i rombi -vuoti, con le az.ioni e le decisioni
appropriare per l'algorirmo che si sra implemenrando.

1J C fornisce l'operatore condizionale ( 7:) che strcuamente correlato con la smmura


if I else. Quello condizionale l'unico operatore ternario del C: in alrre parole, accetta ere
operandi. Gli operandi , insieme all 'op_eracose condiziona le, fo rmano una
espressione condiziomdc. Il primo operando l,lI~ cpndiiione, il sccpndo operando il valore
che assumer l' incera espressione co11dizionale, qU:.alora l;t condizione sia vera, menrre il
ceno operando il valore che assLLmer l' imera espressione condizionale, qualora la condizione sia falsa. Per esempio, l'istruzione printf
prin tf{" %s\ n ", grade >= 60?

P~omosso

: ' Bocciato );

conde.ne un'espressione condizionale che rescimir la scnga letterale ' Promosso" , qualora la
condizione grade >= 60 risulti vera, mentre restlcuirJasainga lecrerale ' Bocciato , qualora
l:i. condizione risulci Falsa. Lasrcinga diconaollo del formato per la pr'intf contiene la specifica
di conversione !\ss per visualizzare una scringa dj caracreri. .Oi conseguenza, J'iscruzione printf
precedence eseguir essenz.ialmence la scessa operazione ddl'isrruzione i f I else precedente.

r valori

in una espressione condizionale possono anche essere delle azioni da eseguire.


Per esempio, l'espressione condizionale
grade >: 60 ? printf ( '' Promosso\n') : printf ( "Bocciato\n);
si legger, "Se grade maggiore o' uguale a 60 allora printf ( Promosso\n ), alrrimenci printf ( Bocciato\ n ) ". Anche quesra ~prn.~sionc condizionale comparabile con la
struttura i f I else precedente. Vediemo che .gli operarori condizionali potranno essere
ucilizzaci in alcw1c situazioni dove non potranno essere ucilizzace Je ismizioni i f I else.

Le stmtture i f I else nidifiate sono in grado d ~e.rificare diversj casi, se :;i slscc.mano
dclle if I else a.ll'incern0 di akre mmmr dello scesso pe. Per sempio, la seguenr scru7.lone in pseudocodice., visualizzer A per vorazioni di esame maggiori o uguali il 90, B pe.r
v9d maggiori o uguali a 80, C per voti maggiori o uguaD a 70, O per vocazioni maggiori o
uguali a 80, F per nttte le al tre votazioni.

Se il voto dello studente maggiore o ugi,1ale a f)O


Visualizza ';4"
altrimenti

Se il voto dello studente maggiore o uguale 11 80


Visualizza "B"
altrimenti
Se il voto de//q studente maggiore o ugtlllk a 70
Visualizza "C"
-

Lo SVlLUl'PQ DI PROCl~AMMl STRLDTURA"rl

53

altrimenti
Se il voto dello studente maggiore o uguale a 60

Visualizza "D"
altrimenti

Visunlizu1 "F"
Questo pseudocodicc pu essere scritto in

e come

i f (grade >= 90)

printf ( "A\n");

el-se
f (grade >= 80)
printf (''B\n ");
else
if (~ rad e >= 70)
printf ( "C\n '');

else
i f (grade

>= 60)
printf( "D\n");

else
printf("F\n");

(ual~ra la var~abile grade ~ia m~iorc o uguale a 90, saranno vere le prime quamo condizioni,

ma. sar ~1ta solcane~ I 1srruz1one printf s ~ccess.iva al p~o conrrollo. Dopo che quella
prin.tf sara stara ~gwca, la parte else dell 1srrt1Z1onc i f /else "pi escerna" sar saltata.
Molri programmacon C preferiscono scrivere la precedenre srrurrura i f come

H (grade >= 90)


printf("A\n");
el se i f (grade >= 80 )
printf ( B\ n ) ;
eise i f (grade >= 70)
printf(''C\n");
else i f (grade >~ 60)
prntf( 1' D\ n'' );
else
printf( "F\n '' );

Per
il compilacore
fu come
, , COncepiro
cl.ifft.c

e,

encrambe. le fo arre
lenc1- .1..
Tl I .
sono e(nriv
L"
1.1 urna
rma e pm . sa perc~ evita un rientro del codlce troppo profondo vt:rso jJ margine
descro. Un mie nenrro lascta spesso poco spazio suite righe, c:Ostringndo alla frammentai.ione
delJe scesse e facendo diminuire la leggibilit del programma.

~:t~~rnu:a d.i selezione i'. si asperca un~ sola istruzione nd proprio corpo. Per includere
pm
nel corpo
~ire ({ e }) il gruppo di
.
. .1struzJoru
U
. . di. w1. i f , racchiudete rra pa:renresi 5cu11
1stru~on 1 .. n gruppo d11Strt121on1 concenmo all'io remo di una coppia di pareutesi graffe
una utrttz1one wmposta.

~ _l~ng.~e~w._1e._r_in_d._e_l_so~ifiw _a_re~3~.~'~~~~~~~~~~~~~~~~~~~
Una iJt;uzione composta pu essere imerira in qualsiasi ptzrte del programma in cui pcssn
esure sistemata ima istruzione singola.

CAJ>ITOLo

54

l.:esempi o successivo include una istruzion e compost a nella par~e else c:ji una
.strumua i f I else.
i f (g1'ade >:o 60)

printf ( Promosso. \ n" ) i


else {
print 'f("B.occ iato. \ n");
printf ("Devi ripetere questo corso. \n );
}

ln quesro caso, qualora b votazione fosse inferiore a 60, il programm a seguirebbe entrambe le isrruzioni printf presemi ad corpo di else e visualiz.zerebbe

Bocc.iato .
Devi r ipetere questo corso.
Osservate le parentesi graffe che circondano le due isrruzioni della clausola else. Quesre

parentesi graffo sono i11Jpbrtanri. Senza di esse, l'istruzion e


printf(" Devi ripete r e questo corso.\n ");
se la
sarebbe esterna: al ramo else dell'istruz ione i f e verrebbe seguira. senza conside_rare
votazione sia ono inferiore a 60.
~

co dovranno cissere sistemate all 'inizio di q_lLest'uhi mo, prima d1 ogni isrruzione d i azione.
Discutere mo dell'uso dei blocchi nel Capimlo 5. Eino a qud mome.nrn, il lerrore dovr
evirare l'utilizzo dei blocchi (eccezion futca per il main, nattiralm cme).

La struttura di iterazi one while

3. 7

Una muttttra di iterazione consence al p r.gmmm~to re di specificare che una a1.ione ehe

dice
dovr essereriperut.a finch alcune condiziortl marrann o vere. Lisrruz.inne in pseudoco

Finch ci sono ancora atticoii nelw, mia lista della pesa


Cpmpra ilprossimo articolo e c1111C1:[/Dlo dalla mia Lista
e
1
descrive l icerazioae che si verifica durante una passeggiata per gli acquisri. La condizion
vern,
saJ"
Se
falsa.
o
vera
essere
potr
"ci sono ancora articoli nella mia lisca della spesa"
allora sar eseguita J'az.ione "Compra il prossimo .arcicolo e cancellalo dalla mia lista".
Le
Questa azione sar esegi1ita riperucamence fncaato che la condizion e rimarr vera.
scessll..
della.
corpo
il
ono
istruzioni comenure nella strurrura di i.ceraz.ione finch costimsc
Quesco porr essere fon:naco da una isrruzione singola oppure da una composta.
Infine, la condizion e divencer falsa (quando l'ultimo articolo della lista sar sc:no
acquisraro e cancellato dalla scessa). A quesro punto, il cido potr rerminare e sar eseguca
la prima istruzione dello pseudocodice successiva alla srrurrura di iterazione.

Erro.rf! tipico 3. i

Errore tipico 3.3

~ JJimentican: una o mtrttmbe leparente.si gmffe che delimitano una istruzione composta.
'U.fl errore di sin cassi incercerrato dal compilarore. Un erro.re logico ha il ~uo effetto
predurante l'esecuzione. Un errore logico furale conduce al fallimenco e alla terminazione
e
continuar
di
a
programm
al
corrsenre
fatale
non
matura di un programm a. Un errore logie-o
errati.
risultati
J'eseclrz.io ne ma anche di pr0durrc

Non fornire, nel corpo di :ma strutturtt whil e, una f1.?.?one che faccia eventualmente
dJemare falsa la condizione del while. Notmalmente, 1.ma tafe:st:ruttur.a di iterazione
non avr mai fine: un errore chiamato ''ciclb infinito".
0

Enore tipico 3.4

Scrivere la parola chiave while con ima Wmaiuscola come in While (ricordate che il
C un linguaggio .che distingui! le maiusct)fe i/4/le minuscole). Tutte le parole chia.ve riservate del e come whi le, i f cd else contengono soltanto l.ettere mimacol.e.

Errore tipico 3.2


inserire un punto e virgol.a, d,Qpo la condizione di ttna strtm1'ra i f , cb11d1mebbe a un
errore logico nelle strutture di reiezione singola i f, mentre provocherebbe un errore di
sintassi nelle struttttre di selezione doppia i f I else.
Buonti abitudine 3.5

Alc11.nip1ogra1rtmatoriprej-l'istono digirare lo ptmntesi graJ! ini.zi{l/e e quel/a finale tii


u.na istmzione composta, prima di digitare le singole istruzioni 11il'hnemo delle parentesi grafj. Ci ai11ra a wit1tre di omet:tere u.na o entrambe le parentesi graffi.
ingegneria del software 3.2
Proprio come una istruzione composta potr4 ssere imerha. laddovc potrebbe es.rere sistemata una istruzione singol.a, sar anche possibile non averne j>er nulla, in altre parole, avei-e i'istrrezione vuota. l'i.rtmzione uuONl rappresm.til.ta. dall'ins.erimento di un
punto ~ virgola (;)laddove nonna/mente ci sal'ebbe stn.ta uria istrt1zian,e.
In quesca sezione abbiamo imrodouo la nozione di isrruzione composta. Una istruziodi
ne composra ,pmr anche conreaere <leUe dicbiacw.ioni (come fa per esempio il corpo
blocun
in
ioni
dichiaraz
Le
main). [n questo caso, J'isrruzione eomposra sar detta blbcco.

55

L O SVILUPPO Dl PROGRAf\L"11 STRtrrrtJR ATI

Consideriamo ora, come esempio di una while reale, un segmento di programma progecraro per trovare la prima potenza di due maggiore di 1000. Supponere che la variabile irrrera
product sia stata inizializzata con 2. Nel momento in cui la seguente strumrra di iterazione
while aYJ' terminato la propria esecuzione, product conterr. la rispo~u desidera.ca:

produc t

= 2;

wh ile (product <= 1000 )


product = 2 * product;

rl

scrurrura di
diagramm~ della Figura 3.4 illustra precisamenre il flusso di conrrollo per la

a
iterazione while, Ancora una volca., osse1vare d1e, a parre i cerGhiecri e le frecce, il diagramm
rc.
conceniro
un
di flusso contiene soltanto un rettangolo e un rombo. Immagin ate, ancora,
alue
capiente pieno di smmure while vuoe che potrann0 essere accatastare e nidificate coo
di
controllo
di
usso
fl
strutture di conuollo, per furmare una implmencazione strutturata per il
e
azioni
te
appropria
un algoriuno. l reaangoli e i rombi vuoti saranno quindi completati con Je
emergente
flusso
di
decisioni. ll diagramma di :flusso mostra chiaramence t'iteraz.ioae. La linea

f
56

CAPffOLO

Lo SVlWPPO DI PROGRAMMI S'rRLTTTURATl

dal rerrangolo torna indietro alla decisione, che sar verifcaca ogni volra all'imerno del ciclo,
finch la stessa non divcmer evenrualmeme falsa. A quesrn pumo, la srrurrura while avr
complecaco il suo cornpico e iJ concroUo passer all'istruzione successiva del programma.
Al momento dell'ingresso nella :.truttura while; il va.lore di product era 2. La variabile
product sar. molciplicaca riperuramerue per 2, assumendo nel umpo i valori 4, 8, 16, 32, 64.
128, 256, S 12 e 1024. Nel momento io cui product avr assunto il valore 1024, la condizione
nella srrumu-a while , product <= 1000, sar divenrara falsa. Ci provocher il termine dd
ciclo e il valore finale di product sar 1024, 'Cesecuzione dcl programma continuer con la
prossima isrruzione dopo il while.

immagav.inare i torali nom1alinente devono essere azzerate, prima di poter essere utilizzate in
ua p~g~; alrr~menti la somma includerebbe il valore imm3t>oazzinaro in precedenza nella
J~o.ne_ di mi:morra del totale. Secondo il loro utilizzo, le variabili.contatore sono normaJmenTI'.. i_n~illnare c?n. zero o.~~ ~pr~enrer:mo degli esen;pi che momano ognuno di questi
~). Una vanahrle non inrzial.izzara conaene un valre 'i.mmondiZia": l'ultimo dato imm.agaz21naro nella Jocazione di memoa riservara per quella variabile.

Errore tipico 3.5


Nel cnso irJ cui un contatore o un coral.e non sia stata imz:iali:izato, probabilmente i ri.sultad
dei vostro programma non stmtnno corrett_i. Quest() un esempio di errore logico.
lnizializz11re il totale a zero
Inizializzare il contatore dei 11oti 11.

produet = 2 product

Figura 3.4

3.8

Per mosrrare come sono sviluppati gli algoritmi, risolveremo diverse variami di un problema
per il calcolo della media di una das.5e. cOns.idcrarc la scguemc enunciazione del problema:

Una classe di dieci studenti sos'far1e un esame, Avete a disposiz;ne le vqrazicni. (degli interi
ne/J'interval/Q dn O11 100) per questo esame. Detnninate la media della classe in questo esame.

La media della classe sar uguale alla somma dclJe votazioni divisa per il numero degli studenti.
Calgoricmo per risolvere questo problema su un ~ompurer dovr prendere in input ognuna delle
votazioni, eseguire ll calcolo <leUa media e visualizzare il risultato.
'Usiamo lo pseudococlice, elenehiamo leazioru che dovranno essere eseguire e specifichiamo
l'ordine in cui quesre azioni dovranno esser~ es~guite. U,s.eremo ur,a i'terr:wionc controllata dtz un
eortta~ore, per prendere infoput una pervolra le votazioni. Questa tecnica ur.ili7..7.a una variabile
detta contaJ:ore, per spccilcare il numero di volre che un insieme di isrruz.ioni devr essere eseguito. In ques~o esempio,. l'iterazlone cerminer quai:tclo il conracore avr superato il valore I O. In
quesra sezione, presenteremo solamente Jo psellliococlice per Ialgorirmo (Figura 3.5) e il corrispondente programma C (Figura 3.6). NclJa prossuna sezione, mostreremo come vengono
sviluppaci gli algoritmi in pseudocodice. Una irer:v.ione coorrollara da un conrarore spesso
chiamata iteraziane rkfinita, poich il numero ddJe ireraz.ioni noco prima che il ciclo incominci la propria esecuzione.
Osservate ndl'algoritmo i riferimenti a un corale e a un wncarore. Un wtak una variabile
ucilizi.ara per accumulare 1a somma di una se.rie di valori, Un contatore una variabile ucifo..7.ata
per concare; in quesco caso, per conrare il numen;> dei vori immesso. I.e variabili usare per

w10

Finch il contiltfne resta rhinore o uguale d. dieci


Pn!ndi;re drttl'inpttt il prossimo voto
Aggiungere il voto aL totale
Aggiungere tmo al contatore
Impostare il vawre della media al totale diviso dieci
.
Vi.su.aliz.zare la media

Il diagramma di flusso della struttura di iterazione while.

Formulazione degli algoritmi: studio di un caso


(iterazione controllata da un contatore)

57

Figura 3.5 L'.algoritmo in pseudocodice che utilizza una iterazione controllata da un


contatore, per risolvere il problema del calcolo della media di una classe.
/* Programma per il calcolo della media di una classe
cn una iterazione controllata da un contatore 1

#include <stdio.h>
mai11()
{

int counter, grade, total, average;

I* fase di i nizializ.zaziohe */
total = 0;
counter = 1;

/.* fase d:i elaborazione * /


while (oount er <= 10) {
printf( Enter grade: '' );
scanf( '%d", &grade);
total = total + grade;
counter = counter + 1;
11

/* fase di chiusura * /
average = total / 10;
prirrtf( "Class average is %d\n, average);

(Cb11tinu11)

CAPITOLO

return 0;

/* indica ohe i l programma terminato con successo */

Enter
Enter
Enter
Enter
Enter
Enter
Enter
Enter
Ent_er
Er,ter
Class
Figura 3.6

ff]

grade: 98
grade: 76
grade: 71
grade: 87
grade: 83
grade: 90
gt'ade: 57
grade: 79
grade; 82
grade: 94
aver,age is 81
Programma C ed esecuzione di esempio per il problema del calcolo della
media di una classe, con una iterazione cori~rollata da un contatore.

Buonn. nbirudine 3. 6
Inizializzate i contatori e i totali.

Osservate che il calcolo deUa media ud prngramma ha prodotto un risulcaro intero. ln


realt, la somma delle vot.azioni in quesm esempio 817 che diviso per dieci dovrebbe produrre 81,7, in alrre parole, un numero con una virgola decimale. Vedremo come rrattare
questi numeri (decri in virgola mobile) nella prossima sezione.

3.9

Fonnulazione degli algoritmi con processo top-down


per raffinamenti successivi: studio di un caso 2
(iterazione controllata da un valore sentinella)

Generalizziamo il problema dd calcolo della media di una classe. Considerate il seguente


problema:

Svilitppate ttfl p1'ogramma per iL ca.kof() dtlkt medi di una cl4S$e, che elaborer un nun'll'1'0 arbitrario di votazioni ogni volta che il programma sar eseguito.
Nd primo esempio di calcolo della m~dia di una classe, il nume.ro delle vocazioni (1 O) era
nco in anticipo. fo que$t esempio,. non . sw,~ ~ca alcuna inclicazione su quante vocazioni saranno immesse. JI progl'amma dovr clabmarn un numero arbir~ario di v.ocazioni. ln
quale modo iJ programma pocr determinare cfliando terminare l'immissione deUe votazioni? fn quale modo potr sapere quando calcolare e visualizzare la media della classe?
Una maniera per risolvere quesro problema ru usare un valore speciale, detto
val.ore senti.nella (o anche vakJre di segnd.la.7ion.e, valore durnmy (fitti.zio) o 11alore flag (bandiera)),
per indicare la "fine della immissione dei dati". I.:utenre immerrer le vocazioni finch rurte
quelle legittime saranno state immesse. I:utente irnmetcer quindi il valore sentinella, per
indicare che l'ultima valutazione sar stata imm~a. Le iterazioni controllate da un valore
sentine.Ila sono spesso deru: iterazioni indefinite perch, prima che inizi I'esecuz.ione del
ciclo, il numero delle iterazioni non noto,

Lu SVILUPPO nr PROGRAMMI ~TIHJl" f'lJMTI

59

Cb iar:imenre, iJ valore senciaelJa dovr essere sdrn in modo che non possa essere
confuso con un valore. di input accerrabile. Daro <ilie le valurazioni di un esame sono
nom1almeme degli interi non negarivi, -1 sar un valore seminella accettabile per questo problema. Di conseguenza, una esecuzione del programma per il calcolo della
media di una classe porr elaborare:: un flusso di irrpm q:1me 95, 96, 75, 74, 89 e - 1. LI
programma quindi calcoler e visualizzer la media della clas~e per le \TOta'l.ioni 95. 96,
75, 74 e 89 (-1 il valore sentinella, perci non dovr e:~sere inserito nel calcolo della
media).

~ Errore tfpico 3. 6

Scegliere un vawre sentine/La che sia anche i-m vahre Legittimo per i timi.

Affionteremo ora il problema del calcolo della media di una. dasse, con una tecnica
<':.biamara, top down (datl'a/t(J in basso) per rajfnamenti successivi: una recnica essenziale per
Lo svi luppo di programmi ben strucrurari. Cominciamo con una rappresentazione in
pseudocodlcc del top:

Determinare .Id rntdia della classe per l'esame


Il rop un.a ~in.gola isnuzione. clic specifica rutte le .funzioni del programma. Per come
definito, il rop in effetri w1a rappresencazione complero. di un prgramma. Sfortunaramente, il top speci.ficaiaramenre una quanrir sufficieme di dei:tagli da cui ricavare un programma C.

Per quesco morivo ora diamo il via al processo di raffina.mc.neo. Dividiamo il rop in
una serie di piccole arvir e le elenchiamo nell'ordine in cui dovranno essere eseguite.
Ci produrr il seguenre primo reffinommto.
Jniziaii2.Z11re le variabili
Prendere in input, sommare e conftzre le votazioni deU'esnme
Co/col.ore e uimalizzore I.o media della classe
In quesro caso scara usata solramo la srrurtura di s~quenza: iofu.rci, i passi elencari dovranno essere eseguici in ordine, uno dopo l'akro.

f1['1

Ingegneria del softWarr: 3.3


Ogni rnffinmnento, cos corno lo stesso top, una
varia solo i! livello di dettaglio.

erumci~ione completa de/L'ttlgoritmo,

Per procderc verso il livello succe.~sivo di raffi.uamenco, ovvero$ia il secondo, ci impegneremo nella specifc<i delle variabili. Abbiamo bi$ogno di un totale progressivo dei numeri, un
comatorc de.Ila quanrir di quelli che sono stari elaborati, una v;u:iabilc per ricevere il valore
di ogni valutazione, quando sar scaro immesso nell'input, e una variabile per conservare la
media calcolara. Cistruzione in pseudocodice
Inizializzare le variabili

porr esse.re raffinata come segue:

lnizializzare il totak a zero


Inizializzare il contntore n :uro

'

CAPITOLO 3

60

Osservate che occorrer i.nizialiizare solo il rorale e il contatore. Le variabili per la media
e le vaJutazioni (sperrivamence, per la media calcolaca e l'input deU'uteme) non dovranno
essere necessariamente inizializzate, perch i loro valori saranno sostituiti dal processo di
scrittura distruttiva, di cui abbiamo discusso ud Capitolo 2. L'isrruzione in pseudocodice

Prendere ln inp1(t, sommare e contar.e /, uo(a.zion.i dell'esarrie


richiede una strumua di irei:azione (ovver<;>~ia un ciclo) che prenda in input consecurivamenre ogni vah.1tazione. Dato che non sappiamo in anticipo quante valurazioni dovranno
essere daborare, uril.izzeremo una iterazione contrllaca da un valoresenrindla. l.'.utente digiter
una per volta le-valutazioni legictime. Una volt;i_che l'ultima valutazione legittima sar sr.aca
digitata, l'uteritelnimerrer il valore sentinella.. Per ognuna delle valucaz.ioni immesse, il programma controller l'evenruale immissione dehalreseminella e terminer il iclo quando
l'avr inconrrato. Il raffinamento della precedence iscruzione in pseudocdice s:rr quindi

Prendere in inpu.i fa prima valutazione


Finch l'u'tente non. ha ancora.irttmesso il vale.. sentinella
Aggiimgere questa valutrn:;ione al total.e cor.rente
Aggiungere uno al contatore di valutazioni
Prendere in input /,a prossima valutazione {o forre il valore sentinella)
Osservare che, nello pseudocodice, non utilizziamo parentesi graffe intorno all'insieme di
istruzioni che formano il corpo della srrucmra finch. Facciamo rienrrare semplicemente
queste istruzioni sono il finch, per mosrrare che appartengono rucce a finch. Di nuovo, lo
pseudocodice solr.anto un aiuco informale allo sviluppo del programma.
I:isttuuone in pseudocodice

Calcokme vi.su(J../izzilre I.a medJa della class


potr essere raffinata come segue:

Se it contatore mm uguale a uro


fmpostare I.a media con ili totale diviso per il comatore
Visualizzare la media
altrimenti
VisU11,/Jzza.re "Non sono state immesse valutazioni"
Osservare che~ questo caso siamo scaci artemi a verificare la possibili~ di una divisione
per zero: un errore fatale che, se non fosse stato individuato, avrebbe causato il fallimento
del programl}ia (detto spesso bombing o orashing). Il secondo raffinamento compleco
mostrato nella Figura 3.7.

~ Errore tipico 3.7

Un tentativo didivisione per zero generer un errore forai.e.

Inizializzare il totak d zero


/nizittli.7.zare ii.contatore a zero
Prender.e i'll input la prima vaiutaziohe
Finch i'utente'hon ha ancora immesso il valore sentinella

61

Lo SYILUl'PO DI PROGl~MI STRUTfURATI


Aggiungere questa valutazione al rotale corrente
Aggiungere uno al c_qn>atore di valutazioni
Prendere in input '4 prossimfl valutazione (o forse il valore sentineliti)
Se il contatore non ~ uguale a zero
Impostare la niedid con il totale divi.so per il contatore
Visualizzare la med1.
altrimenti
Visualizzare "Non sono Itate immesse valutazioni"
Figura 3.7

Lalgoritmo in pseudocodice che utilizza una iterazione controllata da un valore


sentinella, per risolvere Il problema del calcolo della media di una classe.

Buona abitudine 3.7

Quando esegrtite 1ma divisione per una espressme chpot1 ebbt: asmmere tm vqfore uguale
r1 uro. tontrollate.esplicitamente quella evetiimza e gestitela in modo '1.J>prpr:tt(J nel vast1Q
programma, per esempio, stampand.o un messaggio. inuet:e di lasciare che urt lfn'Ore fatale
1

ne intenwnpa l'esecuzione.
Nella Figura 3.5 e nella Figura 3.7, per una maggiore leggibilic, abbiamo incluso
aJJ'imerno dello pseudocodice alcune righe complecamenre vuoce. In realr, le righevuoce
separano questi programmi nelle loro varie fasi.

Ingegneria del software 3.4

Mo/Ji programrnipossono essere s11ddivid logicaf!tent in ttefas;, imafase di iniziaji~itme,


che inizializza k var.iabili de/.pro!!amma; unafosi: di elborazione, che prewJe in input
i valori dei dati e imposta conseguentemente Le variabili del programma; uria fase di
chiusura, che calcola e visualizza i risultati finali.
l!aJgoriano in pseudocodice della Figura 3.7 risolve il problema pi generale del calcolo della media di una classe. Quesro algoritmo sraco sviluppato dopo d ue soli livelli di
raffinameoco. A volte saranno necessari pi livelli di raffinamenco.

Ingegneria del seftware 3.5

li programmatore termina ii processo top down per raffinttmenti successivi;. quando


L'algor.itmo in pseudocodice specificato sujfic:ntcmmte dettagliato perch it progrmmatote possa essere in grado di convertirlo in C. Normalmente, a quel p:U.nto,
l'implementazione-~! programma sar lineare.

Nella Figura 3.8 s6.n mosrrati il programma Ce l'esecuzione di e.sempio. Nonostaoce vengano i..mmesse solcanrn delle valutazioni intere, il calcolo della media produrr probabilmence un numero decimale con una virgola decimale. Il cipo di dato int
non pu cappresencare un tale numero. Il programma introduce perci iJ ripo di daro
float per gescire i numeri con Ulla virgola decimale (detti numeri in virgola mobile) e
un operatore speciale, dcto operruore cast (operatori di Gomersione), per g~srire il al~
colo della media. Queste c.ararterisriche saranno spieg!li:e in dettaglio dopo la presentazione del programma.

CAI'tTOLO

r Programma per il calcolo della media di una classe con


Una iterazione controliata da un valore sentinella /
#include <stdio.h>
ma in ()
{

/* il ~uovo tipo di dato * I

float av(:?rage;
int counter, grade, total;
/* fase d i inizializza zione *I
total = 0;
cotJnter "' 0;

chius~ra */

if (counter I= 0 ) {
av.erage = (float) total I counter;
printf("Cla ,s average is %.2f' 1 average);
else
printf ('No grades were entered\n) ;

1 indica ohe il programma termi nato oon successo '/

Enter.
EnteP
Entr
Enter
Enter

Enrter
Enter
Enter
En~er

Class

FiguraJ.8

grade, ~1 t;o end :


grafe, ~ 1 tO end:
grade, -1 to en :
grade, - 1 to end:
grade, 1 to -end:
gr:-ade 1 1 t@ eh'd :
grad.e, -1 to efld :
grade, 1 to end:
grade, 1 to en<I:
a v.e.rage is 8 2"-5'0

Osservare l'istruzione composta nel ciclo while della Figura 3.8. Ancora una volra, le
parentesi_ graffe sono necessarie perch cu[[e e quattro le istru1.ioni sia.no eseguire all'inrerno del ciclo. Senza le parentesi graffe, le tre istruzioni nd co rpo dcl ciclo .ricadrebbero
aJ l'escerno dclla iterazione, indhlcendo il compun:r a inrerp'l'etare erroneament e il codice
nel modo seguente:
while ( grade I= - 1)
total = total + grade;
oounter = counter + 1;
printf( "Enter grade, -1 to end: " );
scanf( "%d " , &grade);
lutazione.

while (grade != 1) {
total = total -t grade;
co.unter = cqunter + 1 ;
printf( "Enter grade, -1 to end: ");
scanf( "%d " , &grade);

return 0;

63

Ci provocherebb e un ciclo i.rifinito, qualora l'urenrt non immettesse -I come prima va-

/* fase di elaborazion e t
printf ("Enter grade, - 1 to end: ");
scanf('!%d", &grade);

/* fase di

LOSVTLUP"PO I)[ PROG l~\fMI STRU"ITTIRJ\11

75

94
97
88
70

64
83
89
-1

li programma e e l'esecuzione di esempio per il problema del calco~o della


media d! una classe, con una iteraiione c?ntroll~ta da un valore sentinella.

Emma abitudine 3.8

lk2J

In un ciclo controllato da nn valore Sifntinelln, ilptoin.pt pr.r la richie.;ta di lmmissione


dei dati dovdt rico1dare esplicitamente rrll'1m11te qual il valore senti11elln..

Le medie non saranno sempre dei valori inceri. pesso, una media sar un valore
7,2 o - 93,5 che comengo no una parte Frazion~ria. Questi valori sonQ indicati
come numeri in virgola mobile e sono rappresenra dal Lipo di daro float. la variabile average dichiara ca con il ripo f loat cos) che possa <:<murare il risultaco frazionario
del noscro calcolo. U.risulram del calcolo tot al I counter sar run:avia un incero,
poich. total e counter sono emrambe del le variabili inrefe. Dividere due inceri
produce una divisionem1 iflter in cui ogni parre frazionaria del calcolo persa (ovverosia
troncata). Daro che il calcolo sar eseguiro per primo, la parre frazionaria sar persa
prima che il risultato possa essere assega4ro ad average . Per produrre un calcolo in
virgola mobile aon dei va.lori inceri, dovremo creare dci dari temporanei che siano dei
numeri in virgola mobile. Per eseguir.e quesm com pico, il C fornisce l'operatore unario cast
(od operatore di conv~rsione). J..:isuuzione

come

average

(f loat) total I counter;

iod ude l'operacore di conversione ( float) che creer una copia tmporanea in virgola mobile dcl suo operand o total. L'utilizzo di un openrore di conversione in questo
modo derto conversione esplicita. Il valore immagazzin ato in total ancora un incero. I.I calcolo, a questo pum:o, consister d i un valore in virgola mobile (la versione
float temporanea di total) d.Ivi.so per un valore incero immagazzina to in counter. Il
per sa solo valutare espressioni in cui i tipi di dato degli argomenri
compilaJ.'ore
assicurarsi che gli operandi siano dello scesso ripo, il compilacore
Per
sono id.en.ci.
se lez iona ci una operazione derta promozione (o anche
quelli
su
eseguir
Per esempio, in una_espres~ione c0ntenenre i ripi di dato int e
impiici't'o).
co1111ersione
speci f<>a che dov ranno essere esegui re delle copie degli operandi
ANSl
standard
lo
f loa t .
essere promosse al cipo float . Nel noscro esempio, una
dovranno
quesce
int e che
la copia di counter e che questa sar stata promossa al
eseguira
v<>lca che sar stata
e iJ risultato della divisione in vi rgola mo):>i lc sar
calcolo
il
tipo fl~at , sar eseguico
ANSI fornisce un insieme di regole per I.a promostandard
Lo
assegna:ro ad average.
Il Capimlo 5 prescmer una discussione di cur i
operandi.
di
pi
zione dei differenti
cli promozione.
ordine
rela.vo
del
e
tipi cli dato stand<trd

CAPITOLO

64

Sono disponibili operatori di conversione per ogni ripo di daco. I.:operar9re di conversione composta inserendo delle parentesi tonde iruorno al nome del tipo di dato. roperarore di conversione un operatore unario, ovverosia un operarore che accerra solo un
operando. Nel Capicolo 2 abbiamo studiato gli operaro aritmecici binari. Il C supporta
anche delle versioni unarie degli operatoci pi(+) e men0 (-),perci il programmatore
pou scrivere espressioni come - 7 o +5. Gli operato.ri di conversione associw da destra
a sinistra e hanno la m:ssa priorit degli altri operatori unari, come il + e il - unari. Tale
priorit a un livello pi aJro di quella degli opctat.ori moltiplicativi.*, I e 9ts e a un livello pi
basso di quella delle parentesi.

li programma nell~ Figura 3.8 urilirz.a per la printf la specifica di conversione lii. 2f
per visualiz.zare il valore di ave rage. La f specifica che sar visualizzato un valore in virgola
mobile. li . 2 la precisione con cui il valore sar visualizzato. Quesca stabilisce che il valore
sar visualizzato con due cifre a desrra della virgola .dci decimali. Nel caso fosse stara u.riliz.zat:t
la specifica di conve.(sione 5\sf, ovverosia senza indicare la precisione, sarebbe stata urilizzara
quella d;. defareltdi Qcifre, proprio come se fm'Se stam mitizzata la specifica di onvers.ione
%. 6f. Nel momenro in cui saranno visualizzari dei valori in virgola mobile ort una dara
precisione, il va10fe visualiz;zato sar arrotondato al numero i.nd.icaco di posizioni decimali. Il
valore nella memoria rester jnalteraco. Una volra che le seguenci istruzioni saranno state
eseguire, sara.nnQ visualizzati i valori 3,45 e 3,4.
/ visualizza 3,45 /
printf {"%. 2f\n", 3.446);
/* visualizza 3,4 */
printf("\. 1f\n", 3.446);

Lo SVl.LUPPO DI PROGRAMM1 srn.1.!ITURAn

65

solamente una quanril: prefissata cii spazio; quindi evidente che il valore in virgola
mobile immagazzinato porr essere solranro una approssimazione:.

3.1 O Formulazione degli algoritmi con processo top-down


per raffinamentj successivi: studio di un caso 3
(strutture di controllo nidificate)
Lavoriamo ora su un altro problema compleco. Utilizzando ancora una volta lo pseud.ocodice
e il processo cop down per raffioamc.mi successivi, formuleremo un algoriono e scriveremo
un corrispondente programma C. Abbiamo visco che le stm:rrure di controllo possono essere
accatastate l'una sull'altra (in sequenza), proprio come i bambini accatastano i marroncini
delle cosrruzioni. ln qucsro srudio di un caso, vedremo l'unico alrro modo strutturato anraverso il quale le strutture di o.mrollo porranno essere connesse in C: ovverosia amaverso la
nidificllZione di una struttura di conrrollo Jn un'altra.
Considerate la segueme..enunciazione del problema:

Una universit offre un corso chepreptzra gli studeizti per l'efrtrne della Licenza di staJ:oper agenti.
immobiliari. Lo scorro nno, mo/Ji degli studenti che hanno completato questo corso ha:no
superato l'esame per ottenere fa licenz,a. Naturalmerrte, l'universit vorrebbe sapere quale sia
staro L'esito dei propri studenti al termine dell'esame. Vi stato chierto di scrivere un progi-amma
che sommi i risultati. Vi sta'fll anche ronsegnata una li.sto. tfi 1Ostudenti. A fianco a ogni nome
stato scritto un L, se lo studente ha supmuo l'esame, e un 2, se lo studente stato respinto.

Errore tipico 3. 8

Il vostro programma dovr analizzare i risultati dell'esame come segue:

e.n-ato usare 1.a precisione in una specifica di cnversione nef/,a stringa per il controllo
delfamu1to diu:na istmzione scanf. Le prcisioni possono essere 11ti!izzate soL{O.nto n~lle
specifiche di conversione di printf.

Buona 4b,_it;14imr 3.3

L Prendere in in pur ogni risulraro della prova (ovverosia un 1 o un 2). Visualizza.te i.I mes~
sggio "Enter resulc'' (im:mer;rere il risultato) sullo sthcrm ogni volta c::he il prgramma
richiede un alrro risulcit della prova.
2. Comare le occorrenze per ogni po di risultato deUa p rova.
3. Visualizzate un riassumo dei risuJcaci, che fodichi il numero degli srudenci che han.no
superato la prova e quello degli scudenci che sono stari respinti.
4. Nel ca.so pi di 8 stude11ti abbiano superato l'esame, visualizzate il messaggio "Ra.ise miiion"
(aumentare le ta.s;e}.
Dopo a~er .letto atrentamen_ce J'enunci:tzione del problema, sviluppiamo le seguenti
oss.ervaz1on1:

N<m esegtJi.te un confionto di ug;u.agliii.rii:f!. di va.Lori in virgola. mobile.

1.

Errore tipico 3.9


Utilizzare i numeri in virgola mobile, presumendo che siano rappresel'Ittlti in un modo

preciso, potri condurre a risultati incorretti. l numeri in virgolll mobile sono rappresenrati
da{fa moggigr parte dei comp1tter solo in moda approssimato.

I numeri in,virg~la mobile banno numero~ applicazioni, nonostante n0n siano sempre "precisi al 100%" . .Per esempio, quanq<;> pa.diamo di ui1a "normale" temperacura corporea di 98,6 gradi..Fahrenheit (37 gradi Celsius), non abbiamo bisogno di essere precisi
fino a un gran numero di cifre. Nel momento in..filli vediamo la temperatura di un termometro e leggiamo 9'8,6, questa porrebbe essere in r.ealr 98,5999473210643. La questione
che leggere sernplicememe quel numero come 98,6 andr bene per la maggior pa.r:t delle
applicazioni. In se~iro diremo qualcosa in pi a proposito di questo problema.
Un altro JI!odo per mezzo del quale potrebbero essere prodotti dei numeri in virgola
mobile artra.ve~sp l~ dlvisioni. Quando dhrid.iamo 1O per 3, li risulmto 3,33.3J333 ... on
la sequenza dci ~ che si r.ipere all'infmito. Per comenere un mie valo.re, il co-i'hpllt-c alloca

n programma dovr elaborare 10.risulcati per la prova. Sai quindi uti lizzato lUl ciclo

controllaco da un conrarore.
2. Ogni risultato della prova sar un nun1ero: un 1oun.2. Ogni voka che legger un_risulcaro della prova, il programma dovr determinare se qud numer sar scaco un l o an.2.
Nel nosrro algoano ci limireremo a controllare il numero 1. Qualora il nwnero non sia
un 1, supporremo che si tracci di un 2. (Un esercizio alla fine del capitolo considerer le
conscgueo.zc di questa supposizione).
3. Saranno urilizzaci due concacori: uno per comare il numero degli studenti che hanno
superato l'esame e l'altro per contare il numero di qu~ che sono stari respinti.
4. Una volta che il programma avr elaborato i risultaci, esso dovr decidere se avranno superato
l'esame pi di 8 scudenti.

66

CAJ'ITQLO

Pro.cediamo con LI processo top down per raffinamenci success


ivi. Cominciamo con

una rapprc!Senrazionc in pseudocodice dd rop:

Amrlizwre i rimlt11ti de/L'tsame e decidere se debbrmo essere numen


tnte le tasse scolastiche
Ancora w ia voi ca, . imporrante mettere in risalto che il top una
rappres<:Ilmzione completa del programm~. ma che probabilmenrc saranno necessari div~rsi
raffinamemi, prima
be Lo pseud0codice possa evolvere natm almeme in un ptqgra
mroa C. li nscro primo
raffinamenro sar
Inizializzare le varJ'abili
Prenden: in input 10 vnlutt1Zioni della prova e contare le promoz,ioni e
IF bocci11t11.re
Visualizzare un sommario dei iisultati de/l'es11me e deddtte se le ttWe
scolartiche debbano
essere aummtate
Anche a questo punto, sebbene abbiamo una rappresenrazione
romplera dell'incero programma, sa.r necessario wl successivo raffina.memo. Ci impegn
eremo ora a specifica.te le
variabili. Saranno necessari dei concarori per regiscrare le promo
zioni e le boroarnre, un
c::ontaro.r.e sar ucilizzaro per conrrollare l'elabotazi0ne del ciclo e
sar occ~aria una variabile per immagazzinare l'input dell'urente. I:isrruzione in pseudocodice
lf1izirtli:z,zrire I.e variabili
porr e.">sere 1affi114ra come segue:

[nizialiZzo:re le promozioni a zero


Iniziali.zuire le bqcciature n zero
lni.zia/i22,llre gli mulenti ti uno
sservace che sono stati ini2ializ7.ari solranco i contatori.e i corali. L:isrrm
ione in pseudocodice
Prendere in input 1() valutazioni dell.1 prova e ctmtare Le promozioni
e le boci:iatur
richieder un ciclo che prender in_ input conse.curivamente i
risulrari di ognuno degli
esami. In quesro caso, si conosce in anricipo ch ci saranno precisa
meme dieci cisulraci di
esame, perci ~ appropriato u.riliuafe un ciclo rnmrollaro da un
C()lltatore. Una str1;1rrura
di selezione doppia all'i.memo dcl <".ido, owerosia nidific~
nel corpo della .irerazione,
determiner se ogni risultato di esame sar sraro una promoz
io)1e o una boccia:rura e
increm~ocerdi oorueguenza i contatori appmpciati.
Il raffinamento della precedeme istruzione
in pseudocodice sar quindi

Finch ii conta,tore degli studenti inferiore o uguale a dieci


Prem/.ere in input il prossimo ri$1,ftato. d'esanu:
Se lo uudente stato pr(Jmo.rsq
Aggiungere uno ai promossi
altrimenti
Aggiunger~ uno aj bocciati

Lo SVILUPPO DI PROGRAMMI STlll.JTf'IJRATI

67

Vsualizzare un sommario di Timitari deLL'esnme e decidere se le t.a..rse


sco/11.Jtiche debbano
essere aumenrote
porr essere raffinata come segue:

Visualizzare il numero delle promozioni


Vsu4ljy.zare_ il mnnero delle bocciature
Se pi di otto studenti sono stati promossi
Vrsualizzare il mesu1ggfo ''Raise mition" (aimibztare le tmse)
Nella Figura 3.9 appare il secondo raffinamento complero. Osserval'e
che le righe vuote sono
usate anche per e.vjderiziare .la srrucrur a dd finch e migliorare la leggibil
ira del programma.

lniziali.zzi1re le promozioni a zero


lw~ia!izznre le bocciature a zero
fnizialiuare gli studenri n uno
Finch iL contatore degli smdenti inferiore o ugU11./e a dieci
Prer.idere in input il prossimo risultato di mzme
Se /.Q studente. stato promosso
Aggiungere uno ai promossi
1dtrimenri
Aggiungere uno tli bocciati

Aggiungere uno ai contatore degli studenti


Visualizzare l.I numero deile promozioni
Vima.Lizzare il numero delle boccint:ure
Se pi di otto J'titde.nti sono stati promossi
Visualizzare il mmaggi.o ''Rahe tuition" (aumentai-e Le tasse)
Figura 3.9

Lo pseudocodice pe r il proble ma dei ri~ultati dell'esame .

Ora questo pseudocodice sufficientemente raffinato per (:$Sere


convertito in C. Nella Figura 3.10, sono .mostr~ ti il progra mma C e due esempi cU
esecuzione. Osservace che
abbiamo approfittato dj una caratcerisrica del che cqnsenre di incorp
orare le inizializzazioni
nelle cUchi:arazioni Una siffatta inizializzazione sar eseglta d urarite
la compilazione.

Obiettivo efficienza 3.1


Inizializza.re le va.rU!bili contestualmente. al/4 Loro dichiar~ione riduce
il tempo. di
esecuzione di un prognimma.
l'!J.geg;neria del software 3.6

Aggitmgere uno al contatore degli studenti


Osservate l'utilizzo delle cighe bianche, per evidenziare la strumu
a di controllo se!nltrimenti
e migliorarela leggibilir del _programma. I:isrruzione in p~eudo
codice

L'esperienza ha dimostrato che, S1{ un computer, la parte pi1~ difficil


della risoluzione
di un problem4 lo sviluppo deil'algoritmo per la sua soluziane. Norma
lmente, una volta
che sia rtato specifica.to un algoritmo corrett-0, il processo di p.roduz.ione
di un p rogramma funzionante sar lineare.

GAPJ.l'OLO 3

p
t

69

fng.egheria. e/et sofrware-3..1

'Erii:te.r: res_U195 ('T=:pa.S.& 1 2='fiafil~ :


E-n:t:e'f ' .r-e's ul?!f (1=pas.s ;~=tail j :
EJJ:te.r fe'sl!llt" (-1=p!B.s.'S-:1 2;;;if.aii:j:
O't.er r"&s.t1J..t ,(i-=pass,,~ail): 2
~nt"er rrt.S.un ( =pas.s 12-=fai ): 1

lYlolti progrdmmatorlscrivoiw; progr"tJ.rf?mi serzi;il rrl!,d uti.ii~tr_rnmo St'/'lmtent(J ~i ~11i


lzppo come lo pseudocodiee. (edono che ~l loio. ~biettivo ~r~n_ctJ,d/. sr'n qt1e~o d1 rrsoL11re il prohl-ema ~u im corn.pt~te1; e che s.m.vere. lo pseudoc(}t/u;e serpa so/o a nttt:rt/d.re la
prod~t.:ione dei risult:_ati ji11'f1./,j,

'E'ntrer r-esui:t (1=pass,.~fail:): ~


Ent-er ris'llilt (1='pass 2=-fail): 1

Anali:si di risul t9.-ti dell'esame *I

~in,~Tude

E.n1!0.r re,soul .(1 =pass j)~fai1.) : 1


'erite1ri ~e:su1't 1 =pas:s,~fall) : 1

<st'di. h>

main()

:Jlt&

/* inl.zalizz-a le varia.bili nelle- dichlarazoni *I


= 0 1 fail.ures = 0, student = 1, result;

passes = pas-ses

else
failures
s'~de nt

faill:ll"~!J);

3.1 I Gli operatori di assegnamento

1111.d~bi/e

k rdarive espre"SS.i0ni.

Per

vartb~/e o;ert(J.r spr'ssian.e;

dove opt1,atore. sia un.o degli ope',ra:tori binar.i +, - , *, / o % ( a.Itri cli cui discuteremo nel

/ * chiusuf a con sucsesso


}

Enit~f'! re'S~l,t (!1=f>YalS-'S,2:-taii) :


rie su u (l =e-ts~ , 2:otail )': 2
Ent~H' r~!J.l::t ( 1=-~sis , 2=-kll).: 2
Erl~~r t'e.~W.1 (1=pa:s---s, 2=fai1): i
Erfter res:i.11~ (1=p'8'ssJa=faai) :

fili~e t'

6fi'1!~1' r~U-J;t (1:'1)a;&si;i 2=fl&il.) I 1

~1

'Capr_roJo 10). po_tr essere scritta J1.eHa focma


ililrabi/e. opi!ttttortt~?SptSsioiJi;
Di conseguenza l'a.sse_gnamenro e += 3 aggiungera 3 a c. L;:i 'Fi'gura 3.11 mostra gU
operawr1 a r iun ;~ici di assegnamento, alcne espressioni di seinpio che li urilinano e
Je rela:.cive spiegazfoni.
Operatore
di assegnamento
Assume~:

int e = 3,

Espressione

di esem,pio

Spieg~.ione

Assegna

12j

= e

+ 7

d = d

1 a d

e * == 5
t /= 3

e = e

2~

'/=

f = f I 3

\=

g %= 9

d = 5, e = 4, f

+=

e += 7

( f.=-pa~, 2=fta~l) : 2

*=

~
Ente.r r,ts~lt ;{1=p~_$,2=1"@.-jl): 1

.Pl;$-l;J4'0 6
Fa.11:~1' 4

Figura 3.1 O Il programma C e l. esecuzioni di esempio pr il problema del risultati


dell'es;;im.

Eperaw[e +~aggiunge il valere ddl'e$pressiooe alla destra ddl'0pera~9re alla var1abile alla
sua sin.isrra, lnmagazzinf.Ilclq il ris.ultato in quesr'itlcim.a. Ogni istruzion.e deLl forma

pass~s);

f tpasses > 8)
J)'r.int'f ( "Rri.S!! "tuition\n'");

E~il~ re~l>t

p.ocr: essere ahbrevi3..~ c6a. l"opera:tre di -assegnamento addizione += c.qme in


e ~= 3;

1i

'*t~fl' 1'esu.it (8f=~assJ2=f.:il'ili):


Elner re:su-it (1=pan,, ~t.:ai~.) :

t ;:G'l;i 0 r:i

print:f .("Pass.ed %d\n'1 ,


prl ntf( "File9 %, i\n",

Ra .1:5"eJ

Il C fornisce divers.i oper~tQri di ass~gnaincnto p:cr a~brviare


~pio, L'isn:uzione e
e + 3;

+ 1;

= failures + 1;

= student +

P,-SS.eCl 9
P&fle,d 1'

irit passs

/* !llabera 1 0 studeni;j,.; ciclo controLlatd da un c.oh'tatore *I


ivhil~ (student <= 10) {
printf (Enter result ( 1==pass 1 2=fail) : " ) ;
scanf("%d", &result);
f .(r!Jsult = 1)
/* if/else nidificato nel wlile "/

r'..sUlt (1<="~8:SS,~"ll;l;;f:ail) :

-=

6, g

= g

Fi_g ura 3. 11 Gli operatori aritmetici di assegnamento.

'

10 a e

ae

2 a 'f
3

a g

70

CAPITOLO

Lo SVILIJPPO 01 PROGRAMMl SrRlflTURAII

JJ. programma visualizzer il valore di e prima e dopo l'utilizzo deJl'pperatore ++. I.;pperatore di decremento ( - ) funziona in modo simile.

Obiettivo efficienza 3.2


Una i.sfTIJ.Zone che utilizzi tm operatore di assegnamento (come in e += 3) sar compilata pi velocemente del siw equivalmte nelltt forma estesa (e = e + 3),_perch la e
della prima espressione tar valutaia soltanto una volta, mentre quella della seconda
es-pressione sar 1;alu.tt1.ta due volte.

Obiettivo efficienza 3.3

/ * Preincrementa re e postincrement are */


#include <stdio . h>
I

111ain ()

int e;

Molti t/ei sur,gerimenti che menzmiaino in questo libro producono dei miglioramenti
irrisori, perci l'utente po'trebbe mere tentato di ignorarli. In realt, sar proprio L'effetto cumula.tivo di httd questi miglioramenti di pmt~ioni ahe consentir unti eseuzione significativammtepi rapida del programma. Un incremento ri'fevante dell'efficienza
sar rfalizzato, inoltre, quando 1111migliornmento1tpparen:temmte in-iforo sar stato
inserito in rm ciclo che potr essere riper:uto un gran numero di volte.

3. 12

I,

71

o = 5;
pri ntf( "%d\n", e) i
printt( "%d\ n", e++);
printt( "%d \n\n'1 , e) i
e = 5;
printf( "%d\n", e) i
pr intf ~"% d\n",

Gli operatori di increment o e di decremen to

Il e forn isce anche l'operatore di incremento ++ unario e l'opera:tore di decremento - unario


che la Figura 3. 12 riassume. Qualora una variabile e debba ess.ere iocremenraca di I, pou:
e~sere utilizzato l'operatore di incremenro ++invece dell'espressione e = e + 1 o e += 1.
Quando gli op.eratori di incrememo o di decremento sono sis[emati prima di una variabile, si dicono risperrivamente o-peratori di preincremento o di predecremento. Quando gli operatoci
di incremcruo o di decremento sono sistemati dopo una variabile, si dicono risperrivamente operatori di postincremenro o di postdecremento. Il preincremento (o il pc.edecremento) di
una variabile provocher in primo luogo l'incremento (o il decremento) di una unir della
variabile e, in ~guito, i1 nuovo valore della va:riabl le sar utilizzato nell'espressione in cu
<!ppare. fl postincremc.nto (o il postdecremenco) deU_a variabile far in m.odo che, nella
espressione in coi appare, sia ucilizzato il valore cocrenre della variabile e solo in seguim
quesr'ulrimo s;u: incremematb (o decremenram) di una unir.
Operatore Espressione di es'empio

Spiegazione

++

++a

lncremenca a di 1 e quindi ucilizza il nuovo valo


re di a nell'espressione in cui essa occorre.

++

a++

Utilizza il valore wrre.me di a nell'espressione in


cui essa occorre e quii;id.i incrementa a di 1.

-b

Decremenra b di 1 e quindi ucili:zrla il nuovo


valore di b nell'espressione in cui essa occorre.

b-

Uciliz.za il valore correme di b nelfespressione in


cui es~a occorre e quin:di decreuienta b d i 1.

t +c);

!* prein oreme nto /

printf{ "\d\n", e);

return 0;

t chiusura con successo * /

5
5
6

fi
Figura 3. 13 Mostrare la differenza tra il preincremento e l postincremenco.
~

Buo.na 11bit1tdln.e 3.10


Gli opemtol'i ima1i devono essere sistemati direttamente n ridosso dPi loro operandi, senza
l'int1'omi.ssione di spazi.

Le rre istruzion i di assegoamenro della f igura 3 .10


passes = passes + 1;

1, 1

Figura 3. 12 Gli operatori di incremento e di decremento.

Il programma della Figura 3.13 mostra la differenm era la versione di preincremenro e


quella di posti:nG!mento dell'operatore ++. Il postinc:remcnto della variabile e prqvocher il suo
incremenco, d0po che la stessa sar st:ara u~ nella istruzione print f . Jl preincrememo
della variabile e provocher il suo incremento, prima che sia utili:z.zaca nella..ist:ruz:ione printf.

I* p.ostin cremente * /

11

fa i lurs = failures + 1 j
st udent = student + 1i

porranno ~sere scritte in modo pi conciso utilizzando gli operatori di assegnamenro, ome in
passes += 1 ;
failures += 1 i
stud ent += 1;
o con gli operacori di preincremenco, come in

1:

++passes;

li

++fail ur,es i
++student;

UJ1LT01.0

71

Lo SVILUPPO ()I PROGRAMMI STRUrrURATI

73

o con gli operatori di postincremenro, come in

Esercizi di autovalutazione

passes++;
failures++;
student++;

3.1

imporcance notare in questo caso che, quando s incrernencer o si ~ecre~encer una

variabile in una istruzione isolata, la forma di preincremenco e quella di posnncrememo


avranno lo stesso effetto. Il preincrememo e il poscincremenm avranno effetti differenti (e,
iIL modo simile, anche il predecremcnro e il poscdecrmenco), solo quando una variabile

b) I.:indicazione dell'ordine: di c:.secuzione delle istruuoni da parce dd compmer detta


e)

urilizzara per l;S\!guire una azione, qualora una


d) La. struttura dJ selc-iionc
condizione sia vera, e un'altra azione qualora qui:lla qmcfu.ionc sia fulsa.
e) Molte istru1.ioni raggruppare all'inrerno d.Lp:arem~i graffe ({ e }) form:ino un - - - - specifica che una isrruzione o un loro gruppo
() La struuura di iterazione
dovr cssel'c eseguico riperuramente, finch~ w1a cerca condr1.ione re.scer vera.
g) I.:ite.ra.zionc dj un insieme tli iscrut.ioni per un numero specifcaro cli volte derra iterazione

Come operando di un operatore di incremento o di decremento, porr essere ucili,zato


sQlo un semplice nome di vaciabiJe.

Errore tipico 3.1 O

Tent11re di tttilizzan: L'operatore di incremento o di decmilento iri una espressione di11ent1 da


un semplice nome di 1.11tttbile, iwaltreparole, scrivere ++ ( K + 1) un errore di sintassi.

h) Quando non noto in anticipo il nu mero di volte che un insieme cli i$truiioni sar
per terminare l'Iterazione.
riperuto, potr essere udli1,wro un v.:ilorc

Buona abitudine. 3.11


.ltJ staruia>dANSJ generalmente non specifica l'ordine in cui s'(lranno valutati gli opertmd~
di un opemwre (anche se mi Capitolo 4 vedremo delk eccezioni a questa 11orma, per al.cum
operatori). Di consegumza, ii programmatore dovr evitare di utiur.zare delle istruzioni, con operatori di incremento o di decremen_to, nelle quali una particolare variabile,
che sia stata incrementata o decremiltara_, compaia pii't volte.

3.2

-=. :::,

ra 3.14 associano da siniscra a destra.


Operatori

Assocjativit

Tipo

( )

da sinis.rra a destra

parentesj

da descsa a sinistra

unaci

da sinistra a des-rra

molci plicatlvi

(tipo)

da sin istra

+
<

<=

>

>=

l=

?:
+=

--

/:::

%=

a destra

addirivi

da sinisrra a destra

relazionali

da sinistra a destra

di uguaglianza

da de5tra a sinistra

condizionale

da desrra a sin:isrra

di assegnamento

Figura 3.14 Priorit degli operatori incontrati sinora nel libro.

Scrv.ete quanro dilTcrcnri istrui.ioni in

e cbeaggiung.auo 1 alla variabile incera X.

Scrivecc un:i singola isrruzionc in C per eseguire ognuna delle artivic scguenri:
a) Asscgrme la somma clix e cli y a z e incrementare il valorc di x di 1 dopo il calcolo.
b) Molripli01re la variabile product per 2, utilizzando l'opcracorc *=.
c) Moltiplica.re la variabile product per 2, utilizzando gli operacori =e *.
d) Controllare se il valore della variabile count maggiore cli rn. Nel caso lo fosse, visualizzate
"Count is greater t han 10 .
e) D ecrementare la variabile x di I e quindi sottraerela dalla variabile tot al.
f) Aggiungere la variabile x alla variabile total e quindi decrememacc x di I.
g) Calcolare il resto della divisione cli q per dvisor e assegnale il risulcaro a q. Scrivere
quesra iscruzione in due modi diversi.
h) Visuali1,zacc il valore 123. 4567 con 2 cifre di precisione. Quale valore sar visualiiz.aro?
i) Visualizza ce il valore: in virgola mobile 3. 14159 con tre cifre a desua del punro decimale.
Quale v;ilore sar visualfaiato?

La tabella in Figura 3.14 mosrra la priorit e l'associativit degli operatori incrodo~


sino a q uesto punto. Gli operatori sono mosmui dall'alto in basso in ordine decrescente di
priorlc. La seconda colonna descrive l'associacivit dgli operatori a ogni livello di priorit. Osservace che l'operatore condizionale (?:) , quelJj unari di incremento ( ++), decremenro ( - ) , adciiz.ione ( +) , socrrazione ( - ) e di conversione, noncb gli operatori di
/=e %= associano da desua a sinisua. La tena colonna
assegnamento=, +=,
assegna un nome ai vari gruppi di operatori. Turci gli akri operatori presenti nella Figu-

Turri i programmi possono essere seri rei in termini di rre srrmrure cli conrrollo: ----~

-----e-----

apparir in una espressione pi grande.

+t

Rispon<lern a ognuna ddle seguenti domande-.


Una procedura per risolvere un problema. defi.n.ira in reanini di azioni che dovranno
essrc csegui1e e dcJl'ordi1ic in cui quelle azioni dovranno essere eseguile de1ea un

a)

3.4

Scrivete una isrruioae C per eseguire ognuna ddle seguemi acrivic.


a) Dichiarare le variabili sum ex di lipo int.
b) laizializzacc la variabile x con 1.
e). lnizializzacc la variabile sum con 0.
d) Aggiungere la variabile x a sum e as~egnace U risultato a quesr'ulrirna.
e). Visualim.atc "The sum is: " seguico dal valore della variabile sum.

Combinale le iscruzioni che a.vete sc;;ritto ncll'Eserci1,io 3.4 in un programma che calcoli la
somma degli inleri da l a 10. UciJizzare la srrumtra while per iterare l isauzioni cli calcolo e di
incremento. li ciclo dovr rcrrrunare quando il valore di X divmer uguale a l L

3.5

Decenninare i valori w ogni variabile dopo l'es~on del calcolo. Supponere che tutte le
variabili abbiano jl valore 5, quando ogni istruzione cominf;e.r la propria esecuzione.
a) product = x++;
b) result = ++x + x;

3.6

74
3.7

CA!"ll'Ol.O 3

Scrivere una singola istruzione C che


a) Prenda in inpul la variabile inrcra x con scanf.
b) Pren.da in inpur la variabile inrer:i y con scanf.
c) Inizializzi la variabile inrera i con 1 .
d) Inir.ializzi-la variabile incera power con 1.
e) Molriplit bilayariabile powe r per x e assegHi il risuJcato a power.
f) Lncre11len.ti la. variabile y di 1.
g) Concrolli y per verificare se sia inferiore o uguale a x.
h) Visualici la variabile intera power con printf.

Lo SVLLUPP() DI PROCRJ\MMI STRUITURl\Tl


c) SUl\I = 0j
d) sum += x; osum = slJJll + x;

e) printf ( ' The sum is: %d\n' , sum);

3,5

t ca1oola la somma degli interi da 1 a 10 I


#include <stdio. h>
main()
{

int sum, x;
X =i j
sum =0;
wtlile (X <= 10) {
sum += x ;
++x;

Scrivete un programma e che ucil.ini le ismriioni ddl'Ese.-ci2.io 3.7 per calcola.re X elevata alla
poumza y. li programma dovra conce nere una ruucrura di controllo cli iccraiione while.

3.8

3.9

ldcmifc:ue e correggere gli erro ri in ognuna delle segut:nti istruzioni:

a) while (e

<= 5) {

product

++e;

= e;

prJ.ntf( "The sumis: %d \ n', sunl);


}

b) scianf( "%.4f", &value);


e) if (gender = il
printf ( "WOman\n') ;

3.6

3.10

3.7

D ice cosa a:on va nella segucnccsrrurru.rn di icerazione while:

while (z >= 0)
sum += z;

Risposte agli esercizi di autovalutazione


a) i\lgotl.rmQ. b) ntrollo di programma. e) Sequenza, selezione, iccraiione. d) i f I e.lse. e)
Istruzione compesra. f) while. g) comrollata da un contatore. h) Scnrinclla.

3.2

3.3

x=x+1;
X t= lj
++x;
x++;
a)

a) product
b) result

else;
printf( "Man\n );

3.8

..

=1;

h)

printf('1o~w ,

power) ;

I eleva x alla potenza y


#include <stdio.h>

~I

main()

int x,y,i,power;
i

=, ;

power " 1;
scanf("%d 11 , &x) ;
sc.anf( '%ci ", &y);

c) product =prod!lct " 2;


printt("Count is greater t nan 10. \11 )..;

while (i<=

e) total -= -x;
f) total += i;<- ;
g) q 9s= divisor;
q = q % divisor;

power
++i;

y) {

x;

printf(''od', power);

return 0;

b) printf( ' %.2f", 123.4567);

visualiizaro 123, 46.

a). 1,nt surn, x~


b) X= J;

=, i

pOl'1er

g)

d) if (oount > 10)

3.4

l.

power = x;
y++;
i.f (y < x)

z = x++ + y;

printf['%. 3f\n" , 3.14159);


h isuali:z:z:ato 3, 142.

scanf( \d, &xl;


scanf( ' ll'D , &y);

a)
b)
c)
d)
e:)
f)

b) product ..=2 ;

i)

=25, x = 6;

=12, x =6;

3.9

n) Errore: manca la p arcnrcsi graffa cli chiusura per il corpo della while.
Correzione: aggiungern la parentesi graffa di ch iusura dopo l'is:rruzione ++e; .
b) e rrore: srata uri.lizzara la precisione nella specifica di conversione dl una scanf.
Corrc~ion e: rimuovete il . 4 dalla spccirica di conv~r.siomt.

75

76

ITOLO

LO SVILUPPO DI l)ROGRA.MM I,STRU'ITUl'tATI

77

int x = 1 , total = 0, y;

c) Errore: il punto e virgola dopo la parte else della smurura i f /else produrr un errore
logico: la seconda printf sar eseguita sempre.
Correzione: rimuovete il punto e virgola dopo I'el se.

while (x <= 10) {


y :o X x;
prir1tf( ,.%d\n~,

"valore deJl3 variabile z non sam mai modficaro all'imemo dellasrrurrura while. staro quindi
crearo un ciclo infinito. Per evitare il ciclo infniro, z dovr essere decrementata in modo da assumere,
ad un certo momcnco, il valore 0 .

3. 1o

y);

tot al +:o Yi

++x;

printf("Total i s \d\n, total);


re.turn 0;

Esercizi
Jdencifoce e correggete gli errori in ognuna delleseguen imuz.ioni (Nota: porr esserci pi di
un errore in ognuno dei pez2i di codice):
a) if (age >= 65);
printf("Age is greater than or e~ual to 65\n");
else

3.1 1

3.14

Scrivere una singola istruzione in pseudocodice che eseg_ua ggnuna delle seguenti azioni:
a) Visualizzate il messaggio Enter two numbers .
b) &segnate a p la somma delle va.ri:ibili x, y e z.
e) La seguente condizione dovr essere concrolhtra in un.a sm.mura di sd enone if I el se: il valore
corrente della vari:ibile m maggiore del doppio di qudlo:comenmo nella varjabile v?
d~ Octenece dalla rasciera dci valori pe~ le v;u:iabili.s, r e t.

~.14

Formuface un algorirmo in pseudocodice Ber ognuna delle seguen:ci anivim:


a) Otcenete due numeri dalla rasciera, calcolarene la somma e visualizzare il risultaro.
b) Ocrenere due nwueri dalla casticra e quilldi dcceaninarc e visuali.zzate il maggiore dei

pr.1,ntf('Age 1s less than 65\ n');

b) int x = 1, total;
While (X <= 10) {
total += x;
;+x;

e) While (x <"' 100)


total += x;

++x;

d) while ( y

> 0) {
pr.iiltf( ''t!d\n, y);

-Hy;
}

3.11

Riempire gli spazi in ognuna delle &asi seguenri:


a) la soluzione di ogni problema richiede !'~cm.ione di una serie di azioni in un _ _ _ __
specifico.
b) Un sinonimo di procedura, _ _ __
c) Una variabile che accumula la somma di diversi nume~i u n - - - - d) 11 processo in cui si impostano certe variabili cqn dci valori specifici all'ini1jo di un programma detto - - - - e) Un valore speciale uriliu.aco per indicare Ja ufuie della immissione dei daci" dccro valore

- -- - - o - -- - una rappreseucazione grafic;i di un algorim\o.


f) Un
g) la un dla.gramma di Bussb, fordi.ne in cui dovranno essere eseguici i passi sar indlcatc:i
dai simboli di _ _ __
di ogni algodtmo.
~ la
h) li simbolo di teaninai,ione iodica l'
i) li simbolo rctta11golo corcisp9nde ai cakoli, eh~nor:tnalmcnte saranno eseguiti dalle istruzioni
_ _ _ __, e alle operazioni dj inpuc/ourpuc! cb:e normalmente saranno eseguite dalle
de.Ila libreria standard.
e
chiamate alle funzioni
) J.:demenco scrirro all'interno cll un simbolo ~ decisione dcrto _ _ _ __

3.13

Che cosa visualizzer il seguente programma?


#include <stdio.h>
main()
{

due, se c'.
c) Orrcnece una serie di numeri posirivi dalla casc.iera e qui11di decerminare e visualizzate la
loro somma. Supponete che l'uceme immecca il valore sentinella -1 per indicare la "fine
dcU'immissione dei dari".
3.16 Scabilfre quali delle seguenti affermazioni sono vere e quali sono fulse. Qualora una alfermazion~ sia falsa, spiegacene iJ morivo.
a) I.:esperienza ha dimoscrato che la parte pi difficile ~lla risoluzione di un problema, su
un compuccr, la produzione di UD progtamma C funzionante.
b) Un valore sentinella dovr essere tale che non possa essre confuso con un valore legirmo
per i dari.
e) Le linee di flusso indicano le azioni da eseguire.
d) 1.e condb.ioni scrirte all'iucemo dci simboli di decision onn;I)gono sempre degli operacori arinnecici (ovverosia+, , , I e %).
e) Nd processo cop down per raffinamenti successivi, ogni rnffinamenro una rappresencazione compleca dell'algoricmo.

Per gli Esercizi daJ 3.17 al 3.21 , eseguite ognuno di~uSti i;iassi:
l. Leggere l 'enu o cia~ione dcl problema.
2. Foun ulate l'algoritmo usando I.o pseudoodi'ce e il proces.so rop down per rffn ttmenti
s.u.ccessivi.
3. Srivctc un programma C.
4. Collaudre, mmote a punto ed eseguire il programma C.
3.17 A.causa dell'alto prezzo della benzina, gliautomobilisciso_i;iointeressati alnumero di chilomerrj
percorsi dalle proprie aucomobili. Un aucomobilsca.bamanccnutQ traccia di diversi pieni di beniina,
!egisc:rando i chilornec percorsi e i liLri uliu.ari per ogni pieno. Sviluppare un programma che
prenda ininput i d1ilometri percorsi e i lirri utilizzati per ogni pieno. Il programma dovr calcolare e
visualir.zare i chilometri per litro orrenuti da ogni pieno. Dopa aver elaboraco rurce le informazioni in
input, il programma dovr calcolare e visualizzare anche i chilomecri per liuo ottenuti complessivamente da rurri i pieni.

CAr1ro1 0 3

78

Lo sVJLu r1c>0 or PROCRAM.Ml STRmTuRJrn

Enter the gallons 1,1sed ( ~ tltci entl) : 12. a


Enter the miles driven: 28T
The miles / -@!on tor tnistank was 22.421875

Entersaies in dollars (1 to end): 00,0.00


-

Sa1afy is: $650. 00

Ent-er r~es in dellal's (-1 to end). : t"234-. 56


Salary fs: $311 . 11

Enter the gallons used ( 1 t0o end) : 10. s


~tef:th.e tfiil~s Qll'ven: z~
The miies I g_1lloh fo.r th'is.:ttank Was 19.'4q1747S

enter S'ahlt in .d:ll.14l'~H


SiiliJr~ is: $298. 00

Enter tlle g_illons used ( -1 tQ end): 5


Enter tfle Aiiles driven: 1~
Tlle miles I !lalion tor this tank was 24. 000000
Enter the :gatlons used ( -l to eni.t) : 1

3.18 Sviluppate un programma C, che detemuni se il clience di un grande magazzino abbia superato il limice di.a;edico sul suo com o. Per ogru cUtnre saranno disponibili i scguemi dati:
I . U numero di como
2. Il saldo all'inizio del mese
3. Il cotale di rnrri gli articoli che il clicme ha messo in como. durame il mc:Se corrente,
4. li totale di curri i credici applicati al corno di questo dieme. durance il mese corrente.
5. li Limire di credico concesso
Il prqgram rna dovr prendere in input meri ques da , cnkol:1re il nuovo saldo (= saldo iniziale +
ardc::oli messi In cciilro-ctediri) e dereaninare se il nuovo saldo super.i il Limi ce di eredit del dicnic. Per
quei dicnri d ie avranno su peraro ilJ1m ire di credito, il programma dovr vjsualizz.'lre ilJoro numero di.
com o, il limire cU credito, il nuovo saldo e iJ messaggio "Credit limir exceeded".
Enter abeo1,1nt

3.20

l:interesse semplice ~u un mutuo calcolato dalla fo rmula


rate

days I 365

'alter dean prino1pal ( 1 'l:o nd) : 1:000 .00


Ent-er ~terest rat: .0Q375
Enter 'term of the lOC!ll in days: 224
The i.nterest charge i& ssi .400

Enter 1-11$1 pr:i.noa.pal ( 1 te end) :

10000...00

Entar ~ere&t riat-: :


En(-er term Of ttie loan in days: 1460
The inte,,est charge iS S3600.00

Enter J.oan principal ( 1 to end) : 1

Enter total cba1ges: 274,73

Enter loan principal ( 1 to end) : 1000 .0'0


Enter ioterest rat: .1
fntep unn of the roarr in days: 385
The mterest oharge is $100.00

Enter tta1.,~r'cli.ts': 500'.00


Enter credi.t l.mit: 5500.-~

Enter account number ( -1 ilo end): 300


Eniter beginhing balance: 500 .00

= principal

precedente.

Enter bei~o:fOg bahlni:e: s394 .18


Ei:iter tota[ oharges: 1:000 00

Enter aceeunt number ( 1 to'.;end): 200


-enter beginning balance: ~000.00
Entertotl oharges: 12:3.45
Enter total credits: 321.00
Enter gr~r,$! lmit: 15~.~

1~8. 89

La formula precedente presume che rate sia il ra.~o di interesse annuale e quindi include la divisione
per 365 (giorni). Sviluppare un progmmma C che prenda in inur principal (e!picale), rate (r:isso)
e days (giorni) per dJversi mmui e visullJiz1.i l'in:reresse semplice per ogni muruo, acllizzando la foa:irnb

number (1 to ;.end) : 100

100
Account:
Credit limlt: 5500. 00
5894.78
Balance:
Ctedi.t Limi-t:E seeJJed.

to ene >:

Enttir sales i n dolllil's ( -1 to end) : - 1

i nter.est

Tue ovrall average miles/~ori was 21.601423

79

3.21

Sviluppare Ull programma e che <lecermii1i la paga lorda per ognuno dci d~vrsi impiegaci. I:aziefr

da, per le prime 40 ore lavorare da ogni impiegam, paga il "salru:io rario di base", .men:rre per rurte le ore
lavorare in aggiunra alle 40. elargisce "una volra e mezza il salario di ase". Vi sono scarifumiri: una.lista degli
impiegaci dell'azienda, il numero di ore lavorare.da ogni impiegar nell'ultima settimana e il salario orario di
base di. ogni impiegaco. Il vosno programma <lovn\ prendere incinpur, per ogni impiegato, le suddecre
i11formazioni e dovr, quindi determinare evisual.iz.-1.are la paga lptii;1di ognuno di loro.
Enter Il of hours worked e 1 to end) : s9
Enter tiourly rate of the YK>rker ($00.00): 10.00

Enter-tota! credits: 100.00


Enter crflit l:i,lnit: 800.~

salcy is S390. 00

Enter a'<:l~ur:ft,nqmber ( 1 -te el'!d): 1

Efite'n ff~J:JPLY rate.,n f ~he wor.l<er (s00.00): 10.00


Salaryis $400.00

Una grande industria chimica rerribuisce i :propri vcn<l.icori basandosi sulle provvigio11i. LI
vendirore riceve $200 la scrcinuna pi il 9 per cento delle proprie vendire lorde portare a termine
durame la sccrimana. Per esempio, un venditore che in una seuimana venda prodorri.rhimici per un
valore di $5000, cicevcr $200. pi i l 9 per cemo di $'5000, ovverosia un tolale di. $q50. Scrivete Lm
programma C, che prenda n inpuc le vencilte lorde di ogni veriditore per l' uJci111a $Crtirm1na C quindi
G<coli e visualizzi il salario per ognuno di loro. Elaoora,n: i <:Qnri d1 un vcndfrore pervolra.

Enter

~- of

tiours worklk'.d H

~o

erio):

4~"

3.19

EnteP:it of hours worked ( 1 to end): 41


EJtter h.o urly rate Of'' the 1110r1<er {$00.00) : 10.00
Salatf,i.$ '$415. ~

Enfor, 4f of tiours Wt>rkel ( 1 to end) : 1

CAPITOLO

80

int oount = 1;

Scrivete un prog:mmma Cche dimosrri la differenza cr:i il pcedecrcmenco e il posl<kcrcmenro,


udli'l.zac;lo l'operatore di decremento-.

3. 2~

while ~count <= 10) l


pr intf( "%s\n', count % 2 1 . ........ ,

3.23 Scrivere un programma che utilizz un ciclo_, per visualizza~e i numeri da I a IO ala.nco a
fianco sulla st<!SSa riga e con tre spazi rra ognuno di essi.
3.24 li processo di ricerca del numero pi grande (ovverosia, del valore massimo in un gruppo di
numeri) ~utilizzaro frcquencemenre nelle applica7.ioni pr corT)pucer. Un programma che dccc.rmini il
vincitore di una gara di vendite; per esempio, prender in .input il. numero degli an~coli v.nduci da
ogni venQ.lt qte. Vincer la gara il venditore che av.r venduto il maggior numero di articoli. Scrivere un
programma in pseudocodice e quindi uno in e, che p.renda in i11put una serie di 1o numeri e in
segui~ de~ermini e visualizzi il maggiore dj qudli. Suggerimenro: il vosrro programma dovr ut:il.i:zzan:

ere vMiabili, come segue:


per mantene.re rraccia di quanti numri
(ovve.resia,
O
I
a
fno
comare
per
concacore
un
counter:
saranno sm immessi e per determinare quando tutti i IO numeri &1.ranno srnri elaborati).
il numero correnre immesso nel programma..
nlJlt>er:
l argest: il nwncro pili grnnde rrovaro sino a questo p.uoto.
3.25

.Sccivecc un programma d1c uriliz un ciclo per visualiz7.are la seguente cabclla di valori:
N

10-N

100'N

10

100

31?

300

40

400

SI)

500
600
700
800
900
1000

81

Lo SVlLUPl'O DI PROGRAMMI STRlJJTUR.>\TI

'++++++++");

++count;

return

3.30

~;

Che cosa-visualii.zer il seguente pragrnmma?


#include

<sttjio.h>

ma.in()
{
111t row = 10, column;

While {row >= 1)


oolumn ~ 1 ;
vihile ( column <= 10) {
printf( '%s", r~v % 2 ? '<': ">');

-=;

l~N

++column;

4
5
6
7
8
9

00
70
8'
00
100

...
1000
2000

- row;
pri ntf ( \ri");

iJ00
7000

return 0;

B000

9000

~
li c:arattcre di ra bulaziooe, \ '1:, pe.. e,~s'ere u ciliz~.:im nll_a iscruzicmc pdntfpr s~par:u:e le colo.bne i::On
1~

delle tabulazioni.
3.26

Scrivere un programma che ucillu.i un ciclo per produrre la seguence tabella di valeri:
~

At2

A+4

'S

10

12

j1

15

12
15

1~

13
16
19

17

18
21

3.27 'Frovace i due numeri maggiori era IO valori, usndo un approccio srnile-all'.Esercizio 3.24.
Nora: porcele prendere in input ogni valore soltanto un:i volta.

3.28 Modificace il programma della Figum 3.1 O, i.n rn;4o da convalidare l'ffipuc. Rei cera.ce su ogni
input, qualer-a.il valore: imtne.i;i;o fqss'c dlvers() tla I o da.2, finch l'mence non immcma un valore corFetto.
3.29

Che cosa visualizzer._il seguente programma?


l#incl.ude .;std10. h>
main()
{

3.31 (Problema deil'else appeso) Dccermirrace l'output d'ognuna delle scgLten istruzioni quando
x 9 e y 11 e quando x 11 e y 9. Osservate che il compihMre ignora i tiemci all' inremo di un
programma C. llcomp .ilarore e inolrre as:socer~ sempre. un !!lSe all'if precedente, sempre che non gli
sia stato derro di fue :rrimenLi. ama.verso la dsposiiion ddleparenresi graffe { }. Daro che, a prima
vista, il programmatore non pu es~ere sicuro ddl:i corrispondenza di Ull else con un i f , questo
problema defnico "dcll'dse appeso". Abbiamo eliminaro i rientri dal codice successivo, per rendere
pi inccressame il problema. ($u.ggerime.mo: applicace le convenzioni dei rientri che a.vece appreso).
a) if (X < 10)

if

(y > 10)

printf( "**"' ..\n" l;

e1Se

pr inrt( ~#####\n 1' l;


printf( '$$$$S\n'');

b) if (X< 10) {
if (Y > 10)
printf('*~\n'li

}
eise {

printf ( "###11#:\n ) ;
pri ntf("$$$$$\n");
}

3.32 (Un alrro problema dell'else appeso) Modi1cace il codice seguence in modo che produca
l'outpur mostraro. Ucilir.lacc le cecaiche di riemro appropriace. Non pocrece cscgLLire..alue modifiche

82

CAPITOL03

che non sia110 degli inserimenti cli parentesi graffe. li ompilarore ignora i rienrri in un programma C.
Abbiamo eUminato L rientri dal coclice seguente, per rendere pi 1meress;1nre il problema. Nora:
probabile che non sia necessaria alouna modifica.
if (y = 8)
if (X _:_ 5)

printf ("@@00!!\n );
else
printt( ' #####\n");
printt( 'S$$$$\n' );
pr intf ( '!&&&&&\n");

a) .Assumendo x

=5 e y

= 8, s_ar prodocro l'0t11:puf seguente.

[
b) Assumendo x

= 5 e y = 8, sar prodono l'orpur seguente.

e) Assumendo x

= 5 e y = 8, sar prodocro l'ourpurseguencc.

Lo svu.urro DI PROGRAMMI STRLfnURATJ

rio" una per volta da de~-rra a sinisrca, u:ti.Li7.zate gli opemrori di divisicme e dl modulo. Nel siscema
numerico decimale, la cifra pi a dscr h;t un valore posiz.ion;tle di I e quclle che si susseguono a
sinima hanno un valore posiaionale di lO, poi '1 00, poi 1000, ecc.; it.llo stesso modo, nel sistema
numerico binario, la ci.fu pi a descra ha un valore posizionale di 1 e quelle ch si susseguono a sinistra
banno un valore posii.ionale di 2, poi i. poi 8, ecc. Di conseguenza il numero 234- pocr essere
inccrpretaro come 4 I + 3 ' 10 + 2' 100. l.:cquivaJcnre decimale del binario 1101 sar I I
+ O 2 + I 4 + I 8 o l + O ~ 4 + 8 o 13).
3.37 Sentiamo p;tclare spesso dj quan.co sian.o veloci i computer. ln che rno<lo peri> tJOtece dt.!rerm lnarequa11to rea,l1nc11 te veloce l:i voscra m acchina~ Se.rivere tLn programma con 'Un dclo while chcconri
uno per volta da 1 a 3.00().000. Ogni volra che il conto raggiungerli un mulriplo dj 1.000.000,
visualizzerete il numero sullo schermo. Ucilizziae il vomo orologio per misurare il cempo impiegaro da
ogni milione di iterazioni :l'inremo dcl ciclo.
3.38 Scrivere un programma che visualizzi J 00 ascerisch.i uno per volta. Ogni dieci asrecischi, il
vostro programma dovr visualizw.re un ca ratte.re newline. (Suggerirne.neo: concare da 1 a I00. Usate
l'operatore di modulo per individ'ua.r:e rurre le volte che Il comarore raggi unge un mufr:ipl.o di 10).

3.39 Scrivece un programma che le&,oain.iaput un incero c. inseguito, determ in.i e-visualizzi quami
7 sono compresi nelle cifre dcll'inrero.

3.40

.-- ... .. '*

..

,_,

[I._ _. . =
:=~---------]
3.33 ScriYce un programma che legga in input illaco di un quadraro e quindi lo disegni uci l iu~1ndo
degll asteris_chi.11 vostro programma dovr funzionare _can runi i quadrati con dilrn:nsioni dei lari
comprese tra 1 e 20. Per esempig, se la djrnensione !erra dal vostro programma fosse 4, dovrebbe:
visualizzare:

vosuo

.. .

..._

Il vos1-ro progran:umt porr utiliz1.are solramo ere istruzioni printf: una della forma
pri~tf( ' ");
una della forma
prirrtf ( ) ;
e una della forma

printf( \ n") ;

visuJi,rncj

Scrivete un prog.r;rnuna che contin_u.i a visualiizare i multipli dell'incero 2, ovverosia 2, 4, 8,

16, 32, 64, eec. Il vostro ciclo non dovr J.lll!:i terminare (dovrcce insomma cre-.t.re un ciclo infnico).

Che cosa succede.cl quando eseguirece qnesro programma?


~ ..

3.35 Un palindromo un numero o una fr.m~ di resto che. da sinistra a desu:a o da desrra a sinistra,
si legge nello Hesio modo. Per esempio, ognuno dei seguenci in ceri di cinque cifre un palindromo:
1232 l, 5555'5, 45554 e !1611. Scl:.ivete un programma che legga in input un lnrero di ci nq ue ci&c
e determini s~ si tratta o n di un palindromo. (Suggcrimemo: per scindere iJ ownero nelle sue singole
cifre, uriliv.ace gli opemrori di divisione e di modulo).

3.36

.~

.. .. .. .... * '
...... . '* ...

3.4 t
[

,.. ~

,.. ~

* ... "' ...... * *

Modificate il programma che avete serino nell'Esercizio 3.33 in modo che visualizzi un qua~;
J, dimc.,,;onc lca> d,J
programm """ 5, "'bbe

vuf ;'."<mpio,

Scrivete on programma che visualizzi il seguente diseg!lo di una scacchiera:

.. . . . "
..
"* " "" * "' .Jr*
...
-- ....

d) Assumendo x = 5 e y =7, sar prpdocto l'ourpuc seguente. Nora: le ulrime ere printf sono
mere parei cli un'istruzi-Ooe composta.

3.34
dn<o

83

Prendere in inpuc un incero corueneme ~oltamo degli O e degli I, ovveiosla un incero "binario", e visualizzare il suo equivalente decimale. (Suggerimento: per prebiare le~cifre del numero "bina-

3.42 Scrivere un programma che legga il raggio di un cerch.io (come un valore di cipo floa:t) e quindi
calcoli e vism1Jl?:7j il diametro, la circonferenza e l'area. Utilinare il valore 3.14159 per te.
3A3 Cosa .non va nella seguente ibtruz.ione? Riscrivere l'ib-:rmziqnc in modo che esegua quello che
probab iI111 ence il prograJilmato re stava rnatando di ocre.nere.
printf ( ' %d' , ++(x + y)) ;

3.44 Scrivere un programma che legga in inpur tre valori di c:ipo float diversi da 1.ero e, quindi,
determini e visualini se possono r:ippresenrarc 1 la di un triangolo.

CAPITOLO

84

3.45 Sccivecc un programma che legga in inpur rre inc:erl diversi da zero e, quindi, determini e
visualizzi se possono essere i lari di un triangolo r~ttangolo.
3.46 Una azienda vuole rrasmerterc: dei dati sulla line;i. telcforuca, ma i suoi responsabili sono
preoccupari dal facto che i propri cdefoni porrebbero essere spiaci. Trnci i loro dac i sono trasmessi come
inceri di quamo cifre. Vi h:inno quindi chiesco di scrivere un programma che crirrograf i loro dari io
modo che possano essere rmsmc:ssi con maggior sicurezza. Il vosno programma dovr leggere un inreco
di quamo cifre e crittograF.ufo nel modo seguente: sostiruice ogni cifra con (la somma di quella cifra pit1
7) modulo 10. 111 scguiro, scambiare la prima cifra con la cerza, e scambiace kt seconda cifra con la
quana. Visuafo.7.are quindi l'incero crirrografuto. Scrivere un programma a parre 'Che prenda in input
un intero crinogrtifaro di quamo cifre e lo decifri, in modo da formare il numero originale.

3.47

nfattoria.le di un intero non~ neg:u:ivo

l1

CAPITOLO

Il controllo del programma


Obiettivi
Essere in grado di utilizzare le srrutnu:e di iterazione fo r e do /while.

si scrive nl (pronunciaco "falforiale di n") cd defnico

come segue:

n!

=11 ...(11- 1

11!

1)

~11-

(per \;ilpri c!i 11.m~ggiori o uguali a I)

2) ... I

(pe.ii

Il=

I
2!

I
3!

e=I+-+-+-+ ...
c) Scrivere un programma che approssimi il valore di , urilizz.ando la formula

J- ~
X
e" =l+-+-+-+ ...
l! 2! 3!

Comprendere la selezione multipla, u.tilnaodo Ja.strucru.m di scle7.iooe switch.


Essere in grado di utilizzare le isrruzioni break e continue per il conrroUo del
program.ma.
Essere in gr:tdo di utili:u.1.re gli operat ori logiei.

O).

Per esempio, 5! =5 4 3 2 l che 120.


a) Scrivere un programma che legga in inpm un lorero non negativo e quindi calcoli e
visualizzi il suo fattoriale.
b) Scrivere un prognunmacheapprossimi ilva.loredeUa cosmmemaremaca e, ucifo..z.ando la
formula:
I
I!

4.1

Introduzione

A questo punro, il !errore dovrebbe essere a proprio agio . on il processo d i scrimira cJj un
semplice ma completo programma C. In questo capitol, sar tr:rrtara pi derraguat:unenre
!'ire.razione e, nello sresso rempo, saranno presentare :llrre srrurru:re cJj controllo per qoe~i:'ul
cima, ovverosia la Struttura for e quelb do / while. Sar imrodorra anche la srrurcur:i. di
selezione multipla swi tch. Discureremo della istruzione break, per uscire immcruacamcnce e rapidamemc da certe srrurrure di controllo, e deUaiscnrzione continue, per ignorare
la parre rimanemc dcl corpo di una srrum1Ta di iterazione e procedere con la successiva
ire.i-azione del ciclo. Il capitolo ruscucer inoltre degli operatori logici utilizzaci per combinare fra loro le cond'Lioni e, infine, concluder con un riassumo dei principi della pl'ogrammazo.ne smmuraca presemad nel Capirolo 3 e nel Capitolo 4.

4.2

Gli elementi della iterazione

I.a maggior parre dci programmi rich iede delle iceta?.ioni o cfrli. Un ciclo (/.Qop) l Ul gruppo
di !!tnrLoni die il computer csc~tlr r iperutamente, f nc.h una .na crmdizio11e di cqnrin.utizi'<>ne del ciclo rimarr vera. Sinora abbiamv discusso cli du~ ci ~J di iterazione:
J . .eicera.zione conrro1lara da un contatore
2. I:iceraz.ione conrrollaca da

Wl

valore sentinella.

J;iterazione concrollara da un contatore derra a volte iterarione definita, perch conosciamo esanamente in andcipo il numero di volte che il cjclo sar~ eseguito. !.:iterazione conrrollara da un valore sentinella decca a volte iterazinne indefinita, perch non noto in anricipo
.U numero di volre che il ciclo sar eseguito.
Nella icerv.ione comrollaca da un contatore, urilizz.a.ra una varinbile di controllo per
comare il numero delle ireraz.ioni. La variabile di controllo sar incremenrara (di solim di 1)
ogni volra che sar eseguito il gruppo di imuzioni. l i ciclo terminer quando il valore della

CAJ11TOLO 4
variabile di controllo indicher cbe sar sr::no eseguito il numero corretto di iterazioni; a
q uel punto, il compurer porr continuare l'esecuzione con Liscruzione successiva alla srrucrura di c-0nrrollo.

I valori sentinella sono uciliz.zaci per conrrollare una icerazione quando:


l. il numero preciso delle iterazioni non noto La.ruicipo e
2. il ciclo include delle isrruzioni che oncrran.no dci dari ogni volca che qucsc'ulcimo sar
escguico.

/* Iterazione controllata da un contatore * /


#include <stdio.h>
main ()
{
int counter

I* inizializzazione *I
1~

condizione di iterazione */

/* increment o * /

d.stinri dalle informazioni vere e proprje.

Iterazione controllata da un contatore

= 1;

while (counter <= 10) {


printf ( ' %d\n", counter);
++counter;

11 valore sentinella indica la "fine dei dati" e sar immesso dall'utente dopo che rutti i veri
elementi informarivi saranno stati fornici a1 program.111:l. l valori sentinella. dovranno essere

4.3

87

lL GONLROU..O Olil. l'ROGRAMM1\

return 0;
,_

Una iteraiiio11e concro.Uara da un comatore richiede;


t. I l nome dj una variabile di controllo (o comacore del ciclo).
2. Il valore iniziale della variabile di conrrollo.
3. Lincremento (o decremento) con cui la variabile di controllo sar modificata ogni voica

2.

a
4

5
6

nel corso del ciclo.

4. La condizione che verificher il val.ore finale della variabile ili conrroilo (ovverosia:, quella
che determiner se il ciclo dovr conrinua.re).
Considerare il semplice programma mostrato nella Figura 4. l che visualizza i numeri da
1 a 10. La ruchiarazione

'T
8
~

10

int counter = 1;

Figura 4.1

assegna un nome alla variabile di conrroUo (counter), la dichiara di tipo inrero, le riserva
uno spazio nella memoria e le assegna il valore iniziale 1. Quesra dichiarazione non una

ra 4. L, inizializzando counte r a 0 e soscicuendo la scrurrur.a while con

istruzione eseguibile.

Avremmo anche potuto d ichiarare e i.nizializzaI:e counter <::on le istruzioni


int countr;
c oljn t~r

= 1;

La dlchiar~one, anche in quesro caso, non una isuuzi:gne eseguibile, mencre l'assegna-memo lo . In seguj co ucili2zerem'o entrambi i merod i per l'iniziali.zzazione deUe variabilL
I:iscruzione
++counter;

iflcretnenter iJ contatore dcl ciclo d i l ogni volta che quesw sat eseguito. La condizione di
cominuazioue del ciclo nella scruccura while comroller se il valore della variabile di conrrollo sia inferiore o uguale a 1 0, ovverosia l'ultimo valore per il quale la condizione risulrer vera. Osservate che il corpo d i questo while sar esguito anche quando la variabile
di conrrollo varr 10. li ciclo terminer quando l<t variabile di <::on aoUo avr super.uo 10
(counter avr assumo il valore 11 ).

Iterazione controllata da un contatore.

Normalmente, i prograrnmamri C renderebbero pi c0nciso il programma della Figuwhil (++counter <= 10)
printt c%d\n", counter);

Q uesto codice consentirebbe di risparmiare una .istruzione, poich l'incremento sarebbe


eseguito direttamenre nella condizione del ciclo while, prima che la sressa ~ia vecifcara.
Questo cod ice el iminerebbe anche le parentesi graffe intorno al corpo del while, perch a
quel punto ess con terr!!bbe u.ua. sola isrruz.ione.. Scrivei:dl c::odice in un modo cosl conciso
richiede una. cerra pratica.

Errore tipico 4. 1

Dato ,he i valori in virgola moble potrebbe:ro essere approssimati, utilizzare dc!Le variabili di quel tipo per il controllo dei cicli, potrebbe produ.rre dei valori impreci del
contatore e provocare dei conrrolli di termitutzi.oiie 1wn acitrati.
Buona abitudine 4. 1
Controllate le iterazioni determinate con dei va/ori interi.

88

UPITOLO

Buona abitudine 4.2

Fate' ~:ientrare con degli spr1.zi e.delle tabul.azioni le istruzioni nel corpodi ogn.111111 delle
stnttture. di controllo.

Buona abitudine 4.3


Inserite una riga vuota prima e dopo ogni principale strzmum di controllo in modo da
e11idrnziaritl afl'interno del progrttmma.

Buona abitudine 4. 4
Troppi livelli di nidificazione potrebbero rendere il programma incomprensibiit>. Come
regola generale, cercate d roitttre l'utilizzo dipi di tre livelli di rientro.

propria co,ndiz.ione di continuazione. Dare che la v:iriahile di conrrollo sar ora uguale a 2,
il valore finale non sar scato ancora superaco e di conseguenza iJ progr<l!l~ma eseguir
ancora l'istruzione pri ntf. Questo processo continue( f ncb la variabile di controllo
count er sar srara incremenmra al suo valore finale 11 . Ci far fallire la verifica della
condizione di continuazione per il ci~lo e ne provocher la term inazione. l1 programma
conrinuer eseguendo la prima istruzione dopo la scrurruri for (in quesro caso, l'isrruzione
r eturn .alla frne dello stesso).

La Figura 4.3 ill usrr-.a pi dett;;igliammente la stru.rrura fo r della Figura 4.2. Nocare
che la struttura for ''fa cucco": specifica ogni elemenro eessario a una iterazione conuollara da un contatore con una variabile di conrrollo. QuaJorancl corpo del for siano presenti pi isrru?;ioni, saranno necessarie delle parenresi graffe per defmire il corpo del ciclo.

Bitona abitudine 4.5

for

e.ii iterazione fOr gScisce aucomacicamente mrri i dctcagU di una l.rerazioue


controllat <li'I un contatore. Riscti.viarno il programma della Figura 4.l, eer .illusrrare la
potenza dell.._ isITU2ione for. n ristrato sar mosrraro nella Figura 4.2.
La Strl:Jtt~tta

main()
{

int counter;
I* inizializ,azione, condizione di iterazone e incremento */
/ * sono tutti inclusi nella intestazibne della struttura for */
for ( count er = 1 ; countr <= 10 i counter++)

printi ( "%d\n", co unte r)';


return 0 ;
}

Figura 4.2

Iterazione controllata da un contatore con la strutturafor.

li progrl).Illila operer come segue. Nel momento in cui la srrurrura for incomincer
a e~sere esc~m, la variabile di ~0 n.rroll.o counter sar ini::dalizzata a 1. In sc.guiro sar
venf.caca la condizi.one di cominuaz.ione del ciclo: counter <= 10. Da1:0 che iJ valore
iniziale di counter sar 1, la condizione sar soddisfatta e quindi l'is;U2one pr intf
visualiu.cr il valore cli count er, vale a dire 1. La variabile di conrrollo sar quindi incremcmaca dalla espressione counter++ e il ciclo ripartir nuovamente, con la verifca dclla

for ( counter

La struttura di iterazione for

/* Iterazione control lata da un contatore con la struttura tor /


#include <stdio.h>

Valore finale
della variabile
di controllo

Nome della
variabile di
controllo

Cqrt1bin411efo le ~pazillhit'e 71tic11,/i inserite pi:ima e dopo le stru.ttiJri! di. co11.tro!lo con
ii rientro d.ei loro corpi in ima porizione pi ifrternn rispttto aile relative testate, ddiete al vostro programma llrut apparenza bidimensionale che ne mig;lio1er enormemente la kggibiiitl.

4.4

89

Il. CONTROLLO DEL l'ROGRAJvlMA

parola chiave

Figura 4.3

1;

counter

Valore iniziale
dell .variabile
di controllo

<=

counter++)

10;

Incremento
della variabile
di controllo

I componenti di una tipica intestazione di un for.

Osservare che la Figura 4.2 milizza la condizione di .conrinuazione Jd ciclo counter


<= 10. Nel caso .in cui il programmatore avesse erroneameme seri.tra counter < 10, il
ciclo sarebbe staro esegulro soltanto' 9 volre. Questo sarebbe stato un ripico errore logica
chi.amaro "errore di imprecisione di uno''.

Errore tipico 4.2


Utilizzare. un operatore relazionale errdto o usare un valore finale erraio per il L'01ltatore d~L dc.lo, tdl'interno df!Lla cond1$ione di una struttura whi le o tor, potrl provocare 4.egli errori di i1nprecisione di uno.
Buona abitudine 4. 6

Urarc il valorefinak insieme all'operatore rektzionak <=, all'interno della condizione di un11
str11tt1m1 while o tor, aiuter a evilflre gli errori di imprecisione di uno. In un ciel.o utilizzato-per vis11hli.2mre i valori da 1 n 1O, per esempio, la condizione di crmtimrazme del
ciclo dovr e!sere counter <= 10 piuttosto che ont:er < 11 o counter < 10.
Il formato generale della smmru:a for
for (espressione]; esprenione2; espresri.one3)
ismlZione

90

CAPITO!,() 4

dove espressiont!l inizialiuecli la variabile di concrollo del ciclo, espressione2 sar la condizione di
concinuazione ed epressiond incrementer la variabile di controllo. Nella maggior parte dci ca~i
lasmmura for potr essere rapprescnram da un while equivalente, come segue:

Errore tipico 4.3


Usnrc le virgole invece dei punti e virgq/11 nella inteitazione di un tor.

espressione] ;

Errore tipico ef.4

while (espressione2)

istruzione
esprmmd;

L'inserimento di un punto e virgola immediatamente alla destm della intestazione di un


tor nnderJ il corpo di quella stmtturn tor una istruzion~ vuota. Questo ' normalmente
un errore di lot)ca.

C~ una eccezione a questa regola che sar discussa nella Sezione 4.9.
Spesso, espressione] cd esprersioru3 saranno delle liste .di esp ressoai separare da
virgole. Utilizzace in questo modo, le virgole saranno in realr d egli operatori virgola
che garant iranno la valutazione da sinistra a d estra dell' elenco di espressioni. Il valore
e il cipo dJ una lis.ta cli espressioni separare da virgole saranno quelli dell' ultima espressi-One ~deUa lii;.ra. l:operarnre virgola utilizzarn m<;>ltQ ~pesso nelle s[rutcurc far . Il suo
ucilii.zo prladpale quello di consenrire al programmatore di uttlizzare le inizializzazioni
e/o le espressioni di incremento multiple. Per eserpio , in una singo la ~trurtura for
potranno esserci due variabijj di conuollo che dovi:ann essere inizializzare e incremencare.

Buona abitudine 4.7


Nelle sezioni di inizializzazione e di incremento di untr struttura tor, inserite solo delle
espmsi<mi che coinvolgano k varia.bili di control/,o. La gestione de/I.e altre variabili dovrebbe
comparire o primo del ciclo (se dovranno essere eseguite una sola volta, come le istruzioni di i11izializ.zazione}, oppure all'interno del corpo del ciclo {se dovranno essere eseguite una volta per ogni iterazione, come le istruzioni di incremento o di decremento).
Le rre espressioni di una scrunura for sono opzionali. Qualora erpressione2 sia omessa, il C presumer che la condizione sia,sempre vera, cre:ndo q uindi un ciclo infinito. Si
porrebbe omcmere espressione], qualora la variabile di conrrollo fosse stata inizializzata
alcrove nd programma. Cespressione3 porr e.sere omessa, ~ualora l'incremento fosse calcol.aro dalle istruzioni interne al corpo della srrurruca for, o qualora no11 sia richicsco alcun
incremen:ro. L'espressione di incremento all'imerno della struttura for agir come se fosse
una isrruzione Ca s srame, posta aUa fine del corpo d<ll for. Di conseguenza, nella sezione
di incremeoro della struttura for, le espressioni
~ou nt~ r count er
co.unter += 1
++counter
counter+ +

91

h. CON'l'ROI 1.0 OL\l. PROGMMMi\

saranno tutte equivaleo. Molti programmatori C preferiscono la forma counter++, perch l'incremcmo avverr dopo che sar sraro eseguito il ciclo all'interno del corpo. Per
q~esro metivo la forma del poscincremenro sembra pili naturale. Daro che il preincremenro
o iJ poscincrcmenro della variabile in quesw caso non ai;>pare in una espressione, entrambe
le forme di incremento avranno lo sresso effetto. Entrambi i punci e vrgola nella scrurrura
dd for sono obbligatori.

4.5

La struttura for: note e osservazioni

1. L'inizializzazione, la cond.iz.ione di concinuazione del ciclo e l'incremento po rranno


co11[enere delle espressioni arkmetiche. Per C$empio, supponcie che X = 2 e y =
10, l'istruzione
for (j = M; j <= 4 * X

* Yi

+= y I X)

$acil equivalente alla isrruzione

tor ( j 2; j

<= 80; j + 5)

2. ".I.:increroeuro" potr essere negacivo (in cal caso sar in realt un decremento e il ciclo
effettivamente coruer a ricroso).
3. Qual.ora la condizione cli concinuaz.ione ~el ciclo sia ~Isa sin dall' ~o, la porno.~e aJJ'~
1
rerno del corpo del ciclo non sar esegum1. 1.esecu:1.1one
proceder mvece con l 1scru210ne successiva alla suucrura far .
4. LavaciabHe di conr:rollo spesso visualizz.aca o ucilirz.ata nei calcoli all'inrerno del corpo
di un ciclo, ma non necessario cbe lo sia. :t. pico usare la variabile di conr:rolJo per
couaollare l'iterazione, senza menzionarla mai nel corpo dclcido.
5. Il di;igrammaddla scrurrura far rnolro simile a quello dellasrnmura while. Per esempjo,
il diagramma di flusso della isrruzione for
fo r (counter = 1; counter
printf( "%d ", counter);

<

10; counter++)

moscrato nella Figura 4.4 . Questo d iagramma di flusso rende evidence cbe l'i1lizializ.7.azione sar effocruara solo u na volta, mencre l' incremento sr eseguico solo d opo che
s;tr stara compleraca l'istruzione all' interno del corpo. Osservare che (a pan:e i cerchiecti
ele frecce) il diagramma di flusso conricf}c solra:m;o dei rerrangoli e un r~mbo. l~ma
ginace, anco(a llna vol ta, che Il programmatore po$a accedere a un conten 1 r~r~ capiente
di srrurmre for vuote. La quantit d i queste cale che, a:ccaca.standole e n1difcanclole
con le alcre suutture cli controllo, egli porr formare unalmp1emenrazione stru rwxara
per i l flusso di controllo di un algoritmo. [ reaangoli.e i rombi saranno quindi completati con le azioni e le decisioni appropriare per l'algociuno.

Buona abitudine 4.8


Nonostante iL valore della variabile di co11trollo poJra essere modificato tmche all'interno del corpo di ttn ciclo far, ci potr generar.e degli errori Logici difficili da
individuare. Quindi sar meglio non cambiare tale valore.

92

CAPITOLO 4

93

It. cm-rmo~.o l)f.L l1ROCRAMMA

Buonn abitudine 4. 9
Le istruzioni d1e precedono un tor e quelle aU'intcnUJ del tuo corpo potmnno spesso essere
compattate nrfla intestazione del f or, ma evitate di farlo poich ci render meno leggibile il programma.

Stabilisce il valore
iniziale della variabile
di controllo
Verifica se stato
raggiunto il valore
>--

finale della variabile


dJ conrrollo

Figura 4.4

printf(.%d,
-.i count er);

counter++

Corpo del dclo.


Pu essere
composto da
molte ltruzioni

Increment a la
variabile di

/* Somma con for */


#include <stdio.h>

ma in ()
{

int sum

controllo

number;

far (number = 2; number


~ um += num.ber;

Il diagramma di flusso di una tipca strutt1,1 ra for.

<= 100 ;

number

+= 2)

printt( ~s um is M\n", sum);

4.6 Esempi di utilizzo della struttura for


l seguenti esempi mosrrano dci metodi per far variare la variabile di conrrollo in una
srrurrura for.

a)

= 0,

r et urn 0;
}

Far variare la variabile di conrrollo da 1 a 100 in incrememi d i 1.

sum is 2 550

for (i= 1; i<= 100; i++)


b) Far varia.re la variabile di conrrollo da 100 a 1 in incremenci di -1 (decremenri di 1 ).

for
c)

(i= 100; i>:::

1; i -)

la variabile di connollo da 7 a 77 a passi di 7 .

_Far variare

tor (i = 7; i

<= 77; i

+= 7)

d) Far variare la variabile di conrrollo da 20 a 2 a pa5si di - 2 .

e)

= 20;

i >= 2; i = 2)

Far variare la variabile di controlJo sullasegueatesequenza di valori: 2 , 5, 8, 11 , 14, 17, 20.

to r ( j = 2; j <= 20 ; )

-t=

3)

f} Far va.ri;ue la variabile di c.ontrolJ0 slla seguente sequcnrza di valori: 99, 88, 77, 66, 55,
44 , 33, 2 2, 11 , 0 .
f or ( J = 99 ; j >: 0 ; j = 11 )

l prossimi due esempi forniranno alcune semplici appliarioni della stmrrura for. Il programma della figura 4.5 ucilizza la srrucrura for per sommare tutti gli interi pari da 2 a 100.

05;5ervace che il corpo della srrucrura for nella -Figura 4.5 in realt porrebbe essere
unico alla sezione pi a destra della incestai.ione del for , utilizzando l'operatore virgola ncl
segoenre modo:
for (number

= 2;

ili.ni7.ializzazione sum

number <= 100; sum += number, number

Somma con fo r.

Buona abitudine 4. 1O
Ljmiutte a una sola riga, se possibile, la dimemione delle intestazioni di uno struttum
di controllo.

Il prossimo esempio calcoler l'inreresse composto, urilizzando la muuu.ra f or. Considerare la seguenrc enunciaiione del problema:

for (i

Figura 4.5

+= 2)

= 0 porrebbe anch'essa essere unica alla sezione di inizializzazione dd for.

Una pmonn investe $1000, 00 i11 un libretto di rispannio, che re7lde il 5 ?erc~nto di
intresse. Calcolate e viswilizznte l'ammontare dcl dntrfo rziil aonto rdbt fine dt. ogm anno,
per JOanni. supponendo che tutto !'interesse sia sw:to ltzJ.citt.to in deposito sul conto. UtiiizMte fa seguente formula per detenninare le suddette cifte:
a= p(l

+ r)"

dove
p

l'ammontare dell'investimento zi:i;i.ale (ovverosia il capitale)

,.

il tasso di interesse a;muale

il numero degli 11nni


/izmmonttire nel deposito alla fine dell'anno n-esimo.

Il

Quesro problema richjedey un ciclo che eseguir i calmi.i indicaci per ognuno dei 1O
anni in cui il denaro rimarr nel deposico. La soluzione mosrrata nella Figura 4.6.
L'lSrrunura fo r eseguir il corpo del ciclo 10 volre, variando una variabile di conrrollo
da 1 a 10 in incrementi di I. li C non include un operm~re per l'operazione di elevamento

9.4

CAPrt"OLQ 4

CQNIROLl.O DE.I.. PROC)RAMMt\

a . I:>Qtem.~, ruravi.a porremo utilizzare a ques.to stopo la Fu.n.zine pow. della libreria srandard. La fu.ntione poW(Ji(, y) ~kola iJ valoi:e dix devaro al.la.y - e.sima pbrenza. Il double
e un tip:o di dat!> in v:go.l rnobile rno.lto Simile .aJ fioat , ma una variab.iJe di tipo doubie
pu immag~ztnare numeri molro pll gr-a:ndi, cwn una precisione pi alca di Ili! float.
Os:Servare che, qtial.ra venga miliuaca una funzione man;matka come pow! dovr essere
focluso il file di intestazione math. h. In Feal:t, ques-t~ programma funzioDerebbe, ina
male, anche senza l' inclusim cli math . h. L.a tu.ni,ioiie pow richiede due argoiiirnd double.
Osserva:re ch year perQ illl iorei:o, Ii fil~ math . h iodu.de appunto dcl.le in.ff>nn.a:zioril cht5
i.o.dic;aao al ompilatore di Gotivertire il v.alore di yar in una rapprSorazione double
-i:.mp.or.;ina, prima di rid1iama.re Ja funzione. "l'hli informazioni sono contenute in WHl
enrit. chlrilara pro.tori.po di jnzione d.i pow. I ,prnrotipi di funzione. sono una n.uqv:a impor~
tarfre e.racterisrici deH'ANSf C e saranno spiegarj nel Capjolo ? Nello stessu c.:iP.it.9lq,
forniremo un compendio di pow e delle al_cr~ funzioni marematiche (!.ella libreria.
./'" Galcolare l ' .i:nte.resse c omposto ,. ,

#include ~s taio . hj
#inlude <math.n>

95

Bu.otta abitudine 4.11


Non .utiliZZ1Jte vartbifi 4it:ipo float o doubl~per (J}eg1/ite cf!.kofi}irian?ifrri. l.'i?'ri.prPsione de;im1meri in pfrgo/!1 mobi/fpotrprovocm'c degli 'mori chp;-6tfumumo vahri.mo'netali
n(m t;'tfrtetti. Negli r:'I1ttki .e.rplor:ri'no {'J.,tifizzq d.e intllri j><rr esegi.tire i CtJlto!if.nanzit1ri.
Ecco una semplice spieg;iz.i9nc;; di quello che potrebbe andar ma.le. qu:aJpra si utilizz;i:s~e il ripp float 9 double per ..rappresenr:a.re d~li foiporti .i.n dollari.

Due qua1frirariv~ di dolfari, espressi in float e im.rn:ag.aminari nella: 4llil'tchioa_. pocrcl;>-bern essere 14,23.4 (che sarebbe visualizzato come !(23 i;:oo ~ . 2f) e l8,<?1B h:q cen
% 2f sarebbe sramparo c::om.e 18,67). Nel momcmto irr cui le suc(d~tte ccifte sa.r:a.n.no s0ni:rflare; produ.rran.no la ~omm 3.2,97 che, ton % 2f sareb.he visua.lizz.'l~<t com 32,Q 1. Di onseg11enza, ~a vo~m vi1>.ualiz.~a.Zione pott~bbe apparire c.Qme:
14,23

+ 1'8,67
32' 9:1

ma.in ( )

~ per evide.nre che la 1iOmrI1'1. d~ singoli nuri:fec-i, cos) or:ne vertgon visualizzaci, debba
ss,efo 32,90! Siet .stati a..v.v.,sa!

int

y~ar;

d'otfb-le amount 1 prinG'ipal


printf ,("~As~21 s'\ n ~ ,

for

1000. 0 1 rate "' . 05;

"Year", "Amount on deposi,i "). ;

(y.~ar : 1; ye.ar .:;= 10; yea.r++) {


amount = prlndp.al :,;,: pow(1.0 ,+,rate, year);
printf("!\i4d7621.2f\n", yearJ amount);

ret.u rn 0'j

>'

Y-ear
1

:Am"U.unt

10!E0. 0'0
11!0~. 5'0

11~.6.2

1 ~15:. 5:il

1'~16' .2'8

1340. 10
14011 . 10.
1#;77 .46

8
9

1551.83

10

M~8'.S9

Figura416

me

a,ppar\r, in 21 pos'izio.fu di visualizzazi.one.11 2 spcifica la previsione .(v.ale a dire, il numer9


d:iposizioni deciinall). Qualora anumero dei caraeteri vsualizza:ci sia inferio re a.14. qimeosio~
oe del <..'ampo., iJ valore sar automaticamenre gjusti.fi.aato a d.fst1-a all'i.n te(Ilo dd 9UTlP.0 .10
sar- p<1rtic0la.rmenre utile per allineai:~ d_~ valori 'in virgola.mobil~ con I(}. ste~a precisione.
Jnserire un - - ($_egpo men9) tra .i.I% e.la dime~ione del qrmpc.'i; per gt,'W;i:fic4Y.a sinistra. ii
valore.iriseci~Q in quel c;amp.o. Osse.r:v.-are..1z.he il se.gp:o nieno porr anche essere urili2.11aro per
giusrifGa.te...;i sinistra gli interi (&me in 515 _6d), o [e srrioghe di cai:a.ti:e1:i ~come in% - as). Nel
Ca:pimlo 9 cr;mei:etno .in dettagli.o le pocenri apa:cir di formattazione U printf e scanf.
0

Gfl depo:sdi~

ru

4spe~il-ca
cmwcrsifm.e %21 2f .~c~r.a urifo.ui..a nd pr:ogram:m~ p.e.r v.is.ualiz?.,ir.e il
val9ce della v~riabile uount f1 21 nel.la.speci6_a.d.I ciinv.e;c;sine-de.noca la difncmme..del campo
io uj i I valore sar wsu.a;l.i.zza.ro. Una d.i.mcttsione di campo 21 specifica
il valore visualizz-at0

Caleelar.e l'interesse composto con far,

Ossn(ate che ob:iam0 dichiararo Ie variab_Jlj amount, princ-:j.pal e rate con .il dpo
.d ouble. A'bbimo "farro ci per scmplici.r, p~rch avremo a cl1 a:re wn parr:i raz.ioriarie
di d.Bllari.

4.7

La struttura di sele~ione multi.pia switch

Nel Cap~co{o,3 , ahbiam0 discussa' della struttura ~ i selezion.e singol.a i .f e di que.Ua di


seleziqne dopfiia i f / .else. A vol.ce per l1.ll ~lg0ririilo perrebbe rid'uede.rl': -che una data
variabile od: ~p ressione venga cuo.fromatil lisdmamerue .con ogmmo dei valori che essa
pu assume.te. e che,, a s'ec:;nda dcl cisufrato del c.onfrruo, .vengano inrraprese delle azioni
d.imnte. u e fo.r.nisce la struttura di selezione mulcipla switoh (interrmrore) per g<!!Scire
una ral ser.ie di d ~isioni.

La strua:u.ra switch cnsistedi una sede di eti-c;bctte'casec.(c:;aso) di un caso 0pzi.onale


default. 11 pr:gramrrm. nella Figu.r.a 4.7 lilizza sw tch, per comare il numer::o di og1runa
delle teccer omilltrre dagli studenti come votazione al rermiDe di un esame.
Nel progra,mm, 11utme i.rtunerter le lettere di yotazi:n d'.1e ~ state ssegnare
un'' dasse. Alfinfruo della irirest!l~ine del whll~
whHe ( (

~Tade

= get<::har ()

) J; EOF)

96

CAllJT()LO

/* Contare le lettere dei voti * /


#include <stdio.h>

97

CONTROLLO DBL PROGRAMMA

printf('C : %d\n', cCount);


printt( "D: %d\n, dCoun t);
prin tf ('F: %d\n, fCount);

main ()
{

retur-n 0;

int grade;
int acount
dCount

0, cCount ;: 0,
0;

0, bCount
0 , fCount

Enter the letter grades.


Enter the E'OF haracter to end nput.

printf("Enter the letter grades.\n');


printf("Enter the EOF character to end input. \ n") ;

A
B

while ( ( grade = getchar() )

switch (grade)

!:

/* switch nidificato nel while * I

aI

case ' A' : ca se


++aCount;
break;

case ' B' : case


++bCount;
break;

I b I:

EOF) {

/ * i l voto er a una A maiuscola


/* o una a minuscola "'/

.,

e
E

1ncorrect lettr grade ente ved. ETitr a new gr ada.


I " i l voto era una B maiusco l a */
/ * o una b minuscola /

case ' C': case e:


++cCou nt;
break;

I " i l voto er a una C maiuscola


/ * o una e minuscola *I

case ' D': case 'd':


++dCount;
break;

I* i l voto era una

D maiuscola
o una d minuscola */

..

.,

/* i l voto era una F mai uscola *I


/* o ~na f minuscola */

case

I*

\ n': case ' '

otals far each l&tter grade are:


A: S
B: 2
e: -s
D: 2
F: 1

Figura 4.7

case 'F ' : case 'f' :


++fCount;
break ;
1

D
F

gnor~.

Gjuesti caratte ri nell' in,put * I

br~ak;

default:
/* intercetta tutti gli altri caratteri */
pri ntf ( 1 rncorrect letter grade ent ered. ");
printf( " Enter a new grade. \n")~
break;
}

Un esempio di utilizzo di switch.

l '~-segnamenco incluso nelJe parenresi ( grade = getchar( ) ) sar eseguito per primo.
La funzione getchar (dalla librerja srao.dard di inpurfourpur) legger tm cararcere daUa
tastiera e lo immagazziner nella variabile incera grade. Normaltner:ite i cararceri sono
immagazzinati in variabili di tipo char. Una importante carnueristica del C runavia che
i earattcri possono essere immagaz1iinaci in qualsiasi cipo di dato intero, poich all'inrerno
del computer sono rappresenrati come interi di 1 byr~. Di cnseguenza, porremo rrarrare
un carattere sia come inrero sia come caratrerc vero e propria, secondo il suo uti lizzo. Per
~empio, l'isrruiione

pr i ntf( ''The character

(\e)

has the value %<1.\n", ' a 1 , ' a ' );

uri.Lizzer le specifche di conversione %e e %d per visualiizare rispenivamence il cararrere a


e il suo valore incero. Il cisulraco sar:

The character (a) has the value 97.


printt ( \nTotals f or each letter grade a_re: \n") i
printf( "A: %d\n", acount);
printf("B: %d\n ", bCount);

J..:.incero 97 la capprcsenrazione numerica del carattere ud compurer. Molri compucer


uciliu.ano oggi l' irmemc di caratteri ASCIJ {American Standard Cwlefor lnformation lnterchtmge,
Codice Americano Sttlndard per lo Scambio delle Informazioni), nel quale il 97 rap presenca la

98

C\l'ITOL.0

lener<i minuscola ' a '. Un elenco complem dei ca.racreri ASCII e dei loro valori decimali
sar presentato ndl'Appc,ndicc O. I caratteri possono esscreJerti coa scanf , utilizzando la
specifica di conversione 91ic.

Le istruzioni di assegnamento, considrare nel loro complesso, hanno in realc un


valore. Qucsm precisamente il valo(e che sar assegnam alla varfabile alla sinistra del
segno=. Il valore dell'assegnamenro grade ~ getchar () sar il cararcere resriruico dalla
getchar e assegnaco alla variabile grade.

li facto che le isrru1.ioni d i assegnamente abbiano dei valori porr essere urile per
inizializzare diverse variabili con lo Stesso valore. Pcr esempio,
a

= b = e = 0;

valurer in primo luogo l'assegnamento e = 0 '(pE>ih l'operaco,re = associa da destra a


sinisrra). Alla variabile b sar g uindi assegnam il valore delPassegnarnento e = 0 (ovverosia
O). In seguito, alla variabile a sar assegnam jJ valore dell'assegnamcnco b = (e = 0)
(anch'esso O). Nel programma, il valore delfassegnrunen.ro grade = getchar() sar confrontato con.i l valore di EOF (un simb lo Hct acr")nimo sca p~r "end ot fJe" , "fine dcl file").
Noi u tilizzeremo EOF (che r10rmalrnence vale - 1) coi:ne valore senrinella. L:utente premer
una combinazione di casti dipendente dal sistema, per in dic.'lre la "fine del fle", ovverosia
"Non bo pi1 dari da immettere". tEOF una costante simbolica ruera definita nel file di
intesrazione <stdio . h> (vedremo come si definiscono le costanti simboliche nd Capitolo 6).
Qualora il valore assegnato a grade sia uguale a EOF, il pr?gramma terminer la propria esecuzione.1nquesro programma, abbiamo scelro di rappreseru:are icaracreri con degli int, poich EOF
ha un valore incero cbe, lo ripcriamo ancora una volra, normalmente -1.

1J. CONTROLLO DEJ. l'R()GRAMMA

99

ognuna delle etichette case. Supponece che l'ureme abbia immesso come vocazione la
lecrera C. Questa sar auromaricamence confroncara con ogni case dello switch. Nel caso
sia scara verificata una corrispondenza (case 'C ' : ), saranno eseguite le istruzioni di quel
case. Nel caso della lettera C, cCount sar .incrementara di 1 e la scrurrura swi tch sar
abbandonata iromediatamenre con J'isrnuione break.
:Cismu.ione break induce il conrrollo deJ programma a con tinuare con la prima istruzione dopo la struttura switch. I.:ismu.ione break urilizzaca perch alaimenci sarebbero
eseguici insieme rurri i case di una istruzione switch. NeJ caso in cui break non fosse
tilizzara. in nessun posto della sc:ruttura switch, allora ogniqualvolca fosse riscontrata una
corrispondenza all'ime.rno della struttura, sarebbero eseguite anche Je istruzioni di rurci i
case rimanenti. Qualora nos1 sia srara riscomrara nessuna occotrehza, sar eseguito iJ caso
default s.ar. visualizzaco un messaggio di erro re.
Ogni case pu contenere una o pit1 azioni. La strutmrn. switch differe.me da rurce l
altre smitnate, poich in u11 case dJ switch no n SOFIO m:.eessarie le parentesi graffe incorno
alle az.ioni. m ultiple. li diagramma di filusso generi.ca per una stru.uura d i selezi'o ne multipla
switch, che utilizzi u n break per ogni case, moscram nella Figura 4.8.

azione del
caso a

break

azione del
caso b

br eak

azione del
caso z

'bre.ak

Obiettivo portabilit 4.1

Le combinazioni di tasti per immettere EOF (fine del file) dipendono dal sistema.

Obiettivo porr:abilitlt 4.2


Controllare la costante simbolic11 EOF, invece che -1, rtn.der i programmi pi portabili.
I.o standmd ANSI srabilisce che EOF deb.ba essere un valore intero negativo, ma non
necessariamente -1. Di conseguenza EOF pot:rebbe avere valori diversi m sistemi differenti.
Sui sistemi UNIX e molti altri l'inclicacore cli EOF immesso premendo la seguenza di casti

<return> <ctri-d>
Q uesra notazione indica di premere il Easro rerum (o em er, o invio) e gujndi d i premere
simultaneamcnce entrambi i tasti ctrl e d. Su alrri sistem i, come sul VAX VMS della
Digical Equipmenc Corporacion o in MS~DOS deUaMicrosofi: Corporarion, l' indicatore di
EOF pu essere immesso p remendo

<ctrl-z>
I:uccrue immetcer le vor.azioni alla tastiera. Nl momento in cui sar scato premuro il
tasto recum (o encer, o invio), i caratteri saranno lerci uno per volta dalla funzione getchar.
Qualora. il carattere immesso non sia uguale a EOF, si entrer nella srrurrura swi tch. La
parola c;hiave swi tch seguita dal nome della variabile grade ua parentesi tonde. Q uesca
denominata espressione di controllo. Il valore di questa e,sprssione sar confromaco con

azione di
default

Figura 4.8

La struttura di selezione multipla switch.

. 100

CAPITOL04

lL CON'm.QLI.O l)l! L PROGRAMMA

Il diagramma cli flusso rende eviderue che ogni istruzione break, alla fine cli un case,

B11ond abitu.dlne 4.. I5

fa in modo che:il comrollo esca. immediatam ente dalla struttura switch. Ancora w1a volra,

osservate che, a rarce i cerchietci e le frecce, il d iagramma di flusso contiene selo rcmu1goli
e rombi. Immaginare, :mco.i;a, che il programmato re abbia accesso a un conrenicore capienre pieno di strurrure swicth vuote. [a quantit di queste raie che il p rogrammaror e,
acc:uasrando le e nidificandol e con le. altre srrurrme di conrrollo, possa. formare una
implemenra4ion<;' scrurrurara per jj flass di controllo di un algori tmo. J rettangoli e i rombi
saranno quini completati con le azioni e le decisioni appropriate all'algorirmo.

Errore tipico 4.5

Dlmentftm-c una trugione break qualom ne iip. necmaria una in una stn~ttura swi tcfi.
Bttona aliitudine 4. I 2
F,mzite .un caso defa.u l t nelle istruzioni swi t;_ch. Nonrt11lm'ente i casi no.n controllati
in modo e~plicito a/L'interno di u1w swi tch saranno ignorati. I/ ctt.so default aimm}
a evitarlo, spingmdo ilprogrammatore a concentrarsi sulla necessit di elobomre le
condizio.n i eccezionali. Ci sonlJ s.ituazioni in cui non sar necessario nemma elaborazione per il ,aso default.
Buona abitudine 4.13

Sistemare il caso default per ultimo ~considerata una bur,mn 11bittJdi'f'te di program.trmzione, sebbene Le clf.t,-usofe case e quella del coso defaultiossa110 p1esentarsi in qualsiasi
ordine tlll'intemo di .una struttttro swi tch.
Buona abitudine 4.14
[r1 una struttura swi tch, tp.mlra la clausolli default sia sistenuita per ultima, l'ism1zfone break ali'intemo di quejl'ultimo caso TlDn sar necemzria. ALettni programmatori per includ.ono 1,guafmente un break per motivi di chiarezza e simmetria con gli
altri case.

l?icordn.te difamelc tn1zioniper l'el11,bomzionc dei camtteri net()/ini: presemi rte!L'inpw,


quando ciahorate i cnratteri imo per volta.
Ossei:vare che le d iverse etichette di caso sistemare insieme (come c ase ' O' : c ase ' d ' :
nella Figura 4.7) significano semplicemenre che per cnrrambi i casi sar esegu i ~9 lo sresso
insieme cli azioni.

Quando urilizzare 1:1 scrurrura swi tch. ri.cordacc che pu e.~sere urilizzara solranto per
conrrollare u na espressio1~e intera costrmu, ovverosia, ogni combina~ione di costanti di caracrere e Lncere che possano essere valutare come v:alori inreri Una costarrre d i tipo carattere
rapprcsenrara con il carattere specifico po$ro tra apici singoli, come in ' A' . Per essere riconosciuti come coscami di tipo carar:rere, quesci.devono essere racchiusi alfinrerno degli apici
singoli. Le cosranri ince.r e sono semplicemem c dei valori inceri. Nel noscro esempio, abbiamo
urili7-zam delle cosrami d i tipo cru;arrere. R icordate e.be i ca.ratceri sono in .retJ lt dei valori
inceri mcroGrin.aci in tJJl byce.

I lingu~ ponabili, come iJ C, devono avere delle climensioni Elessi bili per i tipi cli daro.
Applicazioni differenti possono ave.re bisogno d i i meri cli dimensioni differenti. 1L C fornjsce
d iversi cipi di daro per rappresentare gli inceri. .tintcrvaHo dei valori interi per ognuno dci
tipi fornici dipende @I particolare hardware del computer. In aggiunta ai tipi int e c har,
il fornisce i ripi s hort (una abbreviazione per short int) e long (per l ong int) . Lo
srandard ANSI specifica che il campo di variabilit minimo dei valori i.nreii short dc\(C
essere 32767. Per la gran magg!oranza dei calco!i inreri. sa.r;lnno sufficienti degli interi
long. Lo standard specifica che il campo di variabilit minimo dei valori long deve essere
214748;3647. Sulla maggior parre dei compurer, gli int sono equivalenti agli short oppure ai long. Lo standrd srabifa~ce che iJ campo di vari.abilit dei valori int deve essere
grande almeno quanco q ueUo degli iareri short, ma che non pu e-sserc pi grande i
quello degli inceri long. U cipo d i dato cha r porr essere uciliz.zaco per rappresear.are degli
inceri nel t'.affipo cli va riabilir 127, oppure ognuno dci ca:rarrcri facenri parce dell'insieme
dei caratteri d.el computer.

Obiettivo portahilit 4.3

Nella srrunura switch della Figura 4.7, le righe


case ' \ n ' : case ' ' ;
break;
indurrru.mo il p rogramma a ignorare i caratteri cli newline e di spazio. Leggere i caratteri
uno per volta pu causare -alcuni problemi. Per fare in modo che il programma legga i
cara.a:eri, questi dovranno essere inviaci al computer premendo il tasto invio sulla tastiera.
C i provocher l'inserimento nell'inpu t del carattere newline, subito dop9 quello che si
desideri elaborar~. Tale cara,ttere d i oewline d ovr spesso essere tracrato in modo speciale,
per far funzionare correrrament e il programma. Con l'inclusione dei casi precedenti, nella
nostra scrurrura swi tch, preverremo appunto la srampa del messaggio cli errore od caso
default, ogru volta che nell'input sar .oconrraro tu1 newline o uno spazio .

Errore tipico 4. 6

Non ekt.borare i caratteri di newline nell'inpttf, q11.ando si l.eg,gono dei caratteri rmo per
vtJLt11;. -p_otr prrn10CtLre degli errori Logi.ci.

Qu/ora prroediate di elaborare degli intf!T che possano ricadere n.LL'e.stmio del campo
di. varittbilit 32767, ma desideriate essere in grado dijrfimzio1zare il vostra programm su diversi sisrcmi tli compute1; allora dovreste utilizzare degli interi long. giacch
la dimensione degli i nt pqrrebbe variare dlJ sistema a sistema.
Obimivo efficienza 4. 1

In situazioni in cui le prestazioni sono importanti, in cui la memoria prezioso o necesS1t1ia una cerra velocit, sipotrebbepreferire l'uti&zo della dimensione pi piccola degli. interi.

4.8

La struttura di iterazion e do/while

La srrurmra di irerazione do / while simile alla smmura while. La condizione di


continuazion e del ciclo, nella saun u ra while, controllata aJl'inizio dello sress.o, pri-

ma che sia eseguiro il corpo delJa iterazio ne. L a strucrura do / while conrrolla la condizione di conti n uazione del cid o dopo ch e stato eseguiro il corpo deUo srsso; d i

CAJ!ITOl.O

conseguenza, le istruzioni alJ'imerno del corpo del ciclo sarfillno eseguire almeno una
voka. Al termine di una istruzione do / wh i le, l'esecuzione continuer con l'istruzione
sa ecessiva alla clausola while . Osservate che nella suurrw:a do / while non sar necessario ucilizzare le parentesi graffe, qualora all'interno del corpo ci sia soltanco una
istruzione. Tuttavia, le parentesi graffe sono indas,e di solito per evirare la confusione
tra le srruuure while e do / while. Per esempio,

lLCONTROl.1.0 DF.t PROGRAMMA

103

accesso a un capienre contenitore di srrurcure do / whi le vuote. li numero di quesrc


tale che il programmatore, accatastandole e nidificandole con le alue scrurrure di conrrollo, possa formare una implemenrazione srrurrurara per il Busso di conrroJlo di un
algorirmo. I renaogoli e i rombi saranno quindi complerari con le azioni e le decisioni
appropriare all'algoritmo.

I * Usare la struttura di iterazione do/while */

while(condizme)

#include <stdio.h>

normalmenre vista come l'imescazione di una struttura while. Una struttura do / wh ile
senza parentesi graffe incorno a un corpo formaro da una singola isrcuz.ione apparirebbe
come

main()
{

int counter = 1;

do
irtru:i:ione
v1hile(condizione);

do {

che porrebbe creare confus ione. I:ulrima riga, while (condi zione ); , potrebbe essere
fraintesa dal lettore come una strutrura while conrenente tma istruzione vuora. Di conseguenza, per evirare confusioni una struura do/While on una istruzione si ngola sar
spesso scriua nel modo seguen te:

do {

istruzione
}' while (condizione);

, count er);
printf ( "%d
} wh i l e (++co un ter <= 10 ) ;

ret urn 0 ;
}

Figura 4.9

10

Usare la struttura do / while.

Bu.onrt abitudine 4.16


Alcuni programmatori includono sempre /,e parentesi graffe all'intemo di una struttura
do / while, anche quando rum sono necessarie. Ci aiiaa a eliminare l'ambiguit tra
la struttura do / while contenente una isrruzione singola e la struttura whil e.

azione

Errore ripo 4. 7
i

I cicli infiniti. sono provocati quando la condizwne di continuazione del ciclo in ttna
smmura while, for o do/while non diventa mai falsa. Per prevenirli, assicuratevi
d1e non ci sia zm punto e virgola immediatamente dopo l'intestazione di una struttura
while o tor. In un dcLo controllato da -un contatqre; a.ssicurarevi che-la variabile di
controllo sia ir1crermmtat11 (o detremrmtat:a) n:ei cqrpo dei d.cio. In un cialo contro/!11to
da 1.1:n valore stntineL/a, a.ssicurrttroi che aLla.fjn:e qittfto siapreso in inpitt.
Il p.1:0gramma nella Figura 4.9 utiliza.a una st.rutmra do /while per visualizzai:e i owneri da l a 10. Norace che la variabile cli comrnUo counter stara incremenrara (con un
prdocre.mento) nella sei.ione per il con(.rollo della continuazione dcl ciclo. Osservate anche
l'utilizzo delle parentesi graffe per racchiudere il c;erpo della srmrmra do/while formaro

da u.na isrruzione singola.


11 diagramma di flusso della struttura do / while mom~ro nella Figura 4.1 O. Questo
diagramma dj Busso evidenzia che la condizione cli continuazione del ciclo non sar
ve:rifcaca, fintanto che l'azione non sar srata esegufra a lmeno una volca. Ancora una
v0ha., osservare che, a parce i cercbje:tti e le frece, il diagramma di Ausso contiene
solcanro un rettangolo e un rombo. Immaginate, di nuovo, che il programmarore abbia

vero

o
Figura 4. 1O La struttura di iterazione do / while.

4. 9

Le istruzioni break e continue

Le isrruzioni break e continue sono utiliu.ate per alterare il flusso di comrollo. J.:isrruzione break, qualora sia eseguita in una struttura while, fo r, do / while o switc h, provocher ruscir.a immediata da quella struttura. 'Lesecuzio:nedel p rogramma coorinuer con la
prima isrruzione successiva alla srruttura. I.: utilizzo pieo della istruz.ione break per ancicip~re l'uscita da un ciclo, oppure: per ignora.re la parre rimanente d.i una srn.mura switch
(come nella Figura 4.7). La Figura 4.11 dimosrra_ l'utilizzo della isrrazione break in una

l
CA:rrroLo4

104

smmura di icerazione for . ~iscruzione break sar eseguita quando La Strtlrtura if avr
determinaco che x avr assumo il valor 5. Ci tcrminetl l'esecuzione deUa isrruzioue for
e il programma potr conrinuare con la funzione printf susseguente. TI ciclo s_ar est<guiro
completameme soltanro quarrro volre.
Q ualora sia. esegu ita in una strurtu r'.t While, for o do/while, l'istruzione conti nue far in modo ~he quelle rimanenti nel corpo della. sourmra siano ignorue e che
sia eseguita l' iterazione successivtl del ciclo. Nelle suunure while e do / while, la
condizione di cominuazione del ciclo sar valutata immediacamente dopo l'esecuzione
della istruzione continue. Nella struttura for, prima sar cseguira l'espressione di
incremento e in seguiro sar valutata la condizjcme di continuazione del ciclo. In precedenza, abbiamo affermaco che la srrurrura whi_le p otrebbe essere urilizzaca, nella
maggior parte dci casi, per rappresentare la srrur(\lra for . !:unica eccei.ione si verifica
quando l'espressione di incremento all'interno deUa srrurtura Wh ile segue l'istruzione
continue. 'In questo caso, 1.'incremento non sar cscguiro prima della condizione di
c0minuazio11e della iterazione e .il while no.n sar sguirn allo sresso modo del tor.
La Figu ra 4.12 utilizza L'isuuz.ione continue in una strmmra for. per sakare l'isrrui.ione printf nella sumrrn:a e cominciare l'iterazione successiva del ciclo.

11. CONTim u

/* Usare l ' istruzione


#inlude <stdio.h>
ma in ()
{
int

105

o DEL JIROGltAMMA

con~inue

in una struttura for * /

x;

far (x = 1; x <= 10; x++) {

i f (x -

5)

continue;

printf("%d

/ * saLta i l codice restante del ciclo solo


se x == 5 */

x);

printf ( '' \nUsed continue to skip prin'ting the IJ,alue S\n");


return 0;
}

Buona abitudine 4.17


Almni programmatori pensn110 che break e continue violino le nom1e della programmazione strutturata. Dato che l'effetto di queste istruzioni potrlt anche essere ottenuto
da recniche di progrnmmnztom strutturata, come impareremo presto, questi. programmrttori non itti{izzano break e continue.
/* Usare l'istruzione break in una
#111olude <stdio.h>

struttu~a

Figura 4 . 12 Usare l'istruzione continue in una struttura for .

Obit!tr.ivo efficienza 4.2

for */

Le istruzioni break e continue, qwmdo snnn u.tiiizztJ,te in mod1J apprpriato, samrmo


eseguite pi 11eLoceme11te delle corrp<>ndenti tecniche strutturati/ che a.pprenderer11o
presto.

main ()
{

int

1 2 3 4 6 7 B 9 10
Used continue to skip printing the value 5

Ingegneria del software 4. I

x;

tor (x = 1 .I

C' una dicotomi(l tra la ricerca di una progeu4zione di software di qualit e quella
di software pi efficiente. Spesso uno di questi obiettivi raggiunto a discapito
detii1ltro.

<::e 10 j x++) {

--

5)
if (X
Qreak;

!"'

interrompe i l

~ic lo

solo se

--

~1

4.1 O Gli operatori logici

printt ( '%d n I x);

Fino a questo punco abhia.mosrudiato $olranco delle condigi.oni setnplicicome coun te r <= 10,
total > 1000 e: number I= sentnelValue. Abbiamo espresso quesrc cond-iz.ioni con.
l'uso degli operatori relazionali >, <, >=, <= e di quelli di uguaglianza == e I =. Ogni
decisione ha verificato precisamcncc una condiz ione. Se avessimo voJuro conrrollare delle
condii.ioni multiple in una deci$ione, avremmo dovuto e.seguire i suddetti conaolli con
delle isrruzioni discinte o con delle strucrure if o if /else nidificate.

printf( " \nBroke gut of loop at x -- %d\n " , x);


return 0;

, 2 3 4

Broke out O'f

io~

at x

=:

Figura 4. 11 Usare l'istruzione break in una struttura for .

l i C Fornisce degli operatori Logici che possono essere uciliz7.aci per formare condizioni
p.iw complesse. combinando q_ueUe semplici. G li operatori logicd sono: && (AND logico) ,
: i (OR log~co) e I (NOT Log;o derro anche negaz,one logica). Considereremo degli esempi
per ognuno dei suddetti.

1'ci6

CMI.:TQLQ4

.Sup-ronete he, prima di stegli.re Un determinato percorso di esecuzione, vogliamo


in un cerco punto del programma due condizioni siano entrambe v:ere. In
queste <::as0, porremmo utilizzare f'operat9n; J<i>gJ && o~ segue:

~siturarci <::he

if (:gende r = 1 && age >o: 65)


++$e niorF11mals;

==

Quesr-a istr:zion~ i f contiene due r:.:ond.izioni sempU.eL La condiziQne gender


1 porr./i
essere valutara, per esempiq, p\er detem1.i.n~re se una_p.ersoa:a s~ di-sesso fe.IIllilini.le. La con~zione ~ge >= 65 saj valucai:a pr dete~are. se. un erta persona si.a. urL cittadino
a:n.Ziano. Le du..c0ndi.zioni semplici sil..rarrnO'va1uta1:e. pe.r prime perch le priorit di= >=
scirrd pi alte-di queJJa di&&. lti SegUW, J'i srrazine.i f Gnsid r.t .Ja<ionruz.ione comb.inata
9.~ n d~ r

La. tabella deUa Figura 4. 13 descrive l' 0peramre &&. L1 rabe11a mosrra rurte I.e quattro
possibili combin.az.ioni ~valori zero (falso) e diversi da zero (vero) pernspressione l ed e~pres
sione2. Le tal;>elle di qm;sro, gen~r~ ~ono- sp~~so d1famace ta.k#ledi 1!,"erit. 11 e valuta oo l
ttnte le espres~kuii che includa.n9 degli opeta:t9.r.i c~lazi9nall, !-'li ugugli;tn:>..a ~/Q_logii. S:bb~e il C 4n1?osri_iJ -y,aJore ver:o COI!I l , esso acttr~ come ver ogni v;lliare-dkvrs.o d.a 'Zero.
espressione I

espresslone2

espressione I && espressiene2

diver$o da zero

dive(SO da zero

1Q7

e preruicr lo srudenre on una '~!\." qualora una o eumunbe le co.ndi1,ioni semplici siano
ve.re. Osservare d1e il messaggi'0 '"Student grade is A" n.o n sar visualizzar9 ~0Jo quando
enrrambe !e condizioni sem,plici sa.ranrro false (e.ero). La Figura 4. ~4 una tabclla di \'.e dt
per loperatore JQgio OR (l : ) .
espressione I

espres5n2

espressione I 11 espressione2

(j

diverso d zero

diverso da zero

di verso da :ie.rn

diverso da zero

1 lk& ;;i,@e >= 65

Questa condi:ziorte sar ver:a se e solo se entrambe le amdizio.ni semplici saranno ver.e. Infine,
se 1a sudderra condizione wmbillata saF effetcivamenm vera, alfora il comacore s en io r Fe mal es
sar increniemaco di 1 . Qualqra una f> enrramb le ~onclizj_o,n;i semplici siano false, Ll programmaJgno.rer. l'int,remeoto e procedei: c>n l'kruzione suees.~iva alla struttura if.

Figura 4. 14 Tal:>elladiveritprl'operatore: : .(QRlogco) .

I:operamre && ha una _p1iori-r maggi.o.r lj l :. Emr.ambi g!i <:>_petatod assodano c;la
sinistra a. d~src-a. Una espressone cqnteneme gli opetarori && 0 i : ~ar valutar~ . solranto
fincamo che non sar ntn Jasua verit_0 falsic, Di Cnseguenia, la valmcione della c,:ondirione
~ end er

==

&& age

>::

65

fotmr:, qualora gender 11011 sia uguale a 1 (a qucl pun.ro, l'i.nter:i: espre5sio.ne sar
skurainence falsa); mentre com:inuera, q ualora gender sia uguale a 1 (poich..l'mera espressione
porrebbe ancora essere vera se age >= 65}:

$.

Obietti/lo fficianZIJ 4.3

.
/
cl.iversq da zero

diverso da z.ero

Figura 4.13 Tabella d i verit per l'operatore&& (ANO lo~iCo).

Cot.fsideriam ora l'operarorc : : (OR logico). Supponete he, pr-ima di s~eglie(e un


e.rtti perc0~0 d i esecuzion, vogliamo assjeu:ra.rci clie a un c.eno punt del prdgramma
u.n:i. o eotrambc:. le condi?ioni s.iano vere. 1n ques.to caso useremo l'oprar0.re : : , com nel
s.egueme 1:rui:u:nenrci cl.i programma:
H

lL CGNTRQLLE> DEL l.'.ROG.11AMMA

('s.ernest.erAverage >= 90 : : f.i.nal Exam >-= 90)


prin t'f ( "Student grade iS A\ n") ;

Q11e~ta i~ttu"z.~911.e q ;rn.tie.n.,e anch'e,s~a due .odi1,ieni semp lici. La .cBn.d.i-ti.Q:ne


seme$terl\verage >= 9~ sai'~ vaht.ra~a p:er= deternina.re S:e lo stud~re del cm;so meri
uru1 "A"; grazie -a. un n:mdi-me.n to coname nel cotse .d el semesfre.. La Gbil.di.z:io'n:e
f inaJ;E'xam >= 90 S<it+. valutata. pe.r deterrn.inare: se lo srudence del corso m eriri .urna "A", a
C1isa di'wi t't'mdimento straordin.aci~ nell'esa1mdnale.1n seguico, t'isrruzio11ei f con~idere.
r~ la: condizione combin~ra
se me~ter;A.vrag e

>"' 90_ : : fna l Exam

>"' 90

N~L(nspr.ifi0:11i che tilizzana l'Qpera~iire

&&.-fate in nHJ.tlo che ltt.pr.ima condizione si.a


rptella,.che avr pit pibabUit di essere falsa. Nette e5pressioni che.rJ,tiliZZt.tno .l'operatore f f,fate in mo.do che fa prima condizione sia que/u;. che avr_pi.pvobabilit"di ~J~ere
vera. Cibpotr ridurre il ternpo di esernzione dl prqgrammn.

li C fomis<;e I ~la negazione logka) ().r consentire al prograi:tuna[(;>r.e di .iuverrir.~" il


valore di llna <':ndiziotie. A iiffereu-za. degli operarori && e l :" che combinano due condizi0.ni (e sono qtndi degli operatori binaci), quello di negazione logica. hac solo un:a.. singola
c::ondizi0nc come operando (ed quindi un ope:Ea+9I!! un.aria). 1.'.opetatore di _negazione
legica-a.11<k1 inserito prima di LI.Ila condiziom;, nel caso incui sia.mq ner<;ssm:i a s.cgliere un
pernorso di esecuzi9ne qua.ride la cond.iz.i:011e originale (s~n1,a l'ope.fat0.re cli negazione k>gica) 'Sia falsa, come nel s.egueme &:.ammntodi oli'te:

if (I (.grade =-=- sentine1Va1 ue))


pr i ntf(" The n&xt grade is %f\n, grade);

Le parenresi jucorno a1Ja condfai.one grad = sentinlValue sono necessarie perch


l'operatdre di negw-i.n.e logica -ha. una priorifa m&gire- dell'operato.re di uguaglianza, la
Figura 4.15 una tabella d.i verit per f opcrarore di negnziohe logica.
Ne.Ila, maggior j>:art dei cisi, Ll progam.rtl.4rb,te porr. evitare di u.liz:za:re la rigazio1i.e
logica, e,c;primtndo la condi7jo.ne in mod diverso. con uri a:ppropr.iam operatore relazionale.
P.r e.Sen:1pio., l'isrrnz.ine pm:ed.eme porr essere sGrirra anche nel modo seguen te:

Cwrro1.04

108

if (grade I= sent i nelValue)


printf("The next grade is %f\n", grade_);

La tabella nella Figura 4. 16 mostra la priorit e l'associarivit dei vari operarori introdon:i sino a questo punto. GU operarori sono mostraci dall'alto in basso in ordine decrescence di pciocit.
espressione

lL CONTI~Ol.1.0 DEL l'J{OGRAMMA

rura ru controllo. Lespressionc sar crarrara come flsa qualora il suo valore sia O, mcmrc sar
consider.ira vera ael caso cbe il valore sia diverso da zern. ll secondo aspetto che nel linguaggio
gli assegnamenti producono un valore, ovverosia quello che s~ Ss~aro alla variabile a
sinistra ddfoper-.icore di assegnamento. Per esempio, supponere che vogliamo scrivere:

if (payCode == 4)

printf("You get a bonus!");

!espressione
ma

che acciden.calmeme scriviamo

= 4)
printf('You get a bonus!");

it (payCode

diverso da z:ero

Figura 4. 15 Tabella d verit per l'operatore! (negazione lgica).

Operatori

Associativit

Tipo

( )

da sin istra a de~rra

parentesi

da destra a sinjsrra

unan

da sinistra a destra

molciplicativi

da sinistra a destra

additivi

da sinistra a destra

relazionaJj

da sinistra a destra

di uguaglianza

&&

da sinisrra a desa:a

ANO logico

I I

1 1

da sinistra a dcsrra

OR logico

?:

da desua a sinisrra

condizionale

da destra a. sin.i.ma
,
da sinisrra a desrra

di assegnamento

++

109

( tipo )

+
<

<=

I=

+=

>

>=

*-=

/=

%=

virgola

Figura 4. 16 Priorit e associativit degli operatori.

4.1 I Confondere gli operatori di uguaglianza ( = = )


e di assegnamento ( =)
C' un po di errore che i programmatori e, indipendememente da quanto siano esperti,
rendono a commettere cos) frequenremence che l'abbiamo ritenuto me:citevole di una sezione disr:inra. raie errore consiste nello scambiare accidemalmenccgli operatori == (uguaglianza) e = (assegnamento). Ci che rende questi stambi cos dannosi che essi, solimmence, non provocano degli errori di sintassi. Di solito, infarti, le istruzioni cbc conccngono questi errori sono compilare correttarnenre e il programma sar eseguito fino al suo
compleramenco. generando probabilmcme dei risultaci non correai a causa ru degli errori
logici, durame la fase di esecuzione.

Ci sono due aspccri dcl C che causano qucsri problemi.. Uno che, nel linguaggio C, ogni
~pressione che p1oduca. un valore pu essere utilizzata ndla sezione di decisione di ogni srruc-

Li. prima isuuzionc i f assegnerebbe correrramenre un bonus alla persona il cui codice dJ
pag;imento uguale a 4. La secoi1da isrruzione i f i.nvee, quelJa on l'errore, va.lurerl!bbe
l'espressione di assegnamenco alJ1intcmo della sua condiziorie. Questa espressione un asscgnamenro se,rn:plice il cui valore la cosmnrc 4. Dato che ogni vak>re ,Lverso da zero interpretato
cqme "ve,ro", la condiiionc di qucsca isrruzione i'f sarebbe.considerata vera e la persona riceverebbe semp.re un bo.nus, indipendenccmcme da quale sia il suo reale codice di paga.memo!
r~

Enore tipico 4.8


Usnre L'opemtore ==in un nssegnnmento o uti/i$Ztl.r'I: !'opemtore =in 1m1t crmdiziom
di ugitaglianur.

Normalmeuce i programmatori scrivono le condii.ioni in questo modo x == 7 , con il


nome della variabile a si nisrra e la. cosranre a destr!. Jnvercendo le loro posizioni, facendo cio in modo che la cosrance sia a sinistra e il nome della variabile a destra, come
in 7 == x, il programmarore che soscicuisse accidentalmc:nce l'operatore == con =
sarebbe protetto dal compilacore. li compilarore, infan:i, lo mmerebbe come un errore
ru sintassi, poich sul Lato sinistro di una isrruzione ru assegnamento pu essere sisremaro soltanto il nome di una variabile. Quesro evirer almeno la potenziale devaswione di un errore logico durante l'esecuzione.

1 norill delle variabili sono detti anche lvttlm: (per "lcfr value", valore di sin istra) proprio perch possono essere urilizzari sul laro sinistro ru u n operatore di assegna.memo. Le
comrnci sono dette invece rvttluc (per "righr value", valore di desrra) proprio perch possono essere urilizwre solcanro sul lato destro di lLO opefatore di assegnamento. Osservate che
un lvalue pu anche essere utilizzato come rvalue, ma nQn viceversa.
B11on11 ttbi1udi11e 4. J 8
Qurmd una espressione di .u.guttglianza contiene mm llttricchife e una costt1nt11, come in
x == 1, akuni propmnmatodpreferiscono scriverla con la costante a -sinistra e /11 vnrirzbife
a desh'a, per proteggersi tlati(rrore Logico che si verificherebbe, qualora sostituissero 11ccider1talmente t'operatoie == co11 =.
Caltro lato della medaglia porrebbe essere alrce.rcanro spiacevole. Supponete che il programmatore voglia assegnare un valore a una variabile con una sempUcc isuut.ione come:

= 1;
ma scriva
X== 1;
X

invece

1 LO

Q&rroL04

}mchdn qm.;5r9 ~0 1 non s. crarr.a di un errore di sintassi. 11 ompilaJere valu~e.r pfott>sto catidi'dameru l'espressione condi.zipnale. Qualora x fosse gilllle a 1, b ondizion
sarebbe <'lnsiderar~ vera e l'espre~s_i0ae r~ti tn::ii:ebh~ il valore 1. Qua'.lora x ll'0Il f-0.sse
uguale a 1, la colldizion,e s!:bbe G:ons.iderafa fhl'sa. .. l' esp11essi6ne reSttuirebb:e J1 yalor.e 0.
&id.pendente mente da quale v.aJ.or.e sa:ra resiimim, noti ci sar nessun operarore di a.~se.gn.a
memo, per.ci, il .val:ox;e andr sempliG:ememe pers0, e quello di x x;ester~ inai'trata, eau5ando prnbabilmente un enrore logico durame l'esecuzione; Sfonunatamente non abbiamo a
dispgsizjone un n::ucc:i pr;iJi> per aiu~i cpn ques.ro probl~a!

4. 1l Riassunto della programmazione strutturata


L prngr<miaiaro.ci dvreb.Ber-0 progerutre i programni pioprir on'le glj ardiirerri pigernmo i
f!.Tuzlj, iillpi~l0 l sapienza co1lecriva del.la loro categoria. Il nostro campo e,fir p1 giQvane di, quanm lo sia l'arc::hirettura e la nostra sapienza collettiva considerev01meme pill limitara.
Abbiamo ;ippreso una gran mole di co,se, in ~olq cinquam'auni. Fe>rse, cosa ancora pi importante, abbiamo app(t'So che la prog~:un:.ma.zl0m: stmttur:'1.ta prodqce program.mi che sono pi
sc;rpiiti (ri:pen,o a qdli non stnl.tfuiWi) da co.mp.rendcre e quindi cl~ collaudare, mett~re l\
pw:m), modifiaue e anche da dimos.cyare to:rrem ncl senso matmarico dcl rtrmine.

4- CONTROLLO DJ!.L PROGRAMMA

<Il

<Il
r-i

..-.
.e

~
.e

~
::i
t:

:;:
._
G>

e
o

.H
~

Ul

!!

"O

11'
L..

::i
._.,
.

.b
lii

::J

>

t..

::J

t:

..,::J
L..

lii

1 Capircili ~ e;~ SL$on11> s.offeana,ri sulle stI'l,l~ur.e di 01m0Uo del C. Qgni s.aurrura
sratt presenrara, rappresentata in diagranimi cli flusso e discussa: _separa,ra,rnente con degli
esmpi. Ot:t cicap.icolere.mo l..risu4;i.ti dci Capitoli 3 e 4 e lntrodw:rem o !+Il srnpliG.e lrrsillr:i;le d r~golc per la cs1;rzioae cli progf~mi st'rUrruriti e pr le foro prtop#e.r..
.LaBigra-4.17 cias~lJ.Dl~ Le ,srrurrure cli controllo dl'scusse nei C,apiroli ;3 e 4. l c,;~riliierci
s0no utilizzati.n'ella:fgup per indicare gli unici punti di enc.rara e di uscita di ogni struttura. Collega.::arbirra:cianrent~ j singqli simboli dS UB diagrarrim:a di flusso _pou. nducre a

ptogrfuntili non scrutt4rci. Di ci)a.Segu,nia, la categoria dei -prgtamma'.(ori ha scelto di


itb,mb:in ar'e i simboli per i diagrilrillhl di -flusso, i'n :itiodo rale da formare uri imieme lim.Ltaro di struttur di controllo e di cosrruire sokamo prngiammi srtmrurari, combinando
appwpriatamente le strutture di con troHo ~econdo due sole semplici modalicii. -Per sempliei.r, SQ!IQ ~&.t.e rilizzar soJ~t<;! srrqrrure d:i conrr.0llo ~on \ill:J. s_.agela nr:mJ'a qsi:;ii:a: c'
solo un mq:do per entrare e 4Jll sfila ID4Uie:ra pr ~i~e dalla Stryr_m ra di c0_rrtrqll9. CoJlegar.e !e s.m,i.rttu~_li c;onrr.l!)llo fil.sequenza, in moq0 da fo rm_are-dei _p.rogra.mtni strui!1;urar;i,
sin'p.lice: il punro di uSc.irJi cli lilla scructu r~ di cmrollo. crine~s.6 di.mtameme ;li pumo
li enrrara della stl'w:rura di concrollo scrccessiva, Iti altre parole. le muctuie di comrbllo
saranno S:Stfuate in un pr.ogramma unicamente l\ma dopo l'alrra: ab.biamo perci ehiarnato questo processo "acca~StaJJ,J,ento delle -sa urmre di comrello". Le regole di formazi<r
ne dei programmi scmttrap CQl"l~n-rpe ancht; la_ni~g.zione dellpgmrre di con~U9.

La Pigura_4.J 8. moscra le ri:gol.e per foaiiare ppropriai:ameute dei programmi strurrurati. 1.e regole assumono <::he 0gni simb.olo cli remmgolo nei diagrammi di flusso . possa
essere utiliu~to per Indicare qU;alsiasi a'Zione, incluse quelle cli input/ouq;>ut.
Vap:plicarione dlle regble della Figura 4.18 piodnrr un.diagramma di-flusso sttJJ.tru:r:aro eo'n un aspetto ordunrb e .simile ai mmiiiciti.l delle CdsrruiJoni. Per illsmpi0, applicando ripllitarneme La regola 2' al diagramma di Ausso elemenrart; se ne- produrra uno
scrutnuato c0nte11ente molti rettauge).i in sequenza (Figma 4.20). O sservare che la regala 1
g~nerer u-na Ga't~~ a_ di Sl:rJ.loU: ur~ qi coatrol1o; per questo motivo l:a chiamei;-e:m:0
regqla di tu:ctt:{Jfstamt:nto.

Figura 4. 17 Le strutture di sequenza, selez.ione e riptizk>ne con un ingres'so e una wscita


singoli del lnguagglo C.

11 2

CAP1T01.0

l t. CONTROLLO DEL. PROGRAMMA

113

Regole per la formazione di programmi strutturati


1) Incominciare con il "diagramma di flusso elememare" (Figura 4.19).
2) Ogni renangolo (azione) pu essere sostituito da due recra.ngo.l.i (ai.ioni) in sequenza.
3) Ogni rerrangolo (azione) p u essere sostituito da una qualsiasi suurrura di controllo (sequenza, if, if/else, switch, while, do / while q for).
4) Le regole 2 e 3 possono essere applica.te cip~ruraroenre e in qualsiasi ordine.

L-~--' ',

''

ti

''

''

Regola 3

',,

''

Figura 4 . 18 Le regole per la formazione di programmi strutturati.

''

''

\~

r-------------- --------------,
I
I

I
I
I
I

Figura 4. 19 Il diagramma di flusso elementare.

,,

lt
,~

,.

I
I
I

, 1..---- ------ -

__ ________ f___
I
I
I

I
I

'

I
I

--.

Regola 2

...

Regola 2

Regola 2

...

,
,,

I
I

I
I

I
I

I
I

-------- ---,'
'----------- -- ---~---

;:.

La regola 3 dena regobi di nidificazwne. Applicando ripetutamence la regola 3 aJ


diagramma di Ausso elementare, .5e ne produrr y.no con srrurrure d1 conuoilo nidificare in
modo ord:inaro. Per esempio, nella Figura 4.21, iJ rttallgoJo dd diagramma di 8usso elementare sar prima sostituito da una struttura di selezione doppia (if / else). In segllito la
regola 3 sar applicata di nuovo a enrrambi i rettangoli della srmrmra di selezione doppia,
sostiruendo ognuno di quei renangoli con altre srrurrure di selezione doppia. I rettangoli
traneggiati incorno a ognuna delle struaure di selezione doppia rappresenrano i rettangoli
che sono stari sosciruiri.

I
I

I
I

___________ _
.___
I

'

...

:I
II

I
I

I,
,---- ------ ----- ----- -- --- , I

-------------II'
elementare.

'
,''
'
------------------------,------I

I
I

iI

'

I
I

Figura 4.20 Applicare ripetutamente la regola 2 della Figura 4. 18 al diagramma di flusso

'

'
,,

I
I

Regola 3

,I

''

'

Regola 3

I
I

'
I
I

'I

I
I

I
I

I
- - - - -----~ ---

-------------'

I
I
I

Figura 4.21 Applicare la regola 3 della Figura 4. 18 al d iagramma di flusso elementare.

114

WPITOL04

La regola 4 generer delle $t:rutrure pi grand i., pi complesse e pi p rofondamenre


n idi ficate. 1 diagrammi di Ausso che possono essere formaci, applic-and0 le regole d ella
Figura 4.18, costituiscono l'insieme d i turci i p ossibili diagra.romj dJ Ausso srrutcurati e,
quindi, l'insieme di curti i possibili programmi smmu.rari.

h. CONTROllO DEL PROGRAMMA

La programmazione strurruraE:L promuove la semplicit. Bobm e Jacop.ini hanno dimostrato che sono necessarie solo i'.re forme di controllo:

Mattoncini accatastati

Mattoncini nidificati

D
D
D

Sequenza
Selezione

p roprio grazie all'eliminazione della isc:ruzione goto che questi marroncini di cosuuzione non si sovrappongono mail' uno suH'alrro. La bellezza dell'approccio srrunuraco che
utilizziamo soltanto un piccolo numero di semplici pezzi, con un singolo ingresso e una
sola uscita, e li assem bliamo soJtanco in d ue semplici maniere. La Figura 4.22 mostra i ti pi
di cos~ruiioni, onen ute con L'acc'-a rascam ento dei mattoncini., che si possono formare attraverso l'appliCazio ne della regola 2 e i tipi d i costruzioni, ottenute con l'accarascamento dei
mactonciru, ehe non possono apparire n ei cliagiamm i di Busso scrua:w:ati (grazie alla eliminazione della istruzione goto).

11 5

Iterazione

La sequenza banale. La selezione; implementata in uno dei rre modi:

strutl'ura i f (selezion e sem plictZ}


stru ttura i f I else (selezjone doppia)

struttura swi tch (sele-1.ione mnlcipla)

D i fatto, elementare dimosrrare che la semplice struttura i f sufficieme a fornire ogni


forma di selezion e: mero ci che possa essere fatto con le scrucrure 1f / else e swi tch
porr essere implemencaco con La stru ttura i f .
t:iceraziooe im plcmenrara io uno d ei ere modi:

srru rrura while


struttura do / while
srrurrura for

Mattoncini sovrapposti
(illegali in programmi strutturati)

elementare p r-0.vare che la scrucrura While suffiienre a fornire ogn i forma d i iterazione.
Tu tto ci che p.oss:a essere farro con le srrurrm do/while e for porr essere implemenraro
con la scruccura while.

La combinazione di ques risulraci dimostra che q ualsiasi forma di controllo di cui si


potr aver bisogno in un programma C porr essere espressa con rre sole d i esse:

sequenza
srrurcura if (selez.ione)

Figura 4.22 Mattoncini accatastati, mattoncini nidificati e mattoncini sovrapposti.

Se le regole della Figura 4.18 sono rispettare, ua diagramma di flusso non strurruraco
(come quellq d ella Figura 4 .23) non porr esse.re crearo. Se non siece situ.ci che un particolare diagramma d i flusso sia srrutrurato, appUcate le regole della Figura 4,18 all' inverso in
modo da pro:vate a ridu r.re il di agr~a. di flusso a quello elemencru:e. Se il diagram ma di
fl usso pu essere ridorco a q uell0 elem entar e, allora il diagramma d i flusso originale scrutruraco; altrimenti, nordo .

srruccura

wn ile (iterazione)

Queste srrurrure di controllo potranno es.sere combinare in due soli modi: accarastaodolc e
nidificandole. La programmazione sutLcturaca promuove di cerro la semplicir:.

Nei Capimli 3 e 4, abbiamo discusso di come comporre i programroj wn murrure d i


controllo concenemi azion i e decisioni. Nel Capitolo 5, introdu rremo un'altra u nit di
srrum 1razione del programma chiam ata .f!mzione. Apprenderemo come costruire dei programmi. complessi combina ndo le fun zioni, che saranno formare a loro vofra da scru tr:u re cli
controllo. Discuteremo anche del modo in cui l'urilizzo delle funz ioni promuova la riusabilit
del software.

Esercizi di autovalutazione
4. 1

Figura 4.23 Un diagramma di flusso non strutturato.

____

Riempire gli spazi. in ognuna delle segu<md Frasi.


_,
a) Una .Eerazione concrollara da un co11rarore nora aache come iterazione
perch noco in amicipo il numero di volre che il ciclo sar. cseguiro.
b) Una irerazione concroll:it:1 da un valore scnneUa nota anche come icer:izione_ _ _ __,
perch non noto in ancicipo il numero d volre che il ciclo sar: riperuro.

11 6

CAPITOLO

e) Nelle ripecizioni concrollace da un concacore si utiliz.ta una


per concare il
numero di volte che un gruppo di istruzioni dovr essere ripenuo.
d) L1struzionc:
quando eseguita in una sttucrura di ice.razione, indurr l'esecuzione immc:diara della irerazione successiva dd ciclo.
e) l.:imu1.1one
, quando eseguica in una srruuuradiirerazione o in uno switch,
causer~ l'uscita immediata dalla srrurtura.
f) La
miliu.aca per coorrollare .una parricolare variabile o espressione per
ognuno dei valori costanti inceri d1e essa porr assumere.
4.2
Stabilite se le seguenci affermazioni sono vere o false. Qualora la .risposa! sia falsa. spiegacene .il movo.
a) Il caso default obblgawrio nella srrunura di selezione switch.
b) !.:istruzione break obbligaroria nel caso default di una strurrura di selezione switch.
e) Cespressio11c ( x > y && a < b ) ~ar conside= vera qualora lo sia x > y oppure qualora
In sia a < b.
cl) Una e.~pressione contenerne l'operator~ : : src:;onsidcra'ra vera se uno o entrambi i suoi
openwdi sono veri.
4.3

Sc.i;ivete una isu-uzione o un loro insieme per c~cguire ognuno dei segueoci Cmpili:
a) Sommare gli !meri dispari tra I e 99 urilizz~ndo uua srrurrurn for . Supponete che siano
mtte dichiarate le variabili sum e count.
b) Visualiz1.are Uvalore 333,546372 in un campo lungo 15 caratteri co11lcprccisioni1 , 2. 3.
4 e 5. Giusrilcate a sinisrr.i l'ourpur. Quilisarann,o i cinq.ue valori visualizzaci?
e) Calcola ce il valore di 2, 5 elevaro alla poren.za 3 uriliizando la funzione pow. Visualizzare il
risulrato con precisione 2 i:n un c.unpo con dinie.nsione pari a 10 posruoai. Quale sar il
valore: visualiu,uo?
d) Vsualizutc gli imcri da l a 20 uriliz7.ando un cido whle e la variabile contacorc x.
Supponc1e che x s:1 ~ srara dichiarara, ma mm inizializzal3. Visualiuace solo 5 inceri per
riga. Suggeri memo: usate il calcolo x % 5. Scampacc un caraccere newlinc: quando il valore
di questo calcolo sar 0, akcimenci visualiv..ate un Ctratter di cabuhzione.
e) R.ipecc:te l'Esercizio 4.3 (d), uciJ~zzaude una smmura tor.
I

4.4

1iovate l'errore in ognuno dei seguenci frammenti di codi.c e e spiegate come correggerlo.
a) x=1;
while (X <= 10);

lL CON' rROLLO DEL f)ROCRAMM.I\

Risposte agli esercizi di autovalutazione


4.1
:~) definita. b) indefnit3. c) variabile di conrrollo o conm:ore. d) con1:inue. e) break.
suuuura di sclt'Z.ione swi toh.

4.3

a) sum = 0;
fo r (count = 1 i count
sum += count i
b) Prlntff "%15.1f\n ",
printf( 1'% 15. 2f \n~,
printf('"% 15 . 3f\n",
printf( "% 15.4f\n",
printf( "% 15.5f\n",

case 2:
printf("The number is 2\n");
break;
default:
printf('The number 1s not 1 or 2\ n');
break;
cl) 1l codice seguente dovrebbe visualiu.are i valori da I a I O.
n = 1;

wl.le (n < 10)


printf ( '%d

<=

333.546372);
333. 546372);
333.546372);
333.546372);
333.546372);

i f (X % 5

0)

printf ( \ n ) ;
else
pnntf("\t");
x++;
}

o
X = 1;

while (x <= 20)


i f (X% 5 == 0)

printf("'isd\n', x++l;
else
pr.intf("l\sd\t", x++);
o
X

= 0;

while (+tx <= 20) {


if (x % 5 ="' 0)
prifltf("%d\n", x);
else
printf('l\sd\t", X);
e) for (x = 1; x <" 20; x++)
printf("%d ", x);
if (X \ 5 == 0)
printf ( \n);
else
prntf( \t);
o

n++) i

99; count

e) printf ( "%10. 2f \n", pow(2 .s, 3)).;


d) X = 1 i
while (x <= 20) {
printf( \d", x);

e) switch (n) {
case 1:
printf( 'The number is 1\n");

4.2
a) Falso. Il caso default opzionale. Se non necessaria nesi:una azione di defauJ. t , allora
non ci sar nessun bisogno di un caso default.
b) falso. I.;is1rur.ione break u1.Wzzara_per uscire dalla siruttma switch. l.:is1ru1.ione break
non sar richiesta qualora il caso default s.ia l'u1rimo.
e) 1:a1so. Quando si utilliza l'opera1ore &&, e1:u:ra.mhe le i;spressioni relazionali dovranno essere
vere perch l'inrera espressione sia considerata tale.
d) Vero.

XHj

b) for {Y., .1; y I= 1. 0; y += .1 )


printf(Dilf\n, y);

1 17

for (x

1; x

<=

20; x++)

+~ 2)

I*' visu.alizza a3a 1 s.

f"' visualizza 333,55


I" visualizza 333 , 546
/" visualizza 333,5464
visualizza 333,54637

I* visualizza 15,63

...,,
*I

*/
*/

*/

CAr1ro1.o 4

11 8

g) Il codice segucnre dovrebbe sommare gli i meri da 100 a 150 (supponere cne tot al sia gi
mua inizializzata a 0):
for (x = 100; x <= 150; x++);
tot al. += x;

if

(X\ 5 = 0)
printf("\d \n', x);
else
printf( "\d\t , X)i

4.4

a) Errore: il punco e virgola dopo l'intcswione del while provocher un ciclo inlnito.
Corraione: sosciruire il pumo e virgola con una { oppure rimuovcce il ; e la } .
b) Errore: l'uciliz.w <li un numero in virgola mobile per controllare la scruuura cli itcl3Z.ione for.
Corre.donc: utilizzare un intero ed eseguire j calcoli appropriari per ocrcncre li valore che
desiderate.
for

4. 6
Stabilire quali valori della variabilo:: di controllo x saranno visual.izzati da ognwia delle seguenti
istruzioni for:
~ for(x = 2; x <= 13; x += 2)
printf("\d\n", X);
b} tor(x = 5; x <= 22; x += 7)
printf("%d\nM, x);

(y = 1; y t= 10; y++)
pri.ntf(\f\n .. , (float) y I 10);

e) for(x

t) Errore: manca l'istruzione break tra quelle delprimo case.


Corre-Lione: aggiungere un break.alla1ne dcllelmuzioni del primo case. Osservace d1c questo
potrebbe non essere necessariamente un errore. qualora il programmatore avesse voluto che le
istruzioni dcl case 2: fossero eseguire ogni volta <Shefosse smco eseguito il case 1 : .
d} Errore: sraro utilizzato un operatore r~azionale inappropriato nellacondi21onc di cominuazione della iterai.ione.
Corre2iooe: u~ilizzare <=invece cli<.

= 3; x <= 15; x += 3)
printf("%d\n", x);

cl) tor(x = l; x <= 5; x += 7)


printf("%d\n", x);
tj for(x = 12; x

~= 2; x = 3)
printf( "%d\n ", x);

4 .7

Scrivere delle iscruzion i f or che visualizzino le seguenti sequenze dj valori:


a) 1, 2, 3, 4, 5, 6, 7

b) 3, 6, 13, 18, 23

Esercizi
4.5

11 9

lL CONTROU..O O.EL PROGRAMMA

C) 20 J 14 J 8 t 2 ! "4 I 10
d) 19 , 27' 35, 43, 51

Trovare l'errore in ognuna delle seguemi lsmrzioni CNota: dpotrebbe essere pi di un errore):
a) For (X = 100, x >= 1, x++)
printf(.%d\n ' , x);
b) TI seguente codice dovrebbe visualiZ?.are se un daro intero pari o dispari:
switch (value \ 2) {
case 0:
printf("Even integer\n);
case 1:
pri ntf( 'Odd integer\n);
}

e} U codice scguenre dovrebbe prendere in input un intero e un carattere e visualizzarli.


Supponete che l'urente immerca come input 100 A.
scanf ( "\d" , &intVal) ;
charVal = getchar();
printf( '' Integer: %d\nC'l1aractel": %c\nr, intVal, harval);
d) for (X

= .000001;

X <=

printf(~%.7f\n " ,

.0001 j

e) rl codice scgucnle dovrebbe inviare in OLicpUl gli ioceri clisprui da


for (x 999; x >e 1; x T=2)
printf('\d\n", Xli

f) il codlce segueoce dovrebbe visualizzare gli interi pari da 2 a 100:


counter = 2;

counter += 2;
While (counter < 100);

Ghe cosa far il programma segueme?


~include

<stdio.h>

main()
{

int i, j ,

X, y;

printf(aEnter integers i n the range 120:


scanf( "'6d\d ' , &x, &y);

u);

= 1; i<= y; i++)
tor ( j = 1 ; j <= x; j ++ l

for (1

printf("@");

printf("\n");

X += .000001)

return 0;

x);

Do {
if (counter % 2 =~ 0)
pr1ntf("%d\n, counter);

4.8

999 a 1:

4.9
Sccivere un programma che sommi una sequeaza cli i.ri:teri, Supponete cbeil primo intero leLCo con
la scanf specifichi il numero dei valori d1 dovranno c:ssere. immessi. Uvostro progr.urunadovrli leggere
solo un valore per tigni volra che la scanf sar eseguica. Un.a tipica ~equenza di input porrebbe essere:
5 100 200 300 400 500
dpve 5 inruca cbe dovranno

CS$Cre sommaci i 5 valori sucessiYi.

4. 10 Scrivere un progr.uruna che calcoli e visuali:z:Li la merua di diversi ince. Supponete che l'ultimo
valore lecco con la scanf si:i quello ddla sentinella 9999. Una cipica sequenia di iopur porrebbe essere:
10 8 11 7 9 9999
che indica che dovt essere calcolata la media di umi i valori che precedono 9999.

120

CAJ'lTOL.0

4.11 Scrivere un programma che rrovi iJ minore di diversi imeri. Supponere che il pdmo v::dore letto
specifichi il numero di quelli ancora da leggere.
4.12

Scrivere un progr;'lmma eh..- calcoli e visualizzi la somma degli inreri pari da 2 a 30.

4.13

Scrivere un programma che calcoli e visualizzi il prodorro degli inceri dispari da I a J 5.

la funi.ione faaoriale urilizzara frequ<:ncemern:e nei problemi di probabilica. Il fuccoriale cli


un incero positivo n, scricro o!<.' pronunciaco "f.moaledi n", uguale al prodo tto degli inceri posicivi
da l a n. Scrivere un prQ!,rramma che valuti i furrociali degli inceri da I a 5. VisuaHuare i risulcaci in un
formaro cabularc. Quale ,tifficolr porr impedirvi cli calcolare il furroriale di 20?
4. 14

4.15 Modificare il programma deU'incer\!sse composro deUa Sezione 4:6 in modo che ripeca i suoi
passi per cassi d'imercsse dcl 5, 6, 7, 8, 9 e 10 percenro. Dcilizzare un ciclo fo r per va.tiare il casso di
ince.resse.
4.16 Scrivere un programma che visuafu.zi separaramence l'uno sorro l'akro i seguenti disegni.
Urilizzare <lei cicli for per generare i disegni. Tuni.g~L3l!tcrischi ( ) dovran no essere stampaci da una
singola isru1.iMC printf della forma printf { ); (ci call$er la visua.fizwz.ione fianc0 a fianco
degli asrcrishl) . Suggerimenro: gli ulcimi due disegni richiederanno che ogni riga incomi11ci con un
numero appropriato di spazi.

4. l~ Un:i azienda di vendita per corrispondema vende cinque diftnmri prodoc[i i cui prezzi 11.I
denaglio sono mosLraci nella seguente cabell:i:
Numero di prodotto

(B.)

......

......... ...:1'-t lii"'!\'

1dl1f:Jf. .... -"Jt;_'Ji:lt


~~

*"**

........

ff~~ -.

~~

""1 1

..................

"'*"..

~--
'llw

*......,,. .........

_,.__.. ....... . . . . .

:Jt"**-'fH!r

.,..

(C)

'.lt.t**-"'"'

"'li" *'.fF**c..;"'-***~#A
*'if'if{ii~*

*''*'

..._., .... ~1'"

.......

~.

-'*
..,. ~

(D)

...
lt

~-

*if11 1c
A-+1' lt

t-ri*
~****'ti'

.._.-"*"'"* --

......... ""*
*"

Prezzo al dettaglio

2.98
4.50
9.98
4.49
6.87

3
4

Scrivere un programma che legga una seri.e dj coppie di numeri come segue:
I) Numero d.i pro<lono
2) Quanric venduta i.n un giorno

uo rogramma dovr ucilizt.are umL istruzione switch per aiutare a decennin:ire jl pre-lZO <Il

TI

de;~~lio ~ ogni prodotto. 11 vomo, pr~gr:unm'.1 dovr calcol:tre e visualiz.zare il valore corale al demt-

.glio

cl! turri i prodotti. venduci ndl uluma semmamt.

4.20
{A)

Completate le seguenti tabelle di veric, .riem.pit.mdo i relativi spazi con O o 1.

Condizione I

Condizionel

o
o

o
diverso da 7.ero

d.ivcso da zero

J. TI numero di conto ~d djente


2 . TI limire di aredico del cliente prima della re.::essione
3. Il saldo corrente del dienre (vale a dire, l'ammon:care che il cliente deve all'azienda).
Il voscro programma dovr calcolare e visualizzare. il nuovo lim'ite di credito, per ogni dientc, e dovr
and1e dererrninan: (e visuali~:wre) quali di loro hanno dei saldi correnci che ~cdono il loro nuovo
limire di credito.

4. 18 Una inceressanre applicwone dci computer il disegno di diagrammi e di grafici a barre


(derri a volte aiscogramrni"). Scvere w1 programma che legga cinque numeri (ognuno compreso tra
I e 30). Per ogni numero leuo. il voscro programma dovr visuali7.7.are una riga contenente qul
numero di ascerischi adfaccnli. Per esempio, se il vostro programma leggesse il numero serre, dovr
visualizz.a re .

Condizione I && Condizionel

o
o

diverso da.zero

diverso da zero

Condizione I

Condizione2

Condizione I 11Condizionel

o
o

***"......,. ...... *

4. 17 Riscuotere il denaro divenm sempre pi difficile nei periodi dj recessione, per quesLo
morivo le aziende porrebbero resrringere i loro limi.r.i di cred iro. per evitare che i propri comi di
credito (il denaro loro dovuto) divnrino troppo s.osraniiosi. Come risposta ;t una recessione
prolungara. una aiienda ha dimezzaro il Limice di crcdco dei propri clienti. Di conseguenza, se
un parcicolare cliente avesse avuco un Li.mire di crediro di $2000, questo sarebbe ora di $1000.
Se un clience avesse avuto un limite d i crelico di $5000, ques.ro sarebbe ora di $2500. Scrivete
un programma che analizzi lo scaco di credito per: m: clienti di quesra a7.ienda,. Per ogni cliente vi
saranno fornici :

I i. J

lL CONTROLLQ DEL PRClCRAMMA

di versQ da zero
diver~ da 1.eco
Condizione I

dive rso da zero

o
divecso da zero
!Condizione I

o
diverso da 1.Cro

4.21

Ri,scrjvre il programma della Figura 4.2 in modo chel'iniz.iali7.zazione della variabile counter
sia. esegu:iLa nella dichiarazione, invece che ocUa suurcura f.or.
la vo.rwone media della classe.
della f'gura 4 7 in modo che calcoli
1
"

1
4.22 Mod.i ncate 1. programma

4 2 3 Modificare iJ programma della Figw:a 4.6 in modo che utilizzi sol~ruo degli inr~ri ~er calco~
nerar1e come quanm intere di
I cifr

.
. . . .
lare l'inreresse composro. (Suggerimento: rran:ate ru.uc . e. . e mo . .
rispecualizzando
cencesmu,
e
dollari
di
pomoni
sue
nelle
risultato
1

"separare"
co

In

1
.
.
ceocesuru. segui ,
civamence le.opera2ioni di divisione e modulo. Inseme un punco}.

122

4. 24

GA:l>lTO L.0

&i].1onere che i -"' 1, j = 2, k

3em

2. Che cps;1 visu:izier ~gnu!):i

d,eJlt- -seguenti

i$quz:ion}
:i.} pfintf( "%d", i = 1 ) ;
l'!) pririt f( " ~d " . I = 3);
e) printf ( "%d" ,
\i)' print'f( "%d ",
) priritf ("~e " ,
{) pri,ritf ( "%d',
g') prin'tf ( ' %d ",
h) printf ( 't%d',
i) printf (-''%ti'! ,
j). p.r intf ( "%i:I"" ,

<

= 99

>= i

&~ k <

11 k

--

m);
m);

11
k
111 < j 11 ~ .. j >= k);
tm);
tH . . m).) i
l(k "> m)J;
Hf > kO;

! (,X < 5) && I ( Y :>= 7')


b~ l(a == b) :: !(,g J= 5)

7t=4-.!;1-!_i+i_.!+...
5 7

9 !1

VJsuiiliiz~te una ab:lla: clic mS:u;i il

valore di 7t approssi..maco d;i uno, . du; ere- ... c_crmini di

e) I ((X <= 8) && (Y > 4 ))


d) l ((i > 4) : : ( j <= 6))

rus.aivete il progr:i.mma deUa Figura 4.7 SOSticuendo l'istruzione switch con d,elle. scmrrure
defaul:t. Riscrivere quindi
questa nuova versione, sstituendo le storurrure ff/lse nidi.fie<are wn una s.ecie di i.srruiic:\ni if;
anche questa volta, sfa~ arren a cnmare :i.ppropcia#riiem il ajo di dfaUl t (ci. ~.ar pili dik.il<;
cbe con la ve.i'sion~ delle St;rUCTU!e i f /else nidificare). Questo es_erl;faio dil'nostrer l.1e la smmuta
switch una comodi.c e che ogni switch porr e~ser sostituito on istruzioni di sekzic;m~ singola.

4.3.0

if /else nidifcace: scare ari;em; a c:rrtare appropriataiuc;me il caso di

Cakvlat.c il valore cLi TI a partire dill.a Seri(! in:6n.ita

di cui il v:O..fu. program1,1\_a avr b~og1~0 per caleqlareJa paga di Qglli lip'encl1=:me, in b1.1$e
al pn,>prio codice cli p,a~entoappropriati

a)

4.2:5 v;isualfaz.ate una tabdla di equivalenza rra decimali , binari, ()[rali ed e.sadecima.li. Q ualora non
abbi.are famWarit. c::ou i suddetri. sisi:emi. numerici, cm1sulc:ace prima l'Appendice E, se-volere remare
di eseguire questo eserci11io.
4 .26

123

4. 29 (Leggi di De Morgan) 1n questo capfrolo abbiamo discusso degli opmori logici&&; : : e I . Le


Leggi di De Morgan pou~~o a volte renderci pi prarica la formulazione di un1nsp.ressione logka.
Queste leggi srabiliscono che l'espressione I (conliiionel && concli7.in2) laglcamen.c~ equjvaJeme
alla espressiom: ( I amdiziond : : I 10011dizi1:me2 ); lnolcrc, l'esp.ressione I ( contli:tio.n 1 : I coildizione2) logicamente equivalemeaU.a espressione ( lc;ondizionel && lcondkiooe2) , Utilizzare le L.eggi
di De Morgan per scFivere delle espressioniequivalenti per ognuna di quelle seguenti e quindi scrivere
un programma che .diinosrri ehe l'espressfo.ne-0riginale-e quclla n.uov.a sono, in ogni.ciso, e.quivalenci:

i. >= 1 &g. j < 4) i


ITT

lL CONTROLLO DEL J?ROGlti\MMA

qu~sta

sef.i'e. Qua.i)ci crmini di qt1~$ta '-5Jirie dovrece utiliz.za:r, priin dj ocrcn_


ee 5,14? 3,141? 3, 1'415?

3; Ul);;).?
4.27 ('Fe~ne pitagoriehe) Un rriang0lo retrango.lo f'U avere fari che .siano rutti interi. Dinsieme dei
tre valori interi per i Ia~i dj. .un ttiariKolo rettangolo detto rema pitagoriea. ~uesri rre laci de.v.ono
soddi'sfarcda relazione.secontlo la quale la somma dei quadrati dei due ca~eti uguale:al quadrato della
ipore.nusa: Trovare wrr I.e. reme p.iragoriche per latoi , lato2 e ipotenusa che non sian~ maggio10i di
S:tlfl. Utilizzatoe un tiiplo .Giclo fo.r nd.ifkaro ,che ,provi semplicememe: mrr.e le possib.i.lh. Questo
un esempio cli la.boraiione een "forza bruta'.. Non piaee a mofr dal pt1ro di visra esrecieo.-Esistono
pi:r moh~ ragion l?e'f cui quesrerern.iche ~on0 imporrami. fu p.11i.m'.0Juogo, con .f.ineremenro della
po16mt di cakolo a un t irmo cosl-feaomeJ'ale, le.soluzien che av,r.ebbero richiesto anni o addirirru.ra
secoli di elae.oraiioM; per esse.re ocrenme con_;! a cetnologia di solo un po' di anni fa, o~gio=o
pl:rebor esS'~t Citemtte in.ore, in m.i.oud o addirim1rain.secondi! lnsecondo luogo,.aome aflPr.e nden~re nei-co;rsj pru a-Vailiari di inf6m1acica, e'~ un gran numero di problemi inte_r~sami per i quali
illfo, s'i~r n~sail a1fprO-cio algotirrnico 11oc6' li.yrso da quello alla. fraa rut. fo qudro lbro
nvescigheremo su. ml')lfi tip di mecOlO.gie 'per la s.olui ine dci pr.oblemi. Considereremo mld
;tppr.Qc;cL<.on. fu,rz;i bm~a .a di.versi pio5lani in,teressa:na..

4.28 l.)na azic11la feaibuis~~ j PfO,PQ cLipendenti d.iscin15!1endoli tra managet (.eh<;: riq:vom> un
s-alario fiswsertim;ina1_e), lav~rar9ri ;i ~re(~~ !'i~v<;>no ima p-aga oraria .fi.s:$a p.er le p9m~ 49 ore cli
lavoro e "un'ora e me-1.z.a", gw~r9sia t,5 VQite la [>aga OJ'ar.~, pe_r le Ofe ,cLi ~Cl'OJclimri.9 'effertua.~e),
Li.vero.tori a tJrDV\~giene (che riceNqno $250 p.i il ).7% delle loro vendite lprde serrim3naH), qpp.ure
lavoratori a eorrimo (ehe ricevone unacifra fissa di denaro ad arduolo; per ognuno di quelli proclot:ri:
in q_uesra azienda ogni laverarore a cotmo lav~ra:solramo su un upo d.i arcicoll?} Seri.vere un .progpunma che calcoli I.a g~~a settimanale di egni dipendrote. Non eonoscete in anticipo il .numero dei
dipendcmi, Ogni cipo di dipendente ha il p,roprie codice d.i pagamemo: i n;ianag~r hanne 1, i lavora~
rori .a ore hanno 2, q_uelli a provvigione 'h an.ne ,3,e quelli a eo.rtimo hanno 4. l:Jrilizmre una sa:unura
swi te h per <!a.lcol;ire.1a pag~ di ogni dipe11denre in base al suo eod.ieecli pagru;nemo. All'interno della
Stnutmra:. swi tch, Fichiedere:ll' utenre (o'l'.Verosia all'impiegato a.d detto alle paghe) di immettere i farri

Sc_civere un prqgramma che visua.li1.2.i il scgueme diseg_no di un rambo. Po.crete utiliz.1.re delle
is_rt~iqni pr.intf che visuali.za.ino ogpuna un. singolo asrerisro (*) o Lmo spazio. Massnii.1.are rl
vo~9 uriliz.zo delle ripe:ckieni (con strucmrc for nidificare) e minimizzate il numero di imuzoni

4:.31

printf.
'lr1J,"lf

..,.,"',,.....
"

it',it';ill'

ili/}*.--~

,lo~!-.f~~
,,,~~

A.32 .tvf9dificarc il prog~ che avere scdcco nell'Ese.rcizie 4.31, in modo.da.leggete un numero
4iwarLcompres.o n:ell'imervallo da I a I 9 per specifiGare il numero di righe compte~e ud rombo. li
V<:).SU'fl programma; dovr quindi visualizzare un rombo della. misuta apptpria:ta.
4 .33 Se ayee familW-it 911 i numeri ramani, s.rivece un prO:gtamma eh~ visuali.7.:zi una rabeUa
conceneme m:rri.i llllffi~ti romani equivalemi a quelli decimali bmpre.si ne.ltirtrervallo da l a: 100.
4.~4 Scrivere wi programma che visualizzi una tabella comenellte i numeri binari; orta.li ed esadecimali
equivalenti a quelli decimali rnmpresi nell'lmervaUo dal a 256. Se non avete fumiJi.cit con ql.i.s~i
siscemi rrumerici, consultate prima J"Appendice E; se volere tentare iii eseguire ques.ro .sekizio.

4.35 Descriveteil pr~~ che u$erste per 50stitu.ir LU'I cklq dO'/while oon una.scructur'1-.W'hile
qli,iv";Ilen.r. Qu,i.ie prE:lbie.tna intonrre.re:ste qu.a1er-a cenca~ce cli sO;stiwire Lm ciclo while con una
strurm1:a do/while quivalence? Supponete che vi s.ia scaco chiesEo cLi rimuavr~ un tido while ? di
$osritull:l0 cpn una sJrrrura 'do/while.Di qule alt(.sr.ruttra di eonrroll0 avt\!te b~ggn_o e ime l~
userere, pr ;issi<:;urarvi h iJ prog.m.ma cisultame si omporti esm:ament\! c;omeJ'ori~?

L24

CAJ>l1'9W4

4.36 Scrivere un programma che prenda in inpm un anno compreso nell'intervallo dal 1994 al
1999 e utilizzi una irerazioac con un ciclo for per produrre rrn calendario compend.iat0, v1sualiz.z.aro
in modo ordina.ro. Artenti agli anni bisestili.
Una cricica alle istrui.ioni break e continue che non sono srrua:urace. In realt le isrruzioni
break e continue pos.~ono sempre essere sosriruire con isrruziooi smnru.rare, sebbene furlo possa essere
scomodo. Descrivere in generale come rimuovereste mm: le:isouzioni break dal cido di un programma, e come le sostituireste con qualche istruzione stmnw:ar.a qun~etue. (Suggeri memo: l'istruzione
break abbandona un ciclo dall'interno dd suo corpo. I..'.altra,maniera per abbandonarlo facendo in
modo che il controllo di continuazione dd ciclo fallisca. Nel controllo di continuazione dcl ciclo
considerare l'urilizzo di un secondo concrollo che in~chi "usi;ita.anricipaca a causa di una condizion~
di 'hrea.12"). Ucili7.7.atc la tecnica che avere appreso in quesco esercizio per rimuovere l'iscrm.ionc di
interruzione dal programma delfa Figura 4.11 .

CAPITOLO

4.3 7

4 .38

I )

Le funzioni
Obiettivi
Comprendere come cosrruire i programmi in ~odo modulare partendo da piccoli
pezzi chiamati fum.ioni.

far il scgueme frammento di prngramma?


fo r (i= 1 ; i<= 5; i++) {
Che cosa

Inrrodurre le comuni funzioni matematiche disponibilinella libreria standard del C.


Essere i.n grado di creare nuove funzioni.

-fo r ( j = 1 ; j <= 3; j ++) {


for '( k = 1; k <= 4; k++)
printf{ "~ '');
printf{ '"");

Comprendere i meccanismi tLtilizzari per passare le.infomiazioni alle fi.u11.iot;.

Introdurre le tecniche disimulaz.ione d1e utili7Zlllle1a generazione dinurneri c.'l.Suali.

C-<>mprendere come scrivere e urili'l.z.a.r le funzionj che richilnano se stesse.

pr i ntf ( '' \ n ) ;

Descrivete in generale comesimuovcreste ruue le isrru2i11i continue dal ciclo di un programma, e come le sosri 11 resre con qualche ist:ru.zione smm:w:ara ~quivaleme. U cilizzau: la tecnica che avcte
svilupparo in questo cserci:iio per cimuovere l'istruzione continue dal programma della Figura 4 .12

4.39

Descrivete in generale come rimuoveresre le istruzioni break da una srruuura switch e come
le.sosrituiresce con qualche iscruzione strurruraca equivalcnre. Ucil.izzare la recnica (forse scomoda) che
avere sviluppato in questo esercizio per rimuovere le ismuionj break dal programma della Figura 4.7.

4.40

5.1

Introduzione

La maggior parre dei programmi per computer che siano stari scritti per risolvere problemi dd mondo reale sono pi corposi dei programmi presentati sinora, in questi primi
capiroli. I.:esperienza ha dimostrato che il modo migliore, per sviluppare e amministrare
un pTOgramma corposo, di cost:ruirlo panendo a pezzi p_i piccoli o moduli ognuno dei
quali sia pi maneggevole del programma originale. Questa tecnica derra dividi e conquista
(dal larino divide et impera). Questo capirolo descriver le cararrccistiche dd Linguaggio C
che Facilitano la progertazione, l'implementazione, il funzionamento e la manutenzione di
programmi corposi.

5.2

I moduli di programma in C

1 moduli in C sono chiamatifim.zioni. I progra.mmi C sono scrirci tipicamente combin<indo le nuove fon1.ionj scritte dal programmatore con quelle "preconfezionate" disponibili neUa libr~ri11 sta11dard:del C. In questo capitolo discuterem<;> d i enrrambi i
ci13i di fun.z.ione. La libreria standard deJ C fornis~e una cicca collezione di funzioni
per esegu ire i comuni calcoli macemacici, per la .w;lnipQl~<.me delle stri nghe e dei
cararreri, per l' inp ur/oucpuc e per moire altre operazioni utili. Ci render pi sempUce il lavoro del programmatore, poidl l suddette fu nzioni forniranno molte delle
capacit di cu i egli avr bisogno.

Buona abitudine 5.1

Familiarizzate con la ricca collezione di funzioni ;ncLuse nella libreria rtttndard


de/i'ANSI C.

126

CAPrrorn 5

LEFUN210NI

127

I ngeg;neria dei suftware 5.1


Evitate di inventare nuovamente In ruota. Util~te le fimzioni incluse nella Libreria
standard rlell'ANSI C, qual.ortt sia possibile, invece di scrivere delle nuove fimzi.<ini. Ci
ridurr il ti!rtpo di sviluppo dei progrttmma.
Obiettivo portabilit 5.1
worker 1

worker 2

worker 3

Utilizzare le fimzioni della libreria standard d.eli'ANSI Caiuter a renderepiportabili


i programmi.
Per quamo le funzioni della libreria standard n<>a facciano cec.nicamente parte dd
linguaggio C, esse sono fornire immancabilmente con tut i sistemi conformi allo sraudard
ANSI C. Le funzioni printf, scanf e pow che abbiamo utilizzato nei capiroli precedenr.i
sono appunto delle funzioni della libreria standard .

Per defnire dei compiti specifici, il program.mai;m porr scrivere delle funzioni che
possano essere ucilizzate in molti punti del programma. Queste sonp a volre c;hlauiace
fonzioni definite dal programmatore. Le ist:rnzioni che dd.niscono effetti vameme la funzione, sa.ranno scritte solo una volta e saranno nascoste alle alrre funzioni.
Le funzioni sono invocate da wu chiamata di fimzione. Q uesta specifica il nome della funzion e e fornisce d~e i.nfurmaz.ioni (gli argomentt) di cui la funzione chiamata ha bisogno, per
mmplewe le anivir per le quali scaca progerrara. Una cipica malogia per runo ci queUa
dclla scrurrura gcrarchic::a di un'azienda. Un capo (la funzione chiamante o chiamante} chiede a
un' operaio (la fonzione chiamata) di eseguire un compito e tornare indietro a. riferire, quando il
lavo( sar staco e.seguito. Per esempio, una funzione che voglia visualizzare delle informazioni
sullo schermo richiamer la funzione operaia printf per eseguire quel compito, in ~guito
printf visualizzer le.suddette informazioni e comedLindie.cro a riferire, ovverosia restituir il
controllo del programma, alla funzione chiamante quando il suo compito sar stato complerato.
La funzione capo non sa in che modo quell'operaia ~ i compici che le sono sc;rri assegnati.. Eopcraia potrebbe anche nchiamare alrre funzioni op etaie e il capo non ne sarebbe a conosc.enz.a. Vedremo presto in che modo questo "incapsulamento" dei dercagli dcll'mplemntazione
promuover una buona progettazione dcl sofrwre. La Figura 5.1 mostra la funzione main
mentre comunica c:On diverse operaie in modo gerarchico. Osservare che worker 1 agisce
come una fimzione capo per worker4 e worker5. le relazioni craJe funzioni potrebbero and1e
essere diverse dalla strurrura gerarchica mostrata in questa 6.gW'a.

S.3

worker 4

Figura 5. 1

Re lazione gerarchii::a tra la fu nzione capo e.quelle operaie.

printf( '%.2f", sqrt(900.0));

Nel momento in cui quesra iscruzione sar eseguica, sar invocata la funzione sqrt della
libreria matematica per calcolare la radice quadrar.a del numero conrenuto nelle parentesi
(900 . 0 ) . li n umero 900 , 0 l'argomento della funzione sqrt. I.:isrru1.ione p recedente
visu.alizzer 30, 00. La funzione sqrt accerta un argomento di po double e resciruisce un
risultato double. Tutte le funzioni della libreria matemarica restiruiscono il tipo di dato
double.

Bu.ona abitudine 5.2


f ndudete ii file di intestazione matematico, 11.ti.lizzando la direttiva del pteprocessore
#include <math. h>, quando utilizzo.te Le fanzmi della libreria mmematica.

Errore tipico 5.J


Dimenticare di includere ilfile di irrtestazione mateJnal:ico, quando si utilizzano lefimzmi
della libreria matemnta, potr provocare dei risultati strani.
Gli argomenti della funzione possono essere delle qmanci, variabili o esprSsioni.
Supponendo che c1 = 13,0, d = 3,0 e: f = 4,0, l'istruzione
printf(",9 6.2f", sq 1t ( c1

Le funzioni della libreria matematica

Le funzioni ddla libreria .matematica consencono al programmatore di eseguire celi cipici


calcoli matematici. In quesco conresro urilizzeremo v arie funzioni maremariche per introdurre il concerto di funzione. Pi tardi nd libro, discureremo moire delle alcre ~oni
incluse nella libreria srandard deJ C. Una lista completa delle funzioni incluse nella libreria
standard del C sar fornita oell'Appencilce B.
NonnaJmeme le fum.ion i sono utilizzare in un programma scrivendo il nome delle sresse,
seguiro da una parentesi tonda aperta, dall'argomentu (<;>ppure da una lisca di argomenti separati
da vicgole) della funzione e da una parentesi conda chiusa. Pei: esempio, un program,m ~tored1e
desideri cakolare e visualiz.z.are la radice quadraca cli 900, 0 pocr scrivere:

worker 5

+d

t) )i

calcoler e visualizzer la i;adice quadrata d i 13,0 '+- 3,0 ~ 4,0

= 25,0, vale a dire 5 1 00.

Nella Figura 5.2 sono rissunte alcune delle funzion i incluse nella libreria mare_m atica
del C. Nella figura le variabili x e y sono cli cipo doubi.e.

S.4 Le funzioni
Le funzioni conseruon0 al programmatore di suddividere in moduli un programma. Tu a:e
le variabili dibiarate nelle ddnizioni d funzione sono variabili locali: esse sono n oce
solmnto in quella in cui ,soao srate definite. La ma~gior parte delle funz.ioni con_ ene una
lista di parametri.. Questi forniscono il mezzo per comunicare l_e infoana.7.ioni tra le funzioni. Anche i parametri di una funzione sono delle variabili locali.

12$
Funzione

Descrizine

Esempio

sqrt ( x)

.radk:e quadrata di x

s qrt(900.0 ) ~30 1 0
sqrt (9 .~) 3 1 0

exp(?C)

.funzione esponenziale e

exp( 1 .0) 2 , 7f8282


exp(2.0) 7 ,389056

l og(x)

logaritrri.0 namralc di x (in b.ase e)

log(2 . 7182&2} ~ 1,.~


16g(7 ..389056) . 2 , 0

l,og10(X)

lgl!.ritmq di x (in. bas~ l )

log:10(.1 . 0 ) 0 , 0
log10 ( 10. 0.) 1 , 0
lo_g1~ ( 100 . 0) 2,0

di ~tarda.ripri:t.i.one del odic;.all'in,remo di un prgramn1a. lmpadiertare il C0dicein forma di


fu..dzi~n~ OP.senti~ allo sr~o di essete eseguit.o in div<!:rsi ptmri del programma rihiamande
sempllcem.nte la funziorie.

Ogrti fanz;n dtivr.b}J /Ji'nitr11.-si a sfJ.tlre w1 compito iir.z.goliJ e ben definito, m111ztre il
n~1t d.dlafim~ione. dmirebbe.esjfrfmere.efficac17~ente quel cony>ito. Gi faciliter l'astt-a-

zume upromuo.ver: ltt riusabilit del softwtlre.


Ingegneria del ~oftware 5. 4
Se non ;isdte Il sctgUi tt?l. f1a'IJ1 onr:iso cheJ1tprhnii t'at.tiviti'I. svolta dalla vomnfrtnz.iime, problibile che t{l.tttst sti tffntndii di eseguire troppi compibi diversi. m questi. ~asi,
di solito meglio s.uddivideda in.diverse fan.zioni pi piceale.

val.o re asso Iuro l.i .x

se x > 0 allora fabs(x) x


$e x = 0 aUora t abs (X ) 0 1 0
se x < 0 allora fabs( x ) - x

arrotonda x aU' imero


pi_. pii;:.eqlo non minore dix

ceil(9 .2)

floo r (x )

arroroncla iX" all'in ter0


pi:.i: grande nh n m3:~1ore dix

f .loor (9 . 2 ) 9 , 0
floor (-9 . 8 ) -10,0

p9w(x,

x elev~co alla _pgrnz.a y O

pow( 2 , 7) 128 , 0
pow(9 , . 5) 3.0

degli mcen cpmpreJ tra 1 e J.O (Figy.ra 5.3).

fmol(x, y)

resto di x:!r in-virgola rnobile

fmod(13 . 657 , ? . 333) 1,912

#i~eludi

sin (x )

.~ei'le> rrigonametrlco di x

s i n(0 . 0 ) 0 ,0

fab$ (X)

ceil(x)

y)

(x espr.essa..n
cos(x)

tan( x)

~ 10 , 0

ceil( -9.8) -9 , 0

(adiaotP

coseno rrigonomfiltico dix


(1! ' espressa in ntdiru;ri)

.65 ( 0. 0) 1 , 0

ra.ug~tevi.go.norn~tdca di x

t an(0 . 0 ) 0, 0

5.5 Le defmizioni di funzione


Ognuno :d.ei programmi c:he :i_bbiamo presen~to stato for.Lliaro da: una :fun,ziQ'ne clriarnata
main c;hc;, pi';r eseguire i propri compiti, ha ri:hia.rnaro quelle della li'.brer.i scandard. Consider.iaoio 'o ra in che modo i programmacori possano scrivere le proprie fun:zion i pers0nalizzare.
~;~nsi~rate . un .pmgramma ch urili.zJ.;i

r1iCl
P.

funzione square

per c1k:'olare j

quadraci

I * l)na funzione :?Quare qefJ.n-ita dal p.rog rammatore * /


<stdio.h>

i nt square(int);

I* prototipo a.ella funzione */

main ()
{

i nt X;

(ic espressa in J:':\iliami):


Figu"a S. 2

u.ri

for (x

Funzioni comunemente utllizmte.della libreria matematc~

Ci son ruvr.Semt>.tiyazioni per "Sl;lddividere in funziom".1+11 programma. l'.~pf!rQcie div.idi


e conqu ista rende maneggev:>l lo -svilup,p0 del pmgramm. Un'-alrr~ moriv(lzione l
riusabzY.it del-software. u~eJe funzioni esistenti come l;)Jmiehi di-cosrruzjoru: p,er deare i tiuovi
p.rogtammi. La du~abillr. de! ~.oftware UJl0 degli d emenl!i principali del mov.im.fro per la pto~6.pe . orienr.a.ta. agli qggetti. Con ill! brnn_1.ng!11e di funzione e uAa buona.ddnizioae, i
prog~~pa-rri no e'S.$e tea_ri da fl.1nzigni sranda:rdizzare4ie ~eguao<;> dei compici sped:fki,
piut:o:sro che es5t:e co5trllii uti:llzzando un odie per-g~r'I~. Ql!est.a te~ni~ eqno~ciuta
6nie astrazi.om. Noi usiamo l'astrazl.bneogni volta.cl serivia:.ino dci.prqgrammi che includano
de.llefunuon:i incluse nella librcii:israndard, come printf sanf pow:Un.a ter~.a rqocivaziou
I

r,

10 ; l!<++)
sci uare(x));

r:i ntf ( ~ \n");


l"'eturn 0;

htgigntrin. dt.L ijt:War 5.2


Nei programmi contenenti molte fimzioni, main potxebbe.essr impkment_q.to ciJfhe u71
gruppo di hiamate a fim;liioni che eseguono il grosso Il.et lavbro deiprogram1nit.

= 1j x -=

pri.ntf("%d

'/" De'tini:ilorie dlla funz;ione *.I

int

squ a r~(irit

Y)

,.

returh y .. y;
}

['

Fig ura S.3

16

~li

36

49

64

81

1100

Usare una funzione definita dal programmato r.e.

CAPITOLO

130

~ B11ona abimtline 5.3

lf2J

La funzione squa re sar invocata o richiamata nel eorpo di ma in all'illrerno dell' iscru-iione printf
", squar-e(x));

La funzione square riever una copia del valore di x nd parametro y. In sguito square
calcoler y y. li risulraro sar restituito alla funziqqe printf all'imerno del main n~I
punco dell'invocazione di square e printf visualizzer il risultato. Questo processo sara
ripetuto J O voi ce uciliz.zando la srrurrura di iterazione far.

La definizione di square mosa:a che questa attender il paramerro inrero Y. La parola


cbjave i nt che precede il nome della funzione in-dica che square restituir un risulraco
incero. L'imu'Zione return neJla fum.ione square i:estin, il risultato deJ eak9lo alla
funzione chiamame.

La riga
int square(int);
un prototipo di fo~one. I.:int all'incemo delle pareruesi informa il ~n~pilawreche square
si aspercer di ricevere un valore intero dal chiama:nre. L ~n~ alla s1~1sua del no~e della
funzione square- infoDDa il compilacore che qu~ca resmwr al ch1amance un n~ultato
incero. Il compilarore far riferimemo aJ protocipo della funzione, p~r .c~ncrollare.. ~e le
c:hiamate a s quare contengano il tipo di riromo correrro, il numero e 1 cip1af'propnan per
gli argomenti e che questi siano forniti nell'ordine corretto. I prococipi di funzione sara.Jino
trattati in dettaglio nella Seziaoe 5.6.
Il formaro d una definizione dj funzione

Dimenticare di rertituire un valore da una funzione che dovrebbe farlo potr condurre a erro1i inattesi. Lo standard ANSI stdbilisce che il ris11lt11to di questo tipo di omissmi sar indefinito.
Error tipico 5.4
Restituire un dato dtt untt funzione il cui valore di ritorno sia stato dichiarato di tipo
void provocher. un errore di sintassi.
Buona nbitudin 5.4
Stabilite sempre in modo esplicito il ripa di doto restuo, anche se lo, sua omissione farebbe
restir:uirc un int per default. Il tipo restituito da main, invece, normalmente omesso.
La lista dei par4men-i un elenco concenc11re le d i.i:hiariu.ioni dei paramelri, separati da
virgok, c;he saranno ricevu ti dalla funzione quando sar richiamata. Qualora una funzione
non riceva alcw1 valore, la lista deiparnmetri s:u void. Il tipo di ognuno dei pata:nerri
dovr essere specifcaro esplici(amente, salvo che .non siano di tipo int . Infimi, qualora
non sia scaco specifcarq il con~pilacore presumer che si trarci d i un int.

Errore tipico 5.5


Dichiarare i parametri della funzione, qualora siano dello stesso tipo, usando la fimna
float x, y invece che float x, float y. La dichiarazione flost x, y in realt renderebbe y un parmnetro di tipo int, poich int il default.
Errore tipico 5. 6

! ul'z iJrrore di sintassi inserire un punto e virgola, dopo la parentesi destra che chiude
l'elenco dei parametri in una definizione di funzione.

tipo-del-valore-di-ritorno 11ome-delln-fitnzione(lirta-dej-paramem)

131

Errore tipico 5.3

Inserite una riga vu()ta tra le definizioni di funzione, per separarle e aumentare lo leggibilit
det programma:

printf(''%d

LEFVN7.IONJ

Errore tipico 5.7

dichiarazioni

,! rm errore di sim-assi ridifini;e un parametro d~Lla funzione come variabile loc11le alla
stessa.

istruzioni

di.

Il nome della funzione un qualsiasi idenrifcacore vilido. Il tipo dei vawr:e ri~rno quello del risulraro restituiro al chiamame. Il tifo def.:valore di ritorno void tnd1ca che un-a
funzione non resruir alcun valore. Un tipo det valore di ritorno non specificato sar sempre conside~o un int <dal compilatore.

Errore tipico 5.2


Omettere il tipo per il valore di rirorrw in una definizione di funzione causer tm errore di sintassi, qualora il proeotipo della fimzione specifichi per il valore di ritorno un
tipo diverso da int.

Buona abitudine 5.5

lndudere ii tipo di dato per ogr.1i parametro presente nel relativo elenco, nnche qualora
fosse d.el tipo di defouit int.
Buona abitudin~ 5. 6
Per quanro non sirf. scorretto farlo, non utiliuate gli stessi nomi pttr gli argomenti passati fl una fimzme eper i corri.rpondenti parametri inseriti nello, relativa definizi.one.
Ci aiuter a evitare ambiguit.
Le dichiarazioni e le istruzioni inserire all' imern delle parentesi graffe for.mano il
cotpo della j.nzione. U cor_p della fum.ione chiamato an~he blocco. Un blocco semplkemeni:e un'i,muzione r:omposta che include d elle dichi:arazioni. Le variabil i potranno essere

CAITI'rn.O 5

152

di'chiarat.e in qualsiasi b locco~ questi pottanne ess,~re nidificati. Una fitnzione non pu..rnai
l!s41t .4ef'1'iitil "aitintenw r.li u1la/.trt1 fonzffJ..tre.

El
~

Enw:e tipico 5. 8
Defi.nire una. funzione all'interno di un!aftra funzione im errore di J'intassi.
Buona abit11Jd.in5. 1
Scegliere dei nomi. difunzione e. di pttrllmetto.sig11#ficaiivi i'rtndrl/. i progrtli'!lttI pif.t le%2}.b/.li
e ahtter a eu.itar.e L-'itsn. eccessivo d commenti.
lngegt1flria del rtiftwm 5.5

133

S.6 I prototipi di funzione


Una delle p i impga~~crsrilie ~lrANSJ il prowtipo di,fatizio~ncpmimw.ddi'ANSl
pr~~ in pre,stito quesra. Gtt:arreriscica dagli syil.npp-ar0ri del t++. Un prorocipo di fu.niioe
inl.ica aJ compiL"U,or;, il cipo dd dam tesri'PJJ-rv cblla fun~ion.e, il nurnerb dei p~ameai.clie quella
si aspecra di r.ieev~:~, il cipo dci paramerri e l'ordine in ui questi sono arresi. Il tompilacore
utilizzer i pro:tot!ipi per<ZQovalidare le cliia.mare di funzione. Le versiohl prci:edent'i del e non
eseguivano qucsm tlpo di cnn:ollo, perii:i era possibile richiamare !e funzioni in m0d0 impro~
prio senza che iJ compilarote individuasse degli euori. Dmante la fuse cli esecuzione, tali .c:hia,.
mate avrebbero poruri;i 01usare degli errori furali, Q anhc; npn ~<ali, m~ che avrebbero provoato gegli erro~ lqgici $ubdoli e difficili d:t inclivJdua.re. I prororipi di funzione dell'ANSl C
p<>.ngono rim:ediq a questa la.cuna.

Una ftmzin non dovrebbe essere pi L1mg4. d.i i1:Ua pO:g/n11.1v1;eglio ancora,, 11-1111 jtnzione non do11reb'be es.sere pi lu.nga di una mizza pag:i.a,. Lefo'ri$iorii picolif fo.voriseono la riusabilit dei sofiwa111:.
.

1 * Trovare i l. mC1,ggiore di tre interi "/


#in~lude <std i o.h>

]ng'f;flleriu, del !Oftware5.6

m:ain ()

I prgrarhmi dovrebbero essere scritti come cq[Jezio'tli di fim~i.n~p.iccole. Ci ti tende.rn pi semplici da'scrivere., c'Oi/audt1r., mitt.ere n. pttitto e modifica.re.

r1l:l

printf ( 11,Enter thre-e integers: 11 ) ;


scanf(-%d%d%d , &a, &b, &e);
printf( 11 Maximum is: %d\n 11 .J m.a.x.imum(a, b, e::.));

Und.fa.i:i::itit. chericbiet:/4. u~,gil~n nt.f;ntro:diprmettip'(ft:rebbul_o'l/.P-wolgel'e troppi compiti.


Gniitfertttet/ po1sibilim di SJ4d.i.vidrla in funzmi pi pitcok che tef.gt:lit:Jto de.i ciimpi#
diliimi.. Eitestazme del/afimzion tlovre.bbe 1ientrare in 1d14 rigtJ.., se passi.bile_.
lt.tg~gner.ia dei softwq,re 5. 8

l/.pi<itotip.a, l'in.t{tjzjori' '4 thi4J?'Nft4.d4/liffi~urie dovrbhehl l'u/fi onor4/fre 11eln1mtero,


nei tipotJ nell'Ordine dgli. argo.ftpiti edei pariiinmf. oltre cb.l"1Jl tip.o d.el ualbr tes:ti.tJJi't/J.
E$j~tjn9 tre; mg~i pc;r (~cit\,lire i] pmr_qllo al puntq i.n cui una funzigpe

retu r n 0;

1* Defi ni.z_ion-e della funzione maximum * /


int max_imum(i.nt x, int y, int z)
{

int

srara i.tw0cm~

espressione;

restituir a1 chiamante il valore del!' espressi.one.

Il no~tio-second~ sempie .utiliziJ: 1.ali:u:,ionemaximom defnirn dall'ueen.ce, per de..terroinar e .resrituir il .rD.a~iore fra rr.e inreri {Figura ).Zi). I rre interi s:a:rann.0 presi in
input con sc~nf. In seguiro, gli inceri saranno pass.ri lla .funzione maxirilum che derer;:mineF quale sia il roaggime di essi. QueStO val'oJie sara resmitO aJ ma i n dfil'isrruzi.oae
re:turn deI;!. funz.lone maximum. 11 val~r.c: :r~rituiro sar assegnato alla variabile l argest
he ~ v1~1,1a!izta in s(lgito ..d.a printf .

= ~i

H (z > max)
max

r:-turn;

~etur~

max

i f (y >= max)
max = Yi

ca. N:Gl casp io cui Ja l.m:do'.ne non re.s.tiruisca alcnn risulta.Co, iJ controllo sar r~cituito
sempliemcm,.r qua,nd!) sar r~ggiunra. l;i p:aremesi graffa destra che ch.iude la. fun~ione,
oppure .ei;egueud l'isrrnz1cine
Nel caso che la flmzi0ne rescitujsca .un risultare, J'is.rmziohe

dell.a f. unzione

i nt a, i. g;;

lngegn'ria del s-oftware 5.1-

I"' (1rito'tipQ

int maximum(int, nt, int};

= z.;

return max;
}

linteP 'l:fr.-ee in,1:e:gers:

2~

85 H

Mtttdrllu(ll is: 00

Ente.a tllooe i(lte\QEHis : 85 .22. 17


Mpxd.rnum is: 85

Enter ttrr.:e'El :llnte,ger..s :

.22.

17 8&

Matcimuf!l is;: 8'5,

Figura 5.4

la funzione maximum definita dal progr?mrnatore.

*f

CAPITOLO

Buona abitudine 5. 8

lnrludete per tutte /,e fimzioni; rekttiviprowripi in nwdo da trn.rn vn.ntag,gio daUe cop1uit
di controllo di tipo implementate 11el linguaggio e Utilizzate k dirl!tti11e liinclude del
preprocessore per ottenere, dai file di intestazione op-propria.ti, i prototipi delle fimzioni incluse nello libreria rtandard. Utilizzate inoltre liinclude per ottenere i.file di intertazione
contenenti i prototipi di fimzione utiliuati da voi e dai membri dei vostro gruppo.

Il procoripo di funzione per la maximum dellii.Figura 5.4

135

L BFVNi.'.IONt

Le regole: di promozione si applicano automaric:ameme alle espressioni che contengono dei


valori di due o pi cipi di daro, derte anch.e espressioni di tipo mi.sto. Ogni valore in un'espressione di cipo misco sar promosso aucomacicamcme a quello pi alro dell'espressione (in realc,
sar creaca e urilizzata w1a versione cemporanea cli ognWlo dci valori: quelli originali rimarranno invariati). La Figura 5.5 elenca i tipi di dato nell'ordine da quello pi alto a queUo pi basso,
con le relative specifiche di conversione per printf e scanf.
Specifiche di conversione
per printf

Tipi di dato

Specifiche di conversione
per scanf

int maximum(int, int , int) ;


Quesro prototipo di funzione stabilisce che maximum ricever re argomenti int e restiruir un
risultato dello stesso tipo. Osservare che il prorocipo deUa funi.ione maximum uguaJe alla prima
riga della sua definizione, eccetto che i nomi dei paramecri (x, y e z) non sono stati inclusi.

Buona eibitudine 5.9


A volte, i nomi dei ptll'tJTtietri sarann incli1si nei prototipi di funzione pet scopi documenmtivi. In ogni modo ii compilamr' li igm7rrit_.
Errore tipico 5.9
Dimenticare ii punto e virgolo alla fine deL prototipo di funzione provocher un errore
di sintassi.
Una chiamata di funzione che non corrisponda aJ suo proropo provocher un errore di
simassi. Sar generato un errore anche qualora il prmopo e la defn.izione della funzione non
concordino. Per esempio, se il prococipo della funzione nella Figura ?.4 fosse sra.co serino come
void maximum(int , int , int) ;

il compilatore avrebbe generato un errore perch il po di ritorno void, indicato nel protocipo
della funzione, sarebbe scaco dive~o da quello int specifc::aro nell'inn:sraziooe della Stessa .

Un'alcra imporcanre cararceci.scica dei procoripi di fu.azione la com:izione degli argomenti,


ovverosia la amversione forzara degli argomenci al ripo appropriaro. Per esempio, la funi.ione
della libreria macemacica sq rt porr e.ssere richiamata con un argomento incero, fi.ul.Zionando
ancora correcramente anche se il suo prototipo in math. h specifica. che l'argomento debba
essere di tipo double. t:iscruz.ione
pr'int"f (" %.3f\n 1'

sqrt (4));

valurecl correrramence sqrt ( 4) e visu.afuzer. il valore 2, 000. n protecipo di funzione f in


,modo che il compilarore converta il valore intero 4 in qudlo cli tipo double 4, 0, pdma che lo
'Scesso sia passare alla sqrt. ln generale, i ~alori degli argoin~n.ri che non corrisponda.no precisamenre ai cipi dei para.merci defoci nel prococipo s.rnno converri:ri in modo appropriato,
prima che la funzione sia richiamata. 1li conversioni po.crebbero per causare dei risulraci
scorretti, qualora non fossero rsperrare le regol di. prortJozione del C. Tali regole specificano in
quale modo i vari tipi dj dato possano essere convertiti tra loro sem..a perdita di informazioni.
Nel nostro esempio con sqrt, un int sar convertiroautomaticuneme in un double senza che
ne sia modificaco il valore. Nondimeno un double ~oovertito in int troncherebbe la pane
fuu.ionaria del valore double. Anche converrire i ripi pi grandi degli inreri in quelli pi piccoli
(per esempio, un long in uno short) potr produrre dei_val.ori modi:frca.

l\slf
long double
l\sf
double
l\sf
float
unsigned long int
l\slu
long int
!lsld
unsigned i nt
!lsu
int
l\sd
short
l\shd
!\se
char
Figura 5.5 Gerarcha di promozione per i tipi di dato.

\Lf
\lf
\f

\lu
\ld
\u

l\sd
l\shd
\e

Convertire dei dati nei cjpi pi bassi produce normalmente dei valori scorrerti. Di
conseguenza, i valori potranno essere convenici in un tipo pi basso solo assegnandoli
esplicicamence a una variabile di ripo pi basso, o utilizzando l'operacore di conversione. 1
valori degl i argomenri d i funzione saranno convertici ai ~dpi dci parametri defin iri nel
relarivo prororipo, come se fossero stati assegnaci direrramencc a variabili di quei ripi.
Qualora la nosua funzione square che ucilizza un parame.rro incero (Figura 5.3) fosse stara
richiamata con un argomenc:o io virgola mobile, quSro sarebbe sraco converrito in un int
(un npo pi basso) e square avrebbe resruiro un valore sco.rrerro. Per esemp.io. square (4 . 5)
resrimirebbe 16 invece di 20, 25.

[iJ

Errore tipico 5. J O

Convertire w1 tipo di dmo pi alto, rispetto 1tlla gerarchia di promoziom:. in uno pi


basso potrh modlfic1m1 iL vawre dei dati.
lL compilatore forme r un $UO prorodpo di funzj9ne, qu;tlo.ra questo non sia staro
incluso in un programma, urilitzando la prima qi;:arreru:a del.la fll.flzione: ovverosia. la
dfni.i iooe o una sua chiama.ca. Per default, il compilacore assumer che la funzi one rescicut...-ca un. int e non presumer nulla relacivam.ence agli .argomemi. Ne consegue che, qualora gl i a.rg0menri passati aJla funzione non siano corretti, gli errori non sarann o individuaci dal compilatore.
Error~

tipico 5.11

Dimenticare un prototipo provocher un errore di sintt1.ssi, 9ualora ii ripo restituito dalla


funzione non sia un int e la definizione di quei/a appaia nei programma dopo una sua
chiamata. In caso contrario, dimenticare iLpr(!t(Jtipo di una ftmzme potr causare tm
errore durante la fase di esecuzione, oppure u11 risu./tato inatteso.

136

CMrro.LO 5

Ingegneria del software 5.9


Un prototipo inserito all'esterno di ogni defini:.one di fimzme si applicher a tutte le relati vi: invocazioni che appariranno nel file dapo il prototipo. Un prototipo
inserito a/L'interno di ima funzione si applicher so/o alk chiamate eseguite all'interno
della stessa.

S. 7 I file di intestazione
?gni Libreria standard ha un rorrispondenre file di, ir:te:rtazibneche ronriene i prototipi per tu ree le
tunzioni incluse in qudla libreria, olrre che le defnizioru dei vari tipi di daro e delJe cosrami
oecessa.rl a quelle funzioni. La Figura 5.6 elenca alfabeti<::ameme i file di intestazione della
libreria srandard che potranno essere inclusi nei programmi. Il termine "macro", usato diverse
volte nella Figura 5.6, sar rrarrato in dercaglio nd Capitolo 13, "11preproces.5ore".

137

lEFUNZIONl

File di intestazione
della libre ria standard
<stdd~f. h>

Comiene le defnifjoni comuni dei tipi di daro utiliz-Lari dal

c per eseguire cenj calcoli.


<stdio. h>

Conriene i prototipi per !e fun7.ioni d i inpuc/ourpuc della libreria s1.andard e le informazioni utilin.ate da queste ulrimc.
Contiene i prorocipi delle l;nzoui per 1a conversione dei numeri io ceSto e viceversa, p.r l'allocazione della memoria, per
i nwneci casuali e per altre funz.iouidi ulit generica.
Contiene i promcipi delle funzioni per l'elabora;o,ione delle
srrtogbe.
Contiene i prororipi di fuzine e j [ipi per la manipolazione
dll'o.ra e dllc dat,e.

<~tdlib. h>

<string . h>
<time.. h>

File di intest azione


della libreria standard

<assert .h>

<ctype.h>

<errno.h>
<float.h>
<limits.h>
<locale.h>

<math.h>
<setjmp.h>
<signal.h>

<stdarg.h>

Spiegazione

Conriene le macro e le informazioni per aggiungere delle


istruzioni diagnosridie che forniscono un aiuco duranrc la
messa a punto del programma.
Contiene i prototipi per le funz ioni che verifcano talune
propcier dei ca.rarrcri, nondi per quelle che porranno esse
re utilizzare per convertire le lettere minuscole in maiuscole e
viceversa.
D efinisce le macro che saranno utili per comunicare le con
dizioni di errore.
Contiene ~ limiti del sistema per la dimensione dei valori in
virgola mobile.
Contiene i limjci del sistema per la dimensione dei valori inceri.
Conciene i prorodpi difuazio:ne e alrre informazioni che conseo
tiranno a un pro~ram:ma ili essere ada[tato alla localit in cui
sar eseguito, La nozione dj localit co:nsenre aJ siscema di gesti
re le diverse convenzioni delle-varie aree del mondo per espri
mere infori:naziqpj c0 m<;; la dara, l'ora, la valuca e i grandi
numen.
Concieoe i protocipi per le. funzioni della Libreria matemarica.
Contiene i prototipi per le funzioni che consentono di aggi
rare l'usuale sequenza di chi<1mara e ritorno da Funzione.
Contiene i prococipi di funzione e le macro per gestire le va
rie condizioni che porranno insorgere durance l'esecuzione
del programma.
Definisce le macro che conscritono di gestire delle funzioni
per le quali il numero e i tipi d~i argomenti siano sc.onosciuri.

Spiegazione

Figura S.6

I file di intestazione della libreria standard.

Il programmatore poc:r creare dei file di inresrnzio.ne permnalizzaci. Anche i me di inccsrazione definiti dal programmatore dovranno rerminare in . h e potranno essere inclusi utilizzando la dlrettiva del preprocessore #include. Per esempio, il file di intestazione square. h
potr essere incluso nel nosrro programma dalla dlretriva
#include square.h "
posta all'inizio del programma. La Sezione 13.2 fornir ulteriori informazioni sull'inclusio-

ne de.i fle di inresrai.ione.

5.8 Invocare le funzioni:


chiamata per valore e per riferimento
ln molti lillguaggi di programmazione esisrnno due moru per invocare le funzioni: la
chittmatt1 per valore e la chirm111tn per rijrimento. Quando gli argomenti saranno passati in
una chiamata per valore, sar preparata una copia dei loro valori e questa sar passara alla
funzjone_cb!amara. ~e modi~che efferruate alla copia non inreres.seranno il valore originale
della va:rn1bile definita nel chiamante. Quando un argomento sar passato in un.a chiamara
per riferimento, il chiamanre eonsemir efferrivameme alla funuione chiamara di modi.fcare il valore originale della variabile.

Le chiamare per valore dov,rebbero essere ucilizzare ogniqualvolta la funzione chiamata


non abbia la necessit di modificare il valore ddla va:riahile originale defLllita dal chiamante. Ci pr.ev.e rr gli effetti collaterali accidcmali che inrralciano pesanremente lo sviluppo di
sisremi sofrware correrci e affidabili. Le chiamare per riferimemo dovrebbero essere urili1.zate solo con funzioni affidabili che abbiano bisogno di modifcare 1a variabile originale.
In C, curte le chiamate di funzione sono per valore. per~ possibile simulare la chiamara per riferimento, come vedremo nel Ca.pirolo 7, urilizzando gli operatori di indirizzo
e quelli di deriferimenco. Nel Capirolo 6 vedremo che i verrori sono passad aurornacicamenre
con una chiamata per riferimento simulata. Dovremo aspettare fino al Capitolo 7 per una
piena comprensione di questo complesso argo memo. Per ora, ci concenrreremo sulla chiamata per valore.

138

CAJ'ITOLO

Generazione di numeri casuali

S.9

LE FUNZIONI
{

int i;

Ci prenderemo ora un breve e, si spera, diverrenre diversivo con una popolare applicazione della programmazione, vale a dire la simulazione e il gioco. In questa e nella prossima
sezione, svilupperemo un programma di gioco ben strutturato che includer moire funzioni. 11 programma utilizzer molre delle strurrure di :onrrollo che abbiamo scudiaro.

for (i= 1; i<= 20; i++) {


printt("%10d ", 1 + (rand()% 6));
if (i % 5 == 0)
printf("\n");

C' qualcosa nell'aria di un casin che rinvigorisce ogni tipo di persona; dai giocatori
incallici che aaomiano i lussuosi cavoli in mogano e felrro per il gioco dei dadi a quelli che
infilano monetine nelle macchinerre mangiasoldi. l'elemento della casualit, la possibilit
che quesra possa convertire una manciata di monere in una montagna di riccheuc. I.:clememo della casualit pu essere incrodorto nelle applicazioni per compurer, urilizzando la
funzione rand della libreria standard del C.

ret urn 0;
}

5
2
5
:5

Considerare la seguenre isrruzione:


i

r and{);

La funzione rand genera un intero coh1p.reso rra O e RAND_MAX (una cascame simbolica
defnita nel frle di incescazionc <stdlib. h>). Lo standard dell'ANSJ stabilisce che il valore
di RAND_MAX debba essere almeno 32767, cli and 1 il v;tlore massimo per LU1 intero di
due byte (ovverosia 16 bic). I programmi di questa sezione sono stati coJlaudati su un
siscema C con un valore massimo per RAND_MAX di 32767. Qualora r a nd generasse davvero degli inceri a caso, ogni numero era Oe RAND_MAX avrebbe la scessa possibilit (o probabilit) di essere scdco oglli volra che r a nd fosse cichiamaca.
L'imervallo dei valori prodorri direccamenre da rand spesso differente da quello che
sarli necessario in una specifica applicazione. Per esempio, un programma che simuli il
lancio di una monccina potrebbe cichiedece solcanco O per "resca" e 1 per "croce". Un
programma che simuli iJ lancio di un dado a sei fcce richiederebbe degli inceri compresi
nell'incervallo da l a 6.
Per mostrare l'utilizzo cli r and, svilupperemo un pregramma che simuler 20 lanci di
un dado a sei facce e visualizzeremo iJ valore onenmo da ogni lancio. li prototipo per la
funzione rand pu essere rfrrovaro in <s t d lib . h>. Uri.lizzeremo l'operatore modulo(%) in
congium...ione con rand nel modo seguente:
rand() % 6
per generare degli inceri compresi nell' interv<Jo da O a 5. Questa opct"azionc si chiama
1-iduzione in scala, mcnrre il numero 6 detto fattore di scafa. ln seguiro trasleremo l' intervallo dei nwncri generati, aggiungendo l al nosuo ristJtato precedencc. La Figura '5.7
conferma che i risultati sono compresi neltinre.rvfillc:i da 1 a 6.

Per mosrrare che questi numeri si presnterann6 approssimat:ivamence con la stessa

probabillr, simuleremo 6000 lanci di un dado con iJ programma della Figura 5.8. Ogni
intero da 1 a 6 dovrebbe presentarsi approssimacivan1eme 1000 volre.

/* Gli interi, ridotti in scala e trasl_a ti, generati da 1 + rand() % 6


~1

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

ma in ()

139

[
Figura 5.7

3
2
2

5
5

14'

Gli interi, r idotti in scala e traslati, generati da I

randO o/o 6.

/* Lanci a un dado a sei facce 6000 volt.e */


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

ma in ()
{

int face, roll, frequency1 = 0, f requency2


0,
frequency3 = 0, frequency4
frequencys = 0, frequency6 = 0;

0,

tor (roll= 1; roll<= 6000; rol~++) {


+ rand() % 6;
tace =
switch (tace) {
case 1:
++frequency1;
break;
case 2:
++frequency2;
break;
case 3:
++frequency3;
break;
case 4:
++frequency4;
break;
case 5:
++trequencys;
break;

{cominutt)

14.0

CAPITOLO 5

6:
++f requency6;

break ;.
}
}

Nella Figubl. 5.9 m0.sr:fato t',miliizZ<;> della. fum.iqne srand. Nel prqgrarnma utilizziamo il tip0 di dar un s i g'ned.1 cli unabbrevaz.io1tpe.r un s i gned i nt. uni nt immagazzim1:r in. alm:c.no d!:! byre di tncmJia e pu wntenere valori. posicivi e n.ega:vi. Aoche
una v.liabil cli rip n signd iftu:RagaZizina.ra in almn due byte di memoria. Un
unsigned i nt di l.ue byte pu conrenere s0lcanc0 valori posit ivi compresi nell' inte.r:vallo
da O a 6B5~5. Un uns ~g n_ed i nt di quattro byre pu avere solo valori posiii:vi omprnsi
ne!l'int<;.FVailo da O ;i 4294~6729?. La funzion:e -srand ac.Get:ta come ai:goa:reuro Ufl v;tlqre
1,m ~igned . La ~peci-fca di <::QnVsine \u uriliz?-ata p:e.r Ie;gg~e uo yafo.re. unsgned c0n
la fi.uni0n scanf. TI prQ.to-i;ip,o di funzione pers r and si, trova in. <.s tdlib . h>.

printf ( "%S%13.s \ n", " Face:'' , ' F-reqy,en'.~Y" J;


pr.intf("
1%13.d .\n ff ~ fre<Juency1);
pr)..ntf ( '
2%13d \ n ff , frequen.cy :n;
printf("
3%13.d\n ''., f-requnc'y3);
printrf ("
<t%qd\n", frequeh.c y4);
prir.ltf ( p
!:!.%13d \ n 10 , trequencys};
printf('
.o %13d\n" , tre.quency6);
re.t urn 0;
1

aat
9.6~

Qualora volessimo randoIIJ..izzan: senza la necessita di imrnetwre un se.me qgni volta


porremmo milizz;_rre un'i:sm.izi,ooe c:ome:

10~.

9;74.

11004

11/l~

Figura 5.8

Eseguiamo diverse volre il programma e analizziam9 i risulrari.. o~srv~e cilie ~i ott~r


r una sequem.a diversa di numer.I casual i ogni volta clie iJ pr<'lgramma sa4 eseguito,
pucch ve.i;lg;i fornito un seme diffe~enre.

Fre<111ie.n ifl~

1
:2

srand(tme(NULL));

Landare 6000 vo!t un dado a si fa~c.

Riducendo in scala e rraskn.d:0 l 'i:nte.rvalfo, c;o!Jle mustra l'putput del programma, al;>bi_wie. miliz.t(lro la :fu4tjon~ ran.d p~r s:mula.te re;ilisricamente il lanci9 di un chdq 3 sei
facc~. Qsifetv.ar th' nojl 'Staro fO.miro itessim GL,s~:r ru d~faul t ueJ.ia strattu111 SWtCh.
Osseiyate anche J' urilia.o della sp:ecifka di cnvei:si0ne %s per virualizza.Ee le stringhi: cli
carneri " face ~ e 11 Frequency 11 ~<.mi~ ihresraz.ioni di ctilenna. Dopo aver midiatO. i vettori nd Capitolo 6, mostreremo come sostituire elegantemente l'i'nrera srmrrura swtch
9J1 1,1n'i$~z.ine di una ~9J~ riga.

&eguendo nubv.amem:e i:! programma de.Ila Figura 5.7 si produrr

4
'3
1

2<

5
!ii

141

in g\:lrgo rm1d01ni~o11ce (da. random, a caso) c;;d ~ ($eguira. con la. funzione s rand della
l_ib.r:eri~ St:).,0<4fd. La funzio ne. s rand ricey~ uri rg6meur0 inrcro uns i gned e /11jemi1:1a la
fumone r and, in modo da indurla a generare una diversa s:cqutnza di numeri casuali ad
ogni c:Secuzifle del p.rgramma.

crn~e

~~

l.F. FUNZ.ION)

'5

5
'5
2

f$.q
j

Ql,lesta in:durre.bbe Uocnputer a leggere il su9 orologio interno _r;i.er ottenere a:uro.m.acic;;amnr n v~lor~ per i.I seme. La fon.tlone time restituisc~ l'om cqm;nte clej giorno e:Spn~ss.
in sec.oodL Qu~sro valer!;: sa.r. colivefcim. in uo ~m li.cii:z;t segn e uri.lizzato d>i:i:l: seme
per il generatore cU numeri casuali. La funzitme t me riceve.. come argomento NULL
(nor.tti.iil.mnr.e t ime :i1 gra:do di forci:r al prdgrammarme un. s:rr.inga &e rai:prese.nra
l'ora .del giorno; iJ NULL dsabilirn appunro quc:;sra capacii per una chiamata speoifca di
time). Il premripo di fwl1..ione per time iu <time . h>.
!* Randomz_a re i l pr.0g P.amma .di lan.e io del dado *I
#.inclu.de <stdlib. h>

#J ncJ, ude <'St di9 . h>


ma:in ()

Osservacc che srara visuaJizza~a la sressa sequenza d i valmi. C:ome JlOSsibile che siano
dci numeri casuali? i ronicamente, 'iuesra riprod ucibili& essenziale per cfunostrare che le
:;o uezioni ~ un prngramma fW12i0nano apprnp.ri.arame.nre:

La fu.nzi.oo rand ,gofa in rl.Lt dei mlmeri pseudottasuati. Rid1un:i.ndc;uipemtamenrn


ra:nd> s prodmrebbe utia sequen7.a, di numeri che sembra essere Gasuale; 1n realt; la
sequenza si ripeE~~:c- ogni volra che il programma sar. eseguiro. Una volra che il programma
~a,.r. stato eompletarneate m ~o a p,untQ, pot r eS.~e1e cond.iz.ionaro in_m0cl0 ~ produrr:
,una sequenza diver~ di m.J..01C<ti c<I,SQ.al.i a5'\ ogni sua eseeut.iohe~ Qw~ca op.raZione der:ra:

int

i j

unsi~ned

s'eed ;

printf(" Enter seed: ")i


scanf( ''%u 1' , &S"eed);
$r and.(seed);
for:: (i = I i i <= i 0 i i++) {
pr.inti("%1 0d'1 , 1 -~ (r~nd()

==

f ( % 5
0}
pr-i!lt f( 11 \ n".) i.

% e))i

143

lA-2

facce r1olr:e. ve.i-so l'al'io. Nel e.oso "'4 sorttrtUJ. fos.se 7 o 11 4/ primo tiro, iL gi.ocittre avrebhe
uinto.. Nel Cll$O che lr.i. sommafass.e 2, .3 il 12 iii primo tfro {detta "crtips"), il giocatore avrebbe
pmo. (ovvurosia tt.vreb'be vinto il "banco"): Nit ctt.so fa somma fosse 4, 5. 6; 8, 9~ o 1 (:) -a l
pdrno t:o, 11l/~m quelf.a s.011V!17fl div1J1iterebbeit punteggio" dci giocatore. Per vincere, si deve
i;oirtirr u.ai-e a Ultzciare i d4di ftno 11 '.'attrentie ii vostro pimuggi_q ''. 11 giocar:ore pmlerebbe

return 0;
}

,
[ s

Etit~ ,geti:

fP1

"

:3.

6111~~1" ~e,a:

1
1

\ tf2

.4

_2-,

4,

.Eh)~ ,dea~ 6V

6
6

<~:

Figura 5.9

! valop

6:

-3

4
2

Rndomizirii programma di lancio del dado.

prodotti cl.ir.et:t~ente da rand s,ono sepiptt Col.llp~esi ndl'incervallo:

0 = rnd ( )

= RAND""""MAX

fn p.rec;etl!'.!-nta abbiam9 mo,sp:ato ~ome srivece una singola. i'struzon~ C p.er simulare il
tap:cio d.i J.J n dad0. <t si fac,c~:
tace = 1 .r rand() %. 6j

Q~~l:;l ismii9ne.4~egne~ alla v.arabilface sempre un val.ore intrn (:Scelto a a:so) 'C'.oi:n,pres.b
nell'.inr&-vallo 1 = face = 6. Osservate .che l'mpierut. di qnest lrirervallo, in alue piol la
qillmci.ffi dj inreci consecucivi oompresi nello sresso, sar 6 e d1e il numero di pan:em..a sar 1.
Facndo riferi.mente all'.istn.1.zione pn~cedente, nornre.m.o che l'arnpiema dell'imervall0 S,ar gererminata da:l valore u~to pt;l ri9urrela sca:la rand cqn l'oper:irore moduJo (owerosia-(i), e
che il num~ro. di part~ dcltn.tervallq sar guale a quello eh~ sar stato aggiunta ~ rand ' 6
(pvvergsia 1). Possimo ~cneralizi.ate' ~tiesto tisul.tato ~me segue-:

n =oa + r.and()
dove a ~r~

%b;

il valore di tri/~on (di sa..r uguale.al primo numero d,ell'intervallo d nreri

q11{l(r(I r:eajrR:-Zf!Sse .i~rJ. 7 prim.tt /i o"tft)1er il pri,J?rio pu.nte-ggi..

11 prngpunrna nella F~ura 5,.1.0 simuler il sudderm gioco di dadi. La Figum. 5 .11 mostra
di"1ers~ es~ioni

di

es~mpi .

Osse!'Vat clie .il gioQi:rf.e cl:v-r~ lanciare due dadi con il primo lancio e d.ovr far.e
altreu:anro pi nirdi. con quelli su.cc~siv.i . Definiremo Wl.a fum:ione rollDice pe.r Lanciare
i dadi e calcolare e visualizza.re !almo soJil.Jila. La funzione ro11D.ce sar de6.nica urra sola
volta, ma sar invocata .in ciu pumi del .,pr!;)gram:ma. interessante norare eh.e rollDi.ce
nm dever argontend ~ che. perci abbi.a.mo indkam void nella sua l.is.ta dj paramcrri La
funzi one rollDice rescicwr la sorti ma dei d.l.te dadi, pcu;cib nell'itu~r:io.b.e de.Ba funiio1,ie sat iridica.to un tipo di rirorn int.

n gioco ctbbasumza complicaro. li giocato.re porr vi_nere o :Pet~r con il primo


lancio, oppure potr vincere o perdere q:m qgnu.no di quelli s.vccessi,.,i. La. variabH~ g~mestatus
stani w:lizzara proprio pej: mmen:ere traccia di curo ci.
Quando il gi([l~Q sar sr~ro vinro, al primo lan<eio o a quelli successivi, gameStatus
sar i.qiposta.ra a l. Quando iJ giqco sa.d. stato perso, al primo lancio I) a quelli. succ;essivi,
gamestatus sar~ .imp0sr.ar:i..- a. 2. ln nmi. gli al!ri c;tsi gam~St_a~us varr zcr.o e il giocq
dovr c.ndnuare.
I* Crap-s ii I
#'include <s td'io. li;?#'i n.clude <stdlib. h>..
#in cl.ud.e <t "ime. h>
int roHD.ice(void) i

main ()
{

t:Ohsecucivi desiderato); ,mentre b sar il faccore di scala (che .sar ugual.e all.a amf>i~z
deU' inrervaJ.lo di interi consecutivi desiderato). NegJi esercizi, vedrem0 che sar possibile
sce&llere degli inceri -a i;:aso provenienti da insiemi di valori diversi dagli intervalli di inceri

i nt gamStatu.s , sum, myPoint;

c0nsec.utivi.

sum

I* primo lancio del dado

switcf1 (-sum) {
case 1 :. case, 11:
gamest-.;itus = i ;

/~ v~nce

Errofe tip.ifo. 5.. I 2

Util.zZttre srandir.zvece.di rand per t,ene1iare dei numeri casuali.

5. 1O Esempio: un gioco d'azzardo


Uno dei gi~li d':tl.!za.ajg pr p9p94i.ri qndlo dei d;i.di conosi_u.ro com "mps"" (tiro sfumu:i;it9), che:-& gioc;a~o 1,1ei ca:s.in .e 11~i 'ricali d tlllt U riind$. Le regol d:.l giofo sono semplici:

Un giocatore iaricia due dadi. Ogni-dado ha seifire, 'QJ,estefm-c.ontengono 1~ 2, ~?. 4, 5


e 6,puntini. Dopo che i tfn,di si Sflr.i1n;1 formati, sicakoLrlf, !:a somma dei ptifltinJ !tf/le'!/{{e

sranl(tilile(NUH))i
= roliDi ();

br.eak;
ease 2: ease 3 :. case 12:
2I
gameStatus
break;
default:
9.ameStatus = 0;
rny.Point = sum;

i< J

al prlmo l ancio */

/'* perd.e a.1 prlrn

/* memorfzza

lanc io * /

i l punteggi

1'

i
(continua)

144

CAJ>ITOLO

printf("Point is \d\ n '', myPoint);


break;

while (gamestatus == 0) {
sum = rollDice();
if (sum == myPoint)
gameStatus = 1;
else
if (s um == 7)
gameStatus = 2;

v i n~e

145

Player rolled 1 + 3 = 4
Point is 4
Player rolled 1 + 4 = 5
Player roll ed 5 + 4 = 9
Player rolled 4 + 6 = 10
Playr rolled 6 + 3 = 9
Pla,yer roll ed 1 + 2 = 3
Player t'olled 5 + 2 = 7
P.1ayer loses

I* ntintia a l anciare * /
/*

L E FUNZIONI

ott enendo il punteggi o /

/* perde ott enendo un 7 */

Figura S. I I Esecuzioni d esempio per il gioco dE;li dadi craps.

Dopo il primo lancio, qualora il gioco foss~ fniro, la srrurmra while sarebbe ignorata
perch gameStatus non sarebbe uguale a zero. Il programma proceder con la smmura
if /else che visualizzer "Player wins" se gameStatus varr 1 ~ "Player loses" se
gamestat us varr 2 .

(gameStatus == 1)
pri ntf('Play er wi ns\ n");
el se
pri ntf('Player loses\ n") ;

i f

Dopo iJ primo lancio, qualoJa il gioco 11011 fosse ancora fn ito, sum sarebbe! mem orizzata in myPoi nt. eesecuzione pr.oceder. con la si:rum1ra while perch gameStat us v~m
ancora 0 . Per produr re Wla nuova sum, rolIDice sar invocata ad ogn i irernziooe della
srrurrura while. Qualora sum couispondesse a myPoint, gameStatus sarebbe impostata
a 1 per indicare la vicroria del giocarorc, il comrollo dcll'isrruzione while fallirebbe, la
srrurmra if/else visuali?,Z.erebbe "Player wins" e l'esecuzione tcr.oUnerehbc. Qualora
sum fosse ugu ale a 7, gameStatus sarebbe imposcara a 2 per indicare la sconftca dd
giocacore, il conrrollo dcl while falf oebbe, l'ist ruzione i f I else visualizzerebbe "Player
loses" e l'esecuz.ionc cerminerebbe.

retu r n 0;

int rollDice(void)
{

int die1, die2, workSum;


die1 = 1 + (rand()\ 6 );
die2 = 1 + (rand() \ 6 );
workSum = die1 + die2;
printf("Player rolled %d + %d
return wo r kSum ;

Osservare l'imeressanre srrunura di controllo del programma. Abbiamo ucilizzaro due


funzion i, main e rollDice, e le smmure switch, while, if/ else e delle i f nidificare.
Negli esercizi investigheremo su varie interessanti carattec:isticbe del gioco dei dadi.

%d \n", d1e1 , die2, workSum);

5.1 I Le classi di memoria


Figura S. IO Programma per simulare il gioco dei dadi craps.

Player rolle'd 6+5=11


Player w;i,ns

Player rol.le~ 6 + 6
Player loses

(!(

Player roJ.led
P-0int is 10
Player roll ed
Player roJ.led
Piayer roll ed
Player r oll ed
Player wi ns

4 "' 6

4
6 "I 5
3 + 3
6 + 4
i

12

= 10
6

11
6

10

]
)

N ei Ca:piroli dal 2 al 4, abbiamo utiliuato degli idencifcaro-ri per i nomi di v<1riabile. Gli
attributi cl-elle variabili includono il nome, iJ tipo e iJ valore. In quesco capirolo, ucilizzererno gli idemificatori a.nchc come nomi per le funzioni definite dal.l'urente. In realt, ogni
.idem ificarore in un programma ha anche alui .attributi che in:dudono: la classe cli memoria,

la permam:nza (o durata) in memoria, la vihilit1} e il collegamento.

n e fornisce quamo classi di memoria indica: dal.le Jpecifir:hc di e/asso di menwritt:


auro, register, extern e static. La permanenza in memoria. di un idcmifcarore iJ
period o durante iJ quale quell'idemifcamre esisre in memoria. Alcuni idenci6carori csisrono per un rempo limitato, altri sono creati e djsuurti ~ipemramerue, mentre altri ancora
esiscono duranre l' incera esecL1zione del programma. La visibilit d i un identificatore il
punto deJ programma in cui si pu far riferimento atridemifcarore. Si porr far riferimen
co ad alcuni idencificatori in turco il programn1a, rnnm: ad alrri ~i porr farJo solo da
determinate porzioni del programma. Per Wl progr.itrii:fla farmaco da diversi file sorgcnre,
un argomento che tratteremo nel Capitolo 14, il collegamento di un idencificarore deccrmi.na se un iden rificarorc sia noro solo in quello corrente o in qualsiasi altro file sorgen te che

146

CAPITOLO 5

LEFUNZIONr

147

abbia le dichiarazioni app ropriare. Quesra sezione discucer delle quamo classi di memoria e della permanenza all'incemo della sressa. La .S~one 5.12 cUscu1em invece della visibilit degli idenrificacori. Il Capicolo 141 ''Argnienri avanzac:i", affronrer i cemi el collegamenro dell'idencifcacore e de11a programmazione con cUversi file sorgence.

il compilatore pu ignorare le d ichiarazioni register. Per esempio, porrebbe non


esserci un numero sufficienre di regimi d isponibili all'urilizzo del compilacore. la dichiarazione segueme suggerisce che la variabile. inrera counte r sia sisremaca in uno dei registri
del computer e inizializza.ca a 1:

Le quarrro specifiche ili classe di memoria: possono essere suddivise in due cipi di
permanenza: la permanenza automatica in memorid e la permanenza statica in memoria. Le
parole chiave. auto e register sono uriliuare per dichiarare variabili con permanenza
automatica in memoria. Le variabili con permanenza auromacica nella memoria saranno
creare ogniqualvolta si entrer nel blocco in cui sono scate dichiarate, esisteranno finch
quello rester attivo e saranno distrutte quando si uscir chilo stesso-

register int counter = 1 ;

Solo le variabili possono avere uua permanerrLa au.romarica ncJla memoria. Le


variabili l.ocali di una funz io ne (quelle d ichiarate nella lisca. d ei parametri o nel corpo
d ella funzione) hanno normalrnenre u na permanem..a aumrnarica nella memoria. La
parola chiave auto d k hiarer. espUcitamente delle v~Tia~ ili con perma nenza automac.ica nella memoria. Per esemp io, la seguente dihi;u~z ione ind ica c he float x e y
sara nno delle variabili locali auro mariche e che esisrera:nno solo nel corpo della funzione in cui comparir la d ichfarazione:
auto float x, y;
Le vciabili locali hanno per default uli peananenia auromacica nella memoria, perci la parola chiave auto sar ucilizzara raramenrc. Per il resro del resro, ci riferiremo alle
variabili con uaa permanenza automacica nella. memoria chla.ma.ndole semplicemente va.ciabili automatiche.

Obiettivo efficienza 5. 1
La memorizzAzione au:romatica un mezzo_per rispam1iare la memoria, poich le 11ariabili automatiche esisteranno solo fintanto che saranno necessarie. Esse saranno create qtumdo si entrer nella fonzione in cui sonQ !tllte dichiarate e mr11.1mo di.strutte quando
si t1scir1 da/In stessa.

Ingegneria del softwme 5. l O


La memorizzazione automatica~ u.n &empio del pPincipi() deL minimo P"ivilcgio (ad ogni
istante un utenre o un processo deve averetutri e solo i d i.ritti necessari per proseguire la ompurazione). Per qrtqle fnotivq)e wtiUil;ili dc111rebbe10 essere conserva.te in

memoria ed essere accessibili q1/.ando, d fatto,

7{011 sd:no

neces.silrie?

1 d ari per i calcoli e le alrre el.ahorazii;mi, n,ella. verione in linguaggio macchina d i un


programma, sono caricaci normaimerue nei :registri.

Obiettivo efficienza 5.2


La specifica di classe di memoria registerpotr essere inserita prima della dichiamzione di una variabile 11momtaic11, per suggerire 11L compilawre di conservttre la variabile in 11110 dei registri hard1u11re ad 11lt1111e/()cit detcomputer. Qualbm k variabili utilizznt~
i11tens11mmte, come i conttttori o i totali, potessero essere mantermte nei registri hardware,
potrebbe essere e/;mi1111to il costo ripetuto doV!~to tt1 caricamento deUe variabili dalla memoria
nei regimi e ali'mm11gazzi11ammto dei risultati di nuovo nella memoria.

La parola chiave regster pu essere ucili1.z.ata solo con le variabili con permanenza.
automarica nella memoria.

Obiettivo efficienza 5.3


Spesso le dichiarazioni register non sono neceSS'arie. Le procedure di ottimizzazione
dei compilatori di oggigiorno sono in grado di riconoscere le variabili utilizzare pi
frequentemente e possono decidere di sistemarle nei registri, senza che si renda necessari.a una dichiar11zjone register dD parte d,.L pr(}grtpnmotore.
Le parole chiave extern e static sono urili'l'Za.re per dichiara.re degU idenrifcarori
per variabili e funzioni con una permanenza starica nella memoria. G li identlflcacori con
permanenza statica nella memoria esiscono dal mom.ento in cui il programm.a inizia la sua
esecuzione. Per le variabiJi1 la memoria sac allocata e inizializzata solo una voi ta, quando
il programma in izier la propria esecuzione. Per le funzioni, il nome della funzione esister
sin dal momento in cui il programma inizier la propria esecuzione. Tuttavia, sebbene le
v ariabili e i nomi delle funzioni esisrano sin dall'inizio deU' esecuzione del programma, ci
non significa che quesri idenrifcacori possano essere utilizzaci in tutto il programma. La
permanenza nella memoria e la visibilit (in quali pu.nci del programma pu essere ucili1,zaco UJLilorru:) sono cose disti.me, come vedremo nella.Sezione ).12.
Esistono due ti pi di idenci6cacorj con permanenza sracici nella memoria: gli idenrifcacori
esterni (come le variabili e i nomi di funzione globali) e le variabili locali dichiarate con la
specifica di classe di memoria static. Le variabili e i n omi di funzioni globali sono
definiti per default con la classe di memoria extern. Le variabili globali saranno creare,
inserendo le loro d ichlarazioo.i all'esterno di ognj d~niz.iene di funzione e conserveran no
i p ropri valori durante rutta l'esecU?.ione del progra.mcna. Le vari<!bili e le funzion i globali
potranno essere oggetto di riferimemi da parre di qualsiasi funzione, purch questa sia
successiva alle loro dichiarazioni o definizioni all'imm6 deU.le. Q usta u.na delle ragion i per l' ucilizzo dei prorot:ipi d i fonzione. Nel momenro in i;:ui includeremo stdio. h io un
programma che r1ichiami printf, il proCO'cipo della funzione sar sjscemato all'inizio del
nostro file in modo da far conoscere al resto delle stesso il n>me printf.

~ _l~nt~e~-gn_e_r_
itt_d_e_l_wftw~
~a_1~_5_._l_l~~~~~~~~~~~~~~~~~~

Una variabile dichitzrata globale, invece che locale., consentir il verificarsi di ejferti
collaterali indesiderati, qualora tma fimzione che n.on avesse bisogno di accedervi la
modificasse acculentttLmente omaliziosamente. In generale, l'un'/izzo delle variabili glob11li
dovrebbe essere evitato, tranne che in certe situilzjll.n i in cui sitt richiesta 1m'efficienz.a
particolare (CQme sar discusso nel Ctpitolo J.ef).
Buona abimdine 5.1 O

le variabili utilizzate esclusivamente all'interno di una particolarefimzione dovrebbero


essere dichiarate locali a quella, invece che sfertl:e.

148

C'..APJTOLO

Anche le vttriabili loca.Li dichiarare con la parola chiave sta tic saranno note solo alla
funzione in cui sono definire ma, a differ~ di quelle aummaciche, le variabili locali
scariche conserver..i.nno il loro valore anche quando si sar usciti dalla funzione. Alla successiva invocazione della fum.ione, la variabile starica Loele conterr ancora il valore dell'ultima volra che si usciri dalla funzione. I.:isrruzione successiva dichiarer la variabile locale
count di tipo static e la inizializzer a l.
static int count

= 1;

Tune le variabili numeriche con permanenza statica nellii memoria saranno iuizializzare a zero,
qualora non siano state inizializzate esplicitamenre dal programmatore. (Le variabili di tipo
puruatore, di cui crartercmo nel Capitolo 7, saranno invece inizializzate con il valore NULL).
~

Errore tipico 5. 13
Utilizzare diverse specifiche di cfllSse di memoria per rm ident(fie11.1ore. A
aatore pu essere dppiicrtta solo untl specifica di cit1.Jsu di memori.il.

1111

ideutifi-

Le parole riservate extern e static avncnno w'.l significate speciale quando saranJ10
applicate esplicira.mente agli denrifcacorj esterni Nel Capitalo 14, "Argomenti avanzati'',
discuteremo ddl'uri lizzo espliciro di extern e di static con gli i.denrifcacori estern i e i
programmi formaci da molci file sorgente.

5. 12

149

LEE'UNZlON I

del blocco p ii:1 inrerno. Ci sign ifica che, durame l'esecuzione del blocco pi interno,

q11est0 vedr il valore dcl suo idcnrifcarore locale e non quello dell'identificatore omonimo
dichiarato nel blocco che lo racchiude. Ancbe le variabili locali dichiarate static hanno
una visibilir nel blocco, sebbene esistano sin dal momemo in cui inizia l'esecuzione dcl
programma. Ne consegue che la permanenza in memoria non inAuisce sulla visbilic di un
idenrifcacore.

Gli unici identificatori con una visibilit neiprototipo dijimziv11r sono quelli milizzaci
nella lisi.a dci parametri inclusa in un prorocipo di funzione. Come meoziomno in precedenza, i protoripi di funzione non richiedono dci nomi nella lisra dci parametri: solo i cipi
sono obbligatori. compilarore ignorer ogni nome incluso nella lisca dei parametri di un
prototipo di funzione. Gl i idencifcatori u.rilii:Larl in un prorotipo di funzione potranno
essere riutilizz~.ti altrove nel programm:~, senza generare ddfo ambiguic.

En-ore tipico 5. 14
.Urare accidentalmente, in m1 bloccopit. i,nJm;.o, lt; sttsso rt.MU! di rm identiflc11torC<dichiarato irJ iJn bfoG'l:IJ pi. estern q11a/(1ra iL programmato.re volesse, di fatto, che l'identificatore
dei blocco pi esterno tinumesse attivo per tutta la permanenza di quello pi iiitel'~O.
Buonrz abitudine 5. JI
Evitate nomi di wiriabile che nascondano q1Jelii co.11 visibilitlipi esrente. Ci porr essere
ottenuto evitando iremplictmente di utilizzare in un progn1mma degli identificatori duplicati.

Le regole di visibilit

la visjbilit di un identificatore la pan.ione ciel programma in cui quello porr essere


oggetto di riferimenci. Per esempio, quandu in un blocco dichiareremo una variabile locale; questa potr essere oggetco di riferimenti solo all'imemo di quel blocco o di quelli che
vi si an n idano. I quacrro ripi d i visihilir possibili per un idenrificatorc sono:
visibilit nella funzione, visibilit nelfile. visibilit nel blocco e visibilit nei prototipo di fimzione.

Le echette (un identifcarore seguito da un due punti, come start: ) sono gli unici
idemiftcatori d1e hanno una visibiljt ne!lafimzione. L~ ericbene porranno essere utilizzare
in qualsiasi parte della funzione in cui compaiono, ma non porranno essere oggetto di
riferimenti escemi al suo corpo. Le ecicherte sono utiliZ7..ate nelle scrutru.re swi tch (per
esempio, quelle dei case) e nelle isrruzioni goto (consultare il Capitolo 14, "Argomenti
avanzaci"). Le etichette sono dei dettagli di implem~tazione che le funzioni si nascondono
f unacon l'alrra. Questo oculramenw, duo p i formalnu;nte inapstdizmm~o delle injmur:doni,
uno d ei pri ncipi fondamenrali dl una buona ing~\l~a del sofrware.
Un jde11tificacore dichiarato all'esterno di qualsiasi fum.ione ha una visibilit nei file.
Un tale identif.cacore sar "noto" in tutte le funzioni incluse.fia il punto in cui quello stato
dichiarato e la fne de.I fc. Le variabili global , l~ defmizioni e l prototipi di ru rn.io ne
inseri all'esterno di una funzione hanno run;i visibili nJ file.
Gli idenrifcacori dichiaraci all'inremo di un blocco hanno una visibilit nei blocco. La
visibilit nel blocco termina con la paremesi graffa
di chiusW'a dello stesso. Avranno
quindi visibilic nel blocco le variabili locali che sono scace dichiarate aU' inizio di una
funzione, come pure i suoi parametri, che quella considera alla scregua di variabili locali.
Qualsiasi blocco porr conrenere delle dichiaraiiru di variabili. Qualora i blocchi fossero
nidificaci e un ideot:ifcacore di quello pi esterno avesse lo stesso nome di un identificatore
di quello pi mreroo, l'idcntificarore di quello pi esterno sarebbe "nascosco" fino all:l fine

0)

11 programma della Figura 5.12 illustra i problemi di visibilit relativi alle variabili
globali, alle aJ.LLomaciche locali e a quelle loc.w stati~ . stara dichiarata e inizializzata a l
una variabile globale x . Quesca sa.r nascosta in ogru biodo (o funzione) in cui ne sar stam
dichiarata una, locale, chiamata X. Nella funzione main, Stata dichiarata e miziali'l..Zara a
5 una variabile lo<.-ale x. Questa sar quindi visualizzao per dirn9strare che all' inremo di
main la variabile globale x nascosra. t srato quindi defin ito un nuovo blocco all' incerno di
m~in con un'altra variabile locale x inizial izzata a 7. Questa variabile sar visualizzata per
dimostrare che nasconde la x dichiama nel blocco pi scerno d1 main. La vadabile x coo
il v.alore 7 sar distrutta aucomaricameme all'uscita dal blm:co, menrre la variabiJe locale x
dichiarara jn quello pi esrerno di main sar visualizzata 11U.Ovameme per djmosLrarc che
non pi nascosta. li p rogramma defin isce rrc funzioni che noo richiedono argomenri, n
restiruiscon.o dei risultaci. La fUJizione a dichiarer w1a variabile am9mat:ica x e la iniziali1.1.er
a 25. Quando a sar stara invocata la variabile sar visuaJiZZ1tta, incrementata e visualizzata
nuovamente, p rima dell' uscita dalla funzione. Ogni vilrn che qtJ.e.sta fu11ii9 11e sru: scaca
uwocata Ja va,riabile automa.n X S<'lr in,ii'.iaJ iz~ttll nuovamente a.25. La fumio ne b dichiater~ una variabile static x e b i11izialiZ'ler a 50~ Le variabili locali dichiarate s t atic
couservano i loro valori anche quando sono al di fuori della propria visibilit. Quando b
sat stata invocara X sar visualizzarn, incremcnrara e visualiu.ata nuovamente prima delr uscira dalla funzione. Nell 'invocazione successiva d i g uesm funzione la variabile loc;e
static x conterr ancora il valore 51. La firnzione e non dichiarer alcuna variabile. D i
conseguenza, quando far rifcrimenro a x sar utiJizzaca la variabile. globale. Quando e sar
stara invocarn la variabile globale sar visuafo.zara, moltiplicara per 1 O e stampata ouovamnte prima dell' uscita dal la funzione. L"l prossima volta che la fun7.ione e sar srata
invocata la variabile globale conterr ancora il suo valre modifcaco: 10. lnfLnc, il programma visualli.zer ancora una volta la variabile locale x dichiarata nel main, per dimo-

150

CAPrTOLO

sa:are che nessuna delle funzioni chiamate ne avr modifGaro il valore, poich rum: loro
hanno farro riferimento a variabili con alu:e visibilit.

_LE FUNZIONI
static int x
avviene solo * /

#include <stdio.h>

int

printf( "local static x is %don exiting b\n ", x);

,.,.

I* prototipo di funzione */
prototipo di funzion e *I
prototipo di funzione *I

void c(void)
{

printf( \nglobal x i s !\sd on ente r ing c\n" 1 x);


X*-= 10;

main ()

printf("global x is %d on exiting

int

= 5;

/* variabi l e l ocale rna ln */

t incomincia una nuova visibilit /

int

= 7;

printf("loal

in inner scope

Of

main is %d\n",

a();
/ *a ha una variabile x locale automatica*/
b();
/* b ha una variabile x locale statica*/
c();
/ *e usa la variabile x globale*/
a ();
/* a inzia!lzza la variabile x locale automatica */
b();
/* la variaole x locale statica conserva il suo
valore precedente */
c ();
/ * anche la variabile x globale conserva i l suo valore
precedente */
printf ( "local x i n ma.in is %d\n", x);
r etu rn 0;
void a(void)
int x

= 25;

1~

inizializzata ogni volta che a chiamata */

++x;
printf("local x in a is %d before exiting a\n " , x);
void b(void)

X
X

loC'ai

in euter ~ cop~ !'J'f main i'S 5


;i:n inner scope or m~tin is 7
in outer scope of m~~n is 5

local static x is 50 on ente~ing b


local static x is 51 on exiting b
global
global
loeal
lo e al

r;in entering e
10 on exi ting e

X l.S 1
)( l.S

X
)(.

in a :l.s 25 after entering a


in a is 26 before exitil'lll a

local stati e )( j.s 51 on enter.J.ng Q


local static x .iis 52 on ex:i.ting b
globa1 X ;i...S j'0 on J'lt~ring e
g,;t.obal x is 1e0 on e~UJi'lf;I e

lQbal x in

m~i~

1s

Figura 5. 12 Un esempio di visibilit.

printf("\nlocal x in a is %d after entering a\n', x);


}

local
Loca!

X);

printf("local x in outer scope of main s %d\n ", x);

x);

loca! X io a is 25 after entering a


locai x in a is 26 before exj.ting a

/* fine della nuova visibilit */

c\n ~,

printf("local x in outer scope f main i %d\n", x);

/* l ' inizializzazi.one della variabile statica

++x;

I* variabile globale */

1;

= 50;

/ * la prima volta che b chiamata */


printf( "\ nlocal static x is %don entering b\n " , x);

I* Un esempio di visibilit */
void a(void);
void b(void);
void c ( void) ;

151

5.13 La ricorsione
I programmj dj cui abbiamo discusso sono generalmeiue.strum.i.rari comefuru.ioni che s.i chiamano l'una con l'alrro in modo disciplinato e gerarch.ico. Per alcuni tipi di problemi sar invece utile
avere delle funzioni che richiamino se stesse. Una fimzione ri..corfiva wia funzione che richiama se
stessa direuamente o indirccramcnre attraverso un'alaa funzione. La ricorsione un argomento
c9mplesso discusso a lungo nei corsi superiori di informatica. ln quesra sezione e nella prossima,
saranno presenrati dci semplici esempi di ricocsione. Q"1esro Libro contiene una cliscussionc csrcsa
ddla ricorsione diStribuha nei Capiroli dal 5 al 12. La Figura 5.17 riassume i-31 esempi ed esercizi
sulla ricorsione presenti in quesoo libro.lo primo luogo considereremo la ricorsione dal punto

152

CAPITOLO

considereremo la rioorsione dal punro di visca concenuale e quindi esamineremo diversi


programmi conrenenti delle funzioni ricorsive. Gli approcci ricorsivi alla soluzione dei
problemi hanno un certo numero di elementi in comw1c. Una funzio ne ricorsiva sat
invocata per risolvere un problema. La funzion in realt sa come risolvere soltanto i casi
p.it1 semplici, ovverosia i cosiddcrd casi di basi?. Nel i::sU che la fu n1J0ne veng'd invocaca su
un caso di base, resrimir dirertamenre trn cisulcaco. N.el caso invece che la funzione venga
invocata su Llil problema pii1 complesso, lo suddivider in due patti concerruali: una che la
funzione sa come risolvere e un'al tra che invece non sa come risolvere. Per rendere fattibile
la ricorsione, la seconda parre del problema dovr assomigliare a quello originale, ma
dovr anche essere una versione leggermente pi semplice o pi piccola dello stesso. Daro
che questo nuovo problema assomiglier a quello originale, la funzione lancer (invocherlt)
una nuova copia di se stessa perch Lwori sul problema pi piccolo: questa appuruo ci
che viene defnira chiamata rfrorsilld o an che passo ricorsivo. Il passo ricorsivo includer
anche la parola chiave r~tu rn perch il suo J:isul,raco sar tombinaco con la po.rz.ione del problerna cht! la 6.inrione sa c.bme risolvere, in modo da 'formare il dstdcaro eh.e sar finalmente
restin1ito al chiamante originale, probabilmente i1 maiTI.

TI passo _ricorsivo sar eseguito fnca.nco che la chiamata originaria della funzione sar
ancora aperta, ovvc;rosia non avr ancor terminato la sua esecuzione. Il passo ricorsivo
potr generare moire altre chiamare ricorsive si:mili, man mano che continuer a suddividere nelle <lue pa:rci concettuali ognuno dei problemi su cui scato invocaro. PeJch la
corsione possa lnalmence. terminare, ogni volca che la .funzione richiamer se sressa ron
una versione leggeanente pi semplice del problema originale, questa successione di problemi sempre p i pjc-qli dovr convergere alla fine; ad un caso di base. A quel punto, la
funzione riconosceclL il casq dj base, rcscimir un cisult;tro alla ~ua cop41. p.recedeme e ne
conscguir-. una s~quenza cli resciruzioni lungo tutfa la catena di chiamate, finch quella
della fu nzione originaria non rescicuir. fnalmefn:e al main il risultato fi nale. Tutto ci
sembra alquamo esotico se confrontato con il ripo di risoluzione convenzionale~ problemi cui siamo sciri abituaci fino a qiJesto punto. Scrivere dei programmi ricorsivi, richieder cerramence una buona dose di pratica, prima che il processo appaia na.m.rale. Come
esempio di funziona.me.mo di questi concetti, sriveremo un programma ricorsivo che
eseguir un tipico calcolo matemacico.

153

UFUNZIONI

Per esempio, 5! sar chiacamemc uguale a 5 4!, come dimosrraco di seguita:

5! = 5 . 4 . 3 . 2 . 1
5! = 5 . (4 . 3 . 2 . l )
5! = 5. (4!)

La valut:a7.ione. di .S! proceder nel modo mosn:ato nella Figura 5. L3. La Figura 5.13a
mosrra in che modo la successione delle chiamare ricorsive proceder fiacb l ! sar.. valucaro 1 e rerminer la ricmsione. La Figura 5.13b mostra i valori resriruiri da ogni clllamaca
ricorsiva al suo cb iamanre finch sar staro calcolato e restiruiro il valore finale.

il programma della Figrua 5 .14 u ciLlz.zc.r la ricorsione, per calcola.re e visualizzare il


fatto riale degli inceri compresi era O a 10 (la scclrn del cipo di daro long sar. spie.gara rra
breve). La fi.mzione ricorsiv factorial conrroller in primo luogo se una delle con.dizio.ni
di ceroii n~izio nesia vera, ovverosia se number sia infotiore o uguale n l. N'el caso cbe number
sia sicun~meme minore o uguale a 1, f actorial resciruir: 1, non saranno necessacie al.rre
[icotsioni e il programma tetmined1. Nel caso che number sia maggiore di l , l'ism.1.zi:.one
return number

* f actorial(number - 1);

esprimer:\ il problema corne il prodotto tra number e un.a chiamata ricorsiva di fac1;orial
che valucec il farror iale di number - 1. Osservare che factorial ( number - 1) s~ un
problema lcggermeore pi semplice del calcolo originale facto r i al ( number }.
Valore finale

5! = 5 24 = 120': valore rest ituito

5
4! = 4

3!

Si orten un.<J. dfnizione ricorsiva della funzi0ne Hmorial.e, osservando la segunre


relazione:

n! =n (n -1)!

= 3 .. 2 = 6: valore rest1tu1to
2! = 2 I = 2: valore restituito

con ll uguale~ J e Q! ddniro uguale a l. Per esempio., 5! sar~ il prodrto 5 * 4"' 3 * 2"' l,
che sar uguale a 1..20.

factorial = 1;
for (counter = number; counter >= 1; c'ounte r -)
factorial *= count erj

= 24: valore restituito

l) (n -2)" ... . 1

n farroriale di un intero, number, maggiore o uguale a zero, porr essere ~!colato


itenmvamente (non i.runodo ricorsivo) urilizzando la srruttura fo r come segue:

*6

ll farroriale di un intero non negativo n, scrirrq n! (e proounciaro "fattoriale di n"), il


prodorto
il, (n -

= 120

I: valore restituito

a) successione delle chiamate

b) valori restituit i a ogni chiamata ricorsive

Figura 5. 13 Valutazione ricorsiva di 5!

La funzione factorial sraca dichiarara in modo da ricevere un paramerro di tipo


long e resti tuire W1 risultato ddlo stesso tipo. Q uesta una notazione abbreviata per
long int . Lo standard WSI specifica che una variabile di tipo long int debba essere
mmagazznaca in almeno quarrro byte e, di conseguenza, che possa conrencre un valore
g[ande quanro +2147483647. Come si pu vedere dal.la.Figura S.14, i valori del furro riale

154

CAPITOLO

diventano rapidamente grandi. Abbiamo scelco il tipo di daco lo ng proprio perd1 il


programma possa calcolare dei farcoriaJj mag.gioci di 7! anche su compucer con interi
piccoli (come quelli da 2 byte). La specifica dico!1Versi<;me !lsl d stata utilizzata per visuafrr.z.are
dei valori di tipo long. Sforrunacamente, la funzione f acto rial produrr dei valori grandi cos velocemente che anche un l ong in t non ci aiuter a visualizzare molri vafori
farrociaJi, prima che sia superar la dimensione di una variabile di quel tipo.
Jn definitiva. come esamineremo negli ~ercizi, aJJ'ucente che desideri caJcolare i farroriali
di numeri pi grandi porranno essere necessari clej float e dei doubl e . Tuno ci rende
evidente una debole'"aa del
(peralcro comune aJla maggior parce degli altri linguaggi di
programmai.ione), ovverosia il Fano che esso non possa esse.re ampliato con facilit affinch possa gestire i parricolari i;equistri delle vari.e applic:iz.oni. li C++ invece un linguaggio che si pu estendere e che quindi, qualora lo volessimo1 ci consentuebbe di creare
degli inceri arbimuiameme gran di.

1!

=1

2!

2
6

~!

4!
24
-5 ! = 120
6!
720
7 1 : 5040
40320
8!
9! = 3628l!0
~01 = 3628800
~

Figura 5.1 4 Calcolare i fattoriali con una funzione rico r,;iva.

Erro1'e tipico 5. I 5

5. 14 Esempio di utilizzo della ricorsione:


la serie di Fibonacci

Dimenticare di restituire ~n valore da un funZion ricorsiva, qualora sia nqcessario.

La s.ccie di Fibonacci

o,

Errore tipico 5.16

Omettere ttt1 caso di base oscrivere scortettamnte ilptis.ro di ricorsione 71 modo tale che
non converga ad un caso di base provoche-4.delle ricorsioni infinite, finendo per euwrire la memoria. Ci analogo al problema del ddo infinito di una soluzione iterativa
(non ricorsiva). Una ricursione infinita potr. essereprovocata anche fornendo zm input
inatteso.

l, 1, 2, 3,

s. 8, 13, 2 1, ...

comincia con O e 1 e gode della propriet ch ogni sus_seguenre numero di Fibonacci la

somma dci due che lo precedono.


La serie ba dei risconrri in vari fenomeni naru.rali e descrive in parcolare una forma
di spir;i.lc. il rapporco era i ou.meri consecutivi di Fibonacci converge verso il valore cosrance di 1,618 .... Anche questo numero ha ripecmi riscontri in narura ed staro ddnico

rapporto aureo o divina proporzione.

/* Funzione fattoriale ricorsiva /


#include <stdio.h>

Gli esseri umani banno la cendcnza a considerare la divina proporzione piacevole: dal punro
di visra esreco. Gli archiceni progena.no spe5so finescre, sranze e palazzi le cui lunghezze e
alrezze sono in un rapporto pari alla divina proporzione. Anche le canoline poscali sono
disegnare spesso con un rapporto lunghexz.a/largberia pari alla divina proporzione.

long factorial(long);
;

main()

La serie di Fibonacci pu essere dcfinic:a in. modo ricorsi.va come segue:

i nt i;

fibonacci(O) = O

for ( i= 1 ; i<= 10 ; i++)


p ri n tf ( ~%2d l = %ld\n", i, factorial ( i) );

fihona"i(l) = I

I* Definizio ne ricorsiva d e l l a f unzione fattoria l e */


long factorial(long number)
{
i f (number <= 1)

return 1;
else
return (number

fibonacci(n)

=- fibonacci(1i

- J) + j.borzttcci(1i - 2)

il programma della Figura 5.1 S calcoler in modo rirorsivo Pi-esimo nu mern di Fibonacci,
utilizzando la funzione f i bonaoci. Osservare eh~ i n umeri di Fibonacd tendono a diventare grandi rapidamente. Per questo movo abhillll!Q selto il cipo di dato long per iJ

ret ur n 0 ;

155

LEFVN7JONI

* factorial(number -

1));

parametro e: per il valore resricuiro daHa funzion: fibonacci. NeUa Figura


coppia di righe deU'ourpuc mostra un'esecuzione discinta d el programma.

5.15.

ogni

Cinvocazione di fibonac c i da parre di main non una chiamata ricorsiva, mencre lo


cSaranno rua:e le invocazioni successive di f i bonacci. Ogni volra che f i bonacci sar
stara invocaca, essa controller Lmrnediacarnenre il caso di base: n uguale a O o a I . Verrebbe resciruico n se questa condizione dovesse essere vera. fn modo interessante, se n dovesse
essere maggiore di I , il passo della ricorsione gener~bb.e due chiamare ricorsive, ognuna
delle quali sarebbe effettuata per un problema leggen:nenre pi semplice di quello della

156

Ci\l'ITOl.O

L I! ,~UNZI ONI

157

chiamacaoriginaria a fibonacci. LaEigura 5.16 moscraln che modo la funzione fibonacc i


valucer la chiamaca fibonacci(3) : abbiamo semplicemente abbreviato fibonacci in f
per rendere la figura pi leggibile.

Enter an i nteger: 10
Fibonacci(10) = 55

1~ Funzione r icorsiva fibonacci * /


#inc lude <stdio.h>

Enter an integer: 20
Fibonacci (20)
6765

long fibonacci(long};

Enter an integer: 30
Fibonacci(30) = 832040

ma in ()
{

Enter an i nteger: 35
Fieonacci(35) = 9227465

long result , number ;


printf ("Enter a n i ntege r : ");
sc anf(,,%lo"; &number);
result = f i bonacci(number);
printf("Fi bonacoi(%ld) = %ld\ ~ ", numbef, rsult);
return 0;
}

Figura 5. 15 Generare I numeri di Fibonacci in modo rcorsivo.

I restitu isc e

1~ Defi nizione ricorsiva della funzione fibonac ci */


long f ibonacci( long n)

if (n == 0 : I n == 1)
return n;
else
r eturn fibonacci(n - 1) + fibonacci(n . 2);

restituisce

f( 1)

restituisce
1

~~~~'--~1~~~~~~

restituisce
Enter an integer: 0
fibonacci(0) = 0
Enrer an integer :
Fibonacci~1) = 1
Ent"er an integer: 2
Fibonacci (2) = 1
Enter an infeger: 3
Fi6onacci(3) = 2
Ertt~r an intger: 4
Fibonacci(4) = 3

Enter an integer: 5
Fibonaoci(5)
5

Enter an integer: 6
Fibonacci(6) = 8

}'

restit uisce
0

Fig ura 5. 16 Gruppo di chiamate ricorsive alla funz.ione fibonacci.


Questa figura soUeva alcuni inrercssanri problcnii riguardan l'ordine in cui il compilarorc
prnhlnia d.i.fferenre da quello relarivo
all'ordine in <:U gli operatori saranno applicati ai propri o_perandi, ovverosia all'ordine dettato
daile regole di prjocir degli oper.irori. Dalla Figui:a 5.1 6 appare evidenre che nel valurare f ( 3)
~amnno cffccruare due iJwocazi011i ricorsive, owerosia f (2) e f ( 1). Ma in quale ordine saran-

e valuter gli operandj degli operaroti Questo un

oo effettuare queste chiamare? Molti programmatori presumer;tnnosemplicernence che gli ope.randl


&anmno valucici da siu~ma a dcsrra. Stranamente, lo st:.;l:.ldard ANSI non specifica .l'ordine i.n
cui debbano essere valutaci gli operandi dcUa maggior parre degli operamri (lDcluso +). Ne
eonsegue d i.e il programmatore non porr presumere alcundi sull'ordine in cui saranno eseguite le suddette chiamate. lnfarri f(2) porrebbe essere eseguim prima di f(1 ), ma le sres~e
invocazioni porrebbero a11d1e essere eseguire nell'ordine inverso1 f ( 1) prima di f (2). ln questo e nella maggior parce dei programmi il cisulrat('.) s.arJo sre.sso in ogni caso. In alcuni
programmi, invece, la valuraz.ione di un operando porr pr.odurre degli e.ffmi coUacerali che
potrebbero a loro volra influenzare il risultato fnal dell'es2res.sione. Lo srandard ANSl specifica l'ordine di valuw.ione solo per quarrro dei ranci operacori cnc.lusi nel e, vale a dire &&, : :
l'operatore virgola (,) e 7: . l primi rre sono operacori binari e per i loro operandi sar garamica
la valurazione da sinisua a destra. I:ulrimo l'unico operamre cernario del C. Il suo operando
pi a sinisr:ra sar valucaro sempre per primo; qualora i' operando pi a sinistra fosse diverso da

158

CArrrmo 5

zero, seguirebbe la valurazione di quello di mev,o e l'nlci.mo sarebbe ign.orai:o; qualora l'opcrarore pi a sini~rra fosse valumrp zro, segui1ebb(: invece la vaJurazione dcl cerw operando e quello
di meL.ZO sarebbe ignorato.

Errore tipico 5.17


Scrivere dei programmi che dipendano dall'ordine di va/u(ttzine degli operandi di
operatori diversi da &&, ,' ,', 7: e dall'operatQre virgo/11 (, ) pntr pr<)tJOCare degli errori
perch i compilatori p:f}tr{f.nno f)tt/ut11re gli i7peranai 1 un o.rdine Ghe non sar necessariamente quello atteso dal pr.ogrtt.mmatore:
Obiettivo portabilit 5.2
1 p1fJgrammi clu dipendono dall'ordine di valutazione deg/; operandi di <>peratori d-

vmi do &&, / /. 7: e dall'uperaUJre virgola(, ) potranno funzionare in mode diffemz-

te m sistemi ,on compilatori diversi.


doverq~o spendere una parola clj awcrtimenro sui pr0gr-.lmmi r.icorsivi come quello che
abbiamo usaro qui per geneta.re i numeri Fibonacci. Ogni livello di ricorsione della funzione
fibonacci ha un effecco rnddoppiancc sulla quamic.delle invocazioni; in altre parole, il numero delle chiamate ricorsive che saranno eseguire. per Gaicolare lennesimo numero dj Fibonacci
sar dell'ordine 2 11 Ci andr rapidamente fuori controllo. li solo calcolo dd 20 numero di
Fibonacci richieder una quamir di invocazionj dell'ordine di 220, ovverosia circa un milione
di chiamate; calcolare il 30 numero di Fibonacci rid1iedet Wl.1. quanrir di.invoo1zioni dell'ordine di 2~0, ovverosia ua miliardo di chiamare e cos) via. Gli studiosi di informacica si riferiscono a ci~ con l'espressione complessit esponenziale. I problemi di quesra na.rura sono in grado
di morrfeare anche il pi potente dei compurer! I problemi relacivi alla complessit in generale
e a quella: esponenziale in pan:icolare saranno discussi in dettaglio in "Algoritmi e Suurcure
Dari": un corso di livello superiore incluso nel programma di srudi di informatica.

ru

Obiettivo efficienza. ).4


i'

E.vit11te i progntmrni ricorsivi nello stile di fibonacci che produrano una "esplcsione
ponenziaie di invocazioni.

S. I5

Ricorsione e iterazione

Nelle sezipni precedenti, ah!:>iamo studiato due fw:rtioni che possono esser.e facilmenre implementate in molo. dco.rlivo o itrarivo. I 111 questa: sezione <l:nfroare.reno i due approcci e
discuteremo le ragioJli per le quaLi, in situ:v..ioni parriCobri, un programmatore poa scegliere
un approccio piuaosco che l'frro.
I.:irenrz.ione e la ricorsione SQno basate entrambe su una srrucmra di controllo: l'iterazione
urilizza. urra ripc;rizione; la ricorsione utilir.La una selezione. I.:iceraz.ione e la ricorsione richiedono enrramb~ una ripecizione: la prima urilizza e5pliciramonce una struttura di quel ci:po; la
SeGonda: la ottiene invece attra.v:rso ripecute chiamate di funzione. ~ire~orre e la ricoFSione
richledono entrambe un concrollo di terminazione: l'ireraz.ione cermineF quando sar fullimla
condizione di continuazione del ciclo; la ricorsione ~er invece quando sar scato riconOsciuco un aso di ba.~e. I:ic:crazione con una ripecii.ione concrollaca da un conratore e la ricorsione
si approssimeranno graduahnene alla condusione: l'it~one continuer modificare un con-

UFUNZIONI

1 59

racore finch questo assumer w1 ,ralore che far fallirela rondizione di comi rm.az.ione del ciclo;
la ricorsione co.miru.ier: a produl'J:e versioni pi.1 semplici del problema <>rigina.rio finch non
sar stato otte.nuro un caso <li base. Gterazione e la ricorsione potranno CTll.rambe ripercrsi
all'infniro: con .Pirerazione ol:errerilo un ciclo inCnico qualora il relativo conrroll di continuai.ione non diverui mai f.lso; orn:rrenb una ricorsione infnira qualor-a il passo di ricorsione non
riduca ogni vlca il problema in modo da convergere vcrso un caso di base.

La ricorsione ha molti asperri negacivi. Coinvolge riperuramente il mecc.an:ismo, e di conseguenza il pS0, di una invocazione ili funzione. Ci poa esse.re oneroso in termini di tempo
dcl processore e di spazio di .memoria, Ogni chiamara ricorsiva provocher la creazione di
un'alt.ra copia della funzione (in realt so.lo delle sue variabili); ci potr conswnare una considerevole quamic di memoria. L:iterazione invece normalmeme avverr all'iruerno di una funzione, perci sai.- evicaro il peso dovurq alle ripetute chiamare di funzione e all'assegnamenro cli
memoria aggiuntiva. Pertanro perch scegliere la ricorsione?
Ingegneria del software 5.U
Qua/,Jio,si problema che poJ.StJ. essere risolto in modo rkorsivo potr anche essere risolto
in mani.era iterativa (nn ricorsiva). Nomzaimenu l'approcdo ricorsivp sar preferito
a que!lb iteralivo, qualora il primo rispecchi in modo pi naturale ilproblema e produca un programma che sia pi facile da comprendere e col/au,dnre. Un'altra ragione per
scegliere una soluzione ricorsiva che q11ella iterativa potrebbe non essere evidente.
Obiettivo cjfidenzo 5.5
Evit4.te di usare le ricorsioni in situazioni in roi l'efficienza sia zm aspetto critico. Le
chia1nate rfrorsive richiedonu tempo e consumano pi memorin.
Errore tipico 5. 18

Fare in modo che una funzume non rictmiv11 richiami ttccid.entttlmente se stessn in modo
diretto o indire/Jto attraverso un 'altm frmzione.
La maggior parte dei libri di testo sulla programmazione affrancano la ricorsione pi
rardi dj quanro abbiamo fatto in questo libro. Noi crediamo che la ricorsione sia un
argomenro eos1 ricco e complesso che preferibile affrontare al pi presro, disseminando
il resro del libro con degli esempi. La Figura 5.17 riassume per capiroli i 3 1 esempi ed
esercizi di ricorsione presenti in que,ro resto.
Lasciareci ch iudere quesm capirolo con alcune osservazioni che abbiamo formuJaco
r!pcrucamenre n.el corso del libro. Una buona prngecrazione del software imporrante.
Anche l'efficienza imporrance. Sfortunatamcnce, questi obiettivi sono spesso in contra.sro
l'uno con l'aluo. Una buona progettazione del software di imporcanza vitalet per rendere
pi rnaneggev9l lo sviluppo dei sistemi software pi corposi e complessi di cui abbiamo
bisogno. L'efficienza di imp>rtanza virale, per realir,zare i sistemi del fumro che sorroporranno all' h.a.rd.ware delle esigenze di elaborazione sempre maggiori. Quale sar il ruolo delle
fun7..ioni in questa situazione?

Ingegneria del software 5. 13


La suddivrsione dei programmi in funzioni in una maniera ordinata e gerarchica favorir una buona progettitzione del sofaMre, f(la questo ha un prezzo.

160

CAPITOLO

Obietti110 efficienza 5.6


U11 programma eccessivnmente suddiviso in funzioni, 1ispcuo 11 u1w monolitico (ovverosia
in un unico pezzo) che non k abbia, eseguirpotmzialmenJc un gran numero di chiamate di fimzioni e ci consumer il tempo di esecuzione dei processori di un comp11te1:
Tuttavia, i programmi monolitici smmmo tfijficili da programmare, collnud11re, metrere a pm110, mantener11 e far evolvere.
Suddividete quindi il vosrro programma in fun7.ioni con giudiz.io, renendo sempre a
menre il delicato equilibrio tra l'efficienza e la buona progettazione del software.
Capitolo

Esempi ed esercizi di ricorsione

Capitolo 5

r unzine faccoriale
Fu nzione di Fibonac.ci
Massimo cornun divisore
Somma cli due intt'!ri

Capitai.o 6

LE FUNZIONI

161

Esercizi di autovalutazione
5.J

Rispondere a ognuna delle scguemi domande:


a) Un modulo di programma in C una _ _ _ __
b) Una funzione invocaca con una _ _ _ _ _
c) Una variabile che sia nota solo all'inrerno ddJa funzione in cui sma defniLa una
di una funzione chiainata sar ucilizz3la per resdruire a quella
d) Cisuuzione
d1iamancc il valore di una espressione.
sar uciJ izzarn neJrinresraziont! <li una fu nzione. per indie) La parola ehin ve
care che non re.sciruir un valore o che non c:oort:crr dei pnramerrL
di un idcmifc:ttore la pon.i0ne del programma in cui quello pOLr
f) La
essere udliZ?.aro.
g) 1 ere modi per resriruire il controllo da una funzione chiamaca al chiamanre sono
_ _ __ _

e _ _ _ __

consente nl compilatore di verificare j( numero, i dpi e l'or<lJne degli.


h) Un
argomenti passaci a una t'uni.ione.
ucilizzara per generare dei num~rl casuali.
i) La funzione
utilizzata per impqstarell srne ddnumero c.tsunJci, in modo
j) La fonzionc

Moldpliuiooe cli du~ imeci


E levamenro di un inreyo a una po tenza ill cera
Le corri di Hanoi
La fu nzione man rico(siva
Visuali1.zare al contra.ci.o l'input deUa casriera
Visualizzare la ricorsione

da randomizwre un programma.
k) Le specifiche di classe di memotht sono

Somma degli dementi cli an veuore


Visualizzare un vcrrorc
Visualizzare al cona:ari nn venre
Visualizzare al con rrario una scringa
Verificare se una scringa sia palindroma
Valore minimo cli un vettore
O rdinaptento per selcri9ne

una raccomandai.ione rivolra al compilam) La specifica di classe di memoria


tore affinch immagazzini una vana.bile in uno deLJegisrri dcl compucer.
n) Una variabile dichiarata ali'esrerno di qualsiasi bloeco.o funzione una variabile----o) Perch una variabile locale di una funzione possa conservare il proprio valore lra le diverse
cliiamare alla funzione stessa, essa dovr essere dichiarata c9nla specifica di classe di memoria _____

Quickson:
Ricerca lineare
Ricerca binaria
Le orco Regine

Capitolo 7

Atttaversameruo cli un l:ibirinro

Gapitolo 8

Visualizzare al o.ncrari0 una minga immessa dalla ca.~tiern

Cnpitofo 12

lnserimcmo in uful lista concrenara


Eliminazione da una lisra concatenaca
Ricerca in w1a lisra conea(enata
Visualizzare al conccario una Usca concacenaca
lnserimemo in un albero binario
Visita amicipara di un a.Ibero binario
Visira in ordine (simmetrica) cli u11 albero binario

Visica differita di un albero binario


Figura S. 17 Sommario degli esempi e degl esercizi sulla ricorsione presenti in questo testo.

I) Le variabili dichiara ce m un blocco o nella lisra dei parametri di una funzione, sempre che
non sia scaco speci fcalO diversamemc, saranno considerate della classe di memoria

p) Le quacrro possibili visibilit per un idenficaEore sonQ _ _ _ __, ______,

- - --- e-----

q) Un3 fu nzionc che rk hia ma se stessa ia modo direcro o indiretto una fum.ionc - - - - r) Una funzione ric~miva avr cipicnmente due parti: una che fornisca LUl mezzo per cermie l'alrra che esprima il
nare la ricorsione, verificand0 l'occorrenza di un easo

problema con una chiama.ca ri.corsiv<La Lmo leggcrmeme pi semplice di quello dcUa
chiama(;\ originaria.
Per il scgucrtte programma, stablllte la visibilit (nella funzione, nel llc, nel blocco o nd
5.2
procot:ipo di fum.ionc) di ogow10 dci seguenti elemenci.
a) La variabile x nella funzione main.
b) La variabile y in cube.
e) La funzione cube.
d) La funzione main.
e) Il prorocipo di funzione per cube.
f) I:idenrilcarorc y nel prococipo di funzione di cube.
#include <Stdio.h>
int cube(int y);

162

CAPITOL05

LE lUNZlONl

main()
{

163
return 0;

i.nt

else

Xj

li+

for (X= 1; X<= 10; X++)


printf('\G\n', cube(x));

surn(n - 1) ;

d) void f (float a);


float a;

printf( %f, a);

int cube(int y)

return y y ~ y;

e;)

5.3
Scrivere.un p.rogramma checonrrolli se gli esempi di chiamare :i funzioni della libreria mmemacica mosrrati nella Figura 5.2 producano davvero i risultaci mdica.
5.4

5.5

5. 6

E<once l'inrcsca1.ione per ognuna delle seguenti funzioni.


a)' La funzione hypotenuse che riceva due argomenti in virgola mobile:' a doppia precisione,
side1 e side2, e rescituisca un risulraco in virgola moble a doppta precisione.
b) La funone smalle~t che prenda lreinceri, x, y 2, e re.~cicuisca un incero.
e) La funzione instructions cbe non riceva alcun argomento, n rStiluisa un valore.
(Nora: t:tli funzioni wno ucilizzace per visualizzare delle istruzioni per l'urente.).
d) La funzione intToF1oat che prenda un acgameato incero, number, e restuisc:i un risu.haro io virgola mobile.
Fornire il prororipo di funz.ione per ognuna delle seguenti funzioni:
a) Ca funzione descrit~a. neJJ'.Esercizi.o 5.4a.
b) La ftmziooe descdna nell'E.5ercizio 5.4b.
e) La funzione descrirca ncll'Eserciz.io 5.4<.
d) La fum.ione desccina nell' Esercizio 5.4d.
Scrivete una dichiarazione per ognuna delle seguenti variabili:
a) 'Ci mero count i.'.he dovrebbe essere immagazzinato io un registro. 1niiializure count a 0.
b) La variabile in virgola mobile lastVal che devr conservare il proprio valore rra le chia:111ate alla funz.ione in cu.i verr.clefiniro,
c) 1 l:'incero esterno number fa>~l visibilic dovr esse1e limitata al resco del File In cui verr
definito.

5.7
Trovare l'errore in ognuno dei segucnci segmenti cli progr.unma e spiegare come pou~ essere
correcto (consulrace anche l'Esercizio 5.50):
a) int g (void) {
printf("Inside function g\n");
i nt h(\loid) {
printf( "Inside function h\n');
}

b) int sum(int x, int y) {


int result;
resUlt "' x + y;
c) int sum(int n) {
if (n

0)

voi.d prt:luc't (void) {


l:rit !J, b, e, result;
printf('Enter three integers: ")
scanf(\d\d\d , &a , &b, &e);
result =a b e;
printf ( "Result is %d", re5ult);
return result;

Risposte agli esercizi di autovalutazione


5.1

a) Fuicione. b) Chiamaca di fum.ione. e) Variabile locale. d) return. e) void. I) Visibilit. g)


return; o return espressione; o inoonrrando la paremesi graffu di chiusura d una funzione. h)
Prototipo di funzione. i) rand. j) srand. k) auto, register, extern, static. 1) Auromatica. m)
register. n) E~ma, globale. o) static. p) Visibilit ndJa funiione, visibilic nel file, visibilirl1 nel
blocco, vis.bilit n~ p rototipo di fwizi.ne. q) Ricorsiva. r} Di base.

5 .2
a) Yisibilir; nel blocco. b) Visibilir nel blocco. e) Visibilit nel f:lc. <l) Visibilit nel file. e)
Visibilit nel file: f) Visibilit nel pr0 ~ripo di fum.ione.

5.3

f ' Verificare le funzioni della libreria matematica/


#include <:Stclio.h>
#include <math.h>
main()
{

prntf( sqrt(%. lf) =%.1-f\n', 900.0, sqrt(900.0));


printf('sqrt(\.1f) = %. 1f\n', 9.0, sqrt(9.0));
pri.ntf ("exp(\. tf) =%f\n', t.0, exp(l .0) );
printf('exp(\.lf) = %f\n' , 2.0 1 exp(2.0));
printf('log(%f) = %.1f\n', 2.718282, log(2.71 8282));
printfj ''log(~) =%.1f\n", 7.389056, log (7 .3890~));
printf-("log10 (\.1f) : \,if\n", 1.0, log10(1 .0));
priirff( "log10(%.1 f) =%. lf\ n', 10. 0, 10910 (10.0));
printf('log10(\.1f) =%.1f\n , 100.0, 10910(100.0));
printt(fabs(!k.1f) =%.1f\n", 13.5, fabs(13. 5)li
printf( 'fabs(\.1f) =%. 1f \ n', 0.0, fabs(0.0));
printf("f.abs(%.1f) = \.lf\n', 13.5, fabs(13.5));
printf ( ceil(\.1f) "'%.1f\n" , 9.2, ceil(9.2));
printt(c_e.(%.1f) = %.1f\n1o 1 9.8, ceil( -9.8));
printf( ufloor(9e.1'f) =%.1t\n~, 9.2 , floor (9 .2.) ) ;
prin'tf( "floor(\. lt) = %. 1f\n', 9.8, floor( 9.8 ) l;
printf( "pow~%. 1f, \.1f) =\.1f\n', 2.0, 7.0, pow(2.0, 7.0));
printf("pc.v(\.lf, %.1f) -=%.tf \n' , 9.0, 0.5, pow(9.0 1 0.5));
printf("fmod(\.3f /\.3f) = %.3f\n",

164

LlrlTOIO

LEFUNZ.LONr

13.675, 2.333, fmod(13.675, 2.333));

d) Errore: il punro e virgola dopo la parentesi clcsrrn che chiude la lista dei parametri e la
riclclnii.ione del parametro a nd corpo d.eUa funzione.
CorrC?.ione: eliminare il punto e virgola dopo la parcnce~i desrra della lisra dci para.metri, cd
elimin:ire la dichiarazione float a;.
e) Errore: la funzione resrirniscc un valore.: e non dovrebbe farlo.
Correi.ione; climn;m: l'isr.ruzionc return.

printf("sin(%.1f) =%.1f\n', 0.0, sin(0.0));


printf{"cos(%.1f) = %, 1f, n', 0.0, cos(0.0));
printf('tan{%.1f) =!\l.1f\n" , 0.0, tan(0.0))i
sqrt(900.0~ =30.0
S(li"'tf-9.0) =.'0'
eJ<p(1.0) "'2':n:~
exp(2.0) -=- 7.'389056
log(2.]l82B2) =-1 ..0
109(7 .~o::.2.0
log1 0 (i .0) >=' 0.0
log10(10.0) =-1 ~-0
log10(100.) =2.0

fabs(13.5)

Esercizi
5.8

2., =- \G;,e~
:0-:g.,.:0

a) double hypotenuse (double side1, dol.Jbl.e side2)


b) int sm&J.l~~t(int x, int y, int i)
e} vod .iri's trl.1ctions ( void)
d) float intToFloat(int number)

5.5

a) double hypotenuse ( double, double ) ;


b) i nt smallest(1.nt, int,int);

= fabs(0.0)

x
x

= ceil(0.0l
= fabs(-6.4)
= ceil(-6 .4)

g)

1<

= ceil( fabs.( -B+floor( -5.5 )))

tloor('--9.8), =' 1~_.0


pcN(2.0, i.0) = 128. 0
pbw(9. 0, Q:.S.j =-3.0
fmod(13.~, 2..~) =2.010
sin(0.0) =~.0
cos(0.0) = I .0
tan(0, 0) =0.0

5.4

d) x

ceil:Hi.s) = cs,.0
floqr(.9~2)

Mosr.rare il valore dix dopo che sar.\ smm eseguita ognuna delle seguenti istruzioni.:
a) x = fabs(7 . 5)
b) x = floor(7 .5)

-::e ~3.5

fabs(0.0) ~ 0.0
fabs(-13.s) =13.s
ce;il(~

165

5.9
Un garage addebita un imporro minimo di $2..00 per 1111 parcl1eggi<l fino a cr ore. Dgar.age
:iddebira un'addizionale di $0.50 per ogni ora o frazione cli essa 1:;hc ccce<l:t le ere di base. J.:addebit
massimo per ogni daw periodo di 24ore~S10,00. Assumete che ne.c;suna auto parcheggi pf pi di
24 ore per volra. Scrivecc un programma che calcoli e visualizzi gli addcbit i per ognuno dci ere clienti
che hanno parcheggiam le proprie auto io quesro g:iragc ieri. Dovrete immellcre le ore di parcheggio
per o~ni cliente. li voSIIo programma dovr visualizzare i risu.lraci in un fornmo labulare ordillato e
dovr calcolare e visualizzare il rorale delle ricevuce di ieri. Il programma dovrft utilizzare la fun~ione
calculateCharges per determinare l'addebito di ogni clieme.l vosrri risultaci dovranno apparite nd
segueme formaco:
ear
1

HQUr

1 .S

~Wflle
2.00

4.0

2.50

2~.0

10 .00
14 ..50

TOTAl

29.5

c) void instructions ( vol.d);

d) float ntToFloat(int);

5.6

a)

register rnt count

= 0;

b) stat.ic float lastVal;


e) sta tic int number;
Nota: .l'ultima dichiarazione dovr comparke.all'estc.rno di ogni definizione di funzione.
a) .Errore: la funzione h smra defnirn all'interno della funzione g.
Correzione: spostate la definizione di h alresccrno della definizione di g.
b) Errore: la funzione dovrebbe resciruire un intero, ma non lo fa_
Correzione: eliminare la variabile resU11: e irlsericc nella funzione l'iscruzionc seguemc::
return x + y;

c) Errore: il risultato cli n + sum ( n - 1) oan staro r~ciruico: sum restiru'U: un cisu.lcaco
inappropriaro.
Correzione: riscrivete l'istruzione ncUa clausola else come
return n + sum(n - 1);

5.10 Un'applicazione della funi.ione floor l'arrorondamenro di


I.:iscruzione

un

valore all'irnero pi vicino.

y =floor(x + .5) ;

.arrotonder il numero x all'intero pi. v[cino e :isscgner il ri.su!-raro a y. Scrivete un progra.mrrui che
legga diversi numeri e urilizzi l'istruzione precedente per ltr!'.otondare ognuno dl questi numeci aU'incero pit1 vicino. Per ogui numero chbornto, visualizzate quello originale e quello arrorondaco.
5.1J La funzione floor pu9 es.sere u1ili1.zaca per ai:romnde un numero a unn specifica posraione
dcctmale. L'imuzionc
y

=floor(x

10 + -5) I 10;

arrotonda x alla posizione dei decimj (la prima a desrra dcli.i virgola dei decimali). Cimu7.ionc
y

=floor(x

100~

.5) I 100;

;urotouda x alla posizione dei centesimi .(la seconda :t d.es.cra ddb virgola dd <lt:cimali). Scrivere un

prgramma che de.finisca qtLactro limzioniper 311ocondare un nw::lc.ro x i11 vari medi

166

CAPITOLO

a) roundTointeger(number)
b) roundToTenths(number)
e) ro unctToHundreths(number)
d ) ro undToThousandths(number )
Per ogni valore lcrco, il vostro programma dovr visualiwu:e il numero originale e quelli arrot0ndarhll'intcro, al decimo, al centesimo e al millesimo pi vicini.
5.12

Rispondere a ognuna delle seguemi domande.


a) Cosa significa scegliere dei numeri "a c;aso" ~
b) Perch la funz.ionc rand utile nella simulazione dei giochi d'azzardo?
c) Perch dovreste randomizzare un programma, uJiz.z.ando srand? ln qualJ circostanze
preferibile non randomiz.z.are?
cl) Perch spesso necessario ridurre in scala e/o rraslare i valo.ri prodotti da rand?
e) Perch la simuJaz.ione compucerixzara di situazioni del mondo reale una tecnica utile?

5. 13 Scrivete delle istruzi.oni che assegnino allavari~bile n degLl inter ca~ual i compresi nei seguenti
intervalli:
a) I = n ., 2
b) I = n = 100
e) O= n = 9
d) 1000 = n = 111 2
e) -I = n = I
I) -3 = n = r I
5.14 Per ognuno dei seguend gruppi di imeri, srivece una singola istmzione che visualizzi un
numero casuale uarco dal gruppo.
a} 2, 4, 6, 8, IO.
b) 3, 5. 7, 9, 11.
e) 6. IO, 14, 18, 22.

LE ruNZIONl

5.18 Scrivete uo programma che prenda in inpuc una serie di inrcri e li passi, uno per volm. alla
funzione even, che ucilizzer l'operatore modulo per dererminare se un inrero pari. La funzione
dovr ricevere un argomento incero e rcsriniire 1 qualora l'imero sia pari e 0, in caso conrrario.

5.19 Scrivete una fum.ione che visuaLlzzi al margine sinisnq dello schermo un quadrato pieno di
~cerischi il cui laro sia staro specificaro nel pa.ramet:r0 incero side. Per e.sempio, qualora side fosse 4 . la
funzione dovrebbe visualizzare:

Lato I

Lato 2

3,0
2

.S,O

8,0

4,0
12,0
15,0

5.16

Scrivete una fimzione integerPower (base, exponent) che re.sri.cuisca il valore di

bast!XP011ent
Per esempio, integerPower ( 3 , 4) "' 3 3 3 3. Supponete d1e exponent sia un incero posicivo
diverso da z,ero e che base sia un incero. la funzione integerPower dovr utiliz.zare for per conrrollare
iJ calcolo. Non uciliuarc nessuna funzione deJJa libreria.macematica.
5. 17 Scrivere una fu.nz.iona multiple che per una coppia di inceri determini se il secondo sa un
mulplo del primo. Li fun1.ione dovr ricevere due argo.menri interi e resrituire 1 {vero), qualora il
secondo si.a un muluplo del primo, 0 (falso), in casQ conuacio. Ulixzace qu.esca funzione in un
programma che prenda in inpul una serie di coppje di interi.

5.20 Modificare la funzione cream nell'Esercizio 5.19 in modo da formare il quadrato con qualsia$i
cararrere siac.onreouro ne! paramerro di cipo ca.rartere fillCharacter . O.i conseguenza, qualora side
fossi! 5 e fillCha r acter fosse"#", la fi.mzionedovrebbe.visuali.z.zare:

).21 Ucilizzarc delle tecniche simili a quelle sviluppate negli Esercizi 5.19 e 5.20. per produrre un
programma che cracc1 un'ampia gamma cli forme.

5.22

5.15 Definire una funzione hypotenuse che calcoLl la lunghezza dell'ipotenusa di un triangolo
rettangolo quando siano dari gli alrri due lari. Utilizzare questa funzione in un programma che
dereanini la lungbcz.za dcU'iporenu.~a i>er ognuno dei seguenri rriangoli. La funzione dovr ricevere
due argomenri di cipo double e resciruire l'iporenusa c-0me un double.
Triangolo

167

Scrivete dci segmc.nci di progr.imma che eseguano ognuno dei seguenri compici:
a) Calcolate la pane incera dcl quozienrc ottenuto clal1t divisione degli inreri a e b.
b) Calcolare il resro incero occtnuro dalla divisione degli inceri a e b.
e) Uriliw1te i pe:ai di programma sviluppari in a) e b) per scrivere una funzione che prenda
in input un intero, compreso rra 1 e 32767, e lo visu:i.lizzi come una sequcnia di cifre,
separando ogni coppia dJ esse con due spazJ. P-er esempio~ l'incero 4562 dovr essere
sc:amparo come:
4 5 6 2

,S.23 Scrivete una fum.ione che acceni in in pur lora, ?Uddv!~a in tre argomenci inreri (per le ore, i
minuti e i second), e restituisca il numero dei second~i traSCei!t~i dall'ultima volta che l'orologio "ba
rinwc,aco .le 12". l:Jtilli.iace questa funzione per calcolate la q.u;tnri:t di rempo in secondi che incercorre rrJ due orari, cnrrambi i quali siano compresi all'inremo dl un ciclo di L2 ore ddl'orol(!gio.
5.24

Imple;nenra.ic le seguenti fuozionj intere:


a) La funzione celsius restiruisce l'equiv"J.leme Celsius di una remperarura Fahren heit (utilizzare la formula 0 C={5/9) )( e F-32), dove C rappresenra la tempcrarura in gradi Celsius
e F quella in gradi Fahrenheit).
b) La funzione fahrenheit restituisce l'equivale.me F-ilirenheit di una temperatura Celsius
(utilizzate la formula F:(9/5)C+32. dove C rappreserua la temperarura in gradi Celsius
F quclla in gradi Fahrenheit).
e) Urili21.ace qucsrc fu nzioni, per scrivere un progfl!Jllm3 che visualizzi delle tabelle che
mostrino gli equivalenti Fahrenheit di rum:. le re.mperatur Cdsius comprese era O e I00
gradi, nonch gli equiv:i.lcnri Celsius di rurrele remperarure Fahrenheic comprese era 32 e

168

CAPITOLO

211 gradi. Visualizzate i rsulmci in una forma cabulan.: ordinarn che minimi1.zi il numero
di righe dell'output". puc rimanendo leggibile.

5.25

Scrivete una funzione che re.stiruisca il minore di

tre numeri

in virgola mobile.

5.26

Un numero intero deno numero perfeno qua!o(a I.a somma dei suoi fattoci, incluso l (ma
non se stesso), sia pari a quel numero. Per esempio 6 un numero perfeno pt!!ch 6 ,. I i- 2 + 3.
Scrivete una funzione perfect che detennini se il paramerro number sia un numero pcrfcuo. Utili1zar.e ques1a funzione in un programma che determini e ~-isualizzi rurri i numffi pcrlni trn I e I 000.
Visualiv~re i fattori di ogni numero pcrferco. pcr CQi;ifrm:aredie lo sia vec:l.ll1cn1c. Sfidate la porcm~1
del vscro computer, provando con numeri maggiori di 1000.

5. 27 Un incero dmo primo qualora sia divisibile solranco per 1 e per se stesso. Per esempio 2, 3. 5
e 7 sono primi, mcnc:re 4, 6, 8 e 9 non lo so110.
a) Scrivere una funzione che drm:rmini se un, nu mero sia primo.
b~ U rili'l.z:1tc questa funzione in u11 pmgr;unmache determini e visualizzi tu~ti i numeri primi
mi l e W.000. Quand ili quesci I0.00"0 nuneri dovrete realmente v.erifcare primr;.d i
essere $icuri di aver crov:ic turci i nlillleri p~?
c) [oizioJmcnce pocresre pensa.re eh~ .nfQ sia il limire superiore che dovrete verificirc p.er
vedere se un numero sia primo, m;i in realdi vi baster ;1rriv:1rc alla radice: ql..l<ldratn di n.
Perch? Riscrivere LI programma e fatelo eseguire Ln entrambi i modi. Scimacc li miglior:imenro dd le presrazioni
5.28

Scrivere un;L funzione che prenda un valore imero e lo restituisca dopo avere iovcnito le sue

cifre. Per esempio. dato il numero 7631, la funzione dov resciruirc 1367.
5.29 li massimo comun divisore (MCD) di due inceri l'incero pi grande che possa dividere
es;m:unenre ognuno dci due numeri. Scrivere una rum.ione gcd che rcsriruisca il massimo comun
divi.o.ore di due incc.
5.30 Scrivcle una furo.ione quali tyPoints che prenda in inpuc la media cli uno srudencee resciruisca 4 qualora la sua media sia compresa rra 90 e I 00, 3 era 80 e 89, 2 tra 70 e 79, I tra 60 e 69 e O

qualol'1l sia inferiore a GO.

,.

5 .31 Scrivete un programma che simuli il lancio di una monena. l'cr ogni la1icio della monerina il
programmadovr visualizzare Heads o Tails. l.a.sc,iar che il programma lanci la monetina per I 00
volte e co1lt1lt U numero di <)ccorrcnze per la comp~~ di qgni foccia della monetina. Visua1i1.um~ 1
risulraci. Il programma dovr chiamare ltM fum.ion discinta fUp, che non ricever argomenti e che
r"st.ituLr 0 per croc e 1 per resta. Not;i: qualora il progr:muna simuli realiscicamentc il lancio cli unn
monecina, allora ogni faccia della srcss:i d(.)Vr apparire approssimar:ivameate la met delle volte, per un
torni<.' app ro.ssim:uivo di 50 ~cm e 5() croei.
5.32 1 computer giocano un. niolo sempre p iimportance nell'educazione. Scrivere un programma
.che ai u.ci uno srudenre di scuola elemento.re a(L apprcnd..:rt! la molciplic:izione. Utilzv.ace rand per
produrre due inceri positivi i una cifra. Dovrer..: quindr visualiz1~'lre una domanda come:
1-iow much is 6 times 77

rn seguico lo srudente diglrcr la risposra.11 vosrro prograrmnaconcroUer:\ la risposta dello studcncc. Q.1alora
s:ia correcm, visualizzare very good I e smop0nete quindi un'altra domanda sulla molciplica7jonc. Nd
caso che la risposta.sia sbagliara, visualixzace No . Please 1:ry aga in. e lasci.are quindi che lo srudem.e
provi ancora ciperuramcore la stessa domanda, finch alla fine non avr asposro corremunence.
5.33 turilizzo dei computer nell'educazione dcna iscruzone assistira dal computer (CAl, compucer-assisced insr:ruccion). Uno dei problemi che si sviluppa negli amhienri CAI l'affiuicamento dello

LE 1'0N7.JONT

L69

smdenre. Questo pu essere dirninato, variando il di:tlogo dd computer in modo da manrenere viv:i
l'arrenzion.e dello rudcnt..:. Modifcace il programma ddl'Escrcizio 5.32 in modo che siano visualiv.ati
vari commenri a fronte di ogni risposm corrcrra e sbagliata, come segue:
Commenti per una ri~po~ta correna
Very goodl
Excellentl
Nice work!
Keep Up the good workl
Commenri per una risposra sbagli:ira

No . Please try again.


Wrong. Try once more.
Don' t giVe upl
No. Keep trying.
Utiliu.1tc li generatore ul numeri casuali per ~ccgl iemc ,Uho compres<> rra l a 4 e ~elezio na re un
cotnn:into appropdnto <1 ogni risposta. Uril.izz.ate la srru rtura ~witch con.delle ism.11.ioni pri ntf per
emetrere i commenri.

5.34 I s_isccmi pi raffinaci di ism17.io11c.: assiHit;1 dal compmer mon.icora.no lt: pr~tazioni dcll'uccntc
du rante un cerco pt:riodo. La decisione di incominci.are un. nuovo argomento sar spesso b:i~:im sul
~so dello studenre con gli argomenci prcccdenri. Modificare il programma dell'Esermio 5.33 in
modo da contare il numero di risposte correrce e sbagliare immesse dallo srudentc. Dopo che lo
sruderue avr digimto I Orisposte, il vosrro programma dovr calcolare la percentuale di quelle comme.
Qualora la percentuale. sia inferiore al 75 pe.rcemo, il vosrro programma dovr visuaL1.2..'lre Plesse
ask your inst r uctor for extra help ' e quindi termin'<lt'e la propria t:Secuzione.
5.35 Scrive.ce un programma C che proponga il gioco "indovin:Li..I nwnero" nd modo ~eguence: il
vosuo programma sceglier il numero da indovina.re, sele-Lionan_d o un incero a caso compreso ncll'incervallo d-a 1 a I000. U programma quindi visualined:
nave a number between 1 and 1000.
Can yeu guess my number?
P.lease type your fi rst guess.

11 glocarore :.loro digiter una prima pores. U programma risponder con una delle scgwmti frasi :
1 . Excellent I ~ou gUessed t he number I
Wpu:l:Q Y,o\I ll,ke; to pl~y agaifl ,(y or n,)?
2. Toe low. Try .agun.

.3. TPQ hig~ TQY a~ain.

Q ualora L'ipotesi dcl giocarore sia sbagliata, il voscro pr:ogramina dovr reiterare finchil giocatore non
avr lnalmenrc. indovinaro il numero correno. li vostro programma dovrll continuare a indicare Too
hgh o Too low, per aiurare il giocacorc a "prendere la mira" sulla risposc correcc:t. Nora: la tecnica di
cicerc:i impicgmn in q_uesro problema dena ricerc.i. binari.a. Diremo qualcosa in pi su ci nel prossimo
problema..
5.3 6 Modifcacc l'f--5ercizio 5.35 in modo da comare il numero di ccnra.tivi del giocarorc. Qu;ora il
numero sia inferiore o uguale :i I O, visualizzare "E.it her you know the secret or you got lucky I .
Qualora il giocatore: indovini il numero in 10 renrarivi, visualizzare "Ahah I You know the secret 1".
Qualora il gioca.core faccia pi di IOcenrari,i, visua!izz:rre ''you should be able to do better I. Per
quale motivo non dovranno essere consenrici pi di IO cemarivi! Ebbene con ogni "buona iporesi" il

170

UPlTOL05

giocarore dovrebbe essere in grado di eliminare 1a mec dei numeri. Dimostrare ora in che modo ogni
numero era l e 1000 possa essere indovinaco in 10 cenrarivi o meno.
5.37

Scrivere una fumione ricorsiva power (base, exponent) che quando invoca.ra resriruisca
bnseexpommt

Pel' esempio, power(3, 4) == 3 3 " 3 3. Sup pone~eche exponent sia un incero maggiore o uguale
a 1. Suggerimen:co: il p~so dlricorslone dovr ucilizzare la relazione
bnsPPPnent = base. bnstP-'fJtment-1
e la condizione di rerminazione sar verilcara quand~ exponent sar uguale :t 1 perch

base1 "'base
5.38

L'l serie di Fibonacci


0, 1,

1, 2, 3, s, a, 13, 21,

incomincia con i ce.r:mifli Oe 1 e gode della propriel per la quale ogpj temine Successivosafa pari alla
somma dci due rerrnioiprecedend. a) Scrivere una funzione f ibonacci ( n) 1i,on rricorsivache calcola il
numero ncsimo di.Fibonacci. b) Dcrecminare il numero di Fibonacci pii1 grande che passa essere
visualizzato sul vostro sistema. Modificate il program:ma_della parte a) in modo da usare dei double,
invece degli int, per alcolare.e rcsdcuirc i numeri di Fibonacci. Lasciare reiterare il p(ogramma fnclt
non fallisca a causa di un vAlorc eccessivamente alco..
5.39 (le toai-di Hani) Ogniinfoanarico in erba dovr venire alle prese coo cerri problemi <lassici e le
corri di Hanoi (co~ la Figura5.18) uno dei pi fumosi di questi. La leggenda narrache,.in un rempio
ddl'E.memo Orienre,.~ preri stavano remando di.muovere una pila di dischi da WJ paleuo a un alrro.
La pilo iniz.i:tle avev.a 64 dischi infla su un paletto e ordina io misu.rn decrescenrc dal basso all'alto. J preti
stavano ccmmndo cli muovere fa. pla da qucsco a un secondo palerco, risperta.ndo del.le r<11ole serondo le
quali: pocevl! ssere t'rlo.ss,i:i esarta.menrc un disco per volr;acin_n_es$un momenro un disco pi grande poteva
essere sistenmo su uno pi piccolo. Era disponibile un cerzo pitletto per riporre cemporane:inicnre i dischi.
Secondo la leggenda, qualora i preti avessero complecaro il Loro compiro, sarebbe giuora la fne:dd mondo,
perci non abbiamo molco interesse nel fucifuare i loro sforzi
Supponiamo clte i preri sciano rericando di muovere.i dischi dal p;iletro l al 3. Vogliamo 5viluppare un algoricmo che visualizzi l'esatta sequenza di a:a.sferimemi di paletto elisco per disco.
Se dovessimo affroruarc questo problema Cn.J metodi convenzionaJi, ci rrovererilmo presto
clispcrac.a:mence ingarbugliaci.od ia manipolazione dei dischi. Se invece affrontiamo il rroblema tenendo in mence la ricorsione, esso diventer immediatarileiire trarrabile. Lo spostamento di n clisd porr
essere vism come lo sp.ostamento di soli n - 1 dischi (eq_uncli la ricorsione) come segue:

LEFUNZIONl

171

I . Muovere n -1 dischi dalpalecro I aJ 2, ucilinando il3 come :m<1 di deposito tempoianea.


2. Muovere l'ulcimo elisco (il pi grande) dal paletto I al 3.
3. Muovere gli n - I dischi dal palen:o 2 al 3, urili1..7.ando il palecro l come :tn:a di deposito
temporanea.
il proce,so rerm i.nera quando l'ultimo com piro richied.ei:lt.Jo ~O&tnme.mu di n.,. J dischi, ovverosi;\
i.I caso di base. Ci s;u eseguito sempliccrnenrc spostando il disco, senza la necessit di un'area di
dcp.osico temporanea.
Scrivere un programma che risolva il problema ddle t~lr.ti di Hanoi. U1ilinate una funzione
ricorsiva con quartro paramerl'i:
I. Il numero dei dischi da muovere.
l.
palecro sul quale quesci dischi saranno iniz.ialmeme infilati.
3. li paletto sul quale quesca pila di dischi dovr es.sere spostata.
4. Il palerro eh.e dovr essere udlizzaro come area cli deposito 1emporanea.
li voscro programma dovr v1sualiz.zare le istruzioni precise necessarie per lo sposramemo dci
dischi dal palerco di partenza a quello di desti nazione. Per esempio, per muovere una pila di rre dischi
dal paleno I al 3, il vostro programma dovr visuafo:z.arc la scguenre setie di mosse:

1 -7 3 (Quesw significa muovere Ltn isco <la1 palecro I al pnkrro 3).


l -72
3--+ 2
I--+ 3
2-7 l

2-73
l -7 3
5.40 Ogni programma che possa essere implemem aro in modo ricorsivo porr essere costruito in
maniera iterativa, scbbC!he a volte con maggior.i if6c0lc e minor chiare-ci.a. Cercare di scrivere una
verli(l ne irer;tcivn dcllc torri di Hanoi. Qualon~ vi riusciste, con.frnnrace la vostra vers.ionc ireratlva con
queU<l ricorsivn che avere svilpparo ndl'Esercizio 5.39. Analizzare i probJemi di efftcienza, di.cbia.rezz.1 e la voma capacicl nd dimostrare la corretter.ro dci programmi.
5.41 (Visualizzare la ricor:;ione) interessante osservare la ricor:s.ione "in azione". Modificare la
funzione dcl fanonale della Figura 5.14 inmodo da visualizz.'1.Je le sue variabili locali e i parametri delle
cbiamace ricorsive. Per ogni chiamata ricorsiva. visualiziace gli ourpunu una riga separata e aggiungete
un livello di rienrro. face del vesrro meglio per rendere l'oucpul chiaro, interess:tnrc e signifcarivo. li
vostro obicrrivo in quesro caso sar cli disegnare e implemenrare un foanaro dcll'ourput che aimi una
perso1n a capire megljo la ricorsione. Porresre voler aggiunge.re queste capacit di visuafrzzaz.ione a.i
molti altri esempi cd esercizi sulla ricorsione prc.cnti in quesro cesto.
5,.42 11 massimo coruun divisore dcgliinreri x e y (: l'inrero pi: grande che divida. esanamente:: sia x
che y. Scrivere una funzione tkorsiva god che rescituisc:t il massimo com un divisore dix e y. IJ gcd di
x e y sar del.niro i.o modo rkorsrvo come segue: se y .uguale a 0, allora gcd (x, y) sar x; alcrimenti
gcd(x, y) sar gcd(y, x \ y) dove l\ s:tr l'oper:rmre modulo.
5.43 Pu il ma in essere chiarnaco in modo ricorsivo? Scrivere un programma che conrenga una
funuone ma i n. I ndudcre la variabile locale static count iaizi-alizzaca a I. Ogni volta cht: lafuozione
ma in invocata, applicate l'operatore di postincrcmenro e visualizzate il valore di count. Eseguire il
progr:unma. Che cosa succede?
5.44 Gli Esercizi <la1 5.32 al 5.34 hanno permesso di sviltippare ua programma di istruzione
aJ;sisdra dal co111pucer, per .insegnare la moltipllcwione a u.nci scud.e.nre di scuol:i clemt!ntare. Questo
esercizio suggerlscc dei migli:Otfilnenci a quel programma.

Figura 5. 18 Le torri <:li H anoi per il caso con quattro dischi.

172

CAPITOLO

a) Modificare il programma in modo da consenrire alJ'utcnce di im.mecrere un hvcUo di

d.ifficolr. Un Livello l signHicher utilizzare solo_nwm:ri di una cifra all'inmmo dci problemj, un livello 2 significher utili L7.are aneli~ numeri di due cifre. ecc.
b) Moilc:lie il programma in modo da conspitin. all'urenre di scegliere iJ tipo di problemi
aritmetici che lui o lei dcsidern studia.re;. tJn'0pz1one I signlfdm solo problemi suJl'addizio11e, 2 solo sulla somazione, 3 solo sulla molriplicazione, 4 solo sulla divisicme menue 5
signifdxcr mischiare a ciso problemi di (utri questi tipi.

LE fUNZIONl
5.50

l73

Trovate l'errore in ognuno dei seguenti segmemi di programma e spiegare mme correggerlo:
a) float cube(float); 1~ prototipo di funzione /

Scrivece l:t funzione distance che calcoli l:i cfu~


numeri e i valori resriru.iti dovranno essere di tipo float.

5.45

S.46

tra

due punci (xl. yl) e (x2. y2). Tuni i

cuba (float r111Jliber}

f * definizione d funzione .. f

return number * number numbe r;


}

b ) register auto int x =7;


e) int randomNumber = srand ( ) ;

d) float y = 123.45678 ;

Che cosaf.uJl seguenre programma!

int

main()
{

Xj

X = y;
printf("%f\n", (float)

ilit :;
if ((e = getchar()) l= EOF) {

~);

e) double square (double number)

maiin o;

double number;

printt( "%e!' , e);


}

return number -number;

return 0;
}

5 .47

f)

1nt

sum(urt n)

Che cosa far il seguente programma?


int mystery(int, wt);

main()

if (n = 0)
returfl 0;
else

return n + sum(n) ;

i nt x, y;

printf (<.Enter

two i ntegers: .. ) ;

scanf("%!\id', &x, &y );


prllitf( 1he result is l\id\nr, mystery(x, y));

return 0;

t i l parametro b deve essere un intero po;;itivo


per pN!venire una ricorsione infinita /

int mystery(tnt a, int b)


{

if

(ti

"'= 1)

return a;
else
return a+ mystery(a, b 1);
}

S.4 8 Dopo clieavrere decerminato cosa far il programma dell'Esercii.io 5 .47, modifcacclo io modo
che funzioni correuamente, dopo la rimozione della restrizione riguardamc In posrivil: del secondo
pararneero.
5.49 Sctivet~ un programma che concrolli t:ane_funzioni deJJa libreria matematica deJh figura 5.2
quante ne p0rer_e. Eserdtarevi con ognuna dj queCCf~111'l.oni, facendo n modo che iJ vostro program
ma 11is11;izzj del.le cabeUG: comenen'ri i valori restituiti da. una molteplich di argomern:i.

5.51 Modificare il progrnmm ~t per il gioco dei dadi della Figura 5.10 in modo da consenrire delle
scommesse. lmpacchemue in una fun-1.ione la poc:zione del programma che eseguir un singolo gioco
ai dadi. Iniz.ialinace la variabile bankBalance (saldo) a 1000 dolJa.ci. Ch iedete al giocacore di imme[
cere una wage r (pancica). U liZzate un ciclo while per conuollare che wager sia inferiore o uguale a
bankBalance e, in caso cona:ario, per cliiedere :ill'uu:nce ru immettere ouovamence wage r finclie non
ne si:i St:lt:l immessa una valida. Dopo che sar sc3t:l immessa una wager correcta, eseguite un gioco ai
dadi. Nel caso in cui il giocatore vmca, incremenrerere bankBalance dj wager e visualizzcrece Unuovo
bankBalance. Nel C.'lSO in cul il ~ocamre perda, d.ecremenrerecc bank.B alance ru wager. visuaJiz:Lerete
il nuovp bal)kBalance. verificherete ehe bankBalance non sia diventato zero e, in ca.m contrario,
visu,alizzerere iJ messaggio so,rry, You busted l ".Man m;lil.o h.: il gioco progrt>c.-Llr, visu:llimeretc
vari mess;1.ggi per fu.re un po' ili "chi;Jcchi.e1t'" come "Oh, you ' re going for broke, huh? ", o "Aw
cmon, take a chancel" , o "Yu're up big. Now 1 s the time to cash in your chipsl" .

CAPITOLO

I vettori
Obiettivi

6. 1

Presenrare la scrucmra di da vettore.


ComprendereJ'uso dej vettori per immagazzinare, ordinare e ricercare elenchj e rabelle
di valori.
CoQlprendere come dichiarare e inizializzare un vetro.re e come fure rikcimento a.i
singoli elementi.dello sresso.
Es$ere in grado di pas.:;arc i vettori alle funzioni.
Comprendere le tecniche fondameocali di ordina.mento.
Essere io grado ili dichiara.re e manipolare dci vettori mulcidimensionali.

Introduzione

Q uesto capitolo fu da inn-o.duzione all'imporrante argomemo delle scnmure di dati. l litfttori


spn0 delle srructwe di dati he consist0no di uqfr cii infoni1azione dello ste.~so tipo. Nel
Capitolo 1Odiscuteremo la nozione di struct (suurrura) nd C: una struttura di dari formaiada
unit ili informazione correlare ma con cipi cvenmalmcnce.differenci. I vecrori e le srrurrure sono
"enrir" SC'dtiche, giacch manrerranno le proprie dimensioni durante l'esecuzione del programma. Naruralmenre, essi porranno apparccncrc alla classe di memoria aucomacica ed essere
quindi creaci e disrrurri ogni volra che si entrer e si uscir dai blocchi in cuj saranno stati
dciniri. Nel Capirolo U irurqdurremo le strucrure ru dati dinamiche come le lisce, le code, le
pile e gli alberi che porranno crescere e decrescere durante l'esecuzione del programma.

6.2

I vettori

Un vertore un gruppo di posizioni (o locazioni) di memoria Gorrdace dal facto che tutte
hanno lo stesso nome e tipo dj dam. Per far riferimem.o a una particolare posizione o
elemento ail'ime.rno dd verrore, specificheremo il nome deUo stesso e. il numero di posizione
ru quel parcicolare elememo nel vettore.
La Figura 6.1 mosrra un veccore di interi chiamarn c. Questo vettore conriene doruci
elementi. Ognuno di questi elementi potr essere puncaCQ CQILil nome del venoro::, seguito tlal

.numero ru posizione per quel particolare elemento racchius a:a parentesi quadre ([ J). Il primo
elemc.11co di ogni vercore l'elemento zero. Di consgnenza, il primo elemenro del vettore~ s;it
p.umaco da e [ 0]. iJ secondo elemento del vettore e {;ar punraco da e [ 1 ). il settimo dem.enco
del veccore e sar punrato da e [ 6] e, ln generale, l'iesirilo elemenro d'el verrore e sar puncaco
da e [ i -1]. 1 nomi dei wtto:ri seguono le scesse conveozioru deglj alcri nomi di variabile.

176

CAPITOLO

J VETrORI
Errore tipico 61

Nome del puntatore(da notare che


tutti gli elementi del puntatore
hanno lo stesso nome, e)

importante 1wtare /11 differenza tra "il seitimo elemento dei vettore" e "l'elemento sette
dei vettore~ Dato che gli indici dei vertori incominciano da zero, "ii settimo ekmemo
del vettore" avr l'indice 6, mentre "l'elemento sene del vettore" avr L'indice 7 e sart in
realt l'ottavo elemento del vettore. Questa la causa di errori di "imprecisione di uno ''.

c(0)

-45

c( 11

cf 2]

C[3J

72

C(4}

1543

c [ 5J

- 89

c [ 6J

++

e [? ]

-3

c[8J

6453

I
+ .

c[9]

62

e I 101

e [ 11 J

78

Numero di posizione dell'e~mento


all'interno del vettore c.

177

In C le parentesi quadre urilizzare per racchiudere J'indice di un vettore SODO considerate in


realt un operatore. Esse hanno lo stesso livello di priorit delle parentesi tonde. La tabella nella
Figura 6.2 mosaa. la priorit e l'associacivir degli operatori introdotti sino a questo punro nel
libro. Essi sono mosua dall'alto in basso in ordine dec;rescenr~ di priorit.
Operatori

Associativit

Tq><>

da sinistra a destra

massim a

da destra a sinistra
da sinistra a destra
da sinistra a destra

molti pi i cari vi

da sinistra a destra

relazionali

da sinistra a dcsrra
da sinisrra a_ destra

di uguaglianza

&&
11
11

da sinistra a desrra

OR logico

( )

<

--

-- I

( tipo )

l\s

<= > >=


I=

?:
= +=

/= %=

unari
addidvi

ANO logico

da desu a a sinisrra

condiz.ionale

da destra a sinisrra

di ~ssegnarnento

da sinisua a destra

virgola

Figura 6.2 Priorit degli operatori.

Figura 6. 1 Un vettore di 12 elmenti.

JI numero di posizione contenuw all'imero delle parenresi quadre pi formalmente


noto come indice. Un indice deve essere un incero o un'espressione intera. Nd caso dle un
programma ucilizzi come indice un'espressione, qu~ s;u valutata per determinare l'indice . .Per esempio, se a = 5 e b = 6, allora l'istruzione
cf a + b]

+=

2;

aggiunger 2 alJ'elemento e [ 11 ] dl verrore. ~erva~e he un nome di verrore indiciZ?.aro un


lvalue: ovverosia un'entit che pu essere utilizzata nella parte sinistra di UD assegnamenti:>.
Esaminiamo pi da vicino il vettore e della F igura 6.1. ll nume del vettore c . I suoi
dodici elcmenci sono pLLntari da e ( 0] , e ( 1 ), e [ 2]. ... e [ 11 ] . Il valore di e ( 0] - 45,
quello di c[1] 6 , quello di c(2] 0 , quello di c[7] 62 e quc.llo di c [11 J 78. Per
visualizzare la somma dci valori contenuti nei primi rre dementi del vettore e , scriveremmo

printf( "\d " , c(0] + c[1] + c[2J)i


Se volessimo dividere per 2 il valore del setcimo dememo del vettore e e assegnare il
cisulraco alla variabile x , scriveremmo
X

c[6 ) I 2;

6.3

La dichiarazione dei vettori

1 vettori occupa.no dello spa%io io memoria. Il programmatore specificher il cipo di ogni


.elemenro e il numero di quelli richiesci da. ognuno dei v~-0ci, cos che il computer possa
riservare l'appropriata quantit di memoria.. i>~r ord;ina.re a.I comp u ter di riservare 12
elementi p er il. vetto.l'e di inceri e sar utilizza.ca la dichiarazione:
::lnt e[ 12);

sa:r possibile riservare ddla memoria per diversi verco ri con una singola dichiarazione.
Per riservare 100 elementi per il vercore di inceri b e 27 per il vettore di inceri x, sar
uti.liziata la segueace dichiarazione:

int

b[~00 J,

x[27J;

I vettori potranno essere dichiaraci anche per contenere altri tipi di dato. Per esempio,
un vettore di cipo c har potr essere uciliz.z.aco per immagazzinare una stringa di cararreri.
Le stcioghe di caratteri e la loro somiglia.ma con i vettori saranno discusse nel Capiwlo 8.
La relazione tra i puntacori e i vettori sar invece discussa .nel Capirolo 7.

CAPITOLO 6

178

Esempi di utilizzo dei vettori

6.4

IJ programma ddla Figura 6.3 urilizzer una struttura di ripetizione for, per azzerare i 10
elemenri inreri di uo vea:ore n e visualizzarlo in formaro cahulare.
Osservate che abbiamo scdto di non inserire una riga vuoca tra Ja prima istruzione
printf e la srrurrura for della Figura 6.3, perch esse sooo srrcrrameme correlate. In
quesrn caso l'istruz.ionc printf visual izza Le intestazioni per le due colonne visualizzare
all'imerno della struccura tor. I programmato ri omerrono spesso le righe vuote tra una
scrurrura for e le istruzioni printf srrea:amente correlare.

/* iniZializzare un vettore *I
#include <stdio.h>

1 VEJTORI

179

d1e azzererebbe il primo clemenco in modo esplicito e in amomarico i rimanenti nove, giacd1
ci sono meno inizia.li.zz.acori degli elemenri presenti nd ~QI(!. imporranre ricordare che i
verroci non saranno azzerari auromaricamence. Il progmn:umuore dovr azzerare almeno il pri.IllO elemcnco perd1 quelli rimanemisiano azzeraci amomaricamente. Quesco metodo di azzeramento
degLi dementi di un ven:ore sar eseguito durante la compilazione. Il mecodo urilizzaro nella
Figura 6.3 potr essere: usaco ciperuramcme duranre l'eseavlone dd programma.
1~ Inizializzare un vettore con una dichiarazione */
"include <stdio.h>

main ()
{

int n( 10 )
int i;

ma in()

{32 I 27 I 64 J 18 l 95 l 14 J 90 J 70 l 60 I 37};

i nt n ( 10) , 1 ;

pri nt f { ''%s%13s \n '' , "Element", "ValLl" );

for (i = 0; i <= 9; i++)


n [i] = 0;

I* iniZia:lizza i l vettdre

11

f9r( 1

printf( "%S\13s\n", "Element", " Value");


1 ~ vsualizza l vettore */
f or (i = 0; i <= 9; i++)
printf('%7d% 13d\n", 1, n[i]);

= 0;

<=

9; i++)

printf("%7d%13d\n'', 1, n[i]}i
return 0 ;
}

Element
return 0;

Element

Value

0
1
2
3

0
0

2
3
4

0
0

7,

Figura 6.3

Inizializzare a zero gli elementi d un vettore.

Gli elemen ti di un verrore potrann0 anche essere inizializzaci comesrualmeme ctlla sua
dichiarazione, facendo seguire a questa un segno di uguale e una Lisca (racchiusa tra parcmresi graffe) di inizi11li:<Z11ton separaci da virgole. U programma della Figura 6.4 inizializza
un vercorc di inceri con dieci valori e lo visualizza in formaro tabulare.

Nel caso ci fossero meno inizializzarori lcg1i dememi del vea:ore, quelli rimanenti ,

14
90

6
7

0,
0

Value
32
27
64
18
95

Figura 6.4

70
60

37

Inizializzare gl elementi di un vettore con uria dichiarazione.

~ Enon: tipico 6.2

Dimenticare di inizializ:a.rre gli elememi di tJn vettore qiu1wm debbano essere inizialiZZdri.

La seguente dichiarazione di vettore


int n[SJ

= {32 ,

27, 64, 18, 95, 14};

prqvocher un errore di sinrassi perch ci sono 6 in.izialii.zatori e solo 5 elementi nel


\tenore.

Enore tipico 6.3

sarebbero aucomacicamente azzeraci. Per esempio, gli clementi del vettore n nella Figura 6.3 potrebbero essere azzeraci con la dichiarazione

rm errore di sintnssifornire in una lista di in;p11fizz4ziohe di vettore pir iniz1/ia,atori

int n [ 10] : { 0} ;

di quanti elementi ce ne siano nello stesso.

CAPITOLO O

180

Qualora in una dichiarazione con un.a lista di inizializzazione sia scara omessa la dimensione del verto re, il numero dci suo elementi sar dererminaro da quello degli inizialimtori
inclusi nella lisca di inizializzazione. Per esem_pio,

181

VETI'ORl

Clement

Value

0
1
2
3
4
5
6
7
8

10
12
14
16
18

20

int n [ J = { 1 1 2, 3 , 4 , 5} ;
creer un venare di cinque elemcnci.
Il programma della Figura 6.5 inizializzer i dieci elemenci di un vercore s con i valoci
2 , 4 , 6, ..., 20 e lo visualizzer in formaco rabulare. 1 valori saranno generaci moltiplicando
per 2 il conrarore del ciclo e aggiungendovi 2.
In quesco programma scata inrrodotrala direrriva del preprocessore #define. La riga

6
8

ltdefine SIZE , 0
defmir una costante simbolietl SIZE il cui valore sar 10. Una coscance simbolica un
idenrificatore che sar soscituito con il test di sosftt:uzme dal p reprocessore del e, prima
che il programma sia compilato. Quand0 il programma sar elaborato dal preprocessore,
curre le occo(!'enze della cascante simb9lica SIZE sru:anno sosticuicc dal cesto di sosrituz.i011e
10. Utilizzare le costanci simbollche per specificare le dimensioni dei vettori render i
programmi pit1sca/abifi. Nella Figura 6.5, jJ primo ciclo for potrebbe riempire un vettore
di 1000 elementi cambiando semplicemenre il valore di SIZE nella dirctriva #define da
10 a 1000. Qualora uon fosse scaca ucilizzatala cosranre simbolica SIZE, avremmo dovuro
cambi.ire il programma in ree pos discinri per adattarlo alla gesri.one di un vettore di 1000
elemen. Questa recnka diventer sempre pi ucile per scrjvere dei programmi chiari,
man mano che questi divemeranno pi corposi.

~ Errore tipico 6. 4

Terminare con ttn punto e vgola ttna direttiva #define o #include delpreprocessore.
Ricordate che le direttive del preprocessore mm sono istruzioni del linguaggio C.

/* Inizializzare gli elementi del vettore


'
s con gli interi pari da 2 a 20 * /
#include <stdio.h>
#define SlZE 10

s[j]

=2

/* imposta i valori */

+ 2 j;
1

printf("%s\13s\n", "Element~, "Valu~' );

for (j = 0; j <= SIZ.E - 1; j+-i-)

return 0;
}

Assegnare un vai.ore a una costant.e simbolica in una istruzione es11guibile 1m errore di


sintassi. Una COf'ftlflte >imbolica non una variabile. IL compilatore non le riserva nessuno spaz;o di mmwria, come accade invece con /,e Mriabili che commgono dei valori
durante L'eseettzione.
Ingegneria del software 6.1
Definire In dimensione di ogni vettore con una costanfe simbolica render i programmi
pi scalabili.

~Jemenci in[eri. I.:istruziooc nd corpo dcl ciclo for m ;guir iJ calcolo del rotale-

<= SIZE 1; j ++)

printf('%7d%13d\n ,

Erro1'e tipico 6.5

11 programma nella Figura 6.6 sommer i_ valori eom_enuci n un vercore a di dod ici

int s[SIZE.J, j i

0;

Se la precedente direrriva: del preproce-~sore fosse stara terminata con ua punco e virgola~ mere le occorrenze della cosrame simbolioo SIZE incluse nd progpmma sarebbero stare
sostituite dal preprocessore con il cesto 10;. Ci avrebbe potuto provocare degli errori di
si'ntassi durante la compi lazione o degli errori Logici durame l'esecuzione. Ricordate che il
preprocessore non il C: solo un manipolarorc di resto.

Utilizzate soltanto dei/e lettere maiuscole pe1 i nomi delle costanti simboliche. Ci le
roidenz:r a/L'interno del programma e ricortjer a[programmatore che le costanti simboliche non sono delle v1.~rzbili.

Generare i valori da inserire negli elementi di un vettore.

Bruma abitudine 6.1

ma in()

for (j

Figura 6.5

s[ j]) ;

/*visualizza

valori" /

Il nosrrn esempio urlixzer dei vettori per riassumere i risulrari dei dati raccolti durante un'indagine. Considerare l'enunciato del problema.
>th.to chiesto o quaranta. studenti dfomire zm.a valutazione .sulla qualit dt>L cibo servito
nella mensa dello studente, in conformit a una 1ca/,a da 1 a I O (1 significa tenibile e 1O
eccellente). Sisterrulte i quai-ama responsi in un vettore di interi e riassumete i risultati dei

sondaggio.
/* Calcolare la somma degli elementi del vettore * /
#.incJ.ude <stdio.h>
#define SIZE 12

(e01rti.nua)

C.wrrOLO 6

182

lVEUORl

ma in()

main ()

int a[SIZE] = {1 1 3 1 5, 4 1 7, 2, 99, 16, 45, 67, 89, 45} ;


i nt i 1 tot al = 0;

183

int answer, ratin11;


i nt responses [ RESPONSE_SIZE] = {1, 2 , 6, 4 , a, 5, 9, 7, 8,
10, 1, 6, s, 8 , e, 10, 3, a, 2, 1, 6 , 5, 1 , 6, 8, 6, 1,
5, 6, 6, 5, 6, 7, 5, 6, 4, 8, 6, 8, 10};
ir'lt frequency[ FR'EOUENCY_SIZE] = {0'};

0 ; i <= SIZE - 1; i H)
total += a[il;

f0 r (i

for(answer = 0; answer <= RESPONSE_SIZE - 1; answer++)


++frequency[responses[answ er l li

printf('Tot al of array element values is %d\n", total);


return 0;
}

Figura 6.6

printf( "%s%17s\n, "Rating , "Frequency " );

Total of arl'ay element va lues is -38'3

for(rating = 1; rafing <= FREOUENCY_SIZE . 1; rating++)


pr intf("%6d%17d\n", rating, f r equency( r ating]);

Calcolare la somma degli elementi di un vettore.

Q uesca una tipica applicattion e dei veCToci :{co.nsulcace .la Figura 6.7). Vogliamo riasSllmere il nwner d ei responsi di ogni ripo (vale a d ire, da 1 :i 10). LI vettore responses
sar d u nque formato da 40 elementi che comerra.nno le risposce degli srudeoci. Utilizzeremo uo veccore di undici elementi, f requency, per contare il numero di occorrenze di ogni
responso. lgnoFeremo il primo elemento, frequen c y[0 ]. perch pi logico incremenmre di 1 il responso f requenc y [ 1] che f r equency [ 0 ]. Ci ci consenrir di miliuare
diretcameme ogni responso come indice del venare frequenc y.

ret u r n 0 ;
}

Buona abitudine 6.2


Adoperat~i per la

chit1rezt;11 del progrilmma. A volte potr essln utilerftl1J1u:1/e ad uri


iufo:vm:e-rj'i 1{na ~eritt1m1

11so piu efficiente dt'Lla rnem<1r1, o de.I tempo.dcl proe.rsore,


pi chiara dei programmi.

1:

Rating
1
2
3
4
5
6
7
8
9
10

Fr equency
~

2
2
2

5
11

5
~

Obiettivo efficienza 6 1

A volte L'elemento de/L'efficienza ha molta pi importanza di quello della chiarezza.


Il pdmo ciclo for rilever le risposte, una per volta, dal vettore responses e incrementer uno dei dieci conrarori (da f requency[1] a frequency [ 10]) inl.usi nel vettore
frequen oy. l:imuzione principale nel ciclo :
++frequency,[rspo nses t answer]J;
Q uesta istruzion e incrementer in frequency il comacore appropriac secondo il va.lare di
responses[answer]. Per esempio q uando la variabile coocarore. answer varr 0 ,
responses[answer] varr 1, perci ++frequency[responses [ answer] J; sar;i inrerprerara in realr come
++frequency[1 j;
/* Programma per i l sondaggio degli studenti
#include <stdio . h>
#qefine AESPONSE_SIZE 40
#define F REQU EN C~_S I ZE 11

~1

Figura 6.7

Un semplice programma per l'analisi del sondaggio degli st udenti.

cheincremenrer l'elememo uno del vcccore. Quando answer varr 1. responses [answer]
varr 2, perci ++frequency [ responses ( answer]]; sar interpretata come
++frequency(2J;
che i,ncremenrer l'elemenco due del veccore. Quando answer varr 2, responses [ a nswer J
varr e; perci ++frquency[ responses [ answer]]; .sar interpretata come
+H r equency l 61 i

che incrementer l'elememo sei dc.I veccore e cosi via. Osservare che, indipendememenre
dal numero dc:lle risposte elaborate nel sondaggio, per riassumere i risulraci sar necessario
un"Vetrore di solo undici demenri (ignorando quello con indice O). Qualora i dari concenessero dei valori non validj , come 13, il programma avrebbe centaco dj aggiungete l a
f req uency[13] . Quesro indice per avrebbe superato i timici del veccore. Il C non ha
nessun controllo mi Limiti dei vettori che consentii di evitare che il computer faccia riferir>terr.to
a un elemento inesutentl/. Ne consegue che un programma in esecuzio11e porrebbe ol.rrepassa.te i conft.ni d i un vttore sen~ alcun avviso. Il p rogrammatore dovr quin di assieurarsi.
cbe tu rti i riferimenti al vettore rimangano all'interno dei suoi lim iti.

184

CAPITOLO

E1rore tipico 6. 6
Fare riferimento 11 un elemento errerno ai limiti del vettore.
B11011a

Element
0

Value
19

2
3
4
5
6
7
8
9

15

abitudine 6.3

Quando scorrere un vettore, il mo indice non dovrebbe mai scendere sotto lo Oe dovrebbe
essere sempre inferiore al numero totale degli elententi indusi nel vettore (dimensione I). AJiicuratevi che I.a condizione di terminazione del ciclo prevenga l'accesso a elementi esterni al sudderto imervall{J.
Buona abitudine 6.4

Menzionate l'indice pi alto di ttn vettore in u:ru1 struttura tor, in modo dd aiuture a
climinal"c gli errori di imprecisione-di imo.
Buona 11bintdinc 6.5

) pogmmmi dovrebbero vi:rifli:me lb g,1-rh:te'zza di tutti i v1dori presi in input, in modrJ


da evitare che delle informazioni emJtepssno influenzo.te i calcoli di un programmtt.
Obiettivo efficienza. 6.2

Gu effetti (11ormalmeme gravi) di riferimenti a elementi esterni ai limiti di un vettore


dipendono dai sistmut.
Il nostro prossimo esempio (Figura 6.8) leggera alcun.i numeri da un vettore e preseoccr
quelle informazioni in un grafico a barre o isrogralnma: a fianco a ogni numero sar visualizzato
una barra composta di alrreuanci asterischi. Il ciclo for rudincaco disegner effenivarneme le
barre. Osservare l'ucilizzo di printf ( \ n ) ~ renninare ogni barra dell'istogramma.
/ * Programma per la visualizzati!)ne d::i,
#i nclude <stdio.h>
#define SIZE 10
;

i~tog rammi

185

VETTORI

Figura 6.8

11
9

13
5
17
1

Histogram
..,.~

* 11"*** 'lt lr-lo i!**

***

"'***-**lt.***'*****

.........*'..

,,. **.'I*~~-
**-** ..****
**'******":*:***
"'****

lr ... ***-'!: +;.*dt."ri. lr ...........

"

Un programma che visualizza Istogrammi.

. _ Nel Capirol~ 5, abbiamo affermaro che vi avren;:urr rilosu:aro un metodo pi elegante


diqueUo dcUaF1gura 5.10 par scrivere il programma di }ruJci dei dadi li problema richiedeva di lanciare 6000 volte un dado con sei facce, in mlo da verificare se i.l generatore di
numrj casuali producesse effecti.vamence dei valori a caso. Nella Figura 6.9 mostrata
una -versione con vettori dello scesso programma.

Fino a quesro ptmro abbiamo discusso solranco dei vetto[i di interi. I vercori per sono
in grado di conservare dati di qualsiasi ripo. Discuteremo ora dell'immagazzinamenco delle
stringhe nei vettori di cararceri. Pi.no a questo punrn, l'unica capacit di elaborazione delle
stringhe di cui abbiamo crarraro stara la stampa di una stringa con printf. Nel linguaggio C una stringa come "hello" in realt un verrore di cararu:.ri individuali.
/* Lanciare 6000 volte un dado a sei facce */
~include

<stdio.h>
#include <stdiib.h>
#include <time.h>
#define SIZE 7
ma in ()

main()

int tace , roll, trequency[SIZE] = {0};

int n[SIZEl :: {19, 3, 15 , 7, 11, 9 1 13, 5, 17, 1};


int I j j

srand(~ime(NULL));

prin'tf.( "%s%13s\17s\n" , "Elern!lht"J "V?l.u.i;l", "Histogram")i

f6r (roll = 1; ro ll <= 6000; roll++) {


tace= rand() % 6 + 1;
++frequency[face];
I* sostituisce lo swtch di * /
}
/* 20 righe della Figura 5.8 */

for (i= 0j i <= SIZE - 1 ; i++) {


printf('' %7d%13d
, i, n[i]);
for(i = 1; j <= n[i J ; j++)
printf("%c'', '*');

/* visualiLZa una barra */

printf( "\s%17s \n", "Face, "Frequency')i


for (tace= 1; tace<= SIZE - 1; face++ )
pr intf( "%4d%17d \n", tace, frequency[face])i

printf("\n ' );
}

return 0;

return 0;

(contimill)

186

CArrrnLo6

Fa ce

farro con le altre variabili . Normalmenre l'operarore & utilizzaro per indicare a scanf
la posizione di una variabile all'interno della memoria, cos che vi ci possa imrnaga:u.in.are un valore. Nella sezione 6.5 discmeremo del passaggio dei veaori alle funzioni.
Vedremo che il nome di un ver;rore in realt l'indi.rizw dd suo primo elemento;
proprio per questo motivo che l' opcrarore & non necessario con la scanf.

Fr equency
1037
987
1013
1028

2
3
4
5
6

95~

983

Figura 6.9

Programma per il lancio di un oad c he utilizza i vettori invece di una


struttura switch.
Fi.no a questo punto abbiamo discussQsolranto dc;i vettori di interi. J verrori per sono
in grado di conservare daci di qualsiasi cipo. Uisqicercmo ora_ddJ' immagazzinamenco delle
stringhe nei veuori di caratteri. Fino a questo punro, l'wca capacit di elaborazione delle
srrmghe di cui abbiamo rratraco s tata I.a scampa di una srringa con pri nt f . N el linguaggio C m1a srringa come "hello" in realt un vettore dl caratteri Individuali .

l veuori .di cararte~i hanno molce q ua:lic, singolari. Essi possono essere ini"l.ial izzari
utilizzando una stringa lerterale. Per esempio la d ichiarazione
char string1[] = 'first';
iniz.ializzer gli elementi del vercore string1 con i caratteri individuali della stringa letterale "first . La d imensione del vecrore string1 della precedenre dichiarazione sar decerminata dal compilatore in base alla lunghezza della stringa. importante notare ch e la
stringa f irst conterr cinque caraneri pi n9 speciale, deno carattere nullo, per la
reonioaz.ione della stringa. Di consegueru<L il veuore s tring1 conterr in realt sei dementi. La rapp rcsen razione come coscaoce di caranere del cararcere nullo '\0 '. Turce le
stringhe in C cerroinano con quesco earaccere.. Un ven ore di caraaeri cbe rapp resenti una
srringa dovr sempre essere dichiaraGl con una dimensione sufficiente a contenere il numero dei cararteri della srringa e quello nullo di terminazione.

J vecrori di caracreri possono an che essere ini7.ializzati con singele costanti di caranere
sistemare all'interno di una lista di inizializza,tori. La dichiarazione precedente equivaleore a
char string 1 []

= {'f',

'i ' ,

187

1VEIT0RI

r',

s'! ' t ', '\ 0 '};

responsabilir del program.marore assicurarsi che il veaore destinarario sia in


grado di contenere qualsiasi suinga l' meme possa digirare alla rascicra. La funzione
s canf Legger i dari dalla tastiera finch non avr inconrraro il primo carattere di
spazio bianco: non si preoccuper di quanro sia grande il vertore descinacario. Di
conseguenza, sca nf porr scrivere anche olcre la fine del vetrore.

Errore tipico 6. 7
Non fornire a scanf u.n vettore di camtteri St,(,ffidr~temente grande pt:r imrrlllgnzzinnrc
tt1ir1 stringa digit'titrl ali.a tastiertt, poh" causare in tm progrdmrna una p1:1-dita di dati e
altri errori durnnte l'iecitzione.
Un vetrore di caratt;eri che rapp resenrj una s.tringa porr ssere inviato in ourpur
il venore stri ng2 sar visuali.z.zato con
l'ismiz.ione

~on pri ntf e la speci fi ca di conversione !\ss.

printf( "%s\ n", string2);


Osservate che anche p ri ntf , come sc a nf , non si preoccupa di quanro sia g rande il
vettore di caratteri. I caratteri della srringa saranno visualizzaci finch 1100 verr inconrraro
un carattere nullo di terminazione.

La Figura 6.10 mostra l'inizializzazione di un verrore di cara.aeri con una stringa le.ccerale, la leccura d i un a stringa in un vermre d i cararceri, la stampa di un vettore di caratteri
come una srringa e l'accesso ai singol i caratteri di una srringa.
/*Trat tare i vettori di caratteri come stringhe */
#include <stdio.h>
main()

ctiar string1 [20], s t ri ng2[ 1

~st ring

literal";

Daro cbe una stringa in realt un venre di caratceri, potremo accedere direttamente
a ogrruuo dj essi uriliz1.ando la notazione con gli iodiei di vercore. Per esempio, s tri ng1 {0)
sar il car<'tttere 'f ' menrre string1 [3] sar 's '.

int i;

Porremo anche prendere in input-dalla mstiera w1a stringa e siscemarla di rettamente in


un vettore di cararreri, u tilizzando scanf e la ~ecifiqi di conversione !\ss . Per esempio, la
dichiarazione
char string2[20];

print'f("Enter a s t ring: ");


string 1 );
printf ( 11 string1 is: %s\nstring2: is %s\n"
"stringi with spaces bet wen chara cters is: \ n'',
string1, string2);

creer un vecrore cli caratterj io grado di immagazzinare una stringa di 19 caratteri olrre a
quello nullo di terminazione. I.:isrruzione

fo.r ( i = 0; s t ring 1[ i ] I= ' \ 0 ' ; i ++)


printf( "%c ~ . string1[i]);

~canf ( "%s",

scanf( "%s " , s t rng2);


legger una scrioga dalla casciera e la immagauiner in string2. Osservate che il
nome dd veaore srato passato alla s canf se:nza farlo precedere da &, come abbiamo

p r i ntf( " \n " );


r eturn 0 ;
}

(etmtimUJ)

188

CAPITOLO 6

Enter a string: ~ello there


is: H~tlo
string2 iS: string literal
stringt with spaces between

189

t I vettori statici sono inizializ zati a zero * /


#inolude <~tdio.h>

str~ngt

He l 1 o

I vrnoru

char~cters

s:

Figura 6.1 O Trattare i vettori di caratteri come stringh~.

void staticArr aylnit(vo id);


void a utomatic Arraylnit (void);
main ()
{

printf( First cali to each function: \n'') i


st aticArr ayinit();
automati cArrayin it();
printf( "\ n\ nSecond call tO each function :\n ") i
staticArr ayin it();
automaho Arrayinit () ;
return 0;

La Figura 6.10 ucilizZ. una scrurrura for per scorrere il vettore string1 e visualjz~.re
i singoli ~atteri_, separati da spazi, milizzando la specifica di conversion e ~c . La condizione della smmura for , stringt [i] I= '\ 0' , sar vera finch nella srringa non verr
inconttato il cararrere nullo di rerminazione.

Il Capicolo 5 ha trarraco la specifica cli classe di memoria static. Un variabile loc;ale


static dichiara.ca all'iorerno di una definizione & funzione esister per runa la durata di
un programma, ma sar visibile solcamo nel corpo della funzione. Ponemo applicare static
alla dichiarazione di un vertere locale, per fare in modo ch quesro noo sia crearne inizializzato
ogni volta che la funzione sar imrocara, e che non sia discrurco ogni-volta che il programm a
uscir dalla funzione. Ci ridurr il tempo di esecuzione dd programm a, io modo parricolare per quelli ch prevedono frequenti iovoooon i di funzioni che dichiamoo dei veEtori
di dimensioni ragguardevoli.

I * funzione per di mostrare l ' uso di un vettore locale statico * /


vois staticArr ayinit(vo id)
{

st'at i c int a [ 3] ;
int i;

Obiettivo efficienza 6.3

printf("\n Values on e ntering staticAr rayinit:\ n ");

Qualora una /unzione cnmbiMse fretj11mtemente il suo stato di visibilit e contenesse


dei vem>ri automatici, questi d!Jvrebbero essere resi static in mod!J da evitare che siano
creati <rgni volta che fa fanzione sar richiamata.

tor ( i = 0; i <: 2; 1++)


printf( "array1[% d] = %d

f vercori dichiarati static saranno iizializzaci aucomacicamenre una sola volra, durante la fase di compilat..ione. Qualora un venare static non fosse sraco inizializzato
esplicitamenre dal progralUnator~, sarebbe azzeraco dal compilawre.

ati));

printf("\n Values on exiing staticArr ayinit: \ n" );


tor (i = 0 ; i <= 2; i++-)
pri nt f ( "array1 [%dl = %d

La Figura 6.11 JllOStra la funzione staticArr aylnit che utilizzer un vercore locale
dichiaraco static, e una fum,ione automati cArrayin it che user invece un ven:ore
locale amomaric.o. La funzio ne staticAr raylnit sar ri.chiamarn due v9lre. Il vettore
locale static dichiararo nella funzione sar azzerato dal compilacoI"e. La funzione visualizzer
il vettore, aggiunger 5 a ogni suo elemenro e lo vlsualiu.er nuovamen te. Quando la
funzione verr rkhiamaca _per la sec<;>nda volta, il veccore static coo(crr i valori immagazzinati durante la prima invocazione della funzione. Anche la funzione automtic Arrayinit
sar tichiamaca due volte. Gli elementi del vettore locale aucomacico dichiarato nella funzione saranno inizializzaci con i valori 1, 2 e 3. La funzione visualizzer il vettore, aggiunger 5 a ogni suo elemenco e lo visualizzer nuovamente. Quand0 la fw1zione verr ric.::hiamara per la seconda volca, gli elementi del vercore saranno nuovamente inizializzaci a 1, 2 e
3 poich il vettore avr una permanenza aucomarica nella memoria.

i , a[il += 5)j

}
f~ funz ione per' mostrare l ' uso di un vetto re locale automatic o *I
vod automati cArrayln it(void)

i nt a[~l
int i;

{1, 2 1 3};

printf( "\ n\nValues on enteri ng automati cArrayin it: \n") ;


tor (i = 0; i <= 2; i++)
printf( "array1[%dJ = %d

0[i]) j

Errore tipwo 6.8

printf("\n Values on exiting automatic Array init:\nijl i

Presumere che gli elementi di im vettore locai.e, che sia stato dichiarato static, siano
azzerati ag12i volta die sar richiamata la fonzione in cui il vettore stato dichiarato.

for (i

= 0;

i <= 2; i++)

printt( ija rr~y1[ %d ]

= %d

i, ali) += 5);

(continua)

190

WffbL06

F!irst ~-1;. to eaeh funotto:n:


Value-s on ~nt-e.riong statiGArrayln't:
array1[0J' = 0 ~ rray1l = 0 array1[!2.]., 0
Val.ues. 't>Q ltXiting s.'t'iJ\ ieAr.-raylni.Lt:
ar.'~~y1{0J =- 5 .arrvay1[1j = 5 -<ttr'y1[2] =5
Vi~lues Oli errt~J'-in.Q automraticArrl!~!n!t:

'PraY,ll!l.fl.J = 1 arl?a,y;2[1 l
V~I11~s

=~

arr.ay2t~l ~ r4

Oll eJ<'*';L;ftfl a:LI""to111a1J..0Ar.raytn'it:


e ~~ray_~(1J = .,., arl"afif')

al"r-ay2r0r=

Valffes S:R
~PPQ.V<1 !0]

.on

= -~.

,e!5!,~~ng

'2J

Liil

'aPra$2~tJ

"'!:

2 ~pr~~~1'2l : ~

~e<S on &~~t:<i:n:g ~utomatie-h:P'P~~Init:


~rray2[Q.~ -= 6'' ,af'~lil~.2( ~ .J = 1' !ff~j'.2 (2.)

Obiettivo efficienza 6.4

ll passa~io dei vettori iJ:Z una ,h!'rnataper riferiflf.iifo 1rul4t.ttt. h'ti U:n senso. per ragioni di efftien7,;1z. 1'ijlztti;_passan: unvettore pr valore iip.1ifc4 pmsdre unacopiti di ognuno
t/i siH eLetifenti. Ovvit.zv~e1it,e, per dei v11ttw.i. di dimensioni ragguardeuoli passatifit!qua7itemenfe, ci sarebbe dispendioso in termini di r:empo e si w7mtmerebbe itnaonsidert:110le quantit di memor:ia.per I.a lm"O copia.

/* t1 r'lme di un vettore equivalente a &ar.ray[0J '!!./


#nclud !<stdio.h>.
main.()

Vi..a.lue:s e.A ~ni:eR~ng ~u"j.;,~llfa'ti~A~R<l'YI-noi}-:

i:l"r~ir'U -,,,: i

191

t!sai:;l per vL~l)aliizarq.gli indicizzi. Laspedfca di conversione %p normalmente visualizza gli indir2Z corhe numeri esadecimali. 1 numeri esade<i;in:m.li (in base I 6) si;mo forma.ti dalle cifiei:d~.O a 9
eda.Ue lettere da A a .F. Essi sono uriliza.ari spes;s9 come nor.az.iom:.:abbi;tvi,aca per dci v.lori. interi
g~andi. tAppcndie.e E, "I ~isremi numerici", fomis-ce un~ trarraziomi approfondira. sulle ~ela.zion.i
.rra:gliJ:nreri binaci (in base 2), gli ottali .(io base 8), i d~irna.li (in base IO; gli i.rireri-srandard) e gl.i
~~decimali. Cou:tp~1t1m;istte)" che aiiray e &arry [0 J av.ranno:Io sresso v.lor, vale a ~fae F.FF.0.
I..ipurput.di (JLi_St'o progti:tuina di_pendet dal sisretna, ma gli indirizzi saranno sempre identiei.

en;t~pi,n.g ~a~~A.r.RJlyln,'i.t-:

~r'ra~ tt f4J ,. '5 arrB1yi '2l -= -5..


S*.!iti'OArrtay In.it~
.
am~~1[0J ;:: 1,10 '1fr:ray 1n J "';' 1~ a:p,r-l!iY.1
= 10

Va1ueis

] VEJITORL

='

char array[5J;
pd.ntf ( lo

arr:ay .:: %p\n&array r0] : %p'\ 0 li 1

array, &array[0]);

Figura 6.1 I I v~ttari. statici saranno azzerati _automatic;llTieme; qualora non siano.stati

return 0;

inizjalizzati ~plicitamente dal programmatore.

6.5

Passare i vettori alle funzioni

Indichere[e il nome.del vettoresenza. paremesiq.uadre per passa.re a una JiUIZioii~ un argomento


d.i quel po. -J?-er .esempi~ ~e .il..vbwre hour1yTemper atures fosse staro dichia.ram come
irit heurlYTempratufesf 24 J ;

l':istt.uzioae per la chia:111ata della funzl:one

~rra,y =-

&arr~~(0J

FFF0

=- Fi:F..0

Eigura 6. 12 Il nome di un vettor-e equivalente all'indirizzo del suo prime;> e lemento.

~ Ingegnm,ia.del software 62

modi'fyMray(hourlyTemperatures, 24-) i

p.;issereb.be il ve.ttot~ ho1,1rlyTemperatures e la. sua dimensione alla.-f;i:inzione ~odif~Arra~.


Q.u;i.:ndo $.i p.Ssa a lUl<I, funzione Ili'.) v~r<;>re, sp.esso sar passata anche la sua dimensione, 1~
motlo che fa funzione pssa elaboru,e il 11umcr9 spe.i.fioo degU eJ.ernenci in:duSi nd verror~ Il C
passa i vert0ri ru.le fumoru u.riliz1.arfdo aurmaricamerrre una cliiamam p:cir cifetiti:tenro sim.ufata:
la funzione chiamara porr .modificare i valoti dgli. elmeri inclusl nel vetrQre 0tiginale dd

te, d.a11\tltro i suoi singoli e!em~ri.smfl passati pervalote esato~..irien \e me_actacleper lesempliti

chiama.me. ll nome del vettore in realt l'indirizzo del suo .primo elemenw! Daro che sar
passato l'iodiri220 lnizlal~ dd vrtor, la funi.ione chiamar.a. conoscera precisamente le locazioni
in cui q~t\Jcimo ~rac~ m~orizzarp, Di "onsc:gueoza, quando a.ltimemo del suo corpo la
fi:rmione dllinata modifiche.. gJj dem_nci ~I v.rtort; ~a sr modi.fieando effettiva:rnence
quelli del .c;hiapiante dirertam!'lte. nelle lorq lacZ.ioni di mrndti!j: ocigi.n;i.rie,

La Eigura 6.12 cl:im_ostrero che-:il nome di un venofe in realt l'incilma:o del suo pcimo
e.lem~mo, vis!Jafuzando, ar~y e &array[0] e usando %p: una spe~~.spcifka di ,.onversione

Sar>p,qssibi{f!,j>assa'rt: ttn-tiettoreper iJii!pr, 7.fti/iZZ(l,tu/,p


remq nel Ca.pitoh IO:

i'rt st:mp(ice mtco che spighe-

S.e&t un lato i vmori eompleci sono passa.ti con uua&mulazione de~ G.b.iatna.ta. p:Cr rifcrimen~
variabiJi. Qti~ci semp.lici.siagoli pezzi di dat),sgno dc;tr.i scal~ri o tjil!t1J:#t{J siJ./ifi. Per p:!S.Sarea una
on<; p:n_el~meot9 di un v<;i;rote; uriLiZZ(?reteil .suo nme tn<li.cizizati:> come argoiento nella
,~~tjtdeUa_funzisine. Nel 01piwlo 7" mo-sermo eome siri:rnl:te rrrra.chiamata.per rifeci.men~o p:w,.gll ~ari (ovyerosia, per le sing0lev.i:ribili e gli elemeflti dei vettori)',

La liru..~~i parametri di una fonz.ipne dovr~ s_pecif<;are .es.pliciramente th.e sar rkevufo
u1n:ett~et affint:b_. quest-0 _possa~ere ric;aruro arrtaveri la diiamaca. Pe.1' esempi.o., .l'ini:esrai iqne p.e_i: la funzione modifyArray poa:ebbe esre.re.scrftta ron:ie

1/oid modifyArray(irit b[J,

int

!?iz~)

192

CAPITOLO

J vrri-roru

e Lndicherebbc che modifyArray accetter nel parametro b un veccore di inceri e in


size il numero degli clemenci inclusi nello stesso. La dimensione del vettore all' incerno delle parencesi quadre non obbligatoria. Qualora fosse stata inclusa, il compilarore l'avrebbe ignorata. Dato che i verrot=i so.no passati aucomatica.mence con una chiamata per riferimenco simulata, quando la fwuione chiamaca urilizzer il nome del
vettore b, in realt far riferimenco a quello effecrivamenre dichia.caro dal chiamante (il
veuoce hourlyTemperatures nella chiamata precedente). Nel Capicolo 7 incroduricmo alrre notazioni per indicare che un veu:Oie verr ricevuto da una fum.ione. Queste
no.razioni, come vedremo, sono basare sull srrena correlazione che intercorre ua 1
vettori e i puntarori del linguaggio C.

printt ( Effects of passing enti re array c al "


' by reference:\n \ nThe val ues of the
"original array are:\n");
far (i= 0; i<= SIZE 1; i++)
printf( "\3d " , a[ i J);
printf( "\ n" );
modifyArray(a, SIZE); / * i vettori sono passati per riferimento /
printt( "The values of the modified array are:\n " );

Osservare lo sc:rano asperro dd procotip.o di funzione per modi fyArray

f ar

voi d modifyArray(int (], i nt );


Avremmo poruto scriverlo anche come
void modifyArray(int anyArrayName [ ), i n'I;

~ Buona abitudine 6.6

Alcuni programmatori includano i wmi de!li! vttriabtli all'intemo deiprototipi di fimzione,


in mada da rendere pi chiaro ii programma. Tuttavia, il compilatore li ignorer.

void modifyArray(int b(J, int size)


{

int j;

Ricordare: il procoripo indica al compilatoce il numero degli argomenti e il tipo di


ognuno di quelli che vi appaiono {nell'ordine in cui saranno convalidaci).

TI programma ddla Figura 6.13 mosrrer la differenza tra il passaggio di un incero


vettore e quello di un suo dememo. Il programma visualizzer in primo luogo i cinque
elememi del vertore di interi a . lrr seguiro, a e la sua dimensione saranno passaci alla
funzione modifyArray, dove ogni elemeruo di a sar moltiplicaco per 2. Quindi, a sar
visualizzaco nuovamente alJ' intemo di main. Come dimostrer l'oucpur, gli dementi di a
saranno srari indubbiamente modificaci da modi fyArray. A quesro punto il programma
visualizzer il valore dJ a [ 3) e lo passer alla fumione modi fyElement. Quesca molriplicher per 2 i suoi argomemi e visualizzer il lqro nuovo valore. Osservate che, quando
a[3] sar visualizzato nuovamente all'in r~.mo di main, esso non risulter modificare perch gli elemenci individuali dei vettori sar;mnc;i scati passati per valore.
1~ Pas sa~e alle f unzioni i vettori e i singoli elementi di un vettore */
#include <stdio .h>
#define SIZE 5

void modifyArray( i nt [], int);


vo i d modifyElement(int);

1~ s~ mbra

main()
{

int a[SIZE]
int i;

(i~ 0; i <= SIZE


1; i ++)
prfotf( "%3d", a ( i));

printf("\.n\n\nEffects of passing array element call"


"by val u e:\n\ nT~ e valu e of a[3J is %d\n 11 , a[3 J)i
mod ifyE_lement(a[3));
printf( "The value of a(3) is %d\n", a[3J);
return 0 ;

anyVaria b leNam~);

ma, come abbiamo appreso nel Capitolo), il compilatore C ignora i nomi di variabile
posti all' interno dei prococipi.

193

{ 0 I 1 1 2 l 3, 4.} j

strano */

for (j = 0; j <= size . 1 ; j++)


blj) *= 2;
}

void modifyElement(int e)
{

printf("Value in modifyElement is %d \ n ", e*= 2);


}

fff.&cts of passin:g entfre array eall hy r.efe1renc9:


T~e valu~s o~

ttie originai arra~

0
The

ar.:

values o'f tl'le niditied array ar.e :


2

4. 6

Effects of

pas~ing

array element call

by

value:

Th value of a[3) ia 6
Value in odifyElement ls 12
The value of a[3J is 8
Figura 6.13 Passare alle funzioni i vettori ei suoi singoli elementi.

....................... .................1911...................... ...............aj


194

CAPITOLO

Nei vostri programmi, ci saranno molte situaiioni in cui a una funzione non dovr
essere consenciro di modificare gli elemen t i di u n ven:ore. D aro che i vea:ori saranno
semp re passati per riferimen to simularo, sar difficile conaollare che i valo ri non
fornisce lo special~ qua.lifcatore di tipo con st proprio per
siano m odificari. l i
prevenire, all'interno di una funzione, la modifica dei valori conrenuci in un vertore.
Quando un parametro di cipo vetcore sar preceduto dal q uaLfcarore c o nst , i suoi
elementi d iventeranno delle costan ti nel torpo della fu nzio ne e ogni rencacivo di modificarli, in quel concesco, p rovocher un_ euore in fase di compilazione. Ci consentir
al programmatore di correggere un programma in modo che non provi a modificare
gl i clemen ti del vercore. Per q uanto il q ua.life_a tore c on st sia scato ben defniro nello
scandard dell'AN SI, i vari sistemi C no.n lo appli<:'ano allo stesso modo.

VETTORI

COmpillng FIG6_14.C:
E~ror FIG6_14.C 1o: Cannot mod if~ a ~onst object
Er r or FIG6_14. C 17: Cannot modify a const obje.ct
Er ror FIG6_14 .C 18: Ca nnot modfy a const object
Wa r ning FIG6_14 . C 19: Par ame'ter ' b ' i s never us ed

.La Figura 6. l 4 mosrra l'uso d elqualifca.tre con st . .La funzio ne t r yMod ifyArr ay
s;tr definira con il parametro cons t int b [ ), il quale d ichiarer il vettore b come
una costan te che, in q uruuo cale, no n porr esere modificata. L'o urput mostra i messaggi dj en orc che saranno e messi dal compilacere Bo.rland C ++. I ere rcnracivi della
fu.azione di rnodifcare gli elementi dd vertore p rpvocheranno ognuno l'errore "Cannot
modify a co ns t o bj ect . " ("Lnpossihile modificare un oggetto const.") del compilarore. li q ualifcacore c onst sar discusso nel Capirolo 7.

~L_s0Lifw.~a-~_e_6.~.3~~~~~~~~~~~~~~~~~~~
~ia_de
rti("l _l~1zg;~e2-gn_er

Nella definizione di unn fa1rzJne, il qualij{clltore di tipo const potr mm applicato


a un parametro di tipo 11ettore, per evitare he il vettore originale sia modificatn net corpo
della funzione. Questo un altro esempio del principio dei minimo privilegio. Alle fonzioni non dovrebbe essere mai tUita la possibilit di modificare un vettore, sempre che
non sia assolutamente necessario.

Dimost rare l ' uso del qualifi catore di tipo const */


#include <stdio. h>

figura 6. 14 Dimostrazione dell'uso del q ualificatore d i tipo c onst.

6.6

ma i n ()
{

i nt a [ ] = {10 , 20,

~0} ;

tryToModi fyArr ay( a) ;


pr intf("%d %d !\ld\ n", a [ 0J, &[11, a[2]);
r eturn 0 ;
void tryToModifyArray(con st i nt
{

b[ 0) /= 2
r= 2'
b[2] != 2'

b( 11
}

'

.,.,

I* e r ro re */
I* e rro re
/* erro r e

b [])

L'ordinamento dei vettori

T.:ordinamento dei dati (ovverosia, la loro siscemazione in u n ordine particolare, come


a.s1>endcnce o .d iscendenre) uaa delle ;i.pplicaz.ioni pi imporrami nel campo dell'elaborazione demonica. Una banca ordina rurci gli assegni per numer di i::ooco, cosl che possa
preparare i singoli esrrat:ti conca alla fine di ogni mese. Le comp;ign ie telefoniche ordinano
i propri elenchi per cognome e, nell'ambico di quello, per 110me, in me do da sempliGcare
la rieerca d ei numeri cclefonici. ln reoria, rurre I~ or:ganizzaz_io ni devqno o rdinare qualche
dato e, in molri casi, delle massicce quantit di dati. t:o rdina:menro dei daci un problema
inreressa:nte che ha arri raro alcuni degli sforzi pi intensi ddla rkerca informatica. ln
ge,sro capitolo, d iscuteremo quello che forse lo schem di ordinamento pi semplice tra
quelli no ti. Negli esercizi dd Capitolo lZ esam ineremo cori cura deg!L schemi pi complessi che forniscono prestazioni norevolmeme superiori.

Obiettivo efficienza 6.5


Gli algoritmi pi semplici sono rpersopoco efficienti. La loro virt la facilit con cu;
possono essere scritti, collaudati e messi a pmrtu. Ne co.nsegue che saranno spesso neces-

sari degli tdgormi pi complessi per ottenere il massimo dell'ejficienuz.

/*

void tryToModifyArray(const int [J)i

195

Il p rogramma nella Figura 6.15 ordiner in modo asendente i valori dei dieci elernenci .inclusi nel verrorc a. La tecnica d1e utilizzeremo dcrra bt.1bble sort(ordinameruo a bolle)
o sinking sort (ordinamento con sprofondamento), peh::h i valori pi piccoli "risalgono"
gradualmearc a galla sino in cma al verrore (la prima posizione), proprio come nell'acqua
fe bolle d'aria risalgono in superficie, menrre i valo ri pi grandi sprofondano verso i1 fondo
del yeccore (l'ultima posizione). La tecnica preve!e l'esecuzione di diversi passaggi sul
v~i;r9r~. I n ogn uno di essi sar confroa cata ogni coppia di elementi adacenti. Lasceremo i
v\dgrj c.osl come li avremo r:rovaci, q ualora un~ oppi!l si.a gi in o rdine crescente (o nel
ase che I valori siano identici) . I loro v.alori saranno invece scambiaci di posizione all'interno del vectorc, qualora una coppia sia i n ordine cleerScenre.
/'" Questo pr ogr amma ordina i n modo ascendent .e
i val ori di un vett or e */
-#inlude <stdio.h>
-#define S I ZE 10

mai n()
{

int a[SIZE] = {2, 6, 4,


i nt i, pass, ho"ld;

a, 10, 12, 89,

6~ ,

45, 37};
(a>ntinua)

196

CAPITOLO

printf ("Data items i n original order\n");

1;

pass <= SIZE

a[i]~a (i+1J;

/* passaggi I

1; pass++-)

for (i = 0; i <= SIZE - 2; i++)

/ * un passaggio /

if (a[i J > a[ i + 11 ) (
hold = aL1J;
a[i) = a(i + 11;
a(i + 11 = hold;

/ * un confronto

/ * uno scambio 1

pri ntf("\n Data items i n ascending order\ n 11 ) . ;


f or (i= 0; i <= SJZE 1; i++)
p rintf(~%4 d", a[ i]) ;

a[i + 11

ite~s

in original order
4

1e

12

89

68

45"

~1

Data items in ascending order


8 10 12 31 45 68 89
6
4
2
Figura 6. 1S Ordinamento di un Yettore con il bubble sort.

U programma confronrer prima a[9) con a[1] , quindi a( 1] con a[2] , poi a[2] con
al completamemo del passaggio con il confromo cra a[8) e a[9) . Osserva-

a[3] e cosi via fino

te che saranno eseguici solcamo nove confronti sebbeF1e ci siano 10 elementi. A causa dcl modo
in cui saranno effetruari i con&onci sucSSivi, in un singolo passaggio, un valore grande potr
muoversi di molte posizioni verso il fondo di dcl yttre, mencre un valore piccolo potr
~'luoversi di una sola posiz.ione v:erso l'alro. Dopo il primo passa~io, il numero pi g.rand si
sar s.icurameme adagiato sul fondo dl verrori!, V.vrsia a [ 9). Dopo il secondo pas.~aggo, il
secondo valore pi grande sar sicurameme.affondaro in a ( 8 ) . Dopo il nono passaggio, il nooo
valore in ordine di grandezza sar affondato in af 1] . Tutto ci lascer il valore pi piccolo in
a[0] , perci saranno necessari solo nove passaggi sul vettore per ordinarlo, nonostance questo
concenga dieci elernenci.

!:ordinamento sar eseguito dal ciclo tor nidificato. Qualora sia necessario uno
scambio, quesro sar eseguito dai ere assegna.mena

hold=a[iJ;
a[iJ = a(i + 1];
a[i + 1) = hol d;

a[iJ;

La vi.rc principale dcll'ordinarnenco a bolle la sua facilit di implemencazione.


L:ordinamento a bolle per lenro. Ci diventer evidenre quando si ordineranno dei

vet:cori di dimension i ragguardevoli. Negli esercizi svilupperemo delle versioni pi


effcienri dell'ordinarnenro a bolle. Sono anche srari:sviluppati degli ord inamenti notevolmente pit1 effcienci di quello a bolle. Pi ava.nei in questi) cesro, esaminerem.o con
,u.('3 alcuni di essi. I corsi pi, avanULci esamineranno pi approfondiramen ce l'ordinamen.ro e 1a ricerca dei dati.

Studio di un caso: calcolare la media, la mediana


e la moda usando i vettori

6.7

return 0;

Per esempio, se a [i) fosse 7 e a [i + 1 ) fosse 5 , dopo il p rimo assegnamento entrambi j valori sarebbero 5 e il 7 andrebbe perso, da cui la necessit della variabile suppleme.mare hold.

printf("\n ") ;

Data

197

dove la va riabile su pplemenca.re hold immaganiner remporanearnence uno dd due


valo.ci che dovranno essere scambiaci cli posto. Lo scambio non pu essere esegujro
con due soli assegnamenti:

for (i = 0 j i <= SIZE - 1; i++)


printf("%4d", a[i));
for (pass

l vrrrol\I

Co_nsjdereremo ora un esempio pi corposo. l cemputer sono utiliu.ati comunemente per


la compilazione e l'analisi dei risultaci delle indagini e dei sondaggi di opinione. li programma della Figura 6.16 ucili2zer il vercore response ia.izializzaro con 99 opinioni (iJ
et numero rappresencaco dalla coscame simbolica SIZE) raccolce durante un'indagine.
Ognuna delle opinioni sar un numero da 1 a 9. Il -programma calcoler la media, la
mediana e la moda dei 99 valori.
/ * Questo programma introduce l ' argomento dell 1 analisi dei dati di
un' i ndagine.
Esso calcola la media, la mediana e la moda dei dati */
~include <st dio.h>
#-efine SIZE 99

void
void
voi d
voi d
vo:id

mean(int [ ) ) i
median(int [ J ) i
mode(int [], i nt I 1) ;
bubbleSort(intr I );
printArray( i ntr I l;

main ()
{

int frequency[ 10) = {0}.


response[SIZEJ = {6, 7, 8, 9, !;!, 7, 8 J 9 , 8 , 9,
7, 8,
6, 7,
7, 8,
6, 7,
7, 8,

9,
8,
9,
8,
9,

5, 9 ,
9, 3 ,
8, 9 ,
7, 8 ,
8, 9,

8, 7, 8, 7,
9 , 8, 7, 8,
8, 9, 7, 8,
7, 9, 8, 9,
8 , 9, 7, 5,

8,
7,

9,
2,
3,

(amtin1U1)

198

CAPITOLO

5, 6, 7, 2,
7, 8, 9, 6,
7, 4, 4, 2,
4, 5, 6, 1 J

5, .a J 9, 4,
8, 7, 8, 9,
-5 J ;:i J 8 , 7,
6, 5, 7, 8,

I vmoru

6, 4,
7, 8,
5, 6,
7};

199

for (rating = 1; rating <= 9; rating++)


fre q(rating ) = 0;

mean(response);
median(response);
mode(frequency, response);
return 0;

for ( j =0; j <= SIZE. 1 ;


++f req[answe r[j]) ;

j t+)

pr1ntf('%s%11s%19s \n\n%54s \n%54s \n\ n",


' Response ", "Frequency, 'Histogram ,

void mean (int answer[J)


{

2' ' 5

= 0; ) <= SIZE 1 ; j ++)


total += answer[jj;

pri ntf ('The mean i s the ave rage value of t he data\n"


Mitems. The mean is equal to the total of\n"
"all the data iterns divided by the nu~ber\n'
"of data i tems (%d). The mean vaiue for\n"
'this run is: %d I %d = %.4f\n\n',
SIZE, total, SIZE, (flO?t) total I SIZE) j
void median(int answer [ ])

for (h = 1; h <= freq[rating ] ; h++)


printf("*" ) i
printf( '\ n');
}

printf( ' The mode is the most frequent value.\n "


' For t his run t he mode is %d which occu rred '
%d times.\n", modeValue, largest);
}

printf( \ n\s\n%s\n%s\n%s ",


"****"*** ", ' Melian , '**"'"' "'*** "
"The unsor t ed a ~r ay of respon~es is ");

v~id

bubbleSort(int a[))

int pass, j, hol d;

printArray(answer);
buhbleSort(answe r);
printf( ~ \n\nThe sorted array is")i
printArray(answer);
printf(~ \n\nThe median is ele:ment %d of\n 1'
"t he Sli>rted %d element ar r ay. \,n'1
''Far t l"! is run the medi.an is %d\n\n",
SIZE J 2, SIZE, answer[SIZ~ I 2]);

for (pass

1; pass <= SIZE 1; pass++)

for ( j

0;

<:=

SIZE

2j

j++)

> a[J+11 )' {


hold = a I j I;
a[j ) = a [ j +11 i
a [ j +1 J = hold;

if (a [ j J

}
}

void mode( i nt freq[ J, in t answer[])


{

1t1t* *"".

5 ');

i f (freq[rating] > largest)


largest = freq[rating J;
~odeValue = rating;

far ( j

pr intf("\n\s \n\s\ n\ s \ n' ,

tor (rating = 1 ; rating <= 9; rating++) {


printf ( "%8d%11 d
rating, freq [ratingJ);

int j , total = 0;

int rating, j, h, largest = 0, modeValue

0 J

Vid printArray (int a [ J)

int j;
for

(j

0;

<= SIZE 1; j ++) {

200

G'l_Pl1'0LO

if (j % 20 =

i[ ME'croru

2CH

0)

printf ( 11 \n " );

Ttle

.sQ~~ ~rr'~~ is
., .2 2 ~ t1 ~ s &, 11, ~ 4 '4 4 s e1 s fi a s. s
~ 6 6 '{i' ~ 6 6 61 6 6 '(f,, 7 'ife 'if il- il 7 7 7' '!/
7 7 1 7&. 7 71 i 7" 1. 1 7,. 7 7 e; 8 8 S:rie. $ ~

printf( 11 %2d", alj J);


}
}

tB88~~88881&BaBB~J$

Figura 6 . 16 Programma per l'analisi dei dai di un'indagine.

::S

La media proprio quella arirmetie::a cakolata sui 99 val0ri. La fum..ione mean c,akoler la media sommando i 99 ele.memi e dividendo il cisulrato per 99.
.

f}

a g i9. 9

!:),

;s

9 .9 9 9 9 'S ~

~ .~ ~,

Tfl J11e"d.f~n i'S u~m~nli: ~ ~


:t'fl,e ~. ~.a !ls; e1tim~TI~ arra~.
f'Q,r '14h:il 'f.llli ~h' me~l.,11n ~ 7'

1..a mediana. iJ "valo.re di mezzo!!. La funzione median determiner la mediana


:rkhhunando b.ubbleSort p orcLlnare in mado ascendente il vertore delle opinioni e
sdti0nare il valore di mezzo, answer[SIZE I 2J, del veaor oniinaro. Osservate
che qualora ci fosse un num~fO par.i di e.l(!menti, la m:ecliana dovre.b!:>e S'S'ere ealplata
eome la media dei due valoci di mezzo_,Al rnom:~tQ, la funzfone med.ian o.on dis.pqne
di que$.t a .facolr. La funzi'9 ne printArr'ay sar~ iuv.o c.ara per Lnviar in o~tt;putll yenore re~1:.1onse.
La moda il val:re ch ~i pr~senta pi trequencemenre era le 99 opinkmi. La
fun.z.i.me mode d~tetm.iner la moda cqntndp kocc_o-rr,etize di ~gni ri,po di op.iriione e
s_elezionand9 quella on. il vlore maggiore. Questa v.e1;sicme deUiJ. nlnZ!oae mode non
g~cir .n evenm~e pa.r.eggio (co,1lSWtare l'Eserdzio 6. i 4). La f um.ib.rl.e mode _produrr
~nd~"e un i$,togrmtria p-e r fornire un .supporto grafico alla determinazione deUa moda.
La..Pi_gma 6.17 ntiene un esempio di esecuzione di. q~esto prngrarnma. Que,ro e-$empi9
ctim.prend e la maggior P'!m : del1ri: c0muni manip9lazic;ull ciehies~ splitamen:re dai problemi ~he utilizzano i vecrori, inJ.~o il Loro pas.~aggio alleiun~igni.

1
0

2
.'0

2
5

1
~

8
4'.
g
6
7

2a

1;g

.fl*!-*.tt~

'3'
4
5.
8
g

"'' "*

11 .,

...

~.~ ~~

27

~e~TI

:'"*'*"'*'***

Th'e ~a~ .is ttre a~er11:~:e ~al~ g_f tifi~ ,d<ftQ;


it.R a,. Th~ 111ean ;t e-,,aua;J; ~t1> t-h'e toJ.. m
a1f' the: da;ta r,nms Et'~. l;,~~i:i !fy tne rru'fflt:>er
Qii i;.tatta l:t.e-m:s: {991). 'll:l;l m~iff VJlll:.le f~r
tt:Q:.s run. iS': 6:P1 I l'J.9 '" 6. 8.'1B8
1

tlt~~~

.M'edi:an
~......,*~*
The t;l.n~:gr:~~'.d arr(Y "f r~i:i'in;s'3s ls

eja~a7~9e~1~9s&a1s1B
a 7 a s ~. ~ a v- a r 1 ~ $ a a s s 1 s $
~ 1 a 1 a '1, s & s 2 .,, 1<0 e a g a g 1 :& ~
i) 7 '2 -5 ~ 9 4 6" 7 ~9 6 8.,, 8 9 7 8
.,, ~ f '? 5 3 8 7 5 6 4 ~ 6 1 ~ 5 7 8 7

F.igur.a 6.1 7 Esempio &esecuzione pr il programma di analisi dei lati di uh'indagine.

6~8

La ricerca nei vettori

Gpr~~a.mm.roti. lavci'retanrf~ spesso on grandJ quanti:t~ dl dati im,magazzjf,la:ti io yettpr.i.


A;"vohe, potf::.esse:re Jiecess.ario dernrrcinare se .Un vtl;Of<i: Cllt;etiga: Un lem:Jito .che. o'r~
aspnd.a Un dat va/ore. chiave, li pr0sso di .citrov.amerif.O di un par,cicoJru:e elrnento n
un v,ettore detto ricerca. In quesra $e'liane discuteremo dli.e!: reaniche di ricerca: una
semplic.re d~a ricerca lineare e un'altra pi efficienre detra r:erca binaria. Gli Jiserciz.i 6.~4
et~-?.$, alla fine di qu.esro capi:tolo, vi chiederanno di .imp!flm.e.nrar~ l(} v:e11Sioni ricorsive
d~a..ori<>i;;ra lineare i;' .di quella binaria.
L1.1:icercalineare (Figura 6.18) confronta ogoi.elemetH0 del vercore con la chitwe di ricerca.
Da:tQ eb.eil-vettore non~ in un o:rdin~ p;ucicolare, la probabilit che il valore ricm:ar9 $fa
tiitro:Vato n:l prime) ~emenro sar la sn:.ssa dell;ultim.o. fu mt;dia, quindi, il pregramma
Q.ov;r ceQ:fronJire la chiave di ci'tj!rQ! con Ja mer~, degli elementi inclusi nel verro.re.

202

CAPITOL 6

int linearSearoh(int (], int, int);


main()
{

int a[SIZEI, x, searchKey, element;


a[x]

= 0; x
=2 *

<= SIZE . 1; x++)

/*crea alcuni dati*/

x;

printf{"Enter integ~_r search key:\n");


&searhKey);
elemtint = linearSearh(a, search l<ey, SlZE).;
scanf{~\d",

if (element I= -1)
printf{ "Found value in element %d\n", element );
else
printf{"Value not found\n ");
ret.urn 0 ;
int .linearSearch {int array [], int key, int size)
{

for (n = 0; n <=- sue

VETTORf

203

ricerca lineare inefficiente. Nel caso che il ven:ore sia ordinato, potr essere uciliu.ata la
tecnica notevolmente pit1 veloce della ricerca binaria.

/* Ricerca lineare in un vettore *J


#includ e- <stdio. h>
#define SIZE 100

for (x

1; n++)

if (array[n] =-= key)I


retu rn n;
re-turn -1;
}

t,nter integer ~earctt l<eY(;


36
Pound 11a1ue in element 18

Enter integer seareh key:


37
'v'iillue not fpulltf

Figura 6. 18 Ricerca lineare in un vettore.


Il mccodo di ricerca lineare funziona bene con i vettori di picole dimensioni o con
quelli die non sono stari ordinaci. Per i verrori di dimensioni ragguardevoli, invece, la

Lalgori tmo della ricerca binaria, dopo ogni confronto, scarter mer degli elementi del
vcrrore in cui si eseguir la ricerca. I.:algorirmo individua l'demenro di mezzo dd vercore e
lo confronra con la chiave di ricerca. Nd caso corrispondessero, la chiave di ricerca sarebbe stara individuau e sarebbe rescituiro l'in dice di quell'demenco. Nel caso rum corrispondessero, il problema si ridurrebbe a una ricerca da eseguire in una delle d ue roer del
vettore. La ciensa Saiebbe eseguita nella prima mec del vertore, qualor;.i la cbfave dJ
J:i<.::e.rca fosse inferiore al suo elemenrp di mew.o, in cilSo conrrario, la ticerca saJebbc
eseguita nella sconda mec del vercore. l!algorirmo sarebbe riperum su un quarto del
YCn:ore originale, qualora la chiave di ricerca non fosse stata riuovara nel sottovcrrore
sptcifcaro (il frammento del venere originale). La ricerca continuer finch la chiave non
corrisponda aJJ'elememo di mezzo di un sonoverrore, o finch quesco non sia formaro da
un unjco elemento che non corrisponda alla chiave di ricerca (owerosia, qesta non ba
-alcuna corrispqpdem.a nel vettore).
Nella peggiore delle ipotesi, eseguire una ricerca. binarfa in un vetrnre di 1024
demenci richie~cr soltanto 10 con.fronti. Infarti, dividendo ripetutameme I 024 per 2
si otterrebbero i valori 512, 256, 128, 64, 32, 16, 8, 4, 2 e I. TI numero l 024 (21 O)
pu essere diviso per 2 solo 10 volte per orrenere il valore 1. La divisione per due
equivale a un confronro dell'algoritmo di ricerca binaria. Ne consegue quindi che per
ritrovare la chiave d i ricerca in un vettore di 1,048,576 (220) elementi .farebbero
necessari 20 c0nfromi aJ massimo. Per t:icrovare la chiave dj dcerca in un vettore di
un m iliardo di lemenci sarebbero necessari 30 confronri al massimo. Questo uno
straordinario iucremenco di efficienza rispetro alla ricerca lineare, che richiede invece
di eseguire un n umero medio di confronti con la chiave di ricerca pari alla mer degli
elemenri prcsenri od vettore. Per un vecrore di un miliardo di elementi, si rrarra della
differenza tra una media <li 500 milioni di confronci e un massimo di 30! n nwnero
massimo di confronti richiesti da un vecrore potr essere determi nato, trovando la
prima potenza di 2 ch e sia maggiore del numero di elementi presemi ne] vettore.
La Figur 6.19 presenta La versione ire.raciva della funzione binarySearch . Quesra ritever quarrro argomenri: un venore di interi b , un intero searchKey e gli indici
low e high dd vcrrore. Qualora La chiave di ricerca non corrisponda all'elemento di
mez.z.o di un sorrovettore, sar modilcaro l' indice low o quello high, in modo tale che
la ricerca possa essere eseguira su !1 sottovettore pi piccolo. Nel caso c::he la chiave
di ricerca sia Inferiore all' elemen.to di mezzo, l'indice high sar imposraco cpn middle 1 e 1a ricerca ~ar ripresa su.gli elementi compresi rra low e middle - 1. Nel caso
invece che la chiave di ricerc sia maggiore deU 1 elememo di wez.20, l'indice low sar
impostato con middle + 1 e la ricerca sar ripresa sugli elemenci compresi tra middle + 1
e high . ll progran'Ula ucilizz.er un verrore di 15 elemenci. La prima potenza di due
superiore al numero degli elemenci presenti in quesrn vettore sar dunq1,1e lp (i4),
petci saranno nece,~.$ari al massimo 4 confromi per riuovare la chiav~ di t icerca.
Q_uesrn programma utilizzer la fun.zjone printHeader per inviare in oucput gli indici
del veccore, mentre user la foozione printRow per inviare in ourpur ogni srcovercore
ducance il process_o di ricerca binaria. L'demcnco di mezzo di ogni sonovettore sar
marcato con un asterisco (*), in mGdo da indicare quello con il quale sar confroncaca
la chiave di ricerca.

204

CAPITOLO 6

/* Ricerca binaria in un vettore * /


#include <st dio.h>
#define SIZE 15

! VETIORl

205

/*Visualizza un'intestazione per l'output */


void printHeader(void)
{

int i;
int binarySearch(int [], int, int, int);
void printHeader(void);
void printRow(int [], int, int, int);

printf("\nSubscripts : \n");

main()

for (i= 0; i<= SI ZE . 1; i ++)


printf('%3d , i);

int a[S I ZEJ, i, key, result;

printf( '\n ");

for (i= 0; i<= SIZE 1; i++)


ari! = 2 lt i;

for (i= 1; i<= 4 * SI ZE; i+f)


printf ( '' - ");

printf("Enter a number between 0 and 28: ")';


scant("\d", &key);
printHeader() ;
result = binarySearch(a, Key, 0, SIZE -

pri ntf{''\n "} i


}

Visuali zza una riga di output che mostra la parte


.del vettore che i n corso di elaborazione. * /
vod printRoW(int b[ J, int low, int mid, int high)
1~

1);

(result I= - 1)
printf( '\ n%d found i n array element \d\n", key, result);
else
printf( "\n\d not found\n , key);

if

i nt i;
for (i= 0; i<= SIZE . 1; i++)
if (i< low :: > high)
printf (
);
else if (i == mid)
printf("%3d*", bli]); /*marca i i valore d mezzo "I
else
printf("\3d , b[i]);

return 0;
}

int binarySearch(int b[J, i nt searchKey, int low, nt high)


int middle;

printf ( "\n");
while (low <= hgh) {
middle = (low + high) I 2;

p.rintRow. ( b, low 1 middle 1 hig,h);

E_itte r a number 'between 0 anij 2a: 25

if (searohKey == b(mi-Odle] )
return middle;
else if (searchKey < b(~iddl])
high = middle - 1;
else
low = middle t 1;

Swf>scripts :
0

Hl

11

12

13

14

-- ----- --- - - --------- ~-- ----- 0


2
4
6
8 10 "1 2 1'4'* 16 18 20 22 24 26

16

return 1;

118

22 24
24

28
26 28
26" 28

24~

/ * sea r ch Key non trovata */

25 not tound

(continua}

206

CAPJTOL0 6

l VETIORI

207

Colonna O

Colonna I

Colonna 2

Colonna 3

Riga O

a[0J[0J

a[0][1 J

a[0][2J

af0J (3)

a[1 H01

a[ 1)[1]

a[i] [2J

a [ 11 (31

Riga 2

a[2J[0J

a[2 1 (1 ]

a[2J (2)

a[2][3 J

Enter a number between 0 and 28: 8


SubSerJ,pts:
0

0
0

:!!e

1111

11

12

13

18 20

22

24

26

-- - - - - - ---------------- -- -- --2
2

4.
4

6
6*

10 12
10 12
10* 12

8
8

14!. 16

14'

Riga

~8

8*

Indice colonna

8 fu nd lojl array element 4

Enter

Indice riga

nmber betw,een 0 and 28:

Nome del puntatore

Figura 6.20 Una matrice con tre righe e quattro colonne.


Subsi:lr J;pt'S:
0
2
1
-

0
0

-:J<-' -

!
2

- - - -

3
6
6*

8
8

5
-

6
-

10 12
10 12

7
-

8
-

, 4-1' 16

11

10

-- -

18

20

12

13

~4

_.._ - - -

22

2'4

26

28

6 f ound in a rray element 3


Figura 6. 19 Ricerc;a binaria in un vettore ordinate.

6.9

I vettori multidimensionali

I vectoc.i in C posspno anche avere pi di un indice. Va utilizzo tipico dei vettori mulcidimeosionali
la rappresencaz.ione cU ta.beik di valori formar da informazioni organizzare in righe e cokmJU.
Per idenrificare ua particolare clerpenro della cabella, dovremo specificare due indici: il primo
idemificher per convenzione la riga dcll'dememo, mentre il secondo (sempre per convenzione)
ne idencifcher la colonna. Le cabelJe o i vettori che per identificare un parriEolare elemento
richiedono due indici sono detti vettori bidimensionali o matrici. Osservare the i vettori
multidimensionali possono avere pi di due indici. Lo standard ANSI stabilisce che i sistemi
ANSJ e debbano supporra.(e per i Vettori un mini.mo di 12 indici.
La Figura 6.20. illustra una matrice a. Que~ta onterr rt' cighe e quam:0 colonne,
perci si usa definirla matrice 3 per 4. [n g~tieiile, una rn~rricc con m righe n colonne
sar detra rnatrit:e mper 1~. Ogni elemenco nella matrice a identifcaco nella Figura 6.20
da un nome di dencnco avence la forma a (il ( j] ; a rapprescnca il nome della matrice,
mentre i e j sono gli indici che idencifcano univocamente ogni elemen_co incluso in a .
Osservace che i nom i <legli elemenci nella prima riga hanno cucci 0 com~ primo indice;
mentre i nomi degli elemcmi nella guarta colonna hanno rutci 3 come secondo indice.

~ Et-rore tipico 6.9

PtJ,te rifiiripw,zto afl'elernento a [x) (y] dittna matrice usane/a la forma scnnma af x, y) .

UD vectore 111ukiclimensio11_ale pou essere in izi:tlizzaco cntcstualmence alla propria


dichfa.ra.zione, in un modo m olto simile a quello utilizzato per un vettore unidimensionale.
Per esempio, una marrice b [ 2] [ 2] porr essere dichiarara e inizializzata con
int b ( 2)[2 ] = {{1, 2 }, {3, 4}};

1 valori saran no raggruppaci per riga all'interno di parenresi graffe. Perci 1 e 2 serviranno
per ic:z.jafu.zare b [ 0] ( 0] e b [ 0] l 1 ] , menrre 3 e 4 inizializzeranno b [ 1 ) {0] e b [ 1 ] [ 1 ] .
Mell'evenrualic che per una data riga non sia srarn fornico un numero sufficience di
inizializ.zarori, gli elementi rimanend di qudla riga saranno inizialiu.ari :i 0 . Quindi, la
~.idiiarazione

int b [ 2 J[ 2 J = { { 1 }, {3, 4}} ;

mizi;iliu.er b [ 0] [ 0] a 1, b ( 0 ][ 1 ] a 0, b [ 1] [ 0) a 3 e b [ 1] [ 1] a 4.

La .Figura 6.21 mostra l' inizializzazione di alcune matrici conresrualmence alle loro
dichiarazioni. li programma dichiarer tre marrici di due- righe e rre colonne (ovverosia sej
dementi a cesla). La dichiarazione di array1 fornisce sei inii.ializz."lcori in due sottoliste.
la prima sonolisca inizializzer la prima riga della matrice con i valori 1, 2 e 3; memre la
seconda sortol isra inizializzer la seconda riga della marrice con i valori 4, 5 e 6. Qualora
d.a.Welenco degli inizializzarori di array1 fossero cimosse le rarentcsi graffe che raechiud9ho ognun.a delle sotcolisre, il compilacore provvederbbe !!-UCOmaticamence a inizializzare
prima gli elementi d!ilk prima riga e, solo in seguiro, quelli della seconda riga. La dichjarazione di array2 fornir cinque inizializzatori. Quesci saranno assegnati alla prima riga e
quindi alla seconda. Ogni eJemento che non avr un inizializzacore espliciro sar inizializzato
autoroacica.rnence a zero, perci array2[1 J [2] sar ai:z.eraco. La dichiarazione di array3
:fornir ree inizia1iz7-acorisuddivisiin due sonolisce. Que!Ja destinata alla prima riga inizializzer
esplicitamence i suoi due primi dementi con 1 e 2. I l terzo demenro sar invece azzeraco
automaticamente. La sorrolisra dcscinata alla seconda riga iniz.ializzer espliciramenre il suo
primo elemento a 9. Gli ~cimi due elementi saranno azz~i aucomaticamenre.

li programmainvocher gulndi la funzione pri ntArray per invia.re in outpllt ogni elemento della marrice. Osservace che la. definizione deUa funzione specillea il paramecro delJa matrice
come int a [] l 3] . Le parentesi quadre di un veccore nidimensionale sono vuore, nell lista

208

CAPITOL06

/ " Inizializzare i vettori multidimensionali */


#include <stdio.h>
void printAr r ay(int [](3J);
main()
{

int array1[2][3J
array2{2)[3)
array3[2) [3)

{ {1, 2, 3}, { 4 , 5, 6}},


{ 1 1 2, J 1 4 1 5 } I
{ {1, 2-}, {4} }j

pr i ntf("Values in array1 by row a re : \n);


printArray(array1)i
printf ( "Values i n ar ray2 by row 'a:re : \ n11 ). ;
print Array(arr ay2 ) ;
p rin t f(~ V al u es i n array3 by r ow
print Ar ray{array3);

a r~ : \ n ");

r etu r n 0;

Fornendo i valori degli indici, concescualmente .ali<! dichiarazione del parametro,


tonsent:iremo al cornpilarore di poter indica re aUa funzione il modo per individuare
un qualsiasi elernenco del vettore. Nelle matrici, ogru riga fondamcoralmence un
vetctore unidimensionale. Durame l'accesso aJJa marriGe, il compilarore dovr conoscer esattamente quanti elementi ci sono in ogni riga, cos che possa salrare la quantit
app ropcia~a di posizioni di memoria per individ uare un. elemento in una riga parcicola.re. 1)j conseguenza, il compilarore sapr cbe, q uando nel noscro esmpio dovr acce.de.re ~d a [ 1 ] ( 2], per giungere alla seconda riga (la riga 1), dovr s~ l tare io memotia i
tc'.clemenri della prima riga. Solo allora il cornp l:i,rore porr accedere al terzo element0 di quella riga (l'elemento 2).
Molte manipolazioni tipiche delle matrici uc.iliuano la struttura di ripetit.ione for . .Per
e.Sciupio, la srrum.lra seguente azzerer rutti gli elernenci della temi riga della macrice a nella
Figura 6.20:
<= 3;

column++)

Abbiamo specifcaco la terza riga, di conseguenza sappiamo che il primo indice sar sempre 2 (0 la prima riga, menrre 1 h seconda). Il ciclo for far dunque variare solo il
s&:0ndo indice (ovverosia quello della colonna). La. precedeme struttura for equivaleme
alle isrruzioni di asscgnamenro:

int i, j;
tor (i= 0; i<= 1; ii1-) {

= 0;

dci parametri di una funzione che la riceve come argome.nco. Non obbligatorio neanche
il primo indice di un vettore mulridimensiooale, mentre lo sono rutti quelli successivi. Il
ooffipjlarore ucilizzer que.sci indici per determinare le posizioni in memoria degli dc.menti
dei vettori multidimensionali. Tuni gli elementi dei vettori saranno immagazzinaci in memoria n modo consecutivo indipendencemence dal numero degli indici. La prima riga di
una matrice immagazzinaca in memoria sar seguita dalla seconda riga.

for (column = 0; column


a(2J[column] = 0;

void printArray(int a(][3])

<= 2; j++)
printf ( "\d 11 , a {i'][ j]) ; i

for (j

209

f VETIORJ

printf( 11 \n ) ;

a [ 2] [0J
a[ 2][ 1J
a[ 2 J [2J
a[ 2 J [3J

0;
0;
0;
0;

La seguem:e srrunura for nid.ifcarn dc:tecminer il totale di ttmi gli clemenci presenri nella
m:ance a .

i;iy row

ar-e~

4 5 6

11

Values 1n arr:-ayg Ili row

~r..e :

VQ.~Ue.s

i i:i array.1

1 2 ,3
1 2 3
4 5 0

Values i n ar r ay3

by

row are:

2 0
4 0 0
1

Figura 6.2 1 Inizializzare i vettori m ultidimensionali.

for (row = 0; row <= 2; row++)


f or (colum n = 0 j col umn <= 3;
tot al += a [ row][columnJ ;

c olum n +~)

:Ca srrurrura for sommer gli clcmcnci della matrice una riga per volca. La srrurrura for
pi esterna incomincer mposcando row (ovverosia l'i ndice della riga) a 0 , cosl che la
f!>rIDa riga possa essere sommata dalla struttura for pi incema. La srrurrura fo r pi
esterna incrementer row a 1 , cos) che possano essere sommati gli ebnenti della seconda
riga. la srruttura for pi esrerna incremen:rer row a 2, cosl che possano essere sommari
gli elementi della terza riga. Il risultaco sar visualizzare quando la srrumu:a for nidificata
avr terminato la propria c:secu2one.
] programma della Figura 6.22 eseguir molce alrre manipolazioni tipiche sulla matrice 3
per 4 studentGrades utilizzando delle srrucrure for. Qgni riga della marrice rappresenta uno

210

CAPITO L06

srudente, mentre 0gni colonna rappr~enta una votazione in uno dei quattro
esami che lo
Siudenre ha affroncaro durante il semestre. Le manipolazioni della matrice saranno
eseguite da
quamo funzioni. la fwJ1.ip_n e min i mum dereo:nioer il v0ro pi basso di ogni
srudente nel
semestre. la funzione maximum dcrerminer il \roco pi alto di ogni student
e nd Smcscre. La
funzione averag e determiner la media di un parcic0lare srudentc f1el semestre
. La fu.rrLione
pr in1;Array invier in ourpur la matrice bidimensionale in un fummo cabulare
ordinato.
Ognun a delle funzioni mini mum, maximum e pri ntArra y ricever tre:
argomenci: la
macrice st udent Grades (chiamata grades in ogni funzione), il numero
degli srndenci (le
righe della matrice) e il numer degli esami (le colonne della matrice
) . Ogni funzione
iterer.rulla mar.rice grades urili7.7.<lndo deUe strutture to r. La seguemestrurru
.ra t or nidifcaca
tratta dalla definizione della funzione min imum:
far (i= 0; i <= pupils - 1; i+'+ )
for (j = 0; j <: tests - 1; j++)
if tgrad es[iJ[ jJ < lawGra<:te )
lowGrade = grades ( i)(jJ;

2 11
{

int i, j, lowGrade

= 100;

far (i= 0j i<= pupils - 1; i++)


for (j = 0; j <= tests - 1; j++)
if {grad es(i][j ] < lowGrade)
lawGrade = grad~s[i ] (j ) ;
return lowGrade;
}

/ T ~o~a il voto massimo */


int maximum(int grades [ ] (EXAMS], int pupils , int tests}
f
int i, j, highGrade = 0 ;
far (i = 0; i<= pupils 1; i++)
far (j = 0; j <= tests - 1; j++)
if (grade s[ i ][jJ > highGrade)
highGrade = grade s(i)(j] ;

/* Esempio di matrice */

#mcl.ude <stdio . h>


#defin e STUDENTS 3
#defin e EXAMS 4

return highGrade;

int minimum {int rJr EXAMS ], in t I int) j


int maximum{int [J[EXAMS], int 1 int);
float averag e(int [], int);
void printA rray(i nt [ J[EXAMSJ, int, int);

/* Determina il voto medio per un partic olare esame */


f,loat a-verag e(int setOfGrades [ J, int tests)
{

main()

int i, tota! = 0;

int studen t,
studentGrades[STUDE~TS]( E XAMS]

,.

far (i= 0j i <= tests - 1; i++)


total += setOfGrades [il ;

{{77, 68, 86, 73},


{96, 87, 89, 78},
{70 I 90 I 86 J 81}};

printf {"The array is:\n" );


printA rray(s tudent Grade s, STUOENTS, EXAMS) j
printf( "\n\nL owest grade: %d\ nHighest grade: %d\n",
minimu m(studen tGrade s, STUDENTS, EXAM$),
maximum(studentGr ades 1 STUOENTS, EXAMS));

return (flaat ) total I tests;


}

1w Visual i zza la matric e */


void printA rray(i nt grades[][EXAMS], int pupils , int tests)
{

int i

for (stude nt = 0; studen t <= STUDENTS - 1; studen t++)


printf( ''The averag e grade for studen t %d is %.2f \n ",
studen t, average(~tudentGrades[st u dentJ, EXAMS));

j;
(0]

( 1]

[2]

[ 3] ")i

tor ( i = 0; i<= pupils - 1; i ++) {


printf( "\nstu dentG rades t%dJ , i)i

return 0;
}

/," Trova i l votci mi ni mo "I


int minimum(int grades(J[EXAMSJ, int pupils , int tests)

for (j ., 0; j <::e tests - 1; j++)


printf ( "%5d, grades [ i ][jJ)i
}
}

(continua)

,.

11

212

2 13

CAPITOLO 6

Th~

f) fl proa:Sso che<lete.rrni.nase un vetrore contenga un cerro val<>re d1iavd


detto

array is:
(0)

t, ]

[2:1

s~Udent'G~ades[0J 77
studen tGrade st 1 ) 96

68
87

8'6
89

70

9(ll

81l

studentG~adesr21

73

78
8l

6.2

Figura 6.22 Esempio di utilizzo delle matrld.

La srrun:ura for pi esterna incomineer imposta ndo 1 (ovverosia l'indice


del le righe) a 0,
cos che gli elementi della erima riga possano esser.e confron tati con
la variabile lowGra de
nel corpo della strurcu ra for pi. inrcrna. La srrurrur:i. for pi interna
iterer a sua volta
sulle quattro vocazioni di una riga panicolare e le confron ter con
lowGra de. Nel caso che
un v.oro si:a inferiw e a lowG r ade, quesra ne assume r jJ valore.
L<!- struttu ra for pi
esterna increme mer l'indice di riga a 1 . Gl i elemen ti deUa seconda
riga saranno confron tali con la variabil e lowGra de. La struttura for pi esterna iJ1creme
ncer quindi l'indice di
riga a 2 . Gli elc.menri della ceri.a riga sa.ranno confrontaci on la variabil lowGra
de. Quando !~esecuzione della struttura nidifcara sar stara complcrara, lowGra
de conrerr il voco
pi piccolo prci;ent c nella:.matcice. La fwizion e maximum lavorer in
modo simile a minimum.
La funzion e averag e .ricever due argome nti: i) vettore u nidimensionale setOfG
r ades,
che conterr i r isulrati degli esami per un dato smdent e, e il numero
dei risultaci di esame
presenti all'imer no del vettore. Quando averag e sar invocata, il
primo argome nto passato sar studen tGrade s( studen t] . Con questa istruzio ne sar passato
acl ave rage l'indicizzo d i una riga della marrice. I.;argomenco studen tGrade s [ 1)
corrispo nder all'indir izzo di pa1Tenza della seconda rig~ della matrice. Ricorda te,infat ti, che una
matrice fo ndamemalmerue un vettore di vettori unidim ensionali e h.e il nome di un
verrqre unidim ensionale
corrispo nde al suo indicizzo d i memor ia. La- funzion e averag e calcoler
la somma degli
elementi incltLSi nel vettore, divider il totale otrenu ro per il numero
degli esiti degli esami
e rcstirutr il risultato in virgola mobile.

63

6A

sia fal~a, spiega1cn.c il

a) Un vercore pu immagazzinare valori di molri ripi differemi.


b) _Eindice di un yecrore pui> essere del tipo di -dat float .
. .
.
.
e) Nel caso che in una lisra di inizializzaroci ci siano meno elemenD da quelli presemi nel
vetrore, il C inizializ2.erebbe amomaricameme quellLrimanenti utili:z.zan
do l'ultimo valore
loconcrato nella lista degli ini1.ializ7.acori.
. .
. .
.
d) un errore inserire in un:t lista di inizializzarori pi elemem1 di quano siano
presenta nel
verro re.
e) Qualo~ un singolo elemento di un veuore sia passato a u~a funzione
e ~i<t modific:ico dalla
s~essa., nella funzione chia:m~Te quel~elemenco corucm 11 valqrc m.od1l1caro.
Rispondere alle seguenci domande ciguardanci un yerrore chiamaco f rdac
t ionscl-_
. .
a) Dcfl.nire una costa.m e simbolica SIZE d1c possa essere rim piazzata 1
a rcsco 1 sosaruz1onc
10.
b) Dichiarate un vcrcore con SIZE clcmcnd di tipo float e inizializzateli
a 0.
e) "Puncate al quarto elemento dall'inizio dcl veccore.
d) fate riferimento all'elemento 4 dcl vercorc.
e) Assegnare il valore 1 , 667 all'.eleme nto nove del vertorc.
f) Assegnate il valore 3, 333 al settimo elemento del ve~tore-_
..
._
g) Visualjz:Late gli element i 6 e 9 del verture, con due cLfre di prec1s1one a destra
delia vu gola
decimale e moscr:ue l'outpm che sar cJTetcivamence visualia.."ltO sullo schermo
.
h). -Visualizzare rutti gli elememi del verrore usando lastru~ di ripeuzio
ae ~or. Suppone{e
cJ1e si.a scaca definita la variabile incera x per controllare il odo. Mostrate 1Outpm.
Rispondere alle seguerui domande riguardanti w1~ matrice chiam:na table.
_ . .
a) Dichiarare la matrice di cipo incero con 3_nghe e 3 colonne. Suppon
ete che s1a star-a
definira la cosrn.nre simbolica SIZE con cesm di sostinnione 3.
b) Quarui d ementi comert- )amatrice?
.
c) lJtiliuat.e una munura di pezione for, per inizi~e ?goi elemcn~
o della ma~nc~ con
la somma dci propri indici. Supponete che come van..tb11i i.Li conrrllo siano
srace dach1ar:ue

x e y.

I
. .
d) Visualizzare j valori di ogni elemento della m:mke table. Suppone
te che a marnce m
scat:niz.ia.lizzata con hdichia razione
int table(SIZEJlSIZE]

Esercizi di autov aluta zione


R_ispndere a ognuna ddle seguenti domande:
a) Le liste e le r~belle di valori .~ono i m~a7.7.inate nei - -- - b) Gli dementi di un veuore sono correlati dal farco che hanno lo sces.so

_ _ _ __

motivo.

Lowest grade: 68
Highes t grade: 96
The avera~e grade f'~r studen t' 0 is<. 76 . 00
The ave rage .grade f'Of"' st'UClent 1 is 87. 50
The averag e grade far stuen t 2 is 81.75

6. 1

nel verrore.
g)' 1Jn vettore che ut'.ilizzi due incl.ici detto \ietmre - -- - Smbilite se le seguenti affermazioni siano vere o false. Qualora la risposta

(3 )

={{1, 8}, {2, 4,

6}, {5}};

e che le variabili x e y siano state dichi:l.rute come variabili di conrroUo. Mosrrace


6.,.5
- - -- -e

t) l i numero ucilizzaro per fur rifrimemo u un particolare demem o


di un vecrore il suo
d) Per dichiarare la dimensione di un veaore, dovrebbe essere uciliztar
a una _ _ _ _ _,

perch renderebbe il programma pi scalabile;.


e) il processo di messa in <ndine degli elementi omen.uri in un ve~rore
dea.o _ __ _ _
dcl vcrcore.

Ti;ovate l'errore in ognuno dei seguemi segmenci dl programma e correggc


celo.
a) #de-fine SIZE 100;
~) SIZ:E = 10 ;
e) Assuruc tcintb[ 10J ={0), i;
for (i= 0; i<= 10; i++)

= {{1 ,

'I

b[i] = l i
d) llwcl.Ude <stdio.h >;
e) Assume teint a[21[2]
a( 1, 1J .. 5;

l'ourpur.

2}, {3, 4 }};

214

CAPITOLO

Risposte agli esercizi di autovalutazione

f VETl'ORl

6.5

a) Yeccori. b) Nome, cipo. c) lndice. d) Coscan~.simbolica. e) Ordinamento. f) Ricerca g)


Bidimensionale.

6.1

6.2

6.3

a)
b)
e)
d)
e)

Falso.~~ v~rcor~ pu.immagazzinare slcanco valori dello scesso tipo.


Falso. I.:indicc di un verrore deve essere un incero o una espressione incera.
Falso. Il C azzerer aucomaticameme gli demenri mancnri.
Vero.

F~. I singoli elem:nu di. un vecroTe sonQ passaci per valore. Le modifiche apporcare
alJ ~remo dclfa funzione chiamata sarebbero..riscpntrabili nel vettore originale, solo se alla
run21one fosse scaco passato l'incero verco.re.

a) lldefine SIZE 10
b)
e)
d)
e)
f)

float fraGtionsfSIZEJ

= {0};

6 .~

Output: 3. 33 1 . 67.
h) for (X= 0j X<= SIZE - 1; x++)
printf ( tractions[%dj -= %f\n', x, fractions[xJ);

=0.000000
fractions[l J =0.000000
traetions[21 = 0.000000
fract1ons(3J =0.000000
f raetions[41 = 0.000000
fractions[SJ =0.000000
traotions(6J =3.333000
tractions[7) "'0.000000 ,
fractions[8) =0.,000000
fractionsf91 = 1. ,667000

a) int table( SIZE li SIZE l j


b) Nove elememi.
e) for (X = 0; X <= SIZE . 1; x++)
for (Y =0; y <= SIZE - 1; y++}
table!Xl !Yl =X+ y;

tor

= 0j X<= SIZE. l; xt+}


(y =0; y <= SIZE - 1; y++).
pl'ifltf ( fftable [%d ][9iidl = 'td\ "", x,

y,

table rx J[ y I ) ;

6.7
Stabilire quaJj delle segue.nei affe.rmarioni siang ver quali fal$c; per quelle fa1$e. spiegare
p,crch lo sono.
a) Per far riCecimenco a u:ia particolare posizione o elemnCo all'imemo di un vettore, specificheremo il nome di quesco e il valore di quel parc;olare de.memo.
b) La dichiarazione di un vetrorc gLl riserver uno sparlo in memoria.
e) Per indicare che debbano essere riservate 100 posizioni per il vettore d incri p, il programmatore scrjvec la dichiaraz.ione

Ou:put:
table[0J [0)

p[100];

=l
=a

table(0][1J
table(0][2J = 0
table[l ][01 = 2
table( 11( 1 J = 4
table( I ][2] = 6
table[2) (01 =s
tablel2Jl1J = 0
table(2Jl2J = 0

Riempire gli spazi in ognuna delle seguenri cighe:


a) ne immag:izzina le lisce di valori nei - - - - b) GJi elementi di un vcrrore sono correlaci dal fatto c;he _ _ _ __
e) Quando si fa rifertmento a un clemenco di un vetto~. iLnumero di posizione conumuco
all'incerno delle parencesi quadre decco _ _ _ __
d) 1 nomi dci cinque elcmenci del vettore p sono _ __ _ _, ____ __. - -- - - '
_ _ _ __ e _ _ _ __
e) U cooccnuLO di un particolare elemento di un verrore il
dcll'elemenro.
f) Dare un nome a un vecrore, scabilime il cipo e specificare il numero degli elemenci conrenuci nello stesso la
del verrore.
g) Il processo di siscemazione in ordine ascenderne o discendente degli elementi contenuti in
un vercorc chiamato _ _ _ __
h) 1n una mauice, il primo indice (per convenzione) idcmifca la
di un demenco, mencre il secondo indice (per convenzione) identifica la
di un
clemenco.
i) Una matrice m per n conciene _ _ ___ cighe, _____ colonne e----clemenri.
j) 11 nome dell'elemenco n.ella riga 3 e nella colonna 5 di una rnatcice d _ __ __

Output:

fract:ions[0J

d) for (x

a) Errore: il punto e virgola alla fine della direiriYa #defi ne del preprocessore.
Corre-Lione: eliminare il punro e virgola.
b) Errore: assegnamemo dj un valore a una costim:e simbolica urili'l.7.3ndo un'isrruiione di
assegnamento.
Correzione: assegna ce il valore dclJa cosranre simbolici in una direcciva #def ine del
preprocessore, $enu ucilizz.are l'operatore di assegnamemo. come in #def ine SI ZE 10.
e) Errore: riferimento a un elememo merno ai limici del verrre (b [ 10 J).
Correi.ione: modifica ce a 9 il valore 6nale della variabile di controllo.
d) Errore: un punro e virgola alla fine della direuiva #include del preprocessore.
Corre1,ione: eliminare J punro e virgola.
e) Errore: indice della marrice scrro in.modo swrrertp.
Cor.rczione: cambi:ve l'isrru1.ione in a[ 1J l1 J = 5;

Esercizi

fr~ctl.OhS[3]

fractions[41
f.raoti()ns[9J =i .667;
fractions[6J = 3.333;
g) printf( ~9ii.2f %.2f\ni, fractions(6J, fractionsf9]);

6.4

215

d) Un programma C che azzeri i L5 elementi di un vettore dovr contenere un'isrruzionc 'for.


e) Un programma C che sommi gli elementi di una matrice dovr concenere delle istruzioni
for nidificare.
E) La media, la mediana e la moda del seguenre gruppo di valori sono risperrivameme S, 6 e
7: 1, 2. 5, 6, 7, 7. 7.
6.8

Scrivere delle istrw.ioni C che eseguano ognuna delle seguenri arrivic:


a) Visualiuare il valore conrenuro nel sercimo elemento del venore di caratteri f .

......mi................................................... .................................!!!!!!!!!!!!!!!!" '\

~~~~~--

216

CAJ 1TOLO 6
1

I VEJTQIU

a) Dopo il primo pa.r;saggio, il numero pigrande..sar staro si~entesi~c~aro ne_ll'clcmen~o


con l'indice pi alto del vettore; dopo il secondo p:issaggi~,J due~umen ~IU g~d1 s:iranno a
posto" e cos via. I nvecc di cseguircrn.ove confronti ad ogru~o, modifcare I o'.dinamento
'
a bolle cos che esegua ono confronti nel secondo pa.~ggi~, serr7 nel rerz::i.e cos via.
b) 1dati nd venore pocrebbcro gi essere nell'ordine appropnaro o m uno v1.C1J10 a ~ues~o, perc10
perch eseguire nove passaggi quando ne porrebbero basr.ar~ meno?.Modi~c:'1re I ~rdinan:ienro
a bolle in modo da verificare se alla fine di ogni passaggio Stano .srao eseguili degli scambi. Nel
caso che non ne siano sra eseg_uiti, allora i dari =no gi nell'ordin~ approp~aco, ~e:ci ~
programm:i dovr rerminare la propria esecuzio~e. Nel caso invece che siano scan esegwu degli
scambi, sar necessario almeno un alcro passaggi.o.

b) Prendete in inpur un valore: e siscemarelo ncll'elemcnro 4 dcl vea:orc unidimensionaJe di


valori in virgola mobile b.
e) lniz.aliz1.ne a 8 ognuno dei 5 clementi inceri q>menuci nel vctrore unidimensionale g.
d) Sommare i 100 elementi comcnu nel vettore di valori in virgola mobile c.
e) Copiace il verro re a nella prima panione del ven()re b. Assumere che sia gi stata scrina la
dichiarazione float a( 11 J, b(34 ];
f) Oererminare e visualizz.are il valore pi piccolo e quello pi grande conrenuci nel venare w
di 99 elementi in virgola mobile.
6.9

Considerare la m:u:cice di interi t di dimensioni 2 per 5.


b) Quance righe av r t ?
e) Quante colonne avr t?
d) Quanti elementi avr t ?
e) Scrivete i nomi di curri gli elemend corucnuti nella seconda r:ig.1 di t.
f) Scrivere i nomi di tucri gli elementi conrenuri nella rena colon1la di t .
g~ Scrivete una singola iscrl!Zionc: C che ai.Zeri glidemem i cl.i t contenmi nella riga I e nella
colonna 2.
a) Scrivere una ilichiarazione per t .

h) Scrivere una serie di isrruzioni C che azzerino ogni elememo cli t. Non utilizzare una
strunura di ripetizione.
i) Scrivere un:l srnmura for nidificata he azzeri ogni elemenrn di t .
j) Scrivece un'isrruzione e che prenda in inpur dal rermrn:ile i valori pe.r gli elementi d i t .
k) ScrivcLe una serie di istruzioni C ch dererminino evisualinino il valore pi piccolo
conrenuro nella matrice t .
1) Sc:rivcre un'iscruzione C che visualizzi gli elementi comenuti ncll:t prima riga cli t .
m) Scrivere un'isttu7.ione C che sommi gli elemenri conrenu nella quarta colonna cli t .
n) Scrivere una serie cli istruzioni C cli:e visualizzino la macrjcc t in un formaro tabulare
ordinato. Utilizzare gli indici delle colonne omeinccstaz.oni da porre in cima alla tabella
e, allo stesso modo, visualizzare gli indici delle rjghe a sinistra di ognuna di esse.

6.1 O Utilizzate un venore unidimensionale per risolvere il scguenre problema. Un'a:Lienda retri buisce i .suoi venditori con delle provvigioni. Un vendirore ricreve $200 la serrimana pi il 9 percento
delle proprie vendite lorde portare a 'cermi.nci a quell_a-sercimaoa. Per esempio, un vendi core che faccia
incassare $3000 di venduro lordo, io una setti.mana, ricever $200 pi il 9 percento di $3000,
ovverosia un cocaJc di $470. Scrivere un programma C, ucilizzando un veccore di contatori che
dercrmini quanti venditori abbiano guadagn;1ro una retribuzione compresa in ognuno dei seguenri
ime.rvalli (supponete che la recribuz.ione d.l ogni veodicor s:i.a troncata a una somma incera):

J. $200-$299
2. $500-$399
3. $400-$499
4. $500 -.$599
5. $600-$699
6. $700-$799
7. $800-$899
8. $900-$999
9. $I 000 e olcrc
6. J I L'ordinamenro a bolle presentaco nella Figur~ 6.15 inefficiente per verrori d i grandi
dimensioni. Apportare le seguenti semplici modifiche in modo da m igliora:re l'efficienza dell'ordinamcnro :i bolle.

2 17

6.12 Scrivere delle iscru1Joni singole d1e eseguano gnuna delle seguenti operazioni su vettori
unil.iri:Je.nsionali:
.
..
a) Azzerare i 10 elementi del venare cli imeri. count~ .
b) Aggitmgece La ognuno dei 15 elem~ comnmr nel veuore d1 mrcn bonus.
e) Legge~e dalla casLera i 12 valorifo virgola m_obile del va;~re m~nthlyTemperatures .
d) Visuali1.~.:tl~ in colonM i 5 va1<lri comenud nel ve.rr9re di.inteo bestscores.
6.13

Trovare l'errore in ognuna delle seguenci istruzfoni:


a) Assumere: chr str[5];
scanf(.%5 ", str); /L'utente digita hello */
b) Assumere: 1nt a(3J;
printf("Sd \d \d\n", af1], a(2], a(31);

c) float f[3) = {1.1, 10. 01 , 100.001, 1000.0001 };


d) Assumere: double dl 2 J f 10 J ;
d[1, 9] =2.345;

6.14 Modificare il program ma della Figura 6.16, in modo che la :um.ione ~ode. sia in grado ~
gesre an pareggio per il valore della moda. ModificaEe anche la funzione median, m ':o.do che sJ~
calcolaca la media dei due dementi cli mezzo, in un verrore che contenga un numero pan di elemeno.

6.15 Urilizzatc un vercore unidimensionale per solvere il seguence p~blema. Leggere in input 20
numeri, ognuno dci quali sar compr~ tm _LO e lO_O, esrremi inclu$i. ?~volta eh~ le~re u~ mt~~;o
visualizzatelo qualora non sia un duplicato d1 uno gi letto. Prepararev1 al caso peggiore .ro cw rurn 1 O
mtteri siano cllfferenci. Uciliu.are il vettore pi piccolo possibil per risolv.re questo problema.
().16 Ericherrare gli elementi della matrice 3 per 5 sales, in modo da indicare l'ordine in cui
essi saranno azzeraci dal seguen.re segmento di programma:

.
for (row = 0; row <= 2; row++)
far (column =0; col umn <= 4; columnt+)
salesfrOWJ( oolumn] =0;
6.17

Che cosa far il scgueme programma?


#include <Stdio.h>
#defi ne SIZE 10

nt wllatisThis(int I J, int) i
main()
{

int total, a(SIZEI = {1 , 2, 3, 4, 5, 6, 7, 8, 9, 10};


tota! = \tlhatlsThis(a, SIZE};

218

CArrrm.o 6
printf( "Tota.i ot array elemeht values is %d\ n" , total);
ret urn 0;
}

i nt whatrsThis(in t bi'], int si ze)


{

it (size

1)

return bl0J;

else
ret urn b [ size 1 ] + whatlSThis:(b 1 size . 1 ) ;

6.18

Che cosa far il sgueme programma?

sm 10

void someFuncton(int [ J, .int);


main()
{

int a[SfZE} = {32, 27, 64, 18, 95 , 14, 90 , 70, 60, 37};

printt( The vales in the array are:\n"li

someFunction(a, SIZf) ;
printt ( ' \n" ) ;
return 0 ;
voia SOl!leFunotion ( int b rI ' int size)
{

i'f (size > 0) {

someFunction(&b[1J, size. 1);


printf ("%d , bi 0)) ;
}

6. l ~ ~ere un pr~ma e che-runuli il lancio di due dadi. Il programma dovr uriliz:zare rand per
lanaare il ~nmo dad~ e mv~ nuov.ameo re per lanciare il secondo dado. Dovr quindi essere akolara la
so~ma dci ~e val on. ~ota: poich ogni dado pv moscrare UJl valore intero compreso tra J a 6, la son1 ma
d! due ;aJon ~ccl vaaare tra 2 e 12, con 7 come somma pi frequencc e 2 e 12 come somme meno
freq~en~. La P1~ 6.23 mostra I~ _% possibili combinl!7ioni dei due dadi. D vostro programma dovr
lan~e .due dadJ 36.?00volre. Uril!Z.Zatf: un vettore unidimensionale per sommare il numero di occonen7.i! di 0.~ s~p:una _poss1~ile. Visualizz.ate i $ulraci in un formaio cabuJare. Decerrninare anche
se i tclfali sono

sensaC1: Cl ~ono set

modaper ottenere un 7, perci cirai unsesro dei lanci dovrebbe ottenerlo.


2

IO

10 Il

IO Il 12

I
l
3

2 19

6.20 Scrivc1e un pr>gramma che esegua 1000 volte il gioco dei dadi (cmps) e rispondae a ognuna
delle seguenri domande:
a) Quanti giochi sono stari vind al primo lancio, aJ secondo, ... al \remesimo lancio e dopo il
ventesimo?
b) Quanci giochi sono scaci persi al primo lancio, al secondo, ... al venceslmo lancio e dopo i.I
ventesimo?
e) Quali sono le possibilit di vircoria al gioco dei dadi? (Nom: sappiate che il gioco d~ dadi
uno dei r iequi ma quelli dn casin. A quale conclusione vi porro questa con~idernzione?)
d) Qual la lunghezza media di un gioo a dadi?
e) Le probabilit dJ virroria aumentano con la lungheua dd gioco?

6.2 J (Sistema di p~enomzio ne per lince arce) Una piccola compagnia aerea ba appena comprato un
computj!r per il suo nuovo s.isw.ma di prenomzio.nt:.aucomari<;!i. TI presidenKvi b.<t chiesto di progr:unmare il nuovo sisrcma in C. Voi dovere scrivere un programma ch assegni i posti su ogni volo
dell'unico aereo dell'aerolinea (capacit: I O posci).
Il vostro programma dovr visualinare il seguente menu di scclrc:

I/include <stdio. h>

lldefine

J VETIORl

' .
Figura 6.23 I 36 possib1h
n sultatr del lancio d1 due dadi.

Please type 1 for "smoking"


Please type 2 tor "nonsmol<ing''
Nel caso che i.I cliemc digiti I , allor.i il vostro programma dovr assegnare un posro nella ~~.ione
fum.i.rori (quelli d:i 1 a 5). Nel caso che il clicmedigici 2, allora il vomo programrn3 dovrcassegnare un
posto nella sezione non fumatori (quelli da 6 a 10). U vosuo progrnmma dovr quindi scampate una
carra di imbarco, che dovr indicare il numero di posro assegnaro al passeggero e se quello si trova nella
senone} fumatori o non fumarori dell'aeroplano.
Utilizzare un vcnorc unidimensionale per rappresentare la mappa dei posti sull'aereo. Aizcrare
rutti ~li d ementi del verrore in m0do da indkare che nmi i [)Osti sono vuoti. Man mrum che i posri
sarann sr_ari assegnaci, imposte re re a l l'elemenro corrispondente del verrore in modo da indie.are che
il posco non pi disponibile.
Naruralmenre, il vostro programma non dovr mai assegnare un posro che sia gi stato assegnaco.
Quando la sC?.ionc fumarori sar piena, il vosrro programma dovr eh ic<lere al clience se sia disposto ad
accecrare w1a sisremaiione nella sezione dci non fumatoci (e viceversa); Eseguire l'appropriata assegnazione di pasco, qualora la sua risposra sia :iffcrmava. Visualizzare il messaggio "Next flight leaves
in 3 hours ( Il prossimo volo decoller f ra 3 ore), qualor.1 la sua risposra sia negativa.
6.22 u~Uizza.re lma ma.tricc per risolvere il seguenrc problema. Un'azienda ha qua.mo venditori
(numerari da .I a 4) che vendono cinque differerrri prodotti (numerari eh l a 5). Una volra al giorno,
ognuno dei venditori fornisce u.n ragliando per ogni tipo di prodorro venduro. Ogni ragliando
conaene:
L li numew del venditore
1. 11 numcw del prodorto
3. li valore corale, espresso in dollari, del vcnduro giornaliero di qud prodorro
Di conseguenza, ogni venditore fornisce era O e 5 ragliandi al giorno. Supponete che siano disponibili
i dari dei tagliandi delJ'uJrimo mese. Scrivere un programma che legga le suddette informazioni,
riguardami il venduro de.ll'u.ldmo mese, e sommi le vendi ce ro rali per venditore e per prodono. Tutci
i rotali d1,wranno esse immagaxz:inar nella matrice sal es. Dopo avere elaboraro 1ucrc leinformaz.ioni
dell'ultimo mese, visualizzare i risulcati in formato tabulare in modo che Le colonne rappresenno i vari
venditori e le righe rapprese.orino i singoli prodotti. Sommare ogni riga, in modo da onenereJe vendfoi
totali ilell'ulrimo mese pe.r ognuno dei prodotti; sommate ogni colon.na, in modo da orcenere il corale
delle vendite dcll'ulrirho mese per ognuno dei venditori. La vostra scampa tabulare dovr.lncludcre i
sudderri rotali a dcma delle righe e io fondo alle colonne.

220

Cl\'PITOLO

6.23 (Turcle G.raphics) !l linguaggio Logo, parricolanncme popolare tra g1i uccnri di persona! computer, ha reso famoso il concclto di rurcle graphics (grafici della tartaruga). fmmaginacc una can:aruga
meccanica che girow1ga in una sr:anza sorroil concrolhdi un programma C. La tart.arug:i ha una penna
iu una delle due posizioni, alzara o abbassata. La ra.rraruga traccia ddlc lince man mano che si muove
con la penna abbassata; <juando questa alzara, simuove liberamence senza scrivere niente. l.n questo
problema, siraulercre le operazioni della camu:uga e creerete, allo stesso cempo, un bloccherco per gli

~chizzi.

Significato

Abbas~a

Gira a destra
Gira a sinistra

5, 10

la penna

6
9

Fine dei dari (valore senrinella)

Suppoaere che la tartaruga sia in wta qualche posizione vicina al centro del pavimcnco. Il seguente
"programma" disegnerebbe e visualizzerebbe an qmulraro 12 per 12:
2
5, 12

o
2

6
7

3
3

Vai in avanti cl.i IOspazi (o un nwnero diversa da lO)


Visualiua la matrice 50 per 50

5, 12

Il cavallo compie ddle mosse a forma di L: due casdle in una direzione~ una in un~ dircmice
---L
scacchiera vuom,
perpendicolare aqucua precedente. Ne consegue che, da una casella centrale d1 unad-'
F"
G24
il cavallo porr eseguire ocro differenti mosse (numerare da Oa 7), come mostrato ;uJa 1gura -

Alza la poana
2

221 '

[.vlITTRl

Utiliz:zace una matrice floor SO per 50 e ;izze~ela. Leggere i comandi da un vettore che li contenga. fnogn momenro, manrencte crac.eia della posizione correnie della carcaruga e dello staro (alzar:i
o abbas$am) della penna. Supponete che la ranarnga comin9 sempre dalla posizione 0,0 dd pavimenw con la peana ah.ara. l:insieme dci comandi per la r:in:;i.ruga che il vostro programma dovr elaborare
sar:

Coma ndo

s, 12
3
5,12
1

6
9

Man mano che la tartaruga si m uover Con la penna abbassaca, impq~"l:erere gli elementi corrispondenri
della ma.rrice f loor a 1- Nel momenco in cui il programma avr imparrit0 il comando 6 (visualizza),
scamperete un asterisco, o qualsiasi altro carattere abbiate sc;:clco, in (;{,>rrispondenza di ogni 1 incluso
nella matrice. St:unperece invece uno $pazio in corrispondenza di ogni zero. Scrivete un programma C
che implementi le capacic grafiche dcUa ca,naruga discusse in quesco esercizio. Scrivete diversi programmi di rnrtle graphics, in modo che .siano disegnate delle forme interessanti. Aggiungete alrri
comandi per incrcrnencace la porenza dd vo.sc:ro linguaggio di rurtle gmphics.
6.24 (Il Giro del Cavallo) Uno dci problemi pi inrei:essanci per gli appassionaci del gioco degli
scacchi quello del Giro del Cavallo, proposto originariamente da,( maremarico Eulero. La questione
quesra: pu il pezzo degli scacchi chiamaco cavallo muoversi in una scacchiera YUOca, visitando una sola
volta ognuna delle 64 caselle? Studieremo approfondiwnenre questo problema affascinante.

Figura 6.24 Le otto possibili mosse per il cavallo.


a) D isegnare una scacchiera 8 per 8 su un foglio cl.i ~ e eco.rate~ po_rc~re a termine ma deI cavallo
un
n ualmenre un giro
.
. [nsecirere un .l . nell a pnma
. . easella
. . LD cw v 1 m uovercre.
f:
. 2
nella seconda, un 3 nlla terza, ecc-, Prim~ di mcommc1are il ~o, provare a .are ~1 na s~u;n~
delle mosse che riuscirete a compier.e, ricordando che un gtro completo cons.isce d1 6
mosse. Dove si.ere :mivati? Visi ecc avvicinati a.li.a vosrra.stim~ .
.
b) Ora svilupperemo un programma che muover il cavallo 111. giro per la scacchiera. La
scacchiera s.ressa sar rappresencara dalla marrice 8 per 8 boa:~ _Ognun:i, ~elle caselle sar
iniz.ialmeme azzerata. Descriveremo ognuna delle orro possibili mosse sandendole nelle
loro componenti oriZ'lOntali e verticali. Per es~pio, ~a. mos.sa cOIJle la O mostrata ncl_la
Figura 6.24 porr essere scomposta in untnovunemo. oazzonral: (d~e ~eUe a desrra) e m
uno spostamento verticale (una casella. in alto). La mossa 2 c~nsmera di uno s~osra.menro
orizzoncalc (una casella a sinistra} e di uno sposramenro ve.rucale_ (d~e caselle 10 _alro). l~
(zzoncali a sinistra e quelle vercicali verse L'll.lco saranno indicare con dea numeri
mosse o '

.di
. 1 h . o tal
negativi. Le orco mosse porranno essere descrmeda dne-verrori uni mens1ona 1, oru n
e ver t i cal, come ~egue:
horuontal[0J =2
horizontal[ 11 = 1
horizontal[2] 1

222

G\PlTOLO 6

horizontalf3J = -2
liorizontalf4J = -2

horizontalf5J

= -1

horizontal[6J : 1
=2

horizo~talI7J

vertioalf0J

=-1

= -2
verticall2J = -2
vertical[3) = - 1
vertical[4J = 1
vertical(S J = 2
vertical[ 6] = 2
verti:cal[1]

vertical[7]

Le variaJ>ili urrenrRow e ctU"renrColumn indicheranno rispcuivamenre la riga e la colonna della posizione correnrc del cavalJ.0. Per eseguire una mossa di tipo move'Number, dove
moveNumber sia comprc,o Ha O e 7, il vostro progra,mma utilizzer qusce istruzioni:
currerrfiow += veM:ical[moveNumber];

currentColOmn +,, hOrizontalfmoveNumberJ;


TJtlizzare un concacore che vari nell'imervaUo da 1a64. Regiscrace l'ultimo valore assunto
dal conta.rare di ogni casella visirat.'\ dal cavallo. Ricordare di veri fcare ognU:nossa potenziale pe.r aS.sicurarvi che il cavallo non abbia gi visiraco quella ca~lla. E, naturalmente,
verifcacc: ogni mossa poreniiale per asskurarvi che il cavallo non cada fuori della scacchiera. Ora scn:.ece un programma che porri il cavallo rn giro per l:t scaccluera. Eseguire il
programma. Quante mosse ha compiuro il cavallo?
c) DC>po a\.:ec rentaro di scrivere ed eseguire un programma cbe risolva il problema dcl Giro del
Cavallo, avrete probabilrnence svilupparo qualche preziosa iacuizione. U.lizzetemo proprio
quelle per Sviluppare uri metodo eurlsrico{ovverosia una strategia) per muovete jJ mvaJJo. I
metodi eurisrici non garantiscono il successo ma, se svlluppari ::1ccnmtame:ntc, awnencano
enormemente le probabilit di succe$O. Dovresre aver notato che le caselle piilesterne sono. io
un cerro senso, pi problematiche di quelle pi vicine al cencro della scacchiera, lnfutti, le caselle
pi pr0blemariche, o inaccessibili, sono proprio quelle dc.i quanro angoli.
wnruizione porr suggerirvi che. al principio, sar meglio tencarc di muovere il cavallo
nelle caselle pi problematiche, lasciando libere quelle pi facili ckmggiungere, in modo
da avere maggiori probabilit di successo verso la fine del giro, quando la scacchiera sar:.)
congesrionam.
Potremo sviluppare una '"euristica dcl.l'accessibilir", classilcando ognuna delle caselle io
base alla. loro actessibilic e movendo conseguentemente l cavallo neUa c!>c.lla. meno accessibile tta queU raggiungibili dal suo particolare movimeoro a L Etichene.reri:ro la marrice
accessi\>ilicy con dci valori che indichino, per ogni casella, il numero di cj'uelle dalle quali
essa p:ocr_essere mggiunro. {n una scicehiera vuota, le caselle del centro saranno dunque
valrmrre 8, quelle degli angoll 2, mentre le alrre avranno dei valori d'accessibilit pari a 3, 4
o 6, come segue:
2 3 4
3 4 6
4 6 8
4 6 8
4 6 8
4 6 8

6
8
8
8
8
3 4 6 6
2 3. 4 4

4 4 3 2
6 6 4 3
8 a 6 4
8 8 6 4
8 8 6 4

8 8 6 4
6 6 4 3
4 4 3 2

Vl!TIORI

223

Ora scrivete una ver~ione del programma per il Giro del Cavallo che urilizi.i l'c.:urisca
detraccessibilir.1n ogni momenro, il civalio dovr.muoversi nella casella con il numero di
accessibilit pi bassq. fn caso di parit a:a caseli~. il caY<llio porr muoversi verso u.11a
qualsiasi di quelle a pari merito. Di conseguenz:i, il giro pOtf cominciar ja uno ~asi
dei qua cero ang_o4. (Nora: il voscro programma d.ovr_ridu.rre i valorJ di acccssi billt:~ polc.b
con lo sposramemo del cavallo suUa scacchiera aumenter il numro di ca~ell gi visirnci:..
In questo modo, io un qualsiasi momento del giro, il nwnero di acccssibilic.di ogaicasella
rimarr esanamcnre uguale al numero di caselle dalle quali ~sa porr essere r:aggiuara).
.Eseguire quesca versione del voscro programma. Avere otcenuro un giro complero? Modificace ora il programma facendo in modo che il cavallo compia 64 giri, partendo da ognuna
delle caselle della scacchiera. Quanti giri compleci avere orrenuto?
d) Scrivere una versione del programma del Giro del Cavallo che, qualora si imharra in un
pareggio tra due o pi ca.selle, decida quale scegliere dopo aver dato uno sguardo alle c.aselle
che porranno essere raggiunte da quelle :i "pari meci.ro". Il vostro programma dovr m.uovere i.I cavallo nella caseUa da cui sar possibile raggiungere quella con li valore di accessif?ilit pi basso.

(,.25 (Il Giro del Cavallo: approcci brucali) Ndl"Escrcizio 6,24' abbiamo sviluppaco una soluzione
per il problema del Giro del Cavallo. I.: approccio uriliz1..ar9, detto "eUI.isc:ica dclt'accessibilir", gener,i
moire soluzioni ed eflc.;ienre.
Man mano che la potenza d ei compurcr continuer ad aumentare, saremo in grado di risolvere
~old problemi sfrurcando solamente le loco capacir di calcolo e degli algoritmi meno sofisticati. In
genere questo ripo di appro~o alla soluuone dei problemi detto "brutale o con la forza brum".
a) Urilizzare un gen.erarore di numeri C'..tSuali pe.r consentire al cavallo di girovagare a caso
per la scacchiera, naruralmen1e rispettando il suo legittimo incedere a L. Il vosuo
programma dovr t:;.segui.re un giro e visuali?,7..re la scacch.iera risultan1c:. Quanta suada ha percorsoJl cavallo?
lii) TI programma precedente avr prodono molro probabilmente un giro relacivam~ate
breve. Modifcate 9ra il vosrro programma in modo da tentare 1000 giri. Otilizz~re L1n
verrore uniclimensionale per conservare le occorrenze delle varie lunghe1.1.e ocrcmae
da ogni giro. Nel momcnro in cui avr completaw i suoi I 000 rcnrarivi, il vosrro
programma dovr visualizzare le sudderce informazioni in un formato rabula.re -ordinato. Qual Star-0 il risultato migliore?
c) TI programma precedente vi avr fornico molto probabilmcore qualche giro "degno di
nor:J'', ma nessun giro completo. Ora "lasciatevi andare" e lasciare andare anche il
voscro programma, finch non riesca a produrre un giro complero. (Aucnzione: questa versione dcl programma porrebbe durare per ore anche su un computer potenre).
Ancora un11 volca, conservate in una rnbella le occorrenze delle varie lunghezze oi:cenute da egni giro e visualiziarela, quando sar scaro rrovaro il primo giro compleco.
Quanci teatarivi ha compiuro il vostro programma, prima di produrre tm giro com~
pleto? Quanto tempo ha Lmpiegaro?
d) Confrontare la versione brucale del Giro dcl Cavallo con quella che ha ucilizzato
l'eurisric.a dell'accessibilit. Quale versione hs richiesto uno studio pi accura.ro del
problema? Qua.le algoritmo stato pi difficile da sviluppare? Quale ha richiesto pi
porcaia di elabor.azione? Sar possibile avere a priori la ccrrezza di ottenere un girq
complern, usando l'approccio dell'euristica dell'accessibilit? Sar possibile avere :1
priori .la cerrezza di oaenere un giro compi.ero, usando l'approccio con la forza bmra?
Argomen.race i pro e i contro della risolu1.ione dei problemi urilinando la furza bruca
in gencral.

224

CMffOLO 6

6.26 (Le orco Regine~ Un. altro problema per gliappassionari del gico degli $C'achi quello delle
Otto Regine. Decto sempUccmente: possibile sistemare Otto regine su una scaccb.icra vuota in modo
che nessuna di lor "artacchi" le alcre, ovverosia i.n..modo che non ci$iano due regine sulla stessa riga,
sulla medesima colonna o lungo la sressa diagonal Utilizzare il tipo dj ragionaJllnco sviluppa.ro
nell'Esercizio 6.2.4 per form ulare un merodo euriscio che risolva il problema dlle Orto Rt:gin.e.
Esegujtc l vostro programma. (Suggcrimenw: sar'. possibile assegnare un valore n.qmerico a o~rn.i
ctslla della scacchiera, tn modo da indicare il numero di quelle che saranno "escluse". in uoascacclera
vuota, unn volra che una regina sari stata sisremaca in quella casella. Per esempio, a ognuno dei quarrro
angoli sarebbe assegnato il valore 22, come mosrraro nella Figura 6.25.)

** ** * * .
*

...

Figura 6.25 Le 22 caselle esduse sistemando una regina nell'angolo in alto a sinistra.
Una volta ehe questi "numeri di esclusione" saranno semi sisremru:i io rune le 64 caselle, un
merodo euristico appropriato pocr~ essere: sistemare la prossima regina nella casella con il numero di
dimina:z.ione pi basso. Per quale motivo questa strategia iocuicivamence atcraence?

6.27 (Le orco Regine: approcci..brurali) In quesco esercizio sviluppeme diversi approcci brucali per
risolvere il probl.emadelle ono Regine introdono nelrEserciz.io 6.26.
a) Risolvere il problem.1 d_elle orro Regine, utilizzando la tecnica della forza brura casuale
~-vilupp,.ta nell'&ernizi.;i 6. 25.
b) Usare una temica sa~ti\l<I: tenmecio rum': le possibili combinai.ioni per il posizionamemo
delle otto regine sulla sEacchiera.
c} Per quale morivo pens:uecbe l'approccio esaustivo con la forza bruca non sia appropriato
per solvere il prob!emadd Giro del Cavallo?
d) Confronta.re e contrastate i due approci brutali, casuale:e:esaustivo, in generale.
6.28 (Eli~ione dei duplicati) Nel Capirolo l2 esploreremo le strutture di dari con ricerca
binaria ad alta velocira. Un:i caraneristica degli alberi di ricerca binaria che i valori duplicati samnno
sca.mlci, nello sre5so momento in cui ~i dementi saranno inseriti nell'albero. Questa cararrecisc:ica
detea appunto elimJnazione dei duplicati. Scrivere un programma cJie produca 20 numeri casuali
cpmpresi tra l e 20. Il programma dovr immagazzina.re in un vettore tutti i valori non duplicaci.
Ucilizzate il wmore pi piccolo possibile per portare a rermioe quesco ompico.
6.29 (Il Giro dd Cavallo: Verifica del Giro Cidico) Nel Giro del Cavallo, definiremo completo un
giro in cui il cavallo avr effenuaro 64 mosse, cocg mdo ogni casella della scacchiera una sola volta.
Definiremo ciclico un giro completo in cui la 64 p.osizione di sci una messa da quella in cui il cavaJJ.o
Ji::i comiociaro il giro. Modificar<; il programma del Giro del Ca~o ahc avere sc~.irro neU'Ese.rci7.i.o 6.24, in modo da verificare se un giro complero si~ anche ciclico.

6.30 (li Crivell9 cli Erarosceoe) Un oumero primo qualsiasi incero che possa essere diviso soltanto
per se stesso e per 1. n Crivello cli Eratosre.ne appunco un mecodo per rrovare i numeri primi. Es.so
funziona come segue:

l VETfORJ

225

l ) Create un vertoron runi gli elemenci inii.ializz.ali a 1 (vero). Gli dementi dcl vettore-i cui
ind.ici corrispondano a un nwnero primo rc:sceranno a I . Al ccrmine della elaborazione,
rucri gli al cri elemc.n dd vetro re saranno azzerari.
2) Pa.n:endo dall'indice 2 del vcrrore (l'indice l primo per definizione), qualor il valore
deU'elemcnco pumaco sia l , scorrere il res.co del verrore e zcratc g.Li dememi i cuLindici
siano mulcipli cli quello detl'elemcmro puncato. Nel caso dell'indice 2, saranno azzerati
tutci g1i elemenci successivi del venare con indici che siano mulripli di 2 (ovveros_ia gli
indici 4, 6, 8, 1O, ecc.}. Nel caso dell"indicc 3, saranno arterati cu:rci gli dcmenri successivi
del veccore con indici dle $iano nilripli di 3 (ovverosia gli indici 6, 9, 12, 15, ecc.).
Nd momemo in cui que~'to processo sar s.taro completato, g!i elemenri dcl venore che conrerranno
ancora il valore uno indicheranno che il loro indice un num(.{c.o pri.m0 e, di coo~enia, cl1 porr
essere visualizzato. Scrivere un programma che uci.Liz.z.i un vercore di 1000 elementi per detetrnin~re e
visualizzare i numeri primi compresi tra I e 999. Ignorare l'elemento Odel verror.

6.3 1 {Buckec Sorr) Un buckct son incom.ina dichi:i.r:mdo un vcrrore unidimensionale di inceri
posicivi, q4ello d1e dovr essere ordinato, t una marrlce di in.ceri con le righe indicizz.ace da Oa 9 e le
colon.oe da Oa n - L, dove n . iJ numero dei valori pre.5enti nel veno.re che dovr essere ordinato. Ogni
riga della marrice dctra bucket (secchio). Scrivere una funzione bucketSort che riceva come argomenti un verrore di inceri e la.sua dimensione.
Calgorirmo . iJ seguente:
I) Scorrere il venare unidimensionale e sistemate ognuno dci suol valori in u11a riga della
matce, basandovi sulla cifra delle unir. Per esempio, il 97 sarsi:stemaco nella riga 7~ il 3
sar inserito nella riga 3 e il 100 sar posco nella riga O.
2) Sorrecela marrice e riportare i valori nel vcccore originario. Nel verror<; unidimcnsionaleil
nuvo ordine dei suddeni valo ci sar: I 00, 3 e 97.
3) Riperece que!Sto processo per ogni succe~siva posizione delle cifre (decine, centinaia, migliaia, ecc.) e fermarvj quando sat srarn elaborata h cifra pi signilcava dcl numero pi
grande.
Al rcrmine del secondo passaggio.sul veno re, il I 00 sar siste:maro nella riga O, il 3 S4r inserito nelluiwi
O(poich ha solo una cifra) e il 97sar posro nella riga 9. I.: ordine.dei valori nel vettore unidimensionale
sar a quesr.o punro: 100, 3 e 97. Al termine del ceno passaggio, il 100 sai sisremaco .ndla riga L, il 3
:e 11 97 saranno inserici nella riga O(il 97 dopo il 3). 11 buckec sorr gar.1Jtisce che tuni i valori sirnno
ordinaci appropriacamence, 4opo cl1e sar stata. elaboraca la cifra pi significativa del numera pi
grande. Il buckec son sapr di avere cerminato il proprio compito, quando rurci i valori saranno st.aci
ricopiaci nella riga zero della.marcicc.
Osservare che la matce avr una dnlcnsfooe pari a dieci vo}te quella del vettore di inceri da
ordi nare. Questa recnica pi d:Ecieme di 4'1Udla dell'o.rdinamemo a bolle. ma richiede una ca:pacic
di memoria nocevolmenre superiore. I.:ordinamenro a bolle richiede solo una posizione di memoria in
pi per il tipo di daro da ordina.re. Il buck;t sorc un esempio di compromesso tra consumo di
memoria ed eflciema: vero che uufo.u pi ~emoria, ma anche vero che pi efficiencc. Questa
versione del bucket sorr richiede che per ogni passaggio i daLi siano ripon.ari nel vecrorc originale. Si
potrebbe anche creare una seconda marrice e sposrare ripetutamente i dati rra le due matrici.. fmch
non siano stati ricopiati ruu:i nella riga zero di una delle due. A quel punto la ri,,11a_ zero conrerrebb il
vettore ordinato.

Esercizi sulla ricorsione


6.32 (Ordinamento per selezione) Un ordinamen.to per selezione ricercher~ in un vertere l'demenro pi piccolo e, quando l'av.t.individuaro. lo scambier d.i posro con il primo elemento del vercore. Il
processo si ciperer per il soa:ovettore che comioda con il secondo elemento del vettore. Ogni passaggio

226

Ul'ITOL.06

sul vettore far in modo che un clemenco sia sisrt:rn:Honella posizione appropriata. Qu~ro ordinamenro richiede capacir di elaborazione simili a quelle deU'ordinamenro a bolle: per un venore di n
elementi, dovranno essere eseguiti n - l passaggi e, per ogni sorroverrore, dovranno essere compiud
n- l confronci per individuare il valo re pi piccolo. U vettore risulrer: erdfoaro nel momento in cui il
son:ovecrore da elabcmue coarerr W 1 solo ekm~nto. Scrivere una funzione cicorsiva selectionSort
d1e i.mplemenci questo algoprmo.
<i;.33 (Palindromi) Un palindromo una scringachesi legge aUo sr$So modo da sinisua a descra e da
desua a sinisua. Alcuni esempi di palfodrom.i sono: ".radar", uable was i ere i saw d ba" e "a man a pian
a canal panama". Scrivete una funzione ricorsiva testPalindrome eme rescirubca I , qiaaloxa la stringa
ili1m;1gallinara nj vectore sia un palltidromo, e Oin caso comrario, La fum;ione dovr igncma.re gli
SJ?azi e la punceggiarura cvenmalmentc presenti nella minga.

CAPITOLO

I puntat ori
Obiettivi

6.34 (Ricerca lineare) Modificare il programma della Figura 6.18, in modo da uriliZ:tare una fum.ione ricorsiva linearSearch che esgua una ricerca Jineare all'interno del venoce. La funzione dovr
c;:evere come argomenti un vercore di i meri e la sua dimensione. Nel caso che la diiavc di ricrc:i si~
S\a.ra cirrovam, restiruirere l'indice de.I vetrore, :da:im,enci rcsriruirere - l.
6.35 (Ricerca binaria) ModifC<1te il programma della Eigura 6.19, in modo che utilizzi una funzione rcersiva binarysear ch che esegua una ricerca binaria all'inrerno del vcLrore. LLfu:nziooe dovro
ricevere, come argomenri, un vettore cliin.ceri e gli indici di inizio e di fine dd sorrovettore in cui dovr
essere eseguita la ricera. Nel c:iso che la chiave di ricerca sia stata ricrovata, restimirere l'indice del
verrore, akrimenri rescitulrere - l.

6.36 (Le otro Regine) Moclitc<l!C iJ programma delle orro Regine che avere creato nell'Esercizio 6.26 cosl che solva il problema in modo ricorsivo.
6.37. (V$ualiZ?.are un vettore) Scrivere una funzio:nc ricorsiva printArray che riceva come argo
mentr un vercore cda sua dimensione e non resriruisca alcun daco. la fum.ione.dovi: terminare la
p.repria elaboraz.ione e rstiruire il d:mcrollo a quella chiamante, quando avr ricevuco un vertere di
dimensione O.
6.38 (VisuaJizza:r.e una stringa al mmrario) Scrivete w1a funzione I i:orsiva stringReverse che
riceva come a:rgomenro un vettore Jii caiarreri e non reslruisca nes:sun daco. La 'funzione dovr
rermina.re la propria. da bo.razione e rcsclruire il conaollq a quella cbiamanrc, quando avr incomraro il
tru:artere nullo di cea:nioaz.ionc della srringa.
6.39 (Trov;ue il valore tnlnimo in un vercore) Scrivere una funzione ricorsiva recursiveMinimum
:hciceva come argomenti un venare di interi e la sua dimensione e resrituisca l'elem~m pi piccolo
dt!~ veuore. La funzione dovr rerminare la propria elaborazione e restituire il controllo a quella
diia.man.ce, quando avr..riccvuco un vectore che coJltenga un solo elemenco.

7.1

Essere in grado cli acilizzare i punta.cori.

Essere in grado di utilizzare i puntatori per simulaie il passaggio perriferimento degli


argomenti delle funzioni.

Comprendere la stretta correlazione tc-.t i puntatori, i vettori e le ~-cringhe.


Comprendere l'urili1:Z0 dei puntatori a funzioni.

Essere in g;.ido di dichiarare e utillu.are i vettori di stringhe.

Introduzione

[n questo capitolo, cliscmererno una delle pi porenci cararreristiche del linguaggio di programmazione C: i ptmtatori. Questa una delle cararreristiche del C pi difficili da padroneg.,i:rlare. I
punracori consentono ai programmi d i simulare le chiamare per rifecimemo e di creare e
manipolare le strutture di dati dinamicb:e, ovverosia quelle che possono ~rescere e decre5cere
durante l'esecuzione di un programma, come le lisre Cbncarenate, le code, le pile e gli alberi.
Quesro capitolo spiegherl concerri fondamentali dei punrarori. li Capitolo 1O invece esaminer l'uciliz;zo dei puncarori con le scrucmre. U Capirolo U introdurr le tecniche di gesrione
dinamica della memoria e presenter degli esempi che creeranno e urilizzeranno le smm:ure di

dad dinamiche.

7.2

Dichiarazione e inizializzazione dei puntatori

J punc:amci sono delle variabili che come valore conc:engono degli indirizzi di memoria. Di
norma una variabjJc coririene diremunente un valore specifico. Un punrarore invece coiirieue
l'i.ndjriizo di una vadabile nella quale immagazzinato quel valore spec::ifc,o. In questo senso, il
nome di una variabile fa direttamente riferimento a un valore, mentre un punra.rore lo fa.in4iretrammte (Figura 7 .1). Per questo m otivo .iLciferimenro a un valore per mezzo di un puntatore

detto derifen'ment().

count

[]
countptr

fa direttamente
riferimento ad una variabile il cui
valore 7
COt:Jnt

count

count Pt r fa indirettam~nte
riferimento ad _una variabile il cui
valore 7
Figura 7. I

Far rife rimento a una variabile in modo diretto e indiretto.

228

CAPITOL O

I puntarori, come ogni altra variabile) devono essere dichiarati prima di poter essere utilizzati. La dichiarazione

I PUNTATO RJ

229

'

int *count Pt r, co unt ;


dichiarer la variabile countP tr di tipo int * (ow.erosia, un puntato re a un valore intero)
e si legger "count Ptr un puntatore a int" o "count Ptr punta a un oggetto di tipo
incero,,. Anche la variabile count sar dichiarata di tipo incero, ma non sar un puntatore
a un intero. I.:asrerisco (*) presence nella dichiarazione sar applicato solo a countP tr. Un
* che sia stato uriliz.zato in una dichiarazione nel modo che abbiamo visco, indicher che la
variabile dichiarata sar un puntatore. f puntato ri porranno essere dichiaraci in modo da
fare rife menro a oggetti di ql1alsiasi tipo di dato.
Errore tipico 7. 1

L'operatore di deriferimento ,.. non sar applicato a tutti i nomi di variabile che siano
stati inclusi in una dichiarazione. Ogni pun:tatore dovr essere dichiarato cori un ,.. che
precedfJ, iL suo nom.e.

yPtr

Figura 7 .2

Rappresentazione grafica di un puntato re che punta a una variabile intera


contenuta nella memori a.

La Figura 7.3 mosrra la rappr~senrazione del puntatore all'interno della memoria, suppo11endo che la variabile y sia stata immagazzinata nella locazione 600000 e che il puntatore yPtr sia
staro sistemato all'indirizzo 500000. Loperando delroperatore di indirizzo deve essere una variabile; l'operatore di. indirizzo non potr essere applicato quindi a costan, espressioni o~ variabili che
siano stace dichiarare con la specifica di classe di memoria registe r.

BUQna abitudine 7.1


yPtr

Includete le lettere ptr nei nomi per le variabili di tipo puntatore, cos da. rendere ezJidente che siano dei puntatori e che sar necessario manipolarli in modo approptiato.
1 puntatori dovrebbero essere inizializzati e ci potr essere fatto o contestualmente alla
loro dichiarazione o con un'istruzione di assegnamenro.. U.n puntatore porr essere inizialimto
con e, NULL o con un indi.rizzo.. Un ptintarore che contenga il valore NULL non far riferimento
a nessun dato. NULL una costan te simbolica definita in molti file di intestazione, tra cui
<stdio . h>. Cinizialirnz.ione di un puntatore con 0 equivalet1te a quella eseguita con il valore
NULL ma preferibile uril'izzare quest'ultimo. Ci perch uno 0 che s.ia staro assegnaco a un
puntatore sar prima converro in un puntatore di tipo appropriato. Lo 0 l'unico valore incero
che porr essere assegnato direttamente a 11na \iariabile di tipo puntatore. ~as.segnamenc dell'indirizzo di una variabile a un puntatore sar discusso nella Sezione 7.3.

Buona abitudine 7.2

Inizializzate i puntatori in modo da prevenire dei risultati inattesi.

7 .3

Gli operatori sui puntatori

Lampersand (&, e commerciale), od operatore di indirizzo, un operatore unario che restituisce l'indirizzo dd suo operando. Per esempio, assumen do le dichiarazioni

nt y = 5;
nt *yPtr;
l'istruzione

yPtr

= &y;

assegner al puntatore yPtr l'indirizzo della variabile y. Si dir quindi che la variabile yPtr c'punca
' y. La Figura 7 .2 mostra una rappresentazione schematiea della memotia in seguito all' esecuzione dell;~egnamenro precedence.

500000

Figura 7 .3

600000

y
600000

Rappresentazione di y e yPt r in memoria.

L'operatore *, detto comunemente operatore di deriferimento od operatore di risoliezione


del riferimento, restiruisce il valore dell'oggetto puntato dal suo oprando (ovverosia dal puntatore).
Per esempio, 'istruzione

ptintf( ''%d", *yPtr);


visualizzer il valore della variabile y, vale a dir 5. L ucilizzazione dell'ope rato re * in questo
modo detta risoluzione del r-iforirne11to di un puntatore.

Errore tjpico 7.2


Risolvere il riferimento di un pt-tntatore che non sia stato appropriatamente_inizializzato,
o che nn sia stato impostato in modo da puntare a una specifica locazione di memoria. Ci potr causare un error:e fatale in fase di esecuzi(Jne, o potr modificare accidentalmente dei dati importanti e consenti.re 41 programma di compktare la propria esecuzione,
producendo per dei risultati errati.
Il programma nella Figura 7.4 mostra l'urilizzo degli operator i dei puntatori. La specifica cli conversine %p della printf invier in output la locazione di memoria, convertendola in u11 intero esadecimale (consultate l'Appendice E, r sistemi numerici", per orrenere
maggiori informazioni sugli interi esadecimali). Noterete che nell'out put l'i.ndicizzo di a e
il valore di aPtr saranno identici, conferm ando cos che l' indirizzo di a sar stato sicuramenre assegnato illa variabile cli tipo punrarore aPtr. Gli operatori & e * sono l' uno il comp lemento ddl'altro: qualorafossero applicati consecutivamente ad aPtr in qualsiasi ordine, si
otterrebbe lo stesso risultato. La tabella deUa "Figura 7.5 mostra la priorit e l'associativit
degli operatori introdotti sino a questo punto.

CAPI TOLO

230

Ii

7.4

/ * Usare gli oper ator i & e * */


#inc lude <std io.h >
{

int a;
int *aPt r;

/ * a un inte ro */
/ * aPtr un punt ator e a un inte ro * /

a ~ 7;
aPtr = &a;

1
indi rizz o di a * /
i
con
stato
impo

/ * aPtr

prin tf (" Tne addr ess of a is %p\ n''


''The valu e of aPtr is %p\ n\ n'' , &a, aPtr );
prin tf( "Th e valu e of a is %d\ n''
"The valu e of *aPt r is %d\ n\ n" , a, *aP tr);
prin tf( "Proving that * and & are complements of ~
"each othe r. \ n&*aPtr = \ p\ n*&aPtr = %p\ n ,
&*aPtr, *&aPtr);
retu rn 0;

In

of a is FFF4

The valu e of aPtr is FFF4


The valu e of a is 7

The value of aPt r is 7


P:rov ing that
&'*aPtr- = FFF4
&aPtr FFf4

and

&

are cmplemertt:s of aach

Ope rato ri
( ) [

o1:t\e~.

'

Gli oper atori sui puntatori & e * .

Figu ra 7 .4

La chiamata per rife rim ent o delle funzioni

e,

i prog ramm atori ut ilizza no i puntato ri e l' oper atre di derif erim ento per

simu lare una chiam ata p e r ri ferim e nto. Per richi amare una fun zione co n degli argo men ti che d ebba no essere modi ficat i, si passerann o dunq ue i loro indirizzi. Norm almen te, ci potr esser e otten uto appli cand o l'ope rator e di indir izzo (&) alla varia bile
che d ovr essere modifi cata. I vetto ri invec e n on saran no passari u til iz.zando !,op erato re & p erch , come abbi amo visco 11el Capi tolo 6 , il C passe r auto mati ca men te la
locaz ione dj mem oria del loro prim o elem eno (poic h il loro .nom e sar se mpre equi valen te a &arr ayNa me[0 ] ) . Nel mQm ento in cui !, indir izzo d.i ttna varia bile sar stato
passa to a un a funz.io 11e, n el co rpo di ques ta potr esser e u tili zzato l'o peratore di
deriferi men to (*) per m odificare il valo re della varia bile imm agaz zinat a nella mem oria
del chiam a nte.

}
a~dress

23 1

Esist o no due mod i per p assare gli argo menci a una fun zio ne: per vaJore e per riferi ment o. Tu tte le chiam are di funz ione in C so no per valore. Com e abbi amo visco nel
Capi tolo 5, l' istruz ion e retu rn potr esser e utiliz zata per restit uire un valore da una
funz ione chiam ata a quella clu aman te (o anch e per restit uire il co nt rollo da tLna fun zione c hiam ata, senza resti tuire alcun valore). M o lte fu nzion i per porre bber o avere la
nece ssit di modi ficare alcun e delle varia bili ricevure d al c:hiam anre, o di passa re un
punt atore a un ogge tto di d ati di dimen sioni raggu ardev oli, per evita re il dispe ndio
causa to dal passa ggio del suo valor e (che, co me sapp iam o, richiedere b be la prep arazione di una copia deU ' ogge tto). Per ques ti scop i il C forni sce la possi bilit di simtt lare
un a chiam ata per rifer imen to.

main ()

The

I PUNTATORI

Associativit

Tipo

da ~in isrra a destr a


da destra a sinis tra

mass.tma

I prog ramm i most rati nel la Figu ra 7 .6 e n ella Figu ra 7.7 corri spon dono a due
versjoni di una funzione che eleve r al cubo un inter o: cube ByVa lue e cube ByR efere nce.
Quel lo della Figu ra 7.6 passer la v~ri abile rium ber alla funzi one oube ByV alue ut.i.lizza_ndo una chi a mata p er valor e. La funz ione cube ByV alue eleve r al cubo il suo argo men to e restit uir al main il nuov o valore utiljz zand o un,is uuzi one retu rn . Il nuovo
valor e sar asseg nato a num ber nella funz ione main .
Il prog r amm a del la Figu ra 7. 7 pass er la var iab ile n u mb e r all a ftJ nzio ne
cube ByR efere nce t1cilizzando una chiam ata per riferi ment o, ovve rosia passa ndo l'indirizzo di number. La funzi one cube ByR efere nce ricever come argo ment o un puntatore
a int chiam ato nPtr . La funz ione risolver il riferi men co del punt atore ed eleve r al
cubo il valo re punt ato da nPt r . C i mod ifich er il valo re di num ber co nten u to nella
mem oria delJa funzj on e main . Le Figu re 7.8 e 7 .9 an alizz ano graficame nte n ~ll'o rdine
i prog rariun.i della Figu ra 7.6 e della Figu ra 7.7.

da sinistra a destra

mol tiplicarivi

da sinist ra a destr a
da sinis tra a destra

addit ivi

da sinis tra a desu a


da sinistra a destra

uguaglianza
AND logico

da siniscra a destra
da destr a a sinis tra

OR logico
cond izion ale

/* Eleva al cubo una vari abil e usando una chiamata per valo re */
#inc lude <s tdio .h>

da destra a sjnist ra
da sinist ra a destra

assegna.men ro

int cubeByValue (int );

++

--

* & (tipo )

< <= > >=

--

1=

&&
I I
I I

?:

+=

---

*= /= %=

Figu ra 7 .S

Priorit degli operatori.

unar i

Errore tipico 7.3

relazionali

Non risolvere il riferimento di ut1 puntatore, qualora sia necessario farlo per ottenere il
valore cui fa riferimento il puntatore.

virgo la

main( )

(con"tinua)

CAI'lTOLO 7

233

lPUNTATORl

232
All'inizio

printf( "The original value of number is %d\ n", number);


number = cubeByValue (number);
printf(''The new value of number is %d\n'' 1 number);

r1ch1ama

int number = 5;
number

cubeByValue:
r;=-:---=-:-:-~-:--:~~~~~~----.

numb er

main()

int number = 5;

main

int cubeByValue(int n)

return n " n * n.
I

= cubeByValue (number) ;

indefinita

return 0;

}
Dopo

int cubeByValue(int n)
{

r eturn n * n * n;

/* eleva al cubo la variabile locale n */

int numbe r = s;

The originaL ~value of number is 5


The new val~ of nmber is 125
Figura 7 .6

number

ri~eve la chiamata:
r;:-=-~-:---=----~~~~~~~

number

main()

c ub eByValue

int cubeByValue(int n)
{

return n * n " n .

= cubeByValue(n umber);

'

Eleva al cubo una variabile usando una chiamata per valore.

/* Eleva al cubo una variabile usando una chiamata per riferimento */

#include <stdio .h>

Dopo

cu b eByValue fa il cubo del parametro n:

main()
{

int number

v0id cubeByReference(in t *);

ntimber

main()

= 5;

number

int cu beByVal ue(int

125

return

= cube6yValue(number);

0 * n Ji
n

int number

n)

= 5;

printf( "The originai value of number is %d\n", number) ;


cubeBy Referen ce(&num~r);

printf( "The new value of number is %d\n

Dopo

1
'

number);

return 0;

main()

number

int number

*nPtr

*nPtr * *nPtr * *nPtr;

= 5
I

ma i n:

int cubeByValue( int n)

125

return n n n.J

number =(cubeByValue(numbe r);

void cubeByReference(in t *nPtr)


{

cubeByValue

restituisce l valore al

/ * eleva al cubQ number nel main */

indefinita

The O'~ifinal v.alue Of nuqtber is 5

Dopo

main completa l'assegnazione a numb er:

T.he new, va1U<e f nutnber. is 126

Figura 7.7

,.

in t number

Eleva al cubo una variabile usando una chiamata per rif erimento.

Una funzione che riceva come argomento un indirizzo dovr definire un paramecro di
tipo puntatore. Per esempio, l'incestarione della funzione cubeByReference sar:

~i:n-::t--:-:-=--:--:-:--n)
cubeByValue(int:-------------.

n uni ber

ma in ()
{

= s
I

125

I.

number = cubeByValue(number)j

Figura 7.8

n " n.I
n

void cubeByReference(in t *nPtr)

r et urn n

Anaris1. di una tipica chiamata


per valore.

indefinita

234

CAPITOLO

number

i nt number = s;

void cubeByReference(int *nPtr )

235

utilizzata una chiamata per riferirnento. U compilatore convertir cucci i parametri di


funzi9ne che rappresentino u11 vettore unidimensionale, dalla notazione int b [] a
quella int *b co n puntatore. Le due forme sono dunque interscambiabili.

Prima della chiamata oer riferimento a e u be B V Re f ere ne e:

main()

J-pNTATORl

*nPtr = *nPtr nPtr * *nPtr;

Buo1za abitt,dine 7.3

cubeByReferen ce( &number);


}

n Pt r

Dopo la chiamata per riferitnento a

cu beByReference e

indefinita

prima che venga fatto il cubo di

*nPt r :
=

number

main()
{

int number

Utilizzate sempre una chiamata per valore quando passate degli argomer1.ti a itna fitnzione, sempre che non sia richiesto esplicitamente che qttel/a chiamata modifichi il valore
dell'argomento nell'ambiente della jitnzione chiamante. Qitesto un altro esempio del
principio del minimo privilegio.

= 5;

void cubeByRef erenc-e ( int *nPtr)


{

*nPtr

*nPtr *nPtr ,. *nPtr; ,,

cubeByReference(&number);
}

Utilizzare il qualificatore const con i puntatori

Il qualificatore const conse11tir aJ programmatore di informare il compilatore che il valore di una particolare variabile non dovr essere modificato. Il qualificatore const non
esisteva nelle prime versioni del C: stato aggiunto al linguaggio dal con1irato deJl'ANSI C.

Ingegneria del software 7. 1

nPtr

7.5

Il qualificatore const potr essere utilizzato per applicare il principio del minimo privilegio. Applicare il principio del 111inimo privilegio, per progettare in modo appropriato il software, ridttrr drasticamente il tempo di messa a punto e gli inopportuni effetti
collaterali e render pi facile kJ modifica e la manittenzione di itn programma.

Dopo che *nPt r stato moltiplicato al cubo:

number

ma in ()
{

int number : 5;

125

void cu beByReference(int *nPtr)


{

nPtr = *nPtr

~nPtr

*nPtr;

cubeByRefarence(&number);

nPtr
~

Figura 7.9

..;..

Analisi di una tipica chiamata per r iferimento.

La suddetta intestazione sp ecifica che cubeByReference ricever ome argomento


l'indirizzo di una variabile incera, immagazzinandolo localmente in nPtr, e che non
restituir nessun valore.
Il prototipo di fi1nzione per cubeByReference conterr int all,interno d elle
parentesi. Cos com~ acade con gli aJrri tipi di variabile, non sar ncessario includere i nomj dei puntatori all'interno dei prototipi di funzione. In ogni caso, quelli che
saranno stari inclusi per scopi documentativi saranno ignoraci dal compilatore C.
Qualora un,a funzione debba ricevere come argomento un vettore unidimensionale,
nella sua intestazione e nel suo prototipo porr essere utilizzata la stessa notazione con
puntatore usata nella lista dei parametri di cubeByReference. Per il compilatore, un a
funzione che riceva un puntatore sar equivalen te a una ch e riceva un vettore
unidimensionale. per questo moti vo che spetter alla funzione "sapere" se stia ri cevendo un vettore unidimensionale, o semplicemente una variabile per la quale sia stara

Obiettivo portabilit 7.1


Per quanto il qualificatore const sia ben definito ne/L'ANSI C, sappiate che alcitni .risterrii non lo applicano.
Nel corso degli an'ni, si accumulata un'eredit formata da una gra n quancit di
codic;e serit.to con le prime versioni del C, che non utilizzavano const perch non era
ancora disponibile. Proprio per questo mocivo, oggi esistono innun1erevoli possibilit
di miglioramento, ottenibili progettando nuovamente il software scritto co n le vecchie
versioni del C. Oggigiorno esiston o anche moJri programmatori cl1e, malgrado utilizzino I'ANSI C per sviluppare i loro programmi, non adoperano il qualificatore const
perch hanno incominciato a programmare on le prime versioni del C. Questi programmatori scanno ovviamente trascurando molte opportunit per una buona ingegnerj a del software.
Esistono sei modi di utilizzare (o di no11 utilizzare) const con i parametri delle ft1nzioni: due riguardano il passaggio per valore dei parametri e quattro quello per riferimento.
Che cosa guider la vostra scelta su una di queste sei possibilit? Lasciate che il principio
del minimo privilegio sia La vostra guida. Assicuratevi sempre cl1e una fun zione abbia un
diritto di accesso ai d ati contenuti nei propri parametrj tale che possa consentirgli di
svolgere il suo compito, _ma non di pi.

Nd Capitolo 5, abbiamo spiegato che in C tutte le invocazionj di fu r1zion.i so no per


v:alore: esse riceveranno dunque una copia dell'argomento passato attraverso l' invocazione.
Il val.ore originale della variabile rester immutato ncll'ambiente della funzione chiamante,
anche quando la sua copia sar stata 1nodificaca -all' interno della funzione chiamata. le
molri casi, il valore passato a una fi1nzione sar modificai:o in modo che quella possa

CAPITOLO

236

re di
portare a trm ine il proprio com pito . &is ton o tuttavia delle circostanze in cui il valo
ti
trat
si
lora
qua
e
nch
nea
a,
mat
chia
e
zion
fun
a
dall
rato
alte
re
esse
r
dov
non
to
men
argo
un
di una cop ia del valo re originale.
Co.nsiderate una funzione che ri.ceva com e argomenci un vettore uni dimensionale e la
rere
scor
nte
eme
plic
sem
r
dov
e
zion
fun
tale
Una
re.
o
vett
il
zi
aliz
visu
che
e
ione
ens
dim
sua
sar
one
ensi
dim
sua
La
so.
stes
o
dell
ento
elem
lo
ngo
si
i
ogn
put
out
in
iare
inv
e
il vettore
il
utilizzata nel corpo della funzione per determ inare l'ind ice massim.o del vettore, c-0sl che
La
ata.
plet
com
a
star
sar
one
zazi
aliz
visu
la
cui
in
to
men
mo
il
e
nar
rmi
dete
sa
pos
o
cicl
dimensio11e del vett ore non sar dt1nque modificata nel cor po della fun zion e.

Ingegneria rkl softzuare 7.2


Nel ca.so in cui 1.tn valore non sar modificato (o non dovr essere modificato} nel corpo
della funzione cui sar stato passato, quel valore dovr essere dicf1iarato con st per assicurarsi che non sia modificato accidentalmente.
o
stat
sia
cl1e
r
valo
un
are
ific
mod
di
o
ativ
tent
si
lsia
qua
ter.
rcer
inte
tore
pila
Il com
iso
dichiarato con st e, secondo la parricolare imp lementazione ucilizzata, eme tter un avv
o un messaggio di errore.

ere
gen
sto
que
di
re
tato
pun
Un
st.
con
e
ator
lific
qua
il
r
ude
incJ
non
li
dat i var iabi
in
pot reb be essere utilizzato, per ese mpi o, per ricevere un arg om ent o di cipo stri nga
e
ent
alm
ntu
eve
(ed
re
ora
elab
per
ri
tato
pun
dei
a
etic
itm
l'ar
izzj
util
che
e
zion
fun
una
uFig
a
dell
e
cas
per
Up
tTo
ver
con
ne
zio
fur1
La
.
ng~
sui
a
dell
i
ttr
cara
i
mod ificare)
abili
ra 7.10 dich iare r com e suo arg om ent o pro prio u11 pun tato re variabile a daci vari
a
volt
per
e
tter
cara
un
s
nga
stri
l
r
ore
elab
e
zion
fun
La
.
*s)
ar
(ch
s
o
dol
chia man
lusa ndo l arit met ica dei punc.atori. Nel caso che un cara tter e sia com pre so nell 'inte rva
nello a-z , e..sso sar con ver tito nella S\:la corrisp ond ent e le.etera mai usc ola com pre sa
io,
trar
con
caso
in
II;
ASC
ice
cod
suo
sul
aro
bas
olo
calc
un
ndo
izza
util
-Z,
A
l'int erv allo
cl1e
il cara tter e sar ign ora to e sar elab ora to que llo success.ivo dell a srringa. Oss erv ate
ri
inte
ri
valo
a
no
ndo
o
risp
cor
CII
AS
i
tter
cara
di
eme
insi
'
dell
ole
usc
mai
ere
lett
le
e
tutt
ate
sult
(con
32
o
men
la
sco
inu
m
.
era
lett
e
ent
ond
risp
cor
loro
a
dell
lli
que
a
i
equ ivalent
Cal'Ap pen dice D, per una rabeJla dei valori cor risp ond ent i ai caracteri AS CII) . Nel
vercon
la
per
c
del
d
dar
stan
eria
libr
a
dell
r
ppe
tou
e
zion
fun
la
o
erem
ent
pres
8,
lo
pito
sion e delle lett ere min uscole in mai usc ole.
1

/* Co nve rtir e le let ter e min usc ole in let ter e ma ius col e
/ * usando un pun tato re var iab ile a dat i var iab ili */
#in clu de <s tdi o.h >

Qitalora sia stata utiliuata 1.tna chiamata per valore, nell'ambiente della funzione chiamante potr essere alterato itn solo dato . Questo dovr esser assegnato dal valore di ritorno
della fanzione chiamata. Per modificare pi di t.tn dato nell'ambiente di una fanzione
chiamante, dovr essere utilizzata ur1.a chiamata per rifari1nento.

main ()
{

cha r str ing []

= ''ch ara cte rs '' ;

pri ntf {"T he str i ng bef ore con ver sio n is: %s \n" , str ing );
con ver tTo Up per cas e(s trin g);
pri ntf (''T he str ing aft er con ver sio n is: %s\n", str ing );
ret urn 0;

Buona abitudine 7.4

Prima di utiliua.re una funzione, controllate il suo prototipo per determinar se sia in
grado di modificare i valori cl-1e gli saranno pa.sfati.

Errore tipico 7.4

voi d con ver tTo Up per cas e(c har *s)

Ignorare che gli argomenti di una funzione invocata per riferimento siano dei puntatori,
pa.s.sandoli erroneamente come in una chiamata per valore. Alcuni compi/;a,tori potrebbero accettare questi valori e, dando per scontato che siano dei p1-1ntatori, risolverebbero i loro riferimenti. In fase di esecuzione, ci provocher spesso delle vio'4zioni di accesso
alla mmzoria o degli enori di segmentazione. Altri compilatori invece potrebbero rilevare la mancata co,rrispondenza tra i tipi degli argomenti e quelli dei paramett i e genererebbero dei messaggi di errore.

Esis tono ben qua ttro mo di per passare un pun tato re a una funzione: un pun tato re
a
e
abil
vari
re
tato
pun
un
i,
abil
vari
dati
a
te
I:an
cS
re
tato
pun
un
e,
abil
vari
dati
a
variabile
ni
dati costan ti e un pun tato re oostanre a dati costant i. Ogn una delle qua ttro com binazio
fornisce un diverso livello di diri tti di accesso.
i
dat
a
le
iabi
var
re
tato
pun
un
a
d
o
t,
anti
gar
sar
dati
ai
sso
acce
di
alto
pi
llo
Il live
ran variabili. In que sto caso, ovv iam ente dop o averne riso lto il rife rim ento , i daci pot
do
mo
in
to
bia
cam
re
esse
r
pot
sto
q,ue
e
re
tato
pun
il
so
V'er
attra
cati
difi
mo
re
esse
no
e a
che pos sa fare rife rim ent o ad alrr:i dat i. La dich iara zio ne di un pun tato re variabil

..... ...... ... ...... . ... ....... ..... ...... ...

...
.. . ,,
,

*/

voi d convertToUppercase{ cha r *);

Ingegneria d.el software 7.3

237

I PUNTA'"IORJ

'1,

wh ile (*s

1~

'\ 0 ') {

if (*s >: 'a' && *s


s -= 32;
++s;

<=

' z')

/ * conver te all a let ter a ma ius col a del l ' ASCII * /

/ * inc rem ent a s pe r pun tare al prossimo car att ere */

}
}

The str ng bef ore convtsion is: shar-acter-s


The str ing aft er conversion is: CHARACTERS
i
dat
a
e
abil
vari
re
tato
pun
un
ndo
usa
olo
usc
mai
in
ga
strin
una
tire
ver
Con
O
I
Figura 7.
vari abil i.

238

CAPITOLO

Un puntatore variabile a dari costanti potr essere modifLcato in modo che possa
fare rife rimento ad altri da.ci, purch siano del cjpo appropriato, ma questi non potranno essere nlodif.cari. Un puntatore d i questo genere potr essere uti lizzato, per esempio, per ricevere un ai:gomento di tipo vettore in un a funzione che elabori ogni elemento di quest' ul timo , sc; nza m odifica r11e i dati. Per es~mp io, la fu 11zion e
printCharacters della Figura 7.11 dichiarer il param etro s di tipo const char *.
La dichiarazione va Letta d a destra a sjnistra come ''s un puntatore a una cosranc:e di
carattere,,. Il corpo della funzione utilizzer u11a stru ttura for per inviare it1 output i
caratteri della stringa fi oche non sar stato inco ntrato quello nullo. Una volta che ogni
carattere sar srato stampato, il puntato re s sar incrementato cos che possa puntare
al carartere successivo deJla stringa.

/* Visualizzare una stringa un carattere per volta usando */


/* un puntatore variabile a dati costanti
*/
#include <stdio.h>
void printCharacters(co nst char *)i

239

I PUN1J\TOR1

cifecime_nro nell' invocazione di una funzione che lo riceva come argon1 ento. Le struttlLfe invece saranno sem pre passare per valore: sar dunque passata una copia dell'iarera struttura. In fase di esecuzione, ci rich ieder un cerco dispendio di tempo e di
spazio causato dalla preparazione di una copia d i rutti gli elementi prese nti nella srrurtura e, ovviamente, dal relativo immagazzinamento nella memoria delle funzioni chiamate. Porremo invece urilizza re dei puntatori a dati cosranri, qualora dovessimo fornire a un a funz.ione Je i11fo r.m azioni conrenure in un a struttUra, in modo da combinare
l'eff.c ienza di t1na chiamata per r iferirne.neo co.n Ja protezione di una cl1ian1ata per
val.e re. Nel passaggio di un puntatore a una struttura, dovr: essere preparata solo la copia
dell'indirizzo in cui qu.ella sar stata in1Jllagazzinara. Su w1a niacchina che utilizzi degli
indirizzi formaci da 4 byte, sara11no ricopiati solo t1uesri pochi byre di n1en1or.ia, invece
d~e centinaia o forse delle migliaia di byte che la struttt1ra potrebbe i11cludere.

/* Tentare di modificare i dati attraverso

*/

/ * un puntatore variabile a dati cost anti */


#include <stdio .h>
void f(const int *);

main()
{

cha r string [ ]

"print characters of a string" ;

main ()
{

int Yi

printf ('' Th e string is: \ n'') ;


printCharacters(st ring);
putchar( '\ n
return 0;

f(&y);
return 0;

);

void printCharacters(co nst char *s)


{

~oid f

for ( ; *s != \ 0
putchar ( *s) i

1
;

s++~

/* nessuna inizializzazione */

The string is:


print characters of a string
Figura 7. I I VisuaJizzare una stringa. un carattere per volta, usando un puntatore
variabile a dati costanti.

La Figura 7.12 mostra i messaggi di erro re prodotti dal compilatore Borland C++,
qualora si cenci di compilare una funzione che riceva u11 puntatore variabile a dati costanti
e, allo stesso tempo, si utilizzi il puntatore per rencare di modifc.are i dati.
I vetto ri, com sap pian10, sono un cipo d i d ato aggregaro che jmmagazzinano,
sotto un unico nome, molte informazio ni correlate e dello stess0 ti po. Nel Capitolo 1O, discuteremo un alcro ripa di dato aggregato detto struttura (ma anche record in
alrri li nguaggi). Una Struttura in grado di immagazzinare, sorra un unico nome,
molte informazio ni co rrelare e di tipo differente (per esempio, porr im magazzinare i
dati di ogni impiegato di un'azienda). Un vettore sar passato automacicamenre per

(const int

*x)

*x

/* f tenta una modifica i l legale */

= 100;

/* non si pu modificare un oggetto dichiarato const */

Compiling FIG7_12.C:
Error FIG7_12.C 17: canno.t modif'~ a const object
Warning FIG7_12.C 18: Paramet~ r ' x ~ is never used
Figura 7 .12 Tentare di m odificare dei valori attraverso un puntatore variabile a dati
costanti.

Obiettivo ejficier1za 7. 1

Passate gli orgetti di di112ensioni ragguardevoli, come Le strumt.re, uti,Liuartdo dei p.urttatori
a dati costorzti in modo da cornbirzare i benefici dell'efficienza di itt1a chitt1'J1'ata per
rifetimento con La sicztrezza di 1.tr1tl chit{.mata per valore.
u n siffatto utilizzo dei pt1n catorj a dati costanti un esempio di conipromesso tempo/
spazio. I nfatti , sar ,p referibile utilizza re i puntatori nei casi in cui la 1nemoria sia
scarsa e !,efficienza sia un interesse di primaria importanza. Mentre, nei casi in cui la
memoria sja abbondante e l'efficienza non sia un interesse di p rimaria importanza,
sar prefe ri bile passare i dati per valore, in modo da rispettare il principio del minimo

240

CAPI TOLO

privi legio . Rico rdare che alcun i siste mi non implemen rano co rrerr am enre il quali ficat ore
cons t, pe rci la chi am.ata per valo re sar semp re il mo.d o migli ore pe r preve nire la
modi fica dei dati.

Un punt arore cos tanre a dati varia bili fa riferj mento sen1p re alla stess a posiz ione
di mem oria, m enrre i dati che vi so no imma gazzi naci potra nno esser e modi ficaci per
mezz o d ello stess o. Quesro tipo di punt atore il defa ult per il n ome di un veno re.
Ques to, infar ti, un punt atore costante al l'iniz io d el vetto re. Tutti i dati d el vetto re
potra nno essr e letti e modi ficat i ut ilizzando il suo nom e e un indic e. Un punt atore
costa nte a d ati varia bili potr essere utiliz zato, pr esem pio, per ricevere un argo mento di tipo vetto re in una funz ione ch acced a ai suoi elem.eoti utiliz zand o esclusivament e la notaz ione co n gli indi. i di vetto re. I puntatori dichi arati con il q .u alifc atore
cons t dovr anno essere inizia liz-z ati co ntest ualm ente alla loro dichi arazi o ne (qual ora il
punt atore sia il param etro di una funz ione, sar inizia lizza to con quell o che sar stato
passa to nella sua invocazio11e) . Il ,p rogra mma della F igura 7. 13 tenter di mod ifica re
un punt atore cos tante , ptr che sar stato dichi arato di tipo int * con st. La dichi arazio ne va le tta da destr a a sinis tra come "ptr un pun tator e costa nte a un intero". li
puntato.re sar inizia lizza to co n l'indirizz o della varia bile inter a x e, quan do il program ma tente r
asseg nare a ptr !)ind irizzo di y , sar gene rato u n m essaggio
error e.

ru

/* Tent are di mod ifica re un punt ator e cost ante a * /

/ * dat i cost anti.


#inc lude <std io.h >

*/

m~in()

int X = 5, Yi
cons t int *co nst ptr = &x,
*ptr = 7;
ptr = &y ;
retu rn 0;
}

'Compiling FfG7_14. C'!


.
Erra r FIG7 14.C 10: Cannot modfy a cons t obje ct
"
Erro r FIG7 14. e 11 .~ Oannot modify a cons t obj eet
waraing FIGll<~:14. ~ 13: ' pt r-~ is assig ned valu e that is- neve r used
warning FIG1_14.C 13: 'Y' is decl ared but neve~ used

ru

/* Tent are ai mod ifica re un punt ator e cost ante a * /


/ * dati vari abil i
*/

241

I P9NT ATORI

'

Figu ra 7 .14 Tentare di modificare un punta tore costante a dati costanti.

#inc lude <s td io .h>

7 .6
main ()

I.! ord ina me nto a bolle utilizzando


una chiamata per rife rim ent o

int x, y;
int * cons t ptr

&x;

ptr = &y;
retu rn 0;

Mod ifich rem o ora il prog ramm a p er l'ord inam ento a bolle della Figu ra 6. 15, in mod o
da utiliz zare due funz ioni: bubb leSo rt e swap . La fun zione bub bleS ort eseg uir
l'ord inam ento del vetto re e rjchi amer swap , per scam biare di posto gli elem enti arra y[ j 1
e arra y[j + 1] del vetto re (con sultate la Eigu ra7. 15). R icord are che il C appli ca
!'inc apsu la ment o delle infor mazi oni tra le fun zio.r1i , perci swap . non avr accesso ~i
singo li elem enti del vetto re
bubb leSo rt . Dato che ques ta desidera che swap abbia
accesso agli elem enti del vetto re cos ch e possa scambi3:1"li di posto ,. ~u.bbleSo~t pas~
ser a swap ognu no di quegli elem enti artra verso una chiamata per r1fe r1me nto: tn altri
term ini, sar passa to in mod o espli ciro l' iodj rizzo di ogni elem ento del vetto re. U n
vetto re com pleto , come sapp ia mo, sareb be passa to auto mati came nte per rifer imen to,
ma i singo li ele ment i di un vetto re so no d egli scala ri e saran n o pa~s.ati nor~almente
per valor e. Di co nsegu enza, nella chiam ata a swap , bubb leSo rt ut tlizzer l oper ato re
di indir izzo (&) con ognu no degli elem enci del vetro re, ael mod o segu nte

ru

Compiling FIG7_13.C:
'
'
Erro r FIG7_13.C 10: Cannot modify a cons t obje ct
warning FIG7_13.C 12: 1 ptr' is assig oed a valu e that is neve r used
warning FIG7_13.C 12~ 'y' i% decl ared .but Aever used
'

Figu ra 7.13 Tentare di modificare un punt atore costante a dati variabili.


Il diritt o di accesso mini mo sar garan.rito da un puntatore costante a dati costanti. Un
punta tore di questo genere far riferimento semp re alla stessa locazione di memoria e j dari che
vi saranno conte nuti non porra nno essere modificaci. Questo il tipo di puntatore eh.e dovrebbe essere uti lizzato, per esempio, per passare un vena re a una funzione che la veda utilizza ndo
solo la nocazione con gli indici ili vettore e che non modifichi i valori dei suoi e1eme 11ri. 11
progr amm a della Figura 7.14 dichiarer un punta rore ptr di tipo cons t int * cons t. An:che questa dichiarazione va letta da destra a sinistra come <'ptr un punta tore costante a una
costa nte inter a". La figura mostra i messaggi di errore che saran no generati, qualo ra si cenci di
modificare i da punra ti da ptr o l'indirizzo immagazzinato nel punta tore.

swap (&ar ray[ j], &arr ay[j + 1]);


per esegu ire una chiam ata per rifer imen to. La funz ione swa.p ricever .&ar ray[ j] n~l
pun tato re elem ent1 Ptr. Sebb ene alla funzi o ne swap no n s1a conse nt ito con oscere 11
nom e arra y [ j] a causa d ell'incapsu lame nto delle infor mazi oni, essa potr coin unq u
utiliz zare *elem ent1 Ptr come un sillo nimo per arra y [ j) . D i co nsegu enza , q ua ndo
swap far rifer imen to a *ele men t1 Ptr, in realt st ar punt ando ad arra y[ j l di
bubb leSo rt. I n mod o simil e, quan do swap far riferi ment o a *ele men t2Pt r, in realt star punt ando ad arra y[ j + 1) di bubb leSo rt. Per quan to a swap non siano
cons entit e delle istru zioni co.m e

24 2

CA PITOLO

voi d swap (i nt *e l ement 1P t r , int *element2P tr)

temp = arr a.y [ j);


arr ay [j] = arr ay[ j + 1];
arr ay [ j + 1) = temp;

int temp;

lo stesso pre ciso effe tto sar o tten uto inse rei1do le istr uzi oni

tmp = *el em ent 1P tr;


*el em ent 1P tr = *el em ent 2P tr;
*el em ent 2P tr = temp;

temp = *el emen t1P tr;


*el em ent 1P tr = *el emen t2P tr;
*el em ent 2P tr = temp;
}

..

nella fi1nzione swap del la Figura 7.1 5 .

Data ite ms in ori gin a! ard er

l.
ina
re,
ord
tto
i
ve
/ ~ Qu est o programma i nse ris ce de i va lor in un
va lor i in modo asc end ent e , e vis ua l i zza il ve tto r e ris ult an te * /
#in clu de <st dio .h>
#de f ine SIZE 10

voi d bu bb leS ort (in t *, con st int ) ;


main ( )
{

int i, a[SIZE]

{2, 6, 4, 8 , 10, 12, 89, 68 , 45, 37} ;

pri ntf ( "Data ite ms in ori gin al ord er \ n") ;


for (i= 0; i< = SIZ~ - 1; i ++)
pri ntf ( 11 %4d 11 , a [ i]) ;
/ *o rdi na il ve tto re* /
bu bb leS ort (a, SIZE);
pri ntf ( "\ nData ite ms in asc end ing ord er \ n") ;
i ++ )
for (i = 0; i <~ SIZE - 1;
'.
pri ntf ( "%4d '1 , a[i ]); '
pri ntf ( \ n" );
ret urn 0;
11

voi d bu bb leS ort (in t *ar ray , con st int siz e)


{

int pas s, j;
vo id swap (in t * , int *) ;
for (pa ss
for

= 1; pas s <= siz e

(j -

2
I

l:

10

12

68

89

45

37
I'

asc end ing -0rder


in
ms
ite
Data

Fgura 7. I S

.8

I...'. ord ina me nto

10

12

45

3.7

68

89

_.

a bol le con chiamata per rife rim ent o.

ince L'
a.
not
di
e
egn
d
ero
avv
d
o
n
so
ort
leS
bb
bu
e
n
zio
fun
a
lJ
de
e
ich
rist
Mo ire car atte
,
[]
ay
arr
int
e
com
che
ece
inv
~
ray
*ar
int
me
co
ay
arr
rer
hia
dic
staz.ion e della fun zio ne
(rilc
ona
11si
i1ne
d
uni
re
ro
vet
un
nto
n1e
rgo
a
e
com

ver
rice
ort
leS
bb
bu
che
c
peI ir'ld icar
e
siz
o
etr
am
par
Il
).
bili
bia
cam
ers
int
o
son
li
o1
azi
not
ste
que
che
ta
vol
una
pet iam o an co ra
qua nto iJ
sar di chi ara to con st per obb edi re al pri nci pio del minLn1 0 privile gio . Per
e riceva una copia del valore conse rvato nella fun zio ne main e pe r qua nro

param etro siz


di
o
ogn
bis

avr
.011
n
.
ort
leS
bb
bu
,
ario
gi11
ori
ato
d
il
rare
alte
r
pot
non
la SLta mo dif ica
tor e rest er fissa
vet
del
e
ion
ens
n
di1
la
i,
att
111f
o.
pit
com
suo
il
re
gui
ese
per
e
siz
re
var ia
pe r
nst
co
rata
hia
dic

sar
e
siz
1za,
u.e1
seg
con
Di
.
ort
leS
bb
bu
di
ne
zio
ecu
dut ante lies
l algori t mo di o rdiass icu rars i che non sia mo dif i cara ac ide nta lme nte . pro bab ile che
sia mo dif i cat a
re
to
vet
el
d
ne
io
ens
dim
la
ora
ual
q
,
nte
e
tam
rret
co
ni
zio
fu11
non
o
nam ent
1

duran te l' ela bor azion e.

leS ort poid1


Il pro tot ipo della ft1 11zio ne swap sta ro i ncluso nel co rpo di bu bb
ort
leS
bb
bu
in
po
ri
ro
pro
il
re
eri
Ins
.
er
am
chi
ri
la
che
e
n
zio
fun
ca
LLni
l'

questa sar
gui re
ese
e
ell
qu
a
nte
me
iva
lus
esc
p
swa
ne
zio
fun
ella
d
i
bil
erta
acc
ni
zio
Limi ter le u1voca
re swa p
oca
inv
di
re
ta
n
te
ro
sse
ove
d
che
11i
zio
fun
e
alcr
Le
.
ort
leS
b

bub
d.i
rno
all' inte
pilacom
al
be
eb
tter
spe
i
c
per
ne,
zio
fun
di
ipo
t
to
pro
to
s
giu
al
o
ess
acc
ero
non avrebb
un pro co cipo clic
tor e gen era rne uno aurom aticam enr.e. M a ci pro dur r nor.n1al menre
Ltn err ore del co mp ilat o re,
r
ere
gen
e
ne
io
z
fun
ella
d
one
azi
est
int
all'

der
pon
rris
co
non
o
sian
tri
e
a1n
par
i
suo
i
e
ne
zio
fun
la
dal
ico
ricu
res
ore
val
il
e
ch
er.
sum
poi ch quesro pre
di tip o int .
I11geflzeti.a del software 7.4

1 ; pass++)

0; j <: siz e - 2; j ++ )

if (ar ray [j] > arr ay [j + 1])


swap (& arr ay[ j] , &a rra y[j + 1]) ;
}

24 3

I PUN1';\ TO RJ

ciprin
nl
sce
edi
obb
ni
izio
fier
e
altr
le
del
i
ior1
iniz
def
le
del
rno
inte
all'
pi
toti
pro
i
Inserire
pio del 1ni?zi1'1'10 privilegi.o, attraverso lo limitazio11e delle invocaz ioni amrnissibili alle
fi1nzior1i in citi compaiofJO i p rototipi.
d el
e
ion
e11s
dim
la
etro
am
par
ne
co1
er
ce\r
ri
ort
leS
bb
bu
e
n
u.io
fur
la
O sservate cJ1e
la s ua dim e nsi on e.
ver tore . Per poterlo ord ina re, infaTfi, la fu nzione dov r co nos ce re
ria rela 1no
111e
di
izzo
dir
l'in
ve
rice
a
est
qu
e,
n
zio
fun
u11a
a
e
tor
vet
un
di
io
g
Nel passag
ne ri gua rtivo al suo pri mo ele me nro . I.:indirizzo no n for11isce per alc una info rmazio

244

CArnow 7

dante il numero degli elementi presenti nel vettore. Di co nseguenza, coccher al prograroroaco re forn ire alla ft1nzione la dimensione del verco re.
Nel programma, la din1ensione del vettore sar passata alla funzione bubbleSo rt
in modo esplicito. Qwesto approccio offre due principali benefici: .la riusabilit del
software e una corretta progettazio ne dello stesso. Definendo la funzi9ne in modo cale
che riceva la dimensione del vettore per mezzo di un argomeoto, faremo s che la
funzione possa essere u tilizzata da un qualsiasi programma che abbia la necessi t di
ordinare dei vettoci tt n idimension ali di inreri che, tra l'altro, potranno avere una dimensione qualsiasi.

lngegn.eria del software 7.5

I PUNTAro~ 1

l,Ul

245

In fase di com pilazione potr essere determin ato anche il numero degli elemenci di
verrore. Considerate , per esempio, La segueoce dichiarazio ne di venore:

double real[22];
Le variabili di cipo double saran110 11or111aln1eate i1nrnagazzi11ar.e in 8 byte di memoria. Di
conseguenza., il vettore real conterr un totale di 176 byres. Per determinare il nL1mero
degli elemenci presenti nel vettore, porr essere uri lizzata la seguente espressio11e:

sizeof (real ) I sizeof(dou ble )


Questa determiner il numero di byte contenuti nel vettore real e divider quel valo re per
la q_uancir di byte util izzata per immagazzinare un valore double i11 m~moria.
/* i oper atore sizeof quando usato con il nome di un vettore */
/* restituisc e i l numero di byte presenti nello stesso
*/
1

Quando passare un vettore a una fanzione> fornite anche la si1.4 dimensione. Ci aiuter a generalizzare la. funzione. Le funzioni ge11eralizzate saranno spesso rizJ.tilizzabili
in molti programmi.
Avremmo potuto immagazzin are la dimensione del vettore in una variabile globale
che fosse accessib ile al l'incero programma . Questo approccio sarebbe stato anche pi
efficiente, poich non ci sarebbe staca la necessit di creare una copia della dimensione durante l'in vocazione della funzione. Tuttavia, gli altri program_mi che event uaLnente richiedesser o l'ordinamen to di vettori di interi porrebbero 11on contenere la stessa
variabile globale e, di conseguenz a, non potrebbero utilizzare la nostra funzione.

#include <stdio.h>
main {)
{

f l oat array [ 20 J ;

printf{ 'The number of bytes in the array is %d\n


sizeof{ar ray));
1

11
1

ret urn 0 ;

Ingegn.eria del software 7. 6

Le variabili globali vio/,ano ilprincipio del minimo privilegio e sono un esempio di una
scadente progettazione del software.

The nu~ber of bytes i n the array is 80


_____:_

..
_ ......:..::.;

Obiettivo efficienza 7.2

Il passaggio della dimensione di un vettore a t{na funzione richieder del tempo e avr
bisogrzo di uno spazio aggiuntivo nell'ambiente della. funzione., poich dovr essere preparata una copia della dimensione. Le v4riabili globali, invece, non richiederanno tempo
e spazio aggiuntivi, perch vi si potr accedere direttamente da ogrzi funzione.
Avremmo anche potuto inserire la dimensjone del vettore diretcaroent e nel la funi.ione. Questo approc.::.c o per avrebbe limitato l'utilizzo della funzio11e a vettori di una
particolare dimen.sjone e avrebbe ridotto notevol n1eote la sua riusabilit. La ft1nzione,
infatti, sarebbe stata u ril izzabile solo da p rogrammi che avessero elaborato vettori
unidimensi onali di interi co n una dimensione uguale a quella codificata al l,in terno
della funzione.

Il
fornisce l'apposito operatore unario sizeof per determ inare la dim ensione in
byte di un vetto re, o d ogni alrro tipo di dato, durante la .fase di compilazio ne. UtiJizzaro con il 11ome di un vettore, come mo$ trato neJJa Figura 7.16, l'o peratore sizeof
restituir un valore intero pari al nume ro totale di byte contenuto nello stesso. Osservare che le variabili di tipo f loat saranno normalmen te immagazzinar.e in 4 byte di
memoria e che array sar dichiarato con 20 elementi. Di conseguenz a, in array ci
saranno in rotale 80 byre.

_____

~--~

Figura 7 .16 L.:operatore sizeof, quando usato con il nome di un vettore, restituisce
il numero di byte presenti nello stesso .

Il programma della Fi:gura 7.17 calcoler il numero d i byte utilizzaci per immagazzinare
i tipi di dato standard su un PC compatibile .

Obiettivo portabilit 7.2

Il numero di byte utiliz,zati per irnmaga.~inare un particolare tipo di dato potrebbe


variare tra i diversi sistemi. Nello scrivere dei programmi che dipendano dalle dimensioni dei tipi di dato e che debbano essere eseguiti su diversi sistemi di computer,
utilizzate sizeof per determinare il ni1.mero di byte utilizzato pe,. immagazzinare
i vari tipi di dato.
L'operatore sizeof potr essere utilizzato con ogni nome di variabile, tipo di dato o
c~srante. NeJ caso che sia utilizzato con il nome di una variabile che non sia un vetroreJ
o c;:on q uello d.i una costante, sar restitu ito il n:umero di by~e usati per im magazzinare il
tipo specifico d i qu.ella variabile o costante. Osservate che le parentesi ucilizzate co n
sizeof saranno obbligatorie , qualora il suo operando corrisponda al nome di un tipo di
dato. Le parentesi non saran no necessarie, invece, qualora il suo operando corrisponda al
n ome di una variabile.

247

I Pl'lITATORJ

/* Dimostrazione di utilizzo dell operatore sizeof */


1

locazione

#include <std io . h>

3004

3000

3008

3012

3016

main ()
{

p ri nt f

s-i z e of ( eh a r) - %d \ n "
sizeof (short) = %d\ n
aizeof (int) = %d \ nll
Il
sizeof (long) = %d \n
sizeof (float) = %d \ n
sizeof (double) = %d\ n''
"
' sizeof (long double) = %d \ n'
sizeof ( char) 1 sizeof ( short) , sizeof ( int),
sizeof( l ong), sizeof(float), sizeof(double),
sizeof(long double))i

v[2]

v(4]

v[3]

("

11

11

11

11

1
'

11

variabile puntatore vPt r

'

return 0I
sizeof(char) sizeof ( short) sizeof (int) s izeof ( lon_g) sizeof ( f'loa't) siz_eof (do~b l e) sizeof (long double) =
~

Figura 7. 18 Il vettore v e una variabile puntatore vPtr che punta a v.

Obiettivo portabilit 7.3

La 1t1aggi-orparte dei comp1-1ter 11tilig::za110 oggigi.01?W interi di 2 o 4 byte. Aicztnc del/,e Pnncchinepit't recer1ti tJti!izzan1J invece degli interi di 8 byte. Lnritnzetic11 dei purztato1i dipemlente
dalla 1nacchina, giacch i stioi risultati dipendllno dalla dimensio11e degli oggetti puntati.

Nell'arianecica conve112ionale, la somm<l 3000 + 2 rescicuisce il valore 3002. Qusto


per non normalmente il caso deU 'ariunerica dei punta tori. Nel momento in cui si
sommer o si soraarr un incero da u11 puntator~, questo non sar sen1plicem ente incrementato o decrem entato con quel valo re, bens di qu.ell,inrero moltiplicato per la dimensione dcll,oggetto cui il punracore far riferimento. La dimension.e dcll'oggerco dipender dal
suo tipo di dato. Per esea1pio 1 l'istruzione

2
2
4
4

8
10

Figura 7.17 U sare l'operatore sizeof per determinare le dimensioni dei tipi di dato
standard.

7. 7

vf1]

v[0]

Le espressioni con i puntatori


e l'aritmetica dei> puntatori

I puntacori sono dei_validi operandi per Le espressio ni arirm.etiche, quelle di assegnamerito e


quelle di confronto. Tuttavia, non rutti gli operatori ucilizzati normalmente in. questi tipi di
espressione sara nno ammissibili in co mbinazione con le variabili di tipo puntatore. Questa
sezione descriver proprio quegli operatori cl1e porranno acceuare dei puntacori come loro
operandi e del modo in cui questi operatori sararino util izzati.
Con gli operacori potr essere utilizzaco un insietn e limitato di operazioni aritmetiche.
Un puntato re potr essere incremenrato (++) o decrementato ( - -), vi si potr sommare (+
o +=) o sottr<ure ( - o -=) un intero, o si potr sottrarre u11 puntatore da un altro.
St1ppon,ete che il vettore int v [ 100 J sia stato dicliiaraco e che il suo primo elemento
si trovi nella locazio ne di m emo ria 3000. Supponere ai1che che il ,p untacdr vPtr sia stato
i11izializzaro in modo da fare rit r,i mento a v[0] : in alt ri termini, che il valore di vPtr sia
3000. La Figura 7.18 .rappresenta co n u11 diagramma propri 0 que~ta sJruazione, u1 tina
n1accl1ina in cui gli interi siano di 4 byre. Osservate che vPtr potr essere inizializuiro, per
far s cli.e punti al vectore v, co n una delle seguenci istruzioni:

vPtr += 2;
prodtirr 3008 (3000 + 2 * 4), supponendo che un intero sia inunagazzinato in 4 byte di
memoria. Nel vettore v, vPtr punterebbe ora all'elem en,co v[2] (Figura 7 .1 9). Nel caso
che un inrero sia immagazzinato in 2 byte di memqria, allora il calcolo precedente avrebbe
w:odouo co me risulraro la locazione di n1emoria 3004 (3000 + 2 * 2). Qualora il vettor
fosse stato di un tipo di dato differen_te, il calcolo precedence avrebbe u1cren1encato il
puntatore di due volte il numero di byte necessari per immagazzinare un oggetto di q uel
ripe di dato. I risulrati dell'aritmetica dei puntatori co1nbaceranno co n gli esiti di queUa
regolare, sol o quando saranno eseguite delle operazio ni sui vetra ri di cara tteri, po ich
o~no di essi lungo un byte.

locazione
3000

3004

v[0]

3008

V[ 1]

3012

v [ 2]

3016

v [3]

v[4)

"

variabile puntatore vPtr

vPtr = v;

vPtr = &v [ 0] ;

Figura 7.19 Il puntatore vPtr dopo un'operazione di aritmetica dei puntatori.

248

CAPITOLO

I .PUNT ATORJ

dato senosciuro: di conseguenza, il con1pilatore non in grado di co11oscere il numero preciso


dei byre cui il puncarore fu riferimento. TI comp ilarore deve dunque conoscere iJ cipo di daro,
pe.r determinare il numero di byre in cui si risolver il riferimenro di uno specifico puntatore.
Nd caso di un puntatore a void, questo numero di byte- non potr essere determinato dal po.

Qualora vPtr fosse staro incrementato a 3016, che punterebbe a v [ 4 ] , !,istruzione

vPtr

-= 4;

av rebbe imposrato vPtr di nuovo a 3000, ovverosia all'in izio del vettore. Q ualora un
puntatore debba essere incrementato o decrern.en taco di uno, potranno essere utilizzati gli
operatori di incremento (++) e di decremenco ( - -). En rrambe le seguenti istruzion i

Errore tipico 7. 8
.Assegnare tJn puntatore di un tipo a uno di t./.n altro tipo qt1alora nessztno dei due sia ttn
void *provocher un errore di sintassi.

++vPtr;
vPtr++;

Enore tipico 7.9

increme11ceranno il puntatore in modo da fargli fare riferi mento alla posizione successiva
del vettore. Entrambe le seguenti istruzioni

- -vPtr ;
vPtr - - ;
decrem entera nno il punrarore in modo da fargli fare riferimento all' elemenro precedence
del vercore.
Le variabili di cipo punta-core possono essere sottratte l' una dall'altra. Per esempio, se
vPtr contenesse la locazione 3000 e v2Ptr contenesse !,indirizzo 3008, l'istruzione

= v2Ptr

- vPtr;

assegnerebbe a x il numero degli elementi dcl vettore compresi era vPtr e v2Ptr, in questo
caso 2. Laritmetica dei puntatori non avrebbe senso q_ualora non foss~ utilizzata con un
vettore. Non possiamo presumere che due variabilj dello stesso cipo siano immagazzinare
in modo contiguo nella memoria, sempre che quelle non siano due elementi adiacenti di
un vettore.

249

Tentare di risolvere il rifetimento di un ptcntat.ore voi d *.


I puntatori porranno essere confrontati uti lizzando gli operatori di uguaglianza e quelli
rlazionali, ma tali co11fronti non avranno significato qualora i pun ratori non facciano
riferimnto a m embri dello stesso vettore. I confronti era puncarori raffrontano gli indirizzi
che vi sono immagazzinaci. Un confronto rra due puntatori che si riferisco no allo stesso
vettore potrebbe moscrare, per esempio, che un puntatore fa riferimento a u n elemento
con un indice di veccore pi alco dj quello puntato dall'altro. Un unlizzo tipico dei confronti
era puntato ri di determ inare se un puntarore sia NULL.

7.8

La relazione tra i puntatori e i vettori

I vettori e i puntatori sono strettamente co.rrclaci in Ce porranno essere urilizzaci in modo


quasi interscambiabile. Il nome di un vettore porrebbe essere considerato com e un puntatore
costan te. I puntarori potranno essere utilizzaci per svolgere qualsiasi operazione che coinvolga gli indici di un vettore.

Errore tipicp 7.5

Obiettivo efficienza 7.3

Utiliu,a.re l't;.ri"tm.etica dei puntatori su un puntatore che non faccia riferirrie1zto a un


vettore di valori.
Errore tipico 7.6

La notazione con gli indici di vettore sar convertita in fase di compilazione irz quella
con i puntatori, perci utilizzare questa notazione con i vettori potr far risparmiare
del tempo in fase di compilazione.

Sottrarre o confrontare due puntatori che non facciano riferimento allo stesso vettore.

Buona abitudine 7.5

Errore tipico 7. 7

Usate la notazione con gli indici di vettore mvce di quella con i puntatori qitando gestite
i vettori. Il programma potr richiedere un tempo /.eggermentepi lungo in fase di compii.azione, ma sar probabilmente pii't chiaro.

Sttperare uno dei due linziti di un vettore quando si utilizz,a l'aritmetica dei pz~ntatori.
Un puncacore potr essere assegnato a un altro puntatore, qualora siano enrrambi dello
stesso ripo. Nel caso che non lo fossero, si porr utilizzare l'operatore di co:nversione per
7
assegnamento nel tipo di quello a. sinistra. reccezione a
dell
destra
a
puntatore
il
convertire
questa regola il puntatore a void (ovverosia void *), perch questo generico e pu rappresentare qualsiasi tipo di puntatore. Un puntatore a void porr esser assegnato a rutti gli altri
ti1)i di pu11tatori questi porranno essere assegnati a un puntatore a void. In entrambi i casi
non sar necessaria alcuna operazione di con.versio11e.

Supponete che il vercore di in teri b [ 5] e la variabile dj tipo puntatore a inceri bPtr


siano gi stari dichiaraci. Dato che il nome del vettore (senza !,indice) un puntatore al suo
pr:mo elemento, potremo imposrare bPtr con !,indi rizzo del primo elemento del vettore b
con l,istruzio,n e:

Non possibile risolvere i1 riferinlenco di un puntatore .a voi d. Per esem.pio, il con1pilarore


4
sa che un puntatore a int punta a quattro byte di memoria, su una macchina con interi
byte, ma un puntatore a void contiene semplicemente una locazione memoria per un tipo di

modo seguente:

ru

ru

l::>Pt r

= b;

Q uesta istruzione equivalente all,indirizzo del primo elemento del vettore rilevato nel

bPt r

&b[0 ];

250

CAPITOLO

I PUNTA1'0RI

Leiemen[o del venore b [ 3] porr anche esser~ pun[a[O usando tespressio11e con puntatore:

*(bPtr + 3)

11 3 nella st1.d detta espressi0 ne I' offiet (lo scosramento) dal pu!11tatore. I.: offset indicher
quale elem ento del vetto re dovr essere pur1cato e coi ncider con il suo indice, qualo ra il
puntatore faccia riferimento all'inizio di ur1 vetto re. La notazione precedente detta
nutazione con ptJ.ntatore e offset. Le parentesi sono ne.cessarie perch la priorit di * maggiore di quella di +. Sen?.a le parencesi, la suddetta espressione avrebbe aggiunco 3 al valore
di *bPtr (i n alrre parole, il 3 sarebbe srato aggiunto a b [ 0] 1 sempre supponendo cl1e bPtr
punti all'i1tizio dd vettore). Lelemenco di un vettore pocr dunque essere puntato co n una
~pressione d i ti~)O punrato re, ma an,che il suo indj rizzo

&b [ 3]

potr essere ottenuto co n I' espressio11e di tipo puntatose

bPtr + 3

Lo stesso vettore porr: essere aattato com e un pur1tato re e utilizzato sfruttando le regole
della relativa ariraneria. Per esempio, anche l'espressione

251

della FigUia 7.21. Enuambe le funzioni co pi eranno una stringa (ovverosia un vettore
d i cararceri) in un altro vettore di ca ratte ri. Dopo aver confrontato i prororipi per
copy1 e copy2 le due funzioni ci sen1bre rann o identich e. lnfattj, eseguiranno lo stesso
compito, ma nonostante l e apparenze, le d ue funz io .n i so no state irnpleme11tare in
manier a differe n te.
La ft1nzione copy1 urilizzer la notazione con gli indici di vettore per copiare la stringa
s2 nd vettore d i caraueri s 1. La furuione dichiarer un contatore, la variabile intera i , che
per utilizzer solo come indice del vettore. L'intera operazione di copia sa r esegwra
cW.l'mtestazion.e della struttura f or: infatti, il suo corpo un'istruzione vuota. .Linrescazion,e specifica cl1e i sar .Zzerata e incrementa ta di uno ad ogni iterazio ne del ciclo. La
Gendizione della struttura for, s1 [i] = s2[1] , eseguir l'o perazione di copia da s2 a s1
un carattere per volta. Nel momento in cui sar staro inco ntrato il carattere nullo di s2,
esso sar assegnato a s 1 e il ciclo rermir1er, poich il valore intero del carattere nullo
zero (falso). Ricordare che il valore di un'istruzion e di assegnamen to quello assegnato
all 'argomento dj sinistra.

/* Usare le notazioni con indici e puntatori per i vettori * /

#-include <stdio. h>

*(b + 3)

main()

panrer ali' elemento b [ 3] del vettore. In generale, tutte le espressio11i co11 gli indici di
vettore potranno essere convertite in quelle con punrarore e offset. In questo caso specifico, abbiamo urilizzato una notazione con p un tatore e offset in cw il nome del vettore
stato utilizzato nella sua veste di puntatore. O sservate che l' istrttzione precedente non m odificher in alcun modo il no1ne del vecrore: b punter ancora a1 suo p rimo elemento.

int i, offset, b[] = {10, 20, 30 , 40};


/ * ta puntare bPtr al vettore
i nt *bPtr = b ;
print f( "Array b printed with : \ n"
'' Array subscript notation\ n'');

I puntatori pocranoo essere usati in combinazio n i con gli indici. esattamente co.me i
vettori. Per esempio, l'espressione

f or (i = 0; i <= 3 ; i++)
prin t f( "b[ %d] = %d\n", i, b[i]};

bPtr[1]
punter all 'elemento b [ 1] del vettore. Questa appunto la notazione con puntatore e indice.
,

printf( "\ nPointer / offset notation where \ n"


'' the poi nter is the array name \ n''};

Ricordate che il nome di un vettore essenzialn1e nte un puntatore costante: esso fa


sempre riferimento all 'i.ruz.io del vettore. Di conseguenz a, l'es1)re_~sione
b

fo r (offset = 0; of fset <= 3; offset++)


pri ntf("*( b + %d) = %d \ n'' , offset, *(b +offs et)} ;

+- 3

non sar vaJida., perch tenter di modificare il valore del nome del vettore con l'aritn1etica
dei puntatori.

printf(''\n Pointe r s ubscript notat ion\n'' );

Errore tip ico 7.10

f or (i = 0; i <: 3; i++)
printf( "bPtr[%d ] = %d\ n" 1 i, bPtr [ i]);

Tentare di modificare il nome di urz vettore con l'aritmetica dei puntatori iJ.n errore
di sin tassi.

printf('' \ nPointer/ offset notat ion\ n'');

Il programma della Figura 7.20 utilizzer. i quattro 1netodi per puntare gli elementi dj
un vettore di cui abbiamo discusso ("con gli indici di verto re,,, "con puntatore e offset"
usando il nome del vettore come puntatore, "con gli illdici di puntato re", "con pun1acore e
offset" usando un puntacore) per visualizzare i quatrro elementi dd vettore d i tnteri b.
Per illustrare u1 reriorn1ente l'interscambiabil it dei vettori e dei puntatori, daremo uno
sguardo alle due funzioni per la co~-,ia di stringhe, copy1 e copy2, incluse nel programma

b */

for (offset = 0 ; offset <= 3; off set++)


printf( "*( bPtr :r %d} = %d\ n", f fset, *(bPt r +

offs~t});

r eturn 0;
}

{continua)

CAPITOLO

Array b printed with:


Array subscript notation

/* copiare una stringa usando la notazione con vettore

b[0] = 10
b(1]
20
b[2)
30
b(3]
40

=
=

main()
{

= 19
= 20;

*'(b + 1)

e la notazione con puntatore */


#include <stdio.h>
void copy1(char *, const char *);
void copy2(char *, const char *);

Pointer/offset notation where


the pointer iJ tbe array name
(b + 0)

char string1[10], *string2 = "Hello


string3[10], string4[] = Good Bye '';
11

11

*(b ... 2) = 30
*(b
+ 3)
~

copy1(string 1, string2);
p rin t f ( " stri ng1 = %s \ n stri ng1 ) ;
11

Pointe~ sub'se~ipt

bPtr[I]

- 10
21

bPtr(2)
bPtr[ 1]

bPtr(3J

....,,

nQtatien

copy2(string3, string4);
printf( "string3 = %s\ n" , string3);
return 0;

'
38

- 48

"

'

/* copia s2 in s1 usando la notazione con vettore * /

Pointer/offset. notation

253

PUNTAT ORI

(bPtr + I) \t
*(bPtr + 11 =ai

* (bPtr +. 2) = 4r

...

void copy1(char *s1, const char *s2)


{

int i;

*( bPtr + , 3) = 4@ ,

far (i = 0; s1 [i] = s2[i]; i++)


;
/* non fare niente nel co rpo */

Figura 7 .20 Usare i quattro metodi di puntamento agli elementi di un vettore.

La funzione c opy2 utilizzer invece i puntatori e la: lo ro ari~~etiea per copiare la


stringa s2 nel vettore cli caratteri s1 . Anche in questo caso l,i11testazione della struttura for
eseguir 1,inrera ope.razione di copia. !.:intestazione non include nessuna inizializzazione di
variabiu. Proprio come aella funzone copy1 , la condizione (* s 1 = * s2) eseguir I, operazione di copia. Dopo aver risolto i dferimenci dei due puntatori, il carattere puntato da s2
sar assegnato all'elemento cui s1 far riferimento. Dopo l'esec11zione dell'assegnamento
nella condizione~ i p11ntatori saranno entrambi incrementati in modo da puntare rispettivamente all'elemento successivo del vettore s1 e al prossimo carattere d ella stringa s2. Nel
momento in cui sar stato incontrato il carattere nullo della stringa s2, questo sar assegnato all'elemento puntato da s1 e il ciclo terminer.

o~rvate che iJ primo argomento di entrambe le funzioni, copy1 e copy2, dovr essere un
vettore sufficientemente grande pr contenere la stri nga del secondo argom~o. ln caso contrario potr verificarsi un errQre, qualora si tentasse di scrivere in una locazione di memoria che
non appartenga al vettore. Osservate anche che il secondo parametro di ognuna delle due
funzioni dichiarato come-const char * (una stringa costante). Questo perch in entrambe
nzioni il seeo.ndo argom"erito sar ricopiato nel primo: i suoi caratteri s:tranno letti uno per
ma non saranrto mai modificati. Per questo motivo, il secondo paramrro stato dichiamodo da puntare~ un valo.re costante, rispettando cosl il principio del min imo privile;suna delle due funzioni ha la necessit di modifica.re il secondo argomento, perci tale
a' non e' stata concessa a nessuna delle d ue.

copia s2 in s 1 usand o la notazione con puntatore */


void copy2(char *s1, const char *s2)
{, *

for ( ; *s1 = *s2; s1++, s2++)

/* non fare niente nel corpo */


}

'

string1 = Hello
string3 = Good Bye

'

Figura 7 .21 Copiare una stringa usando la notazione con vettore e quella con puntatore.

7.9

I vettori di puntatori

I vettori possono contenere anche dei punt~to~i. Un utili~zo tipico per questo genere di s_mit~
tura di dari la formaz.ione d i un vettore di stringhe. Ogru elemento del v~rrore una stringa~
ma in e questa essen'lialmeote un p untatore al suo p,rin10 carattere. 01 co~segue11za, og~
elemento incluso in un vettore di stringhe sar in realt un punratore al prl.Illo carattere di
una stringa. Considerare ora la dichiar~ione di u~ vettore di stringhe suit che possa essere
utilizz.aro per rappresentare un mazzo di carte da gioco:

char suit[4]

= {"Hearts", '' Diamonds", "Clubs " , "Spades "};

254
CArrl'OLo 7

La porzione suit [ 4] della dichiarazione indica un vecrore di 4 d e1nenri. La porzione char


della dichiarazione indica che ogni elemento del vettore suit sar del tipo "punrarore a char".
r q uarrro valori che dovranno essere inseriti nel Vettore sono n Hearts . (Cuoci)' a Diamonds .
(Quadri), clubs (Fiori) e spades (Picche). Ognuno di questi sar immagazzinato in
n1emoria come una stringa di caratteri terminata da un NULL e, proprio per questo, tale
stringa sar lunga un carattere in pi di quelli compresi tra le virgolette. Dunque le quarcro
stringhe saranno lunghe rispettivamente 7, 9, 6 e 7 caratteri. Per quanto le apparenze possano
lasciarvi supporre che queste stringhe saranno sistemate riel vettore suit, in realt in questo
saranno immagazzinati soltanto dei puntatori (figura 7.22). Ogni puntatore pt1nter al primo cararrere della stringa corrjspor1dente. Di conseguenzaJ sebbene l dirpeilSione del verro re
suit sia fissa, que~ro ci permetter di accedere a srringJ1e di qualsiasi lunghezza. Questa
flessibilit solo un esenJpio delle poten.ri possibilit per la strutturazio ne dei dati del linguaggio C.

..
I I
I I .

suit[0]
suit[1J

H'

'e'

'a'

' m'

~+-/---1~1 , e , ,1 ,

,u,

,b ,

..

I I

suit[3]

'r '

' l.. '

;=::::::;

su i t [ 2 J /

,a ,

's'

pI

,a ,

QI

,s ,

'\ 0 '
I

l ai
. l gioco
' .carte da
ddelle
.
. il mazzo
Utilizziamo la n1acr1.ce 4 per 13 deck per rappres~n tare
-. la rtga
deranno ai seilll.
.
(Fim1ra 7.23). Le righe corr1spon
. ialo ia deUe
. era at cuori,
d
. o corrispon
I 3 a1l icche Le colonne corospon eranno u1vece a1 ' r
.
. e
"'O-.
quadri,
al dall 'asso aJ dieci menrre
.
.
eP
la 2 ai r1or1 e a
.
'.
d O 9
. nderanno asper:avamenre a1 v ori
I vetto ri
al faore, alia regina e al re. Dovremo caricare
carte: quelle a a c?rr1spo

.
1no
ll d j LO al 12 corr1spondera1
. . he di caratteri che rappresentano risperrivainente i quattro semi
a
que
con le srr1ng
suitee face
e i udici valori dd le carte.

Cl)

::i

25 5

I pUl\t:rATO Rl

Q)

::i

G.>

5.~

o F

-G.>

dI

eI

.~

Cu.o ri 0
Quadri 1
Fiori 2
Picche 3

10

12

11

' \0'

, \0 ,
rappresenta il Re diFiori

deck [ 2 ] [ 121
I

o z o

V')

o
t:

I \

/'
Fiori

0I

Figura 7.22 Un esempio grafico della matrice sui t .


Avremmo potuto inserire i semi delle carte in ur1a matrice, sistemando .in ognuna
delle rigl\e un seme e in ogn i colonna le singole lettere dei loro nomi. Una rale stru ttura
di d.ati, per, avrebbe dovuto aveJe un numero fisso di colonne pari alla lunghezza
della stri11ga pi lunga. Ne conseguirebbe uno spreco di memoria causato dagli elementi che contengono le stringhe pi corre: uno spreco che diventerebbe moJco pi
co nsistente, qualora in1magazzina;simo un gran numero di stringhe e molt di queste
fossero pi corte di quella pi lunga. N eJla prossima sezione utilizzeremo i vettori di
stringhe per rappresentare un mazzo di carte.

7. IO Studio di un caso: simulazione di un mescolatore


e distributore di carte
In questa sezione, utilizzeremo La generazione dei numeri casuali per sviluppare un programma che simuli un mescol'atore e distributore di carte da gioco. In seguito, questo
programma porr essere utilizzato per svilupparne altri che implementino dei giocl1i di
carte specifici. Per evidenzi4re ale11ni impercettibili problemj di efficienza, abbiamo utilizzato inre.nzionalmenre d~gli algoritmi di n1escolamento e distribuzione non otrin1izzari.
N egli esercizi e nel Capitolo 10, svilupperemo degli algoritmi pi efficierui.

'

Re

utr
I izzata per il. mazzo di carte.
Figura 7 .23 Rappresentazione de11 a matrice

.. .

10
. gue. La( .matrice
. h.Lato cc>me se
e un
3) sara
. d Odeck
li mazzo di carte simulato porr essere 1rusc
.
.
. saranno scelte- a caso una row riga a a
. I
. .
primo lu(oglo az.zedrat~. . ~2s)eg~~',elemenro della matrice deck [ row] [ column 1 sar. inser1arta che sar distribuita dal mazzo
.
. . l
.
column co onna a a
52 in posizioni
.2 3
to il nwnero 1, per indicare che questa ~ar . .a prlIDadc.
11
e con l'1nser1n1ento ei numcr1 '
ale carra sar sistemata nel mazzo mesco. di
mescolato. processo conc1nu r
della matrice deck scelte a ~o, per LDd ~e q~.aa mano che la matrice deck comincer
.
crnquanta ues1m-a.
nda terza
I
i robabile !,estrazione di una carta gi se 1ez1on ara
' ...
a~ com.e ~eco. '
enere di selezioni dovr semplicemente
a riemp1rs1, d1 ve nrer s_err1p re p P) Q
(deck [ row] [ column 1 diversa da z:ro l. uestlo g ali di row e column finch non sar
52
,
. dovranno esegUlfe a tre sce te casu
.
ra selezionata Alla fn e i nu1neri da 1 a
. .,
esser~ ignorato e s1
carcall chde l~on s1~ g1~~~ . Solo a q_ues~o punto il mazzo di carte sar
stata ritrovata una
occuperanno le S2 case e e a marr1ce
. .
Stato mescolato completamence.
1

d . mescoJamenro potrebbe girare all' ir1fnito, qualora la selezione


.
.
Questo .algor1ano r 1 orre d.dJ e carte ehe s;,, ..,o gi state inserite tra quelle mescolare.
U1.LJ

di mescolan1ento m1g iore e e e in11ner

Utilizzando l approccio top-down per raffinamenti successivi , svilupperemo un programma cl1e 111.escolerl e distribuir un mazzo di 52 carte da gioco. L'approccio top-down
particolarmente utile quando si affrontano problemi pi corposi e complessi di quelli che
abbiamo affrontato nei capitoli precedenti.

Obiettivo efficienza 7.4


A volte un at orit:rno che venga in mente in modo 'pontane~"potre~be co~tenere degl~

"b .,~

11.n. diffiri1'nento indefinito. Ricercate degli


come
. blemi di. efficienza
.
.
.
t t p 10
tmpercettz
algoritmi che evitino il differimento indefinito.

256
up1r0 Lo

257

Per d istribuire la prima carta, dovremo rit rovare all'interno della matrice l'elemen to
che soddisfi la condizione deck [ row] [ column] = 1. La ricerca sar eseguita con una
srru~rura for nidificara che varier row da O a 3 e column da O a 12. A quaJe carra
corr1sponde'. que~a casella della matrice? Il vettore su i t sar stato precaricaro con i
quartro senu, perc10 per ottenere quello deUa carta appena individuata visualizzeremo la
stringa di car~tteri ~ui t [ ro~] . [n m odo si mile, per onei1ere il valore d i quella carta stam pere.mo . la srrm~a di caratteri f a~e [ column J. Stamperemo anche la m inga di caratteri 11
of (di), combmandol appropriatamente con le altre informazioni in modo da visua.Llzzare
ogni carra n ella fo rma King of Clubs (Re di Fiori), 11 Ace of Diamonds (Asso d i
Q uadri) e cos via.

Scegliere a caso 1-1na casella del mazzo di carte


Inserire ii nu1nero di estrazione nella casella del mazzo di carte scelta
"Trovare il ntimero dj estrazione n ella matrice dd mazzo di carte e visualizzare il valore e il
seme della carta" potr essere espanso come segue:

Per ogni casella della matrice del m~ di carte


Se la casella contiene ii numero di estrazione
Visualizvire il valore e il seme della carta
lpcqrporando queste espansio ni otterremo il nostro terzo passo d i raffi.n amen co:

Inizializzare il vettore dei semi


Inizializzare il vettore dei 1;alori
Inizializzare la matrice del mazzo di carte

Procediamo ora con il processo top-down per raffinamen ti successivi. U top sar sern p licem en ce

Mischiare e distribuire 52 carte

Per ognuna delle 52 carte

Il nostro primo raffinamnto produrr:

Scegliere a caso una casella dei mazzo di carte


Finch la casella del mozzo di carte ~ gi stata scelta in precedenuz
Scegliere a caso una casel/,a del ma~ di carte
Inserire il numero di estrazione nella casella del mazz,o di carte scelta

Inizializzare il Vettore dei semi


Inizializzare il vettore dei valori
Inizializzare la matrice dei mazzo di carte
Mischiare il mazzo di carte
Distribuire Le 52 carte

Per ugnt'na delle 52 carte


Pe,. ogni casel/,a della matrice del mazzo di carte
Se la casel/,a contiene il numero di estrazione
Visualizzare ii valore e il seme del/,a carta
E con questo passo avremo completato il processo di raffinam ento. Osservate che

"Mischiare il mazzo di carte,, potr essere espanso com e segue:

Per ognuna dei/e 52 car.te


Inserire il numero 4i estrazione in una casella libera del m.4ZZIJ di carte scelta a caso

questo programma potrebbe essere pi efficien te, qualora le po.nioni.delJ 'aJgorirm~ c~e si
ottupano del mescolamento e della distribuzione fossero co.mb1nate, in modo da d1str1buire le cane nello st esso m.o mento in cui sarann state sistemare nel mazzo. Abbiamo sclto
di implem entare separatamente queste operazioni perch le carte norm alm ente sono distrihite dopo essere state mescolate (non m~tre si m scolano).

"D istribuire le 52 can e" po tr essere espanso come segue:

Per ognuna delle 52 carte


Trovare ii numero di estrazione nella matrice dei mazzo di carte e visualizzare il valore
e ii seme def/,a carta

U programma di mescolamento e distribuzione delle cane mostrato della Figura 7.24


mentre nella Figura 7.25 sraro riportato un esempio di esecuzione. Osserv~te l'u~jzzo dell~
specifca di conversione 5'ss ndl'invocaz.ione di printf per visualim re le smnghe di caratten .
Largomento corrispondente a quella specifica nella chiamata di pri ntf dovr essere un puntatore
a char (o un vettore char). N d la funzione dea!, la specifica di formato %5s of %-Bs
vis11alizzer una stringa all ineata a destra in un campo di cinque caratteri seguita da Of e da
una srringa all ineata a sinistra in un campo di ono caratteri. Il segno meno in %-8s sign ifica che

Incorporando le suddette espansi" ni Otterrem o il nostro secon do passo di raffinamen to


co mpleto:

Inizializzare il vettore dei semi


lniziafizza,re il vettore dei valori
Inizializzare la matrice del mazzo di carte
Per ognuna delle 52 carte
inserire ii numero di estrazione in untt casel/,a liberti del mazz di carte scelta 11 caso

la sa:inga sar alli neata a sinistra in un ca mpo di lwigbexza 8.


/ * Programma per la distribuzione del le carte da gioco */

.Per ognuna delle 52 carte


Trovare ii numr.o di estrazione nella matrice del mazzo di carte e visualizzare il valore
.
e il seme della carta
"Inserire il n um ero di estraziGne in u11a casella libera del m azzo di carre scelta a caso,.
.
potra' essere espansa lll:

Scegliere a cas una case!/,a dei mazzo di carte


Finch la casella de.I mazzo di carte gi stata scelta in precedenuz

#inc l ude <stdio . h>


#include <stdlib . h>
#include <time . h>
I

void shuffle (int [][13)) ;


void deal(const i nt []( 13] , const char *l] , const char *[ ) ) ;
(conti.nU4)

CAJ'l'fOLO

25 8

I PU NTAT Oll l

Ace of Spades
Ace of Hearts
Queen of Clubs
Ten of tie-arts
Ten ot Spades
Ten of Di~monds
Four of Diamonds
Six of ' Diamonds
Eight Qf Hearts
Nine of Hearts
Deuo.e- of Spades
Five Of Clubs
Deuce of Dia_monds
Fi ve of Spa.des
Ki.ng of Diamonds
neuce of Hearts
Ace of Clubs
Three of Clubs
Nine of Clubs
Four of Hearts
Ei.ght of Diamon~s
Ja ok of Diamonds
Five of Httarts
Four of Olubs
Ja ck of Clubs

main()
{

;
"}
s
de
pa
"S
",
bs
lu
"C
,
"
ds
on
iam
"D
,
"
rts
ea
"H
ch ar *s ui t[4 ] = {
1 ,
10 ,
11 F ur 1
1
11
e
re
h
T
t1
,
'
e
e
0
u
e
o
c ha r *f a ce [ 13 ] = { Ace " , "
"Seven " , "Eig.h t ",
"Five ", "S ix
11
1
"King "};
,
een
Qu
'
,
''
ck
"Ja
,

en
"T
"Nine ",
in t de ck [4 ][1 3] = {0 };
11

srand(time(NULL));
sh ut tle (d ec k) ;
dea l (d ec k, fa ce , su it) ;
re tu rn 0;
}

vo id sh uf fl e( in t wDec k[ ][ 13 ])
{

in t ca rd , row, column;
f0 r( ca rd = 1; ca rd <= 52; card++) {
row = rand(} % 4;
co lumn = rand(} % 13;
whi le (wDeck[row][colum n]
row = ra nd () % 4;
co lumn = ra nd () % 13 ;

I= 0)

259

Diamonds
Qf Oiamonds
of Hearts
Of Clubs
Thnee of Spa~es
Four of Spades
Ten of Clubs

Ace -0f
aueen
Seven
Oeuce

Si x pf

Spa~es

Thr-ee of Diamonds
Th ree of Hearts
Six ef Hearts
Ei g.h t of Clubs
Ei gh t of Spades
King of Clubs
Ja ck of Spades
Que-en of Hearts
King of Spades
Kiing Of He ar ts
Nine of Spa-des
Qlleen ~'f Spaaes
Ni ne of Diamon(fs
Seven of Clubs
Five of >iamonds
Ja ck .e f Ha ar ts
Se\ien of Spades

rte da gioco.
ca
lle
de
e
ion
uz
trib
dis
la
r
pe
a
mm
gra
pro
l
de
e
ion
uz
ec
es
Fi gu ra 7 .2 5 Esempio di
pi
r
fo
e
ur
utt
str
e
du
Le
.
ne
zio
bu
tri
dis
di
o
rrn
ori
alg
o
str
C' un pu nt o de bole ne l no
an
qu
e
ch
an
,
ck
de
di
nr.i
me
ele
gli
tra
a
nz
de
on
sp
rri
co
in ter ne co nti nu era nn o a cercare un a
to dif ett o
es
qu
mo
ere
gg
rre
Co
.
ivo
tat
ten
0
n1
pri
al
ri
ga
ma
e
ra
do quella sa r gi stara trova
O.
negli ese rcizj e nello stu dio d i un caso de l Ca pit olo l

ce[],
Fa
*w
ar
ch
t
ns
co
,
J
13
](
[
k
ec
D
w
t
in
st
on
(c
al
de
id
vo
c ns t ch ar *w Su it[ ])

7. I I I pu nt at or i a funzioni

wOeC'k[row][column] =c ar d;
}

(j ab bia olo
pit
Ca
l
Ne
.
ria
mo
me
di
o
zz
iri
ind
o
su
il
e
ien
nt
Un pu nta ro r a un a fu nz ion e co
nme
ele
o
im
pr
o
su
l
de
ria
mo
me
di
zo
iriz
nd
l'i,
lt
rea
in
mo vis to ch e il non1e di un ve tto re
qu ale
daJ
ria
mo
me
di
o
izz
dir
l'in
lt
rea
in

e
ion
nz
fu
a
un
di
to. In mo do sim ile, il 11o me
po tr
ri
ato
nt
pu
di
o
tip
ro
es
Qu
e.
ion
nz
fi1
lla
de
ito
mp
co
inizia iJ co dic e ch e eseguir il
ri
al.c
ad
ato
gn
se
as
e
i
r.
tro
ve
in
to
ina
zz
ga
ma
im
,
i
essere pa ssa t e res tit uit o da lle fu nz ion
pu nta tor i a fu nz ion i.
a
mm
ra
og
pr
il
o
ac:
fc
di
mo
o
am
bj
ab
i
ion
nz
fu
a
ri
to
Pe r mo str ar l' ut iliz zo de i pu nt
a
ell
d
o
ell
qu
e
tar
en
em
pl
im
a
d
do
mo
in
,
15
7.
ra
pe r l'o rd in am en to a bo lle de lla F igu
bu bb le ,
ni
zio
n
fu
lle
da
e
in
ma
n
u
da
co
ma
for

a
mm
ra
og
Fi gu ra 7 .26 . Il no srr o nu ov o pr
en to
om
rg
a
me
co
er
ev
ric
rt
So
le
bb
bu
e
ion
nz
fu
L-a
swap , as ce nd ing e de sc en din g.
re di int e ri
tto
ve
un
e
ch
tre
ol
g,
din
en
sc
de
o
ing
nd
ce
as
e,
un pu n tat or e a un a fu nz ion
de bb a
re
no
ve
il
se
re
lie
eg
sc
di
te
en
ut
l'
al
er
ied
ch
rj
a
mm
e la su a dim en sio ne . U pr og ra
tta 1, alla fu nme
im
te
en
ut
J'
ra
alo
Qu
te.
en
nd
ce
dis
o
e
nt
de
en
asc
essere or di na to in mo do

i nt ca rd , row, colum n;
fa r (c ar d = 1; ca rd <=

52 ;

card++)

fa r ( r ow = 0; r ow <= 3; row++)
fo r (co lumn = 0; co lumn <= 12 ; co lumn++)
if (wDeck[row][co lu mn] == ca rd )
pr in tf ("%Ss of %- 8s%c " ,
wFac e[ co l umn], wS ui t[r ow ],
ca rd % 2 == 0 ? \ n : , \ t ' ) i
}

.
co
gio
da
rte
ca
lle
de
e
ion
uz
trib
dis
la
r
pe
ma
ram
og
Pr
Figura 7.24

260

CAPITOLO

essere ordinaco in modo ascendence o discendenre. Qualora l' urenc immecca 1, alla
funzione bubble sar passato un puntatore ad ascending , determinando cos l'ordi namento ascendente deJ vecrore. Qualora l'ucence immetta 2, alla funzione bubble sar
passato un puntatore a descending, determinando cosl l'ordinamento discendente del

void swap (int * 1 int *);

f or ( pass = 1 ; pass <=

vetcore. L'oucpuc del proiramma mostrato 11ella Figura 7.27.

va id bubble ( int 1 canst int, int ( *) ( int 1


i r:i t ase end in g ( eon s t in t , cons t in t ) ;
int descending(canst int, canst int);

1 1 pass++)

if ((*compare}(work[co unt] 1 work[count +


swap(&work[count], &work[count + 1]);

1)))

1
void swap(int *element1Ptr 1 int *element2Ptr)

int}} ;

int temp;
temp = *element1Ptr;
*element1Ptr = *element2Ptr;
*e1ement2Ptr = temp;

main(}
{

int a[SIZE] = {2, 6, 4, 8, 10, 12, 89, 68, 45, 37};


int counter, arder;

int ascending( const int a, const int b}

printf( dEnter 1 to sort in ascending order, \ n"};


printf( "Enter 2 to sort in descending arder: "};
scanf( "%d" , &arder);
printf( ~\ nData

51. ze

far (count = 0; count <= size - 2; count++ )

/ * Programma di ordinamento polivalente che utilizza dei puntatori a


funzioni I

#include <stdio. h>


#def ine SIZE 10

26 1

J PUNTATORI

return

< a;

itms in origina! order\n'l};

int descending(canst int a, const int b)

far (co unter = 0; caunter <= SIZE - 1 ; caunter++)


printf ( li%4d" J a[counter]);

if (.arder== 1) {

Figura 7 .26 Programma di ordinamento polivalente che utilizza dei puntatori a funzioni.

return b

far (countr = 0; counter <= SIZE - 1; caunter++)


printf( N%4d ", a[counter]);
printf( "\ n");
return 0;
}

void bubble(int *work, canst int size, int (*compare}(intJ int))


{

a;

bubble(a, SIZE, ascending);


printf(''\ nData items in ascending arder \ n'' );

,
}
else {
bubble(a, SIZE, descending);
printf( "\ nOata items in descending order \ nM};

>

Enter 1 to sort in ascending order,


Enter 2 to sort in descending arder: 1

Data items in origina! order


8 10 12 89 68 45 37
4
_
Data items in ascending arder
8 10 12 37 45 68 89
6
4
2
2

I
I

Enter 1 to sort in ascending order l


Enter 2 to sort in dscending o~der: 2
Data iteins in origina! o~dgr
8 10 12 ' 89
4
2
6

88

45

37

Data items in desoendi.ng Or"de f'


89

68

45

37

12

10

int pass, count;


Figura 7.27 Gli output del programma di ordinamento a bolle della Figura 7.26.

262

CAr>Jl' OLO

NeU,intestazione della funzion e bubble appare il seguente paramerro:

int ( *compare) (int, int)

263

I PUN1"A"f01?.l

La dichiarazione va lerra cominciando dall'insieme di parentesi pi a sinisrra, "f una


matrice di 3 pu11rarori a funzioni che riceveranno co111e argomento t1n int e che restituiranno voi d 11vettore sraro inizializzato con i nomi delle rre funzioni. 11 valore, con1preso tra O e 2, che l'ul:enre imn1errer sar urilizzaro come indice per il vetto re di puntatori a
fi1nz.ioni. 'Linvocazione della fw12ione sar quindi efferruata nel modo segue11re:
11

Questo avverte bubble che ricever come pararnerro un puntatore a una funzione che
accetta due argomenti inreri e che resruisce un risultato dello stesso tipo. Le paren tesi
intorno a compare sono necci>sarie perch * ha una priorir inferiore a quella delle parentesj che racchiudono i parameui della funzio ne. Se non avessimo incluso le parentesi, la
dichiarazione sarebbe diventata

i nt *compare ( int, int )


che avrebbe dichiarato una. funzione che riceve dLLe pararnerri i11reri e restituisce un puntatore
dello stesso ti po.
U parametro corrispondente nel prototipo della ft.1nzione bubble

i nt

(*)

(int, int)

Osservare che sono sra inclusi soltanto i pi, ma il progra1n1narore .porr indudere per
scopi documenravi dei nomi di paran1erro e di funzione che il compilatore ignorer.
La funzione passata a bubble sar invocata all'interno di un'istruzione i f come segue

( *f ( c h oi c e ] ) ( e h oi e e ) ;

In quesra chiamata, f ( c hoice] selezioner il punrarore immagazzi nato nella posizione


choi ce del vertore. Una volta risolto il riferimento del puntatore, la funzione sar invocata
e choice gli sar fornico coJ11c argo mento. Ogni funzion e visualizzer iI valore dell'argomento ricevuto e iJ proprio noJne di fu.o.zio:n.e pex indicare che sar stata richiamata correttttOJ~L1te. Negu esercizi svilupperete un sisterna guldaro da 1nc11u.

/ * Dimostrazione di ut ilizzo di un vettore di puntatori a funzioni * /


~include <stdio.h>
void function1(int);
void fun ction2(int);
void function3(int ) ;

if ((*compare)(work[c ount], work[count + 1] ))

main ( )

Occorre risolvere il riferimento di un puntatore a una funzio11e per invocarla, proprio


come necessario risolvere il riferimento di un punrarore a una va ri~b i le per accedere al
suo contenuto.

void (*f[3])(int) - {function1, function2, function3};


int choice;

printf( "Ente r a num ber between 0 and 2, 3 to end : ") ;


scanf (~% d" , &ch oice) ;

Avremn10 potuto inv.o_tare la funzione senza risolvere il riferimenro del puntatore,


come nell'istruzione

if fcompare(work[coun t] ,

wor~[count

+ 1]))

while (choice >= 0 && choice < 3} {


(*f[choice])(choic e);
printf( ' Ent er a number between 0 and 2, 3 to end : '' );
scanf('' %d'', &choice);

che utilizzerebbe dirttainenre il punrarore in sostituzione dd nome della funzione. Abbian10


per preferito il primo met-odo di invocazione, perch mostra in modo esplicito che compare
un puntatore di cui stato risolto' iJ riferimento per richiamare la fi1nzione. Nel secondo
metodo di invocazione il puntatore compare sembra essere invece il nome di una funzione.
Ovviamente, ci porrebbe creare confusione in un utente che desiderasse dare uno sguardo alla
definizione della funzione compare e scoprisse che non mai stata definita nel file.
I p untatori a funzioni sono utiliz-zati tipicamente nei cosiddetti sistemi guidaci da
menu. In questi sistem i si richiede all'urente di selezionare un'opzione d.a un menu (per
esempio, da 1 a 5). Ogni pzione sar servita da una ft1nzione differente. I puntatori che
fanno riferimento a ognuna di quelle funzioni sono immagazzit1ati in un verrore di puntatori
a funzione. La scelta dell'urente sar utilizzata come indice del vettore per rilevare il puntatore
che sar utilizzato per invocare la funzione.

printf ("You entered 3 t o end \ n");


return 0;
}

void fun cti on1 (int a)

{
p ri ntf( ~ You

entered %d s o function1 was called \ n\ n'' , a);

Il progra1nma della Figw:a 7.28 fornisce t1n esempio generico dei meccariismi per la
di.cl1iarazione e l'utiUzzo di un vettore di pur1 tatori a funzioni. Son9 state definire rre funziot1i, function1 , function2 e function3, ognuna delle quali ricever w,1 argornento
inrero e non restituir alcun valore. I puntatori cl1e fanno riferimento a queste ue funzionj
sono srati immagazzinati nel vettore f , dichiarato con1e segue:

void function 2(nt b)

void (*f[3]) (int) = {function1 , function2 , function3 };

void fun ction3 (int c)

printf( '' You entered %d so fun ctio h2 was called \ n\ nq, b) ;


}

(cor1tini1a}

264

C APffOLO

265

}PUNTATORI

e) Visualizzare gu elementi dcl vecrore numbers urilizzando la notazione con puntatore e


offset usando nPtr come puntatore.
f) Visualizzate gli demenci d~ vettore numbers urilimndo la notazione con puntatore e
offset usando il nome dcl vettore come puntatore.
g) Visualjzzate gli elen1enci del vettore numbers uciliz'la ndo gli indici applicati al puntatore
nptr.
h) Puncace all'demenco 4 del vettore numbers, ucilizZ<"lndo la nocazione con gli indici di
vectore, queUa con punrarore e offset usando il nome del vectore come puntatore, quella
con gli indici applicaci al puntatore nPtr, e la notazione con puntatore e offser usando

printf( '' You entered %d so function3 was called \ n\ n" , e);


}

Enter a number between 0 and 2, 3 to end: 0


You entered 0 so function1 was called
Enter a number batween 0 and 2, 3 to end: 1
You entered 1 so f unction2 was called

nPtr.
i) Supponel1do che nPt r faccia riferim.e nto all'.iillzio del vecror~ num~e rs, quale in~irizz~
sarebbe puntaro da nPtr + 8? Quale valore sarebbe immagazzinato 111 quella locazione d1
m.emor1.a.
j) Supponendo e.be nPtr faccia riferimenro a numbers [ 5] , quale indirizzo sarebbe puntaco
da nPtr -= 4? Quale sarebbe il val.ore iaJmagazzinato in quella locazione di n1emoria?

Enter a number betw.~~n 0 and 2, 3 to end: 2


You entered 2 sa function3"Was Galled

a number ~etwee~ 0 and 2, 3 to end: 3


You entePed 3 to end
~nter

Per ognuna ddle seguenti accivit scrivete una singola isrruz.ione che esegua il compito indicaro. Sup ponete che siano gi stare dichiarare le variabili in virgola mobile number1 e number2 e che
number1 sia stata inizializzata a 7 ,3.
a) Dichiarare la variabile f Ptr come puntatore a un oggetto di tipo f loat.
b) Assegnare l'indjrizzo della variabile number1 alla variabile di tipo puntatore f Ptr.
c) Visua lizzate iJ valore dell'oggetto puncaco da f Ptr.
d) Assegnare alla variabile number2 il valore ddl'oggerro puntato da f Ptr.
e) Visualizzare il valore di number2.
f) Visual izzare l'indiriz1,o di number1 . Utilizzate la specifica di conversione %p.
g) Visualizzare l'indirizzo immagazzinato in f Ptr. Uciliizace la specifica di conversione %p. 11
valore visualizzato identico a quello deU'indil:izzo dj number1 ?

7 .4
Figura 7 .28 Dimostrazione di utilizzo di un vettore di puntatori a funzioni.

Esercizi di autovalutazion e
7.1

Rispondete a ognuna delle seguenri domande:


a) Un .punratore ~ una variabile che contiene come suo valore !'_____ di un'altra
variabile.
b) I rre valori che porranno essere utilizzaci per inizial izzare un puncarore sooo _ ____,
- - -- - o - - -- -
.
e) I:'unico intero che possa essere assegnato a un puntatore

7 .2 . De~ermiJ1are se le segu~ci affermazioni siano ve.re o false. Qualora la risposta sia faJsa, spiegatene 11 motivo.
a) l:o~e.r~~or~ ~ indirizzo & pu.essere. applicar~ soltan~o alJ.e coscanti, alle espressioni e alle
variabili dich1~Te con la -Specifica dJ classe di memoria register.
b) Il riferimento cli a.n puncaror~ che sia stato dichiarato void pu essere risolto.
e) I puntatori di Tipo differencJ non possono essere assegnati gli uni agli alai senza un' operazione cli conversione.
Rispondete a ognun~ delle segue.nei domande. Supponete che i numeri in vi rgola mobile con
7.3
precision~ sing~la siano '.mmagazzinaci in 4 byte e che l'indirizzo di partenza per il verrore corrisponda
3!1a loc:iz1?ne di memona 1002500. Ogni parte ddl'esercizio, Jaddove appropriato, dovr utilizzare i
risultaci di qudle precedenti.
a) Dichiarare il vettore di cipo f loat chi amaro numbers contenente 10 dementi e inizializzateli
con i valori 0, 0 , 1, 1, 2, 2, ... 9, 9. Suppo11ece che la cosrante simOolic.a SIZE sia sTara
deflnita con il resto cli soscituzione 10.
b) Dichiarate un puntatore nPtr che faccia riferimento a un oggetto cli cip float.
c) VisuaUzzat~ .gli elementi del vectorc numbers utilizzando la notazione con gli indici di
verrore: U~il1zz.are ,~na s~ut:tura fo.r e supponete chela variabile di controllo intera i sia gi
scaca dichiarata. V1sual1zzate og111 nun1ero con l posizione di precisione a destra della
virgola decimale.
d) Fornire due istnizini distinte che assegnino all a variabile di cipo puntatore nPtr l'indirizzo di partenza del vettore numbers.

7.5

.
Esc;gu.ice ognuna delle seguenri attivic..
a) Sccivete l'intescazione di una funzi'one chiamata exchange che riceva come paramecr1 due
puntatori aj numeri in virgola mobile x I,! y e non restituisca alcun valore.
b) Scrivere il protori po per la funzione d.ella parre (a).
e) Scrivete l'intestazione di una funzione chiamata evaluate che resciruisca un incero e che
ciceva co me argomen.ci llintero x e un pW1ta-core alla funzione poly. La funzio ne poly
ricever un paran1ecro intero e restituir un incero.
d) Scrivere il prococipo per la funzion~ della parre (c).

7.6

Trovare l'errore in ognuno dei seguenti segmenti di programma. Supponece che


int *zPtr; /* zPtr punter al vettore z *I
int *aptr = NULL ;
void sPtr = NULL;
int number, i;
int ~[5] = {1, 2 1 3 1 4, 5};
sPtr = z;

a) ++-z:Pt r;
b) / "' usa un puntatore per ottenere i l primo valore del vett ore * I
number =zPtrj

e) / * assegna a number l ' elemento 2 del vttore (il valore 3 ) * /


number = zptr[2] i

266

CA PIT OL O

J PUNTATORI

26 7

vo id ex ch an ge (fl oa t *x 1 flo at *Y)


vo id ex ch an ge (fl oa t *, flo at *);
in t ev alu ate (in t x, in t (* po ly) (in t))
in t ev alu ate (in t, in t (* )(i nt ));

b)

Risposte agli esercizi di au to va lu ta zi on e


7.1
7.2

7.3

a) indirizw. b) 0. NULL, tu1 indirizzo. e) 0.

d)

ert:
ess

pu
n
no
e
ili
:iab
vru
alle
ro
Ean
sol
to
lica
app
ere
e$S
pu
zo
a) Falso. Voperaro.re di iridiriz
r.
applicato a quelle dichjarare con la classe di me mo ria r eg ist e
cli
do
mo
c'
n
Jlo
ch
per
,
lto
riso
ere
ess
pu
n
no
id
vo
a
e
tor
nta
pu
b) Falso. Il riferimenro di un
sape.re esarramence a quanri bycc di memorja si debba pu nta re.
ea
ore
rac
pun
di
i
tip
i
ala
gli
ci
cuc
i
1ac
egr
as
ere
ess
o
nn
tra
po
id
e) Falso. A un pu nta tor e vo
questi pdtr essere assegnato quello di tipo vo id.
, 6.8, 9.9 };
a) flo at numbers[SIZEJ = {0.0, 1.1 , 2.2 1 3.3 , 4.4 , 5.5 , 6.6 , 7.7
b) f loa t *n Ptr ;
c) fo r (i = 0; i <= SIZE; - 1; i++ )
pri ntf ( "%. 1f " 1 numbers[i]);

d) nP tr = numbers;
nptr = &numbers[0J;

e) fo r (i = 0; i <= SIZ E - 1; i++ )


pri ntf ( "%. 1f ", *(n ptr +i ));
f) fo r (i = 0; i<= SIZ E - 1; i++ )
pri ntf ( 1'%. 1f ", * (numbers + i)) ;

g) fo r (i= 0; i< = SIZE - 1; i++ )


pri ntf ( "%. 1f , np tr( i]) i

h) nu mb ers (4]
*(numbers + 4)
nPtr[4]
* (nPtr + 4)

i)
j)

7.4

c)

Cindirizzo 10 02 50 0 + 8 4 = 10 02 53 2. Il valore 8 , 8.
Cindi rizzo di numbers [ 5 J 10 02 50 0 + 5 * 4 = 10 02 52 0.
L'indirizzo di nP tr -= 4 10 02 52 0 - 4 * 4 = 1002504 .
il valore in queUa locazione 1 , 1.

a) flo at *fP tr;


b) fP tr == &number1;
e) pri ntf ("T he va lue of *f Pt r is %f \n" , *f Pt r);
d) number2 = *f Pt r;
e) pr in tf ( "The va lue of number2 is %f \n" , number2);
f) pri ntf (''T he ad dre ss of number1 is %p\n~, &number1);
g) pr in tf( "The ad dre ss sto red in fP tr is %p\n" , fP tr) ;
S. il valore lo sresso.

e)

f)

Errore: zP tr no n staco inizializzato.


Correzione: inizializzare zP tr con zP tr = Zj
Err ore: il riferimento deJ pu nta tor e non sc:aco risolc:o.
Correzione: cambiate l' istruzione i11 numbe r = *z Pt r j
lvere.
riso
da
ro
1en
crin
1if
sun
nes
c'
n
no
i
ind
qu
e
e
tor
nta
pu
n
u

Errore: zP tr[ 2] non


Correzio ne: cambiare *z Ptr [2] in zP tr[ 2] .
ai limici del
o
rn
csr
nto
me
ele
un
a
nro
me
eri
cif
fa
si
e
tor
nta
pu
del
ce
Errore: con l'i ndi
vecror.
utt ura fa r.
str
la
nel
llo
tro
con
di
le
i
iab
var
la
del
Je
fma
ore
val
il
4
in
re
bia
Correzione: cam
i d.
Errore: tentativo di riso lve re iJ riferimento di un ptlllcacorc a vo
ere converriro
ess
ma
pri
r
dov
sto
que
e
tor
nta
pu
del
o
enc
rjn1
rife
il
re
lve
riso
Co rrezio ne: per
t *) sP tr;
in
*(
=
r
e
mb
nu
in
e
on
uzi
istr
ta
der
sud
la
e
iar
mb
Ca
.
eri
int
a
in un puntacore
pu nta tori.
dei
a,
erjc
im1
l'ar
con
e
tor
ver
un
di
e
nom
iJ
re
ica
dif
mo
di
ivo
Error: tenrac
perazione
l'o
re
gui
ese
per
e
ror
''er
del
me
no
del
ece
inv
ore
rac
pun
un
a.re
Correzione: utilizz
vecrore per fare
deJ
me
no
il
con
ici
ind
gli
ate
lizz
uti
re
pu
op
,
ori
rac
pun
dei
di arirn1erica
riferim ent<') a un elemento specifico.

Esercizi
Rispond ere a ognun deJJe seguenti domande:
gazzinaro il suo
ma
im

cui
in
ria
mo
me
di
one
azj
loc
la
e
isc
riru
res
a) ~operacore
operando.
prio operando.
pro
dal
to
nta
pu
to
get
'og
l
del
ore
val
il
e
isc
titu
res
b) ~opcrarore
zione una variabile che
fun
a
un
a
si
pas
si
a
lor
qua
o,
enr
rim
rifc
per
ata
am
chi
a
un
re
ula
e) Per sim
della variabile.
I'
ne
zio
fun
alla
e
sar
pas
ario
ess
nec

sar
e,
tor
vec
un
no n sia
.
rivo
mo
il
e
cen
ega
spi
e
fals
no
sia
ra
alo
Qu
e.
fals
o
e
ver
no
sia
i
.ion
1az
Derermi.nare se le seguenti a.ffem
7 .8
vettori distinti.
a
o
enc
rin1
rife
no
cia
.fuc
e
eh.
ori
r:ar
pun
e
du
re
nra
fTo
con
so
sen
a) No n ha
i
tor
vet
dei
mi
no
i
,
nto
mc
eJe
mo
pri
suo
al
ore
car
pun
un

e
b) Poich il nome di un veccor
possono essere manipolaci ncllo sresso modo dei puntatori.
agazinim
no
sia
no
seg
za
sen
eri
inc
gli
che
ece
pt)n
Sup
de.
ian
don
ici
ucr
seg
Rispondere a ognw1adelle
7.9
memoria 100 25 00 .
di
one
ai.i
loc
alla
sia
e
ror
ver
il
per
za
ten
par
di
o
izz
dir
!,in
che
e
e
zinaci in 2 byt
nti e
n1e
ele
5
e
ent
ren
con
s
lue
va
ato
am
chi
t
in
d
ne
sig
un
o
tip
di
a) Dichjarare il verrore
bolica
sim
re
can
cos
la
che
ete
on
pp
Su
10.
a
2
tra
si
pre
com
i
par
eri
inc
inizializzaceli con gli
SIZE sia gi srata definita con il cesro di sosciruzio ne 5.
ne d in t.
sig
un
o
rip
di
o
err
ogg
un
a
o
ent
rim
rife
cia
fac
che
r
t
vP
e
tor
1ra
b) Dichiarare un pw
vertere. Usare
di
ici
ind
gli
con
e
iop
raz
no
la
o
and
lizz
uti
s
lue
va
di
n[i
nie
ele
e) Visualizzate gli
ta dichia rata.
sta
gi
sia
i
era
int
llo
rro
con
di
ile
iab
var
la
che
e
net
po
sup
e
r
una srrurrura fo
vP t r l' indirizorc
t:ir
pun
o
tip
di
ile
iab
var
aUa
i.rio
egn
ass
che
oni
uzi
isrr
re
cit1
d) Forn.ice dtLe cLls
zo di par tenza del verrore va lue s.
con pu nra tore e
one
a7i
not
la
o
and
lizz
uti
s
lue
va
e
ror
ver
del
nti
me
cle
gli
e) Vsualiv..ace
offser.
pu nta rore e offsec
con
e
on
azi
noc
la
o
and
lizz
uri
s
lue
va
e
tor
vet
del
i
ent
dem
gli
() Visualiz1.ate
e usando come puncatore il nome deJ vettore.

7.7

26 8

CA PIT OL O

un puntatore che
con
ici
ind
gli
.o
and
liiz
uri
s
lue
va
e
ror
ver
del
nti
me
ele
gli
ate
g) Visualizz
faccia rife rimento al vercore stesso.
gli indici di vettore.
con
one
azi
nor
la
o
and
lizz
uri
s
lue
va
e
tor
vet
del
5
nto
me
ele
all'
b) Puntate
ore, quella con oli
ra.c
pun
e
com
e
ror
vec
del
e
nom
il
o
nd
usa
set
off
e
e
tor
nta
pu
quella con
r:i
.
set
off
e
e
tor
nta
pu
con
lla
que
e
e
tor
nta
pu
indici di
in
ato
zin
gaz
ma
i.m
e
ebb
sar
ore
val
ale
Qu
3?
+
tr
vP
da
o
rac
pun
i) Quale indirizzo sare.bbe
quella locazione?
to da
nta
pu
e
ebb
sar
zo
iriz
ind
le
qua
4]
[
s
lue
va
a
~o
men
eri
rif
cia
fac
j) Supponendo che vP tr
one?
vP tr -= 4? Quale valore sarebbe immagazzinaco in quella locazi
pito indicacom
il
gua
ese
che
one
uzi
istr
la
go
sin
a
un
re
jve
scr

ivic
act
ri
uen
seg
7 .1 O Per ognun a delle
va lue 1 sici
che
e
2
lue
va
e
1
lue
va
g
lon
ere
int
ili
iab
var
le
e
rar
hia
dic
te
sta
to. Supponete che siano gi
stata ini zializzata a 200000 .
g.
lon
o
cip
di
o
ecr
ogg
un
a
e
tor
nta
pu
e
com
tr
lP
ile
iab
var
la
e
a) Dichiarat
e lP tr.
b) Assegnare l'indirizzo di va l ue1 alla variabile di tipo puntator
c) Visualizza.ce il valore dell'ogget to puntato da lP tr.
va lue 2.
d) Assegnare il valore deU 'oggerco pun tato da l Pt r alla variab ile
e) Visualizzare il valore di va lue 2.
f) Vis ualizzare l'ind icizzo di va lue 1 .
identico a quello
ato
lizz
ua
vis
o
rizz
ndi
I..:i
tr.
lP
in
ato
zin
gaz
ma
im
izzo
dir
l'in
te
g) V sua lim
di va lue 1 ?

7. 11 Esegt re ognuna dd le segi1enci attivit.


tore bi gin teg ers
vet
un
o
etr
am
par
e
om

avr
che
ro
ze
ne
zio
fun
la
del
e
ioo
caz
ces
l'in
a) Scrivere
di inceri lon g e non rescicujr alcun valore.
b) Scrivere il prototipo per la fun zione della parte (a).
tore di
vet
uo
o
etr
am
par
e
com

avr
che
um
ndS
1A
add
ne
zio
fun
la
del
e
e) Scrive re l'intestazion
interi on eT oo sm all e restirtur un incero.
d) Scrivere il prototipo per la funzione d~ccirra nella parte (c).
risolto
ere
avr
che
ta
vol
a
Un
ivi.
nar
peg
im
a
anz
ast
abb
o
son
.15
7
al
Nota: gli Esercizi dal 7 .12
comuni.
pi
te
car
di
chi
gio
i
e
enr
ilm
fac
re
nta
me
ple
im
di
do
gra
in
ere
ess
questi problemi, dovreste
dispensi
e
n
o.
uzi
uib
dis
di
e
n
.
zio
fun
la
che
do
mo
in
4,
7.2
t1ra
Fig
la
del
a
7.1 ~ Modifqi.re i.I program~
tive:
iun
agg
ni
zio
fun
ti
uen
seg
le
t
ive
scc
o
uit
seg
In
..,
ker
po
di
no
ma
le cinque carte d1 una
a) De terminate s la mai10 con tenga una coppia.
b) Determi nare se la mano contenga una doppia coppia.
ti).
e) Determinare se la mano contenga un tris (per esempio, rre fan
i).
ass
ro
att
qu
io,
mp
ese
r
(pe
ker
po
n
u
ga
ten
con
no
ma
la
se
ace
d) De t~rmin
sso seme).
ste
lo
dd
te
car
e
qu
cin
a,
osi
ver
(ov
ore
col
un
ga
ten
con
no
ma
la
se
e) Detrmjnate
consecutivi).
ori
val
i
cor
te
car
e
qu
cin
a,
osi
ver
(ov
la
sca
a
un
ga
cen
n
co
no
ma
la
f) Decenni.nate se
mma che distribugra
pro
un
re
ive
scr
per
2
7.1
io
ciz
ser
l'E
nel
e
pat
lup
svi
ni
zio
fun
7. 13 Utilizzare le
no migliore.
ma
la

l
qua
ini
erm
det
e
uti
val
le
er,
pok
di
ni
a
m.
e
du
di
re
car
e
isca le cinqu
te
car
que
cin
Le
.
ere
zzi
ma
un
re
ula
sim
da
do
mo
in
3
7.1
ura
Fig
la
7. 14 Modificate il programma del
. il
ere
ved
ssa
po
le
non
ore
cat
gio
il
che

cos
"
gi
in
cia
fac
"a
e
uir
trib
della mano del mazziere saranno dis
r~
dov
lla,
que
di
t
ali
qu
la
sul
osi
and
eas
e,
.
ere
zzi
ma
del
no
ma
la
progran1ma dovr quindi val utare
ndi
qui
r
dov
a
mm
gra
pro
Il
a.
ari
gin
ori
no
ma
la
dal
te
rta
sca
elle
~crar..re altre carre per soscicuire qu
difficile!).
ma
ble
pro
un

sro
que
ne:
zio
ten
(At
.
ere
zzi
ma
del
no
ma
la
e
tar
r1va1L1
amence la
atic
om
auc
tire
ges
sa
pos
che

cos
4
7.1
io
ciz
ser
l'E
nel
o
pat
lup
svi
.a
7 .15 Modificare il programm
grampro
U
ire.
citu
sos
no
ma
sua
la
del
te
car
li
qua
re
ide
dec
di
ore
car
gio
al
ta
mano del mai:zie~e, menrre consen
nuovo
sro
que
ora
are
lizz
Uti
co.
vin

avr
chi
re
ina
erm
det
e
ni
ma
le
be
ma dovr qwndi valutare entram

269

I PUNTATO RI

Fate giocare
ter?
pu
com
il
o
voi
,
pi
cli
nc
vi
ne
i
Ch
er.
put
com
il
tro
con
tire
par
prGgratnma per giocare 20
ltaci di quesre
risu
sui
i
dov
san
Ba
?
i
p.
ce
vin
ne
i
Ch
er.
put
com
il
tro
con
tire
par
uno dei vosrri ainici in 20
che quesro un
(an
co
gio
di
na
n:u
gra
pro
tro
vos
il
are
fin
raf
per
e
icb
clif
mo
une
orr
partite, apporrarc le opp
nuovo programma?
rro
vos
il
glio
n1e
ca
Gio
.
rire
par
20
e
alrr
e
cat
Gio
e).
icil
diff
ma
ble
pro
o
iam
abb
4,
7.2
ura
Fig
la
del
te
car
le
dd
one
uzi
trib
dis
la
e
o
ent
7 .16 Nel programma per il mescolan1

ilic
sib
pos
la
no
do
ero
in
ha
ch
te
ien
ffic
ine
o
enc
lam
sco
n1e
di
intenzion almente ucilizzaco un algoricn10
enro ad alca efficienza
lam
sco
me
di
o
tm
ori
alg
un
te
ere
cre
io
rciz
ese
o
est
qu
ln
i.
nir
efi
di differimenri ind
che eviter il differimento indefinico .
iile
cO
ck
de
e
tric
ma
la
re
zza
iali
lniz
ce.
uen
seg
do
mo
nel
4
.2
ura
Fig
Modificare il programma cl.ella
onna
col
e
riga
i
ogn
su
i
iter
che
do
mo
in
le
uff
sh
ne
z.io
fun
la
te
ica
mosuaro nella Figura 7.29. Modif
iato
mb
sca
ere
ess
r
dov
ro
1en
~en
ni
Og
ta.
vol
a
sol
a
un
i
ent
dem
li
della marri.ce, rocca.odo ogn uno deg
con un ilrr o selezionato a caso dalla ma trice.
scome
to
sca
sia
te
car
di
zzo
ma
il
se
re
ioa
etm
dec
te
sia
pos
che
l
cos
nte
Visualizzate la matrice risulta
ento
lam
sco
me
un
vi
rar
icu
ass
Per
.
io)
mp
ese
r
pe
0,
7.3
ura
Fig
la
nel
lato in modo soddisfacente (come
sh uf f le .
ne
zio
fun
la
ce
voi
pi
ni
iar
rich
a
mm
gra
pro
il
che
do
mo
in
e
far
soddisfacente pocresre anche

1
2
3

0
1
14
27

40

41

15
28

2
3
16
29
42

10

11

12

17
30
43

18

6
19
32
45

20

8
21

33
46

34
47

9
22
35
48

10
23
36
49

11
24
37
50

12
25
38
51

13
26
39
52

8
35
31
29
37

10

11

12

41
17
32
49

18
24

2
7

44
1

47
6

26
20

31
44

Figura 7.29 La ma trice de ck no n mescolata.

19
13

12

50

1
40

28
33
38

2
27
14
15
52

3
25
16
42
39

36
21
43
48

46

10
8
45
9

34
11
3

30

23
51

22

Figura 7.30 Esempio di ma trice de ck mescolata .


ro,
en
lam
sco
me
di
o
an
ori
alg
..
I
i
lior
mig
ma
ble
pro
sto
que
in
to
lim
uci
Osservate che sebbene l'approccio
oi
p
,
2,
la
per
poi
1,
ea
ca.r
la
per
k
dec
e
c
cri.
ma
la
nel
he
erc
ric
le
del
quello di distribuzio11e richieder ancora
nel
ca
car
a
un
e
car
cer
a

uer
tin
con
one
uzi
trib
dis
di
o
irm
gor
l'al
se
per la 3 e cos) via. Co me se non basras 1
in
4
7.2
ura
Fig
la
del
a
mm
gra
pro
il
re
ica
dif
Mo
ca.
bui
cri
dis
e
ta
mazzo anche dopo averla gi ritrova
che
e
a
arl
ov
ritr
per
vi
rari
ren
ri
erio
ulc
cia
fac
n
no
ta,
car
a
un
o
uit
modo che, una volta che abbia disrrib
un
o
em
per
lup
svi
O
1
olo
pit
Ca
l
Ne
a.
siv
ces
suc
lla
que
cli
one
uzi
proceda immediatamente con la distrib
algori tmo che richieder una sola operazione per carta.
rici pi
sto
nti
me
mo
dei
uno
ete
eer
ricr
io
rciz
ese
sto
que
In
e)
kpr
la
e
7 .1 7 (Sim ulazi..one: la tnrtttruga
casuali
ri
me
nu
dei
ne
zio
era
gen
la
te
ere
lizz
Uti
re.
lep
la
e
ga
aru
tart
La
era
sa
imporranri, vale a dire la classica cor
per sviluppare un a simulazione di questo memorabile eveno.
o il. p.ercorso
gon
pon
com
che
70
le
del
"
l
a
sell
"ca
la
nel
sa
cor
o
lor
la
nno
era
i11c
J nosrri contendenti com
a di arrivo
line
La
a.
gar
la
del
so
cor
per
il
go
lun
ili
sib
pos
ni
izio
pos
le
del
una
ta
sen
della gara. Ogni casella rappre
miato con
pre

sar
70
ella
cas
la
to
era
sup
o
ro
un
gi
rag

avr
che
1re
det
ren
con
n10
odia casella nu1ne ro 70. Il pci
a montagna
un
di
co
fian
sul
ndo
gia
peg
ser
ca
rpi
ine
si
so
cor
per
Il
.
che
fres
e
un .secchio di carote e larrugh
in quando.
ndo
qua
di
eno
terr
e
der
per
no
ritn
pot
ci
dcn
cen
on
i
ci
per
e,
vol
sdrucciole

f
I

CAPI TOtO

270

I plJNTATORJ

IJ Sirnplerron contiene u1J arcurn11/11.rore. un "registro speciale" in ~ui sru:nru10 .inseci~e rurce le .~nforn1a-

C' un orologjo che scandjsce ogni secondo. Ad ogni rie dell'orologio il vostro program1na dovr
aggiustare la posizione degli ani mali secondo le seguenti regole:

Anim ale

Tipo di mos sa

Perc entu ale di temp o

Mos sa effet tiva

Tartaruga

Arra11caca rapida
Scivolone
Arrancata lenra

Lepre

Dorm ita
Salto lungo
Scivolone lungo
alco corto
Sci,v ol0i1e corto

50 1Vo
20%
30/o
200/o
20%
10%
300/o

3 casell e a destra
6 caselle a siniStra
1 casella a destra
Nessuna mo sa
9 caselle a desrra
12 casell e a si nistra
l casella a destra
2 case li.e a sin isrra

20%

n1odi. Tutte le tnfonna. rima che il Simplerron possa urilizzarlc per i calcoli o per esammarle tn1var:t
d al e di
'
zioru, P
zioni saran no manipolact: all'interno dd Simpleuo11 come parole. Una paro a e un numero ec1rn
quattro cifie con segno, come ~3364 , -1 ~9~, +0007 , -0001 , ~cc. 11 Simpl~tr~n e~uipaggiaco coo una
aria di 100 parole alle qua.11 raremO riferunentOarrraversO I loro OUITICfl d1 }oCazL One 00, 01 , ... 99.
memPrima di porer eseguire un progcam ma LMS do,rre1no caricarlo o immetterlo nella memoria. La prima
istrGZione (o comando) di ogni plogramma LMS sar sempre ca.ricara ncUa posizione 00.
Qgnj istruzione scritt~ in LMS occuper una parola nella 1uen:oria del .Simplcrr?n .. ~ Co~eguen.z.a:
corrisponder a un numero Jecimale di quattro cifre con segi10. Owiamcnt~ 11 se?110 daogni 1sc:nwone.1!':1S
sar sempre quello ,positivo, n1entre quelli delle parole che concengai10 deJ ,~a ~ocran~o essere ~os1av1 o
rivi. Ogni locazione della niemocia del Siioplerron porr contenere un 1srruz1one, 'ti valore di un daro
:~naro daJ prograrnma, oppure un'area di memoria inurilizzata (e quindi indefirura). ~ prirne d.u~ cifre
di ogni isc:ruzione LMS corrisponderanno al codice dell'opt.'1't1zione eh~ dovr essere esegwca. Lcod1c1 delle
ope.@Zioni LMS sono riassunti nella Figura 7.31.

Codi ce dell' oper azio ne Sign ifica to

Ucilizz.ace le variabili per n1antcnere rraccia delle posizioni degli anintali (owerosia dei numeri da 1 a
70). Fare parrireog:i1 i animale dalla posizine 1 .(vale ad.ire dalle "gabbie di partenza"). Riportate nella casella
l l'animale d1e dovesse cvenrualmence scivolare i11dierro in una posizione precedente a quella.
Gene rare le percenruali mosrrare nella tabella p recedente producendo tLa incero casuale i compreso nell'i ntervallo 1 = i = I O. Nel caso della tartaruga eseguirete LLna "arrancata rapida" quando l = i = 5,
una ..scivolar' quando 6 = i = 7 o una ''arrancata len[a" quand o 8 = i = 10. Utilizzate una recnica
simile per far crrere la lepre.
Cominciate I.a gar:a visualizzando:

Operazioni di i1zputlou1put:
#defi ne READ 10
#defi ne WRITE 11

BANG !!!Il
ANO THEY' RE OFF 11111

#def ine STORE 21

Sez ion e speciale: cos tru ite il vos tro com put er
Nei prossimi esercizi abbandoneremo temporaneamente il ,mondo dcUa programmazior1e con linguaggi di alto UveJlo. Sbucceremo" un comp uter e daremo uno sguardo alla sua suucrura interna.
lnrrodurremo la programmazione in linguaggio macchina e con quesco scriveremo diversi programmi.
In seguic:o, per fare in modo che sia un'esperienza di parricolare valore, costruiremo un computer
(a erraverso la tecnica della sinzztit1zio1ze sofrwar} sul q u.aJe po tre ce far esegui re i vosc:ri progra 111rr sri rri
in lingu aggio nlacchi na!
7 .18 (Prograrntnazione in lir1g1.1aggio mttcchin) Creeremo ora un computer che cl1jarnererno Simplecron .
Come il suo nome lascia in.cend.er si cratra di una rnacchina semplice, n1a co1ne vedremo presto anche
potente. USimplecron eseguici dei programmi scritci nelJ'unico linguaggio che sia in grado di comprendere
direrramenre., vale a .dire il Linguaggio Macch.ina del Sin1p letron 1 che abbrevieremo in LMS.

Legge una pa rola dal te rminal e e la imma gazzi na i11 una


specifica locazione cli memoria.
Scriv e stil cerm i nale la parol a conr.n ura in tLna speci f ca
locazione di n1ernoria.

Operazioni di carica1nentolirnmagauir11lrr1ento:
#defi ne LOAD 20

In segui uo, per ogni tic delJ orologio (ovve tosia per ciascu na ripetizione del ciclo), visualimerere
una linea di 70 posizioni che mostri una lettera T in quella della ra.n:aruga e una L in quella della lepre.
D i quando in quando, i conre ndenci si ritroveranno nellastessa casella. ln tal caso la c:arcaruga morder
la lepie e il vostro program ma dovE visualizzare OUCH 11 I jn qt1ell~ posizione. Tutte le posizion.i di
visualizzazione diverse da T, L od OUCH 111 dovranno resmre vuoce.
Dopo che ogni linea sar scara visualizzata, controllerete se uno dei due animali abbia raggi unto o
superato la casella 70. Jn caso affermativo visualirz.erere il non1e del ' 'incitare e terniinerece la simul.azion.e.
Nel caso che abbia vi nco la tartaruga v.ispal izzerece "TORTOISE WINSI 11 YAYI 11 ". Nel caso che abbia vinco
la lepre visualizzerete " Hare wins . Yuch . N.1 caso d1c entrambi gli animali ragliassero il traguardo nello
stesso tic dell' o.roJogio, potreste favorire la carcaruga (poverina), oppure porreste visualizzare "It ' s a tie. ''
Nel caso cl1e nessuno dei due ai1imali abbia ancora villtoj eseguire w1'alcra volta il ciclo per simulare il
successivo rie dell'orologio. Radunate un gruppo di tifosi che assisrano alla gara, quando sarece pronti a
mandare in esecuzione il vosrro programma. Il coinvolgimen.co del vostro pubblico vi sorprender.

-.

Carica neli 'accu mu lacorc la pa.rola. conre nut a ia u11a specifi ca


loca:zio11e di memoria.
Arch ivia il conte nuto dell'accu_mulato re in una speci fica
locazione di me1no ria.

Operazioni arit1l1etiche:
#def i ne ADD 30

#defi ne SUBTRACT 31

#def ine DIVIDE 32

#def ine MULTIP LY 33

Aggi Wlge la parol a conrcnLLta in un a speci fica


mem oria a que ll a conre 11tica nel.l 'accun1u laror e
questo il risuJcaco).
Sottr ae la parol a co ncen u ra in una specifica
mem o ria d~ quell a once nuta a ell'ac cumu laror e

locaz ione di
(lasc ianclo in
locaz ione di
(lascianc:Lo in

questo il risuJcaro).
Divid e la paro la conc cnura in una specifica locaz ione di
m~mo ri a per quell a co n.tenu ta nel l 'acct~mulatore (lasci ando in
quesco il risultato).
Molc iplica la pa rola C:onrcnura io una s pecifica locaz ione di
memoria per quella conte nuta neU'accumulaco re (lasciando in
questo il risuJraro).

Operazioni di trasferi1nento del controllo:


Salta a ttnaspecifica locazione di memoria.
#def ine BRANCH 40
#def ine BRANCHNEG 41

#def ine r;3RANCHZERO 42

#def ine HALT 43

Salta a una specifica locai.iene di mem oria, se l'acc um ula'tore


cone ne un valore ncgacivo.
Salra a un a specifica locaz ione di mem oria, se l'acc umul aro re
conriene un valore uguale a ze ro.
Ferm a l'esecuzione del programma.

Figu ra 7 .31 I codci di operazione del Linguaggio Macchina del Sim,p letro n (LMS) .

27 2

CAPCTOLO

273

{ pUN TA TO Rl

~ ulti~1edue ~e di

un' istruzione Uv1S rappresenteranno invece l'oper11ndo, ovverosia l'indirizzo delJ


:l
locaz1~~e di memo~~ che concerr la parola su. cui l'operazio
ne sar applicaca. Consideriamo ora alcuni
semphc1 programmi u1 LMS.

e) Leggete una serie di numeri e detern1inate e visualizzate quell o maggiore.


Il primo numero
letto indicher quanti valori dov ranno essere elaboraci.

7.19

Es em pio I
Locazione
00
01
&:!

00
04

es
es
~

llB

es

Nu me ro

lsb'UZione

+1007

(Legge A)
{Legge B)
(CSricaA nel l 'acclJllJlatore)
(SOOlna B ali ' accu111Jlatore)
(Memorizza il valore del l ' acclJllJlatore in C)
(Staq>a C)
(Halt)
(Variabile A)
(Variabile B)
(Risultato C)

+1006

+2f/llfl
+3008
+2109
+1109
+4300
+0000
+t000
+t000

,. Q~ esco programma in LMS legger due numeri dalla tastiera e calcoler


e visualizzer la loro somma.
J.?,struztone +10 07 legger. il primo numero dalla taStiera e lo inserir nella loca
zione di me moria 07 (che sar
~a Stata 3 ~~ ra) In seguito + ~ 008 legger il secondo 11wn ero
nella locazion e 08. Listrui.ione load, +20 07,
SISten:ier 11 pnmo num~o nell accumulatore, menrre l'istruzione add, +30 08,
aggiunger jj secondo numero
a. que llo CO~ten Ut:() neUac~ unul~tore. Tutte I.e operazioni aritmetic/Je del ling
uaggio LM S lascia120 ii wro
multa~ tiell~ccttmu~tore. LIStnlZ.lone store, -t21 09, riporter
il risul caco nell a locazione di memoria 09 dal la
quaJe l 1scruz1on.e wnte, +11 09, lo prelever e lo visualizzer con1e un numero
decimale di quarno cilr ~
T: A

h
1
segno. ~tn.17Jon e ~ aa, +43 00, terminer r esecuzione del programma.
e con
A

Es em pio l
Locazione

Nu me ro

Ist ruz ion e

+1009

(Legge A)

00
01

+1010

&:!

+2009

+3110

04
E
06

+4107

06

es
10

+1109

+4300
+1110
+4300
-+t000

....

(Legge 8)
>' (carica A nel l' acclJllUlatore)
(Sottrae 8 dal l ' accunlllatore)
(sa lta a 07 se l' accUllllatore negativo)
{Staq>a A)
(Halt)
(Staq>a 8)
(Halt)
(Variabile A)
(Variabile 8)

<:luesto progra m ~a LMS le.gger. due numeri dalla msriera e determine


r e visualizzer quello
magg1o~e ..Osse~ate ~ uso della istr uzione +41 07 con1e un
rrasferimenco di con trollo co ndizionale
molco s~il~ ~J 1sauz1one i f del C. Scrivere ora dei p rogrammi in LM
S che eseguano ognuna delle
seguen ti acuvit.
a) Uti lizzate ~ ci~o con crollaco da un valore sennella per leggere
1O num eri positivi e
calcolare e v1sual1zz.are la loro somma.
b) Utilizzate un ~ido.conrrollaco da un contacore per leggere sette num eri,
positiv i e negativi,
e calcolare e visualizzate la I.oro media.

(Un sim11.latore di computer) Porr sembrare sage:raco, ma con questo eserciz


io coscruirece il
oscro computer. No, non dov rete saldare dei compo nenti. Ulimerete
piuttosto la 'potente tecnica
della simu.lazione sofau.1ar~ per creare un modelw software del Simplecron. No
n rimarrete del usi. LI vostro
simulatore Sim pletron uasfoane.r il computer cl1e scatc utilizzando in un
Simplec:ro n e sar!!te eficcivamente in grado cli eseguire, provare e meaere a pun to i programmi LM
S che avete serino nell 'esercizio 7. 18.
Nel mo mento in cui eseguirete il vostro simula tore Sirnpletron questo dovr
incom inciare
visualizzande:
*** Welcome to Smpletron l

***

Please enter you r prograrn one instruction ***


(or data word) at a time. I wi ll type t he ***
location number nd a quest ion mark (?) . ***
*** You t hen type the word tor tha t location. ***
*** Type the sentin el -99999 to sto p entering *'**
*** your program. ***
Simulate la me moria del Simplecron con il vettore unidimensionale mem
ory di 100 eleme11ci.
5,u ppo aete che il simulatore sia gi in escuzione ed esa min iamo il dialog
o eh.e si svil upper con esso,
ma n ma no che im mectiamo il programma mostrato nell'Esempio 2 dell'Es
ercizio 7.1 8:
00 ? +1 009
01 ? +1 010

02 ? +2009
03? +311 0
04 ? +4107
05? +1109

06 ? ~43 00
07 ? +11 10
08 ? +4300

09 ? +0000
10 ? +0000
11 ? -99999

*** Program loading completed ***


*** Program execution begins ***

O ra che il programma LMS scaroimmesso (o caricato) nel verrore memo


ry, il Sirnplecron provveder a esegui rlo. I; esecuzione co1n incer con l'istruzione nella locazio ne 00
e, come in C, contintter in
mo do sequenziale, sem pre che non si clirami in qualche altra parte del
programma a causa di un
trasferi mento di con trollo.
Ut ilizzare la variabile acc um ula tor per rappresen tare il registro accum ula
tore. Usare la v~ialJile

ins tru ct on co un ter per conservare- l'indirizzo di memoria in cui sar


conten uta l'istruzion e da
esegui re. Ucilizzace la variabile o.p era tio nC od e per indicare l'operazio ne
da eseguire, ovverosia le du~
cifre a sinistra nella parola dell'istruzione. Usate la variabile ope ran d
per indicare la locazio ne di
memo ria su cui o,perer 11iscru.zione corren te. 1n alrri cermin i, ope ran d cor
risponder al le due cifre pi
a descra dell'is auz.ione da eseguire. No n eseguite d.irercamente le istruzioni
contenuce nella mmoria.
Trasferire piuttosto q_uella da esegui re dal la memoria in una variab ile chiam
ata ins tru cti on Re gis ter .
ln seguito "staccherete" le due cifre di sinisaa per sistemarle in ope rat ion
Co de e "separerete" le due
cifre di destra per siscernarle in ope ran d.
Nel mo mento in cui il Sirnplerroo comincer l'esecu"Lio ne i registri spe
ciali SaraJ,1110 dun que
inizializzati nel modo seguenre:

'
I

274

CAPITOLO

+0000
00
+0000

accumulator
instructionCounter
instructionRegister
operationCode
operand

00

instructionCounter - operrand;
AEGISIERS:
accuiWatot" +0109

~ memory[ instructionCounter];

11 codice dell'operazione e I'operando saran110 estrarri dal registro delle istruzioni con:
operationCode = instructionRegister I 100;
operand =instructionRegister % 100;
O ra il Simplerroo in grado di determinare che il codice dell 'operazione co rrisponde in realc a
una rend (e no n a una write, una l.oad, ecc.). Una srrurtura swi tch discinguer le dodici operazioni dcl
linguaggio LMS.
Al l'interno della srrurrura swi t ch il comportamenco delle varie istruzioni sar simulato nel n1odo
seguente (lasciamo a voi ) alrre iscruzioni):

read:
load:
add:

tr" di istruzioni. Di conseguenza, l'istruzione di salto incondizionato (40) sar simulara all' interno
ddla suurrura switch con:

00

Ora "seguiamo'' l'esecuzio11e della prima isrruzione LMS: il +1009 sisremaro nella locazione di
memoria 00. Quello che seguiremo derto ciclo di esecztZione deii'struztze.
La variabile instruct i onCounter ci indica la locazione della prossima istruzione da eseguire.
"Preleveren10" dunque il contenuto di quella posizior1e dal vettore memory usa.ndo l'istruzione C:
instructionRegister

275

scanf ( "%d 1 &rnemory [operand] ) ;


accumulator = memory[operand];
accumulator +~ memory [operand) ;

Varie istruzioni di salto: ne discuteremo tra breve.


Questa i struzione visualizza il messaggio
**"' Simpletron execution terminated ***

halt:

e in segujco visualizzer'd il nome e il conrenuto di tutti i registri, cos co rne quello di rurca.1a memori a.
Un output di questo genere spesso chiamato dtttnp del cornpiJ.ter (ovverosia deposito del computer,
che no.n per il posto dove vanno a fmire i vecchi compurer). Per aiutarVi a irn.plmenrare la vostra
funzione dj durnp nella Figura 7.32 abbiamo riportato un esempi.o per il forn1aro dcl dump. Osservare che un dump esegillro alla fi ne d~U'csecuzione di un progran1ma Simplerron dovrebbe moscrare
i valori corre.ari delle iscruzionj e dei dari, cosl come sono in quel momento.
Procediamo con lesecuzione della prima isrruzione del nostro programma, vale a dire la + 1009 della
pos.iz.iot1e 00. Come abbiamo affermato prima, la struttura s wi t ch la simuler eseguendo l'istruzione e
scanf ( "%d 1 &memory [operand] ) ;
Prima che la funzione s canf sia esegui ca, dovr essere visualizzato un punr.o interrogativo(?) per
richjedere l'inpur dell'ucerite. Il Simpletron accender che l'utene.e immena u:n valore e prema iJ
tnsto invio. A quel punto il valore sar sistemato nella locazione 09.
La simulazione della prima istruzione stata fu1almcnce completata. Ci rimane soJo la preparazione del Simpletron all'esecuzione cieli.a prossima iscrw.ione. Dato che l' iscruz.lone appena esegwca 11on
era un trasferimento di controllo, avremo semplicen1ence bisogno di incremenrate il registro contacorc
dell.e istruzioni, nel modo seguente:
++instructionCounter;
Questo passo compi.eta davvero l'esecuzione sim ulata della prima istruzione. L..J1cero processo
(ovverosia il ciclo di esectJZione dell' istruzione) ricomincer nuovamence con il rcupero della prossima
istruzione da eseguire.
Ora esan1iniamo in che modo saranno sin1ulace le iscruzioni di salco, ovverosia i rrasferimenci cl.i
conrrollo. Ln effetti, sar necessario solo aggiornare in modo appropr:iaro il valore contenuto nel conca-

9
..., .......... ~ ........ +Me +00110 ~ . . .
+8010
te +eeee ..... ~ ........... +teee .. . .
a +eee ~ w +eeee t0111 +.a 1eeee +eeee +eeee +teee +eeee
0

+
.............. .................... ....
~

.............. .. . +eeee . . . +e801 "tl888 . . . . . . .

se .... ,..., .... ............ +8080

V. . .

. ....

.. .

61 ......... .. . . . . . . . . . . +8888 ,. . , . . . . +011188 ....


79 . . . . . . .. . . . . . . .. . . .. . . . . iMll .... +8010
. .. . . . . . . . . . .. . +1108 ........ ftee8 . . . .. . .

se ~ +ea eeee

0180

eeee....,.. -tteee +9000 +eeee +eeee

Figura 7.32 Un esempio di dump.


l.!istruzio,ne condizionale "salto se l'accum.ulato.r~ uguale a zero" sar simulata con:
if (accumul ator = 0)
instructioncounter

= operand;

A.questo punto, dovreste essere ia grado di in1plementare il vosrro simulatore di Simplecron e di


seguire ogL1uno dei programmi LMS che avete scritto nd.L'Esercizio 7 .18. Porrete abbellire il linguaggio lMS con delle caratcerisciche aggiuntive e implemntarle nel vostro sim ulatore.
Il vostro simulacore dovr efferruare dei con crolli per vari ripidi errore. Per esempio, du.ran ce la fase
di earicamento del programma, ogni numero che l'utente tenter di immettere ne.I verrore memory del
Simpletroo dovr essere compreso ne.ll' inrervallo da -9999 a +9999. IJ vostro simularore dovr quindi
ucilin.are un ciclo while per controllare che ogni numero immesso sia compreso in que.ll' incervallo e,
in easo contrario, continuare a richiederlo all' utente finch non n e avr immesso uno corretto.
D urante I.a fase di esecuzione, il vostro simulatore dovr effettuare dei controlli per vari errori
gravi, come i tentativi di eseguire de.Ile divisioni per zero o di eseguire dei codici di operazione non
validi. il su.peramenco della capacit dell'accumulacore (owerosia le operazioni arirmeriche che producono valori maggiori di +9999 o minori di -9999) e altre cose simili. Insonuna. occorrer gestic gli
errorifaU1li. Nel momento in cui avr inrercercaco un e.rior.e facale, il voscro simulatore dovr visualizza.re
un rn~~aggio di errore come:
*** Attempt to divide by zero ***
*** Simpletron execution abnormally te.rrninated ***

e ~isual i:zzare un dump completo del computer nel formato di cu abbiamo discusso in precedenza.
Ci aiuter l1urente a individuare l'errore dd programma.

7.20 Modificate il programma di mescolamento e distribuzione delle carte proposto nella Figura 7.24, in modo che le sudderre operazioni siano eseguire da una funzi.o ne unica (s huffleAndDeal).

C'\PJTOLO

276

Questa dovr contenere una srrurrura di iterazione nidificata simile a quella d~lla funzione s huff l e
mostra ca nella Figura 7 .24.
7 .21

277

I ptJNTATORl

7.23 Trovare l'errore in ognuno dei seguenti segmenti di programma. Spiegate in che modo sar
possibile correggerlo, sempre che lo sia.

a) int number;

Che cosa far quesro programma?

printf ( "%d\ n", *number);

#include <stdio.h>

b ) float *realPtr;
long integerPtr;
integerptr = realptr;

void mystery1(char *, const char *);

o) int * x, Yi
X =y;

main()
{

char string1 (80] J s't ritlg2(80);

d) char s [ J = uthis is a character array" ;


int count;
for ( ; *s I= '\0 ' ; s++)
printf ( 1'%c " , *s) ;

printf ("Enter two strings: ~) ;


scanf("%s%s", str.ing1, string2);
mystery1 (string1, string2);
printf( "%s\n" 1 string1);
return 0;

e) short *numPtr, result;


void *genericPtr = numptr;
result = *genericPtr + 7;

void mystery1(char *s1, const char *s2)

f) float x = 19.34;
f loat xptr = &x;

while (*s1 I= \0 ')


++s1;

printf( "%f\n", xPtr);

g) char *s;
for ( ; s1 =*s2; s1 ++, s2++)

/*istruzione vuota ~1
}

7.22

'

Che cosa far

qu~o

programma?

#include <stdio.h>
int mystery2(const char

~}i
I

main()
{
char string[80);

printf( "Enter a string: "};


scanf ( "%s , string) i
printf ('\d\n", mystery2(string));
return 0 ;
}

int mystery2(cnst char *s)


{

int X = 0j
far ( ; s I= '\0
++x;
return x;

st+)

printf( "%s\n", s);

(Quicksort) Negli esempi e negli esercizi dd Capitolo 6 abbiamo discusso le tecniche di ordinamenro a bolle (bubble sorr), di bucker sorc e pei: selezione (scleccion sorc). Presenteremo ora una cecn_ic~
(iCQJSivadi ordinamento cb.iamata Quicksort (ordinamento veloce). Valgorirm.o fondamentale per un
vettore di valori un idime11sionale il seguente:
1) />asso di ripartizione: prendere il primo elemento di un vettore disordinato e determinate la
sua posizione fLnale in quello ordinato. Ci avverr quando rutti i vaJori dd sorcovettore
sinistro, rispetto all'elemento, gli saranno inferiori e rutti quelli del sorcoverrore desrro gli
saranno superiori. A questo punro avremo undemenro sisremaro nella sua giusc:a posizione
e due sorrovercori disordinaci.
2) Posso ricorsivo: eseguite iJ passo 1 su ogni sotcoverrore disordinato.
Ogni volra che il passo 1 sar eseguito su un sottoverrore, un aluo elemento sar siscen1aro nella sua
posizione finale all'inrecno del vettore ordinaco e saranno creati due sorcovertori disordinati. Considerei:emo sicuramente ordinato un sorcovercore che sia formato da un solo elemento e, di conseguenza,
que-sro sar gi nella sua posizione finale.
Calgoriano di base sembra abbascanza semplice, ma in che modo determineremo la posizione
finale del primo elemento di ogni sorcovectore? Come esempio, consideriamo il seguente gruppo di
valori (l'elemento in grasserco quello urilizzaro per la riparrizio11e, ovverosia, quello che sar siscemato
nella sua posizione finale all'interno del vettore ordinato):

7.24

37 2 6 4 89 8 10 12 68 45

1) Partendo da quello pi a descra neJ vettore_,eoofroarate ogni elemento co n il 37 finch no,n

ne rroviace uno mil1ore che scambierete di posco coii il 37. Il primo elemento 1ninore cli 37
12, perci 37 e 12 saran no scambiaci di posto. Il nuovovercore sar:

}
12 2 6 4 89 8 10 37 68 45

LeJemenro 12 in corsivo per ricordare che stato appena scarnbiaro di posco con il 37.

27 8

CAPl1"0 LO

J PUNTATORJ

dd vecrore, ma cominciando da quello successi"vio aJ 12 con fjronrare


2) Parrendo dalla sinisrra

il
zare
aliz
visu
r
dov
e
zion
fun
La
.
orso
perc
del
lla
case
i
ogn
n
i.
x
e
crer
cara
il
rire
labirinro, dovr inse
o.
labirinto dopo ogni mossa cosl che l' urea.te possa seguire la risoluzione del labirint
argo1e
con
va
rice
che
r
rato
ene
zeG
ma
e
zion
fi1n
una
e
iver
Scr
i)
rint
labi
di
tale
cnsi
rle
7.26 (Generttzio
he
anc
r
dov
e
zion
fun
La
.
caso
a
o
rinc
labi
un
a
duc
pro
e
12
per
12
i
tter
cara
di
ce
mento una marri
delrse
ave
eTr
maz
e
zion
fun
rra
vos
la
vare
Pro
o.
rint
labi
dd
ita
usc
di
e
esso
ingr
di
restituire i punti
l'Esercizio 7.25 ucilizzando vari labirinci generaci a caso.
zeGenerator
ma
e
erse
rav
zeT
ma
i
zion
fun
le
ce
iz.ta
eral
Gen
e)
n
n
ensi
dim
si
lria
qua
di
nti
biri
7.27 (La
zza.
gli Esercizi 7.25 e 7.2 6, in modo da elaborare labirinti di qualsiasi larghezza e alre


. d. posto con
ogni e eme nto con il 37 finch non ne troviate uno maggiore cl1e scamb1e 1.ere
1
li
il
to. 11
pos
di
aci
mbi
sca
i1no
sara
89
e
37
i
perc
89,

37
di
e
gior
mag
o
ent
elem
o
prim
37.
nuo'.IO vecrore sar:
12 2 6 4 37 8 10 89 68 45

ogni eletare
fron
con
89,
a
nte
ede
prec
llo
que
da
do
a_n
inci
com
,ma
tra,
des
a
d~l
o
tend
Par
3)
37. Il
il
n
co.
to
pos
di
ce
iere
amb
c
sche
ore
min
uno
are
1
crov
e
n.
no~
he
f~c
37
il
con
m~nto
u nuov0
primo demenco m1Dore di 37 10, perci 37 e IO sa ran no scambiaci di posto.
verro re sar:

12 2 6 4 10 8 37 89 68 45

I
fro
con
10
al
ivo
cess
suc
llo
que
da
o
and
inci
con1
ma
,
stra
sini
a
dall
o
tend
Par
4)
nrace ogru e e,
.
fi h
- 1J
il 37. Ln
men co con 37 ~c non n~ rrov1ace uno ma,ggiore che sunbierece di posto con
co
questo caso non c1 sono alrr1 elementi maggiori di 37 perci>confrontando il 37
se
sres~o, sapren10 che sar gi stato siscemaco nella sua posizione finale all 'interno del vercnore
ordinaco.
ccori
rove
soc
due
nno
sara
ci
,
ione
rtiz
ripa
a
L
ta
lica
app
a
stat
sar
ore
vert
co
dec
sud
aJ
. U.na ~olca che
d v.aJ ori
.
8
10
4
6
.,
12

rerr
cn
37
di
ori
min
ri
valo
dei

ttor
ove
sorr
Il
e1
ac1.
o
qu
d1so rd1n
cre
men
,
e
~ ,
,
,
.J:

1
d
p
que
dun
'
ra
dov
ento
inam
ord
di
3
o
ion
gor
I:al
45.
e
68
89,
a
0 ce ere con a
magg1or1 w 7 conterr
r

b
dJ

U . al
ripartwone .enrram 11sorrovenori nello sresso modo ucilizzaro per riparcire que 0 ongin e.
d

Basandovi sulla d"1scuss1o


di
eh
ort
cks
qui
a
rsiv
rico
e
zion
fun
una
vere
scri
e
ent
e
prec
ne
. .
enti un ~;re;~~
om
arg
e
com
ere
ri~
r
dov
e
zion
fun
La
ri.
ince
..ri
valo
di
aJe
si~n
e?
t~
un
cro~~
\riaJ

di pare . a e uno di fiine. La fu nzio


v ori LDter1 ' un 1nd1ce
rich iamata da
re
esse
r
dov
n
tio
rti
pa
ne
enz
.
.
i k

.
ione
rriz
ripa
dJ
so
pas
11
wre
eseg
per
t
qu e sor

ell

di un labirinto
2
e
ion
nraz
rese
rapp
la

te
uen
seg
lia
grig
La
o)
rint
labi
t'n
di
o
e1'it
rsam
rave
(Att
7. 5
all 'interno di una marrice.
1 11 11 1 11 1 11 1
1000 1000000 1
00 10 10 11 , , 0 1
1110 10000 l 0 1
10000 1110 100
1 1 11 0 10 1 0 10 1
100 10 10 1010 1
11 0 10 10 10 10 1
100000000 10 1
111111011101
1000000 1000 1
1 11 11 1 1 11 1 11

o.
I num~i uno e zero ~appresenran-0 r.ispecrivamenre le pareri e i corridoi del labirint
il ritrovamento
, ~te un semplice algorinn o di attraversamenro di un lab.irinro che garanris
pun ro
al
vo
nuo
di
sre
vere
rirro
vi
e
foss
ci
non
cita
l'us
che
caso
Nel
.
)
una
sia
ne
ce
che
usa a (s;mpr~
in avanri
are
min
cam
a
ace
inc
com
e
rra
des
rra
vos
alla
re
pare
a
sull
tra
des
o
man
la
a~e
oggi
_par~enza.
rra .
des
a
ro
mu
il
ce
ui
seg
tra,
des
a
lra
svo
o
rint
labi
il
Se
re.
pare
a
dall
o
man
ra
vosc
!a
~n fi'muo~ere mai
vosrr~
la
osso
rim
te
avre
non
po
rem
fcar
nel
se
o,
rint
labi
del
a
s~t
all'u
re
me~
ura
s1c
te
vere
a me arri
so ma in
apr
inrr
re
ave
che
llo
que
di
e
brev
pi
o
cors
per
un
ta
esis
chile
bab
pro

e.
arer
mano dal ladp
'
quesco mo o avrete la cercqza di uscire daJ labirinco.

u
La.f
nco
biri
illa
sare
vec
arua
per
se
r
ave
eTr
maz
a
rsiv
rico
e
.ion
Scrivere la funz
ov:r: r.1.ceveone
nz.1.
.
di
.
.
re come ar
ne di
izio
pos
la
e
o,
rint
labi
il
re
enta
pres
rap
per
12,
per
12
i
tter
cara
nce
mat
una
g~m ena
.
l'uscira dal
e
uar
ivid
ind
di
er
tent
e
ers
rav
zeT
ma
che
o
man
n
Ma
so.
stes
o
dell
rno
mre
partenza all

1ell

279

ll modo da uriliz.2
6.2
ura
Fig
a
dell
a
mm
gra
pro
il
ere
criv
Ris
i)
zion
fun
a
ri
tato
pun
di
ori
Vtt
(
7 .28
ti 4 opzioni:
uen
seg
le
te
uren
all'
ire
offr
r
dov
a
mm
gra
pro
1
1
u.
men
da
data
gui
ia
acc
cerf
n
urii
zare

Enter a cb()i ee :
'

e Pr'l nt th array of grade&


1 Find the mininu!J grade
2 Find ttle nlSX:i nun grade
3 Pri nt t~ average on all tes ts for each student
4

EAd prt>,gram

.,

essere dello
ono
dev
ri
tato
pun
i
i
rutt
che

i
zion
fun
a
ri
tato
pun
di
ori
vett
di
zo
riliz
all'u
one
Una restrizi
stesso tipo
lo
e
cucc
no
isca
itu
rest
che
i
zion
fwi
a
ri
tato
pun
dei
re
esse
ono
dev
a,
enz
segu
Con
Di
stesso tipo.
ura 6.2 2
Fig
la
i
ne.
i
zion
fun
le
,
one
ragi
sta
que
Per
.
tipo
so
stes
o
dell
enti
om
arg
o
evan
..ric
di dato e che
o i medesim i
van
rice
e
dato
di
tipo
so
stes
lo
o
scan
itui
rest
che
o
mod
in
cate
difi
mo
re
esse
no
dovran
valore minimo e
il
zino
aliz
visu
che
do
mo
in
imum
max
e
m
imu
min
i
zion
fun
le
cate
difi
Mo
tri.
parame
ave rag e della
oe
z.io
fui1
la
ate
ific
mod
3,
e
zion
l'op
Per
re.
nien
o
scan
irui
rest
non
e
o
sim
mas
quello
uno specifico).
di
lla
que
che
ece
(inv
e
ent
stud
i
ogn
di
ia
med
la
pur
our
in
i
invi
che
do
mo
in
2
6.2
Figura
di pri ntA rra y,
tri
ame
par
si
stes
gli.

ver
rice
e
daco
sun
nes
re
itui
rest
r
dov
non
e
rag
ave
ne
zio
La fun
e
s
ade
sGr
ces
pro
ore
vett
nel
i
ion
funz
ttro
qua
alle
ri
tato
pun
i
ate
zzin
aga
minimum e maximum. Imm
fi1nzio ni.
utilizzare la sce:lta effettuata dall'urente come indice di vettore per richiamare le
e
war
soft
e
ion
ulaz
sim
una
tto
scri
e
aver
l9
7.
zio
erci
l'Es
Nel
ron)
plet
Sinz
ore
itlat
7 .28 (Modifihe al sim
(LMS). l n quesro
di un computer che esegue i programmi scritti nel Linguaggio Macch in-a Sin1plerron
26
12.
i
rciz
Ese
li
Neg
.
ron
plet
Sim
ore
ttlat
Sim
al
nti
ame
lior
mig
e
he
ific
mod
rse
esercizio, proporremo dive
liJ1un
in
rri
scri
i
mm
gra
pro
i
tir
ver
con
che
rore
pila
com
un
di
e
ion
truz
cos
la
o
e 12.27, proporrem
. Alcune
ron
pler
Sim
del
ina
cch
Ma
ggio
gua
Lin
nel
)
SIC
BA
del
ante
vari
a
(un
llo
live
guaggio ad alto
ni dal
o
d.
pro
i
mm
gra
pro
i
uire
eseg
pr
rie
essa
nec
re
esse
no
ran
pot
ie
lior
mig
e
che
dii
delle seguenti mo
compilacore.
ren.ere 1000
con
sa
pos
che
do
mo
in
,
ron
pler
sim
ore
ulat
Sim
del
oria
mem
la
ere
end
Est
a)
locazioni e consenrire al Simplerron di gestire programmi pi corposi.
rio aggiun essa
nec

Sar
o.
dul
mo
dd
olo
calc
il
uire
eseg
sa
pos
ore
ular
sim
il
che
do
mo
in
Fate
b)
gere un'istruzione al Linguaggio Macchina Simplecron.
n.ecessario
Sar
a.
enz
pot
a
o
enc
vam
l'cle
e
olar
calc
sa
pos
ore
ular
sim
il
che
do
mo
1
i1
Fare
c)
aggiungere un'istruzione al Linguaggio Macchina Simpletron.
que lli interi,
di
ce
inve
ali.
ecim
esad
ri
valo
dei
i
z
iz.
util
che
do
mo
in
ore
ulat
sim
il
cate
difi
Mo
d)
per rap.prese ncare le istruzioni del Linguaggio Macchina Simpletron.
line. Sar
e) Modificare il simulatore per consen rire la visualizzazione di un caratrere nw
necessario agginngere un'istruzio ne al Linguaggio Macch ina Simplerron.
virgola n1obi le
f) Modificare il sirnularore in modo che possa efaborare anche d.ei valori in
oltre a quelli interi.
ogni
g) Modificate il simulatore in modo che possa gestire l'input di srringhe. Suggerimenro:
intero
parola del Simplecron porr essere suddivisa in due gruppi concen enci ognuno un

\
280

CAPITOLO

di due cifre. Ogni inrero di due cifre rappresenter il vaJore decima'le ASCIJ cquivale1ire a
un. cararrer~ Aggiun?e ~: un'istruzi?ne in linguaggio mac d1in a che prenda in input una
srnn ~a e la 1mrn_agazz Lru ,m una specLfca locaz.ione della men1 oria del Simplerron. In qu ella
locauon~, la pr:1m a. mera della par~ la conterr il nLm1e.ro di caratteri inlusi nella srrio ga
(ovverosia, la sua lunghezza). Ogru me-zza parola successiva conterr un cararrere ASCU
e_s~resso. con un valo re decimale di due cifre . I.:isrruzione in linguaggio machina ~conver
t1ra o_gru c~tt~e nel suo equivalente ASCII e lo assegner alla mezz a parola.
b) Mod afi.cac e il _s1mulacore in modo che gesti sca l'ourpur deUe stringhe immagazzinate nel
f~rm ato des~ucr~ n~Ua parce_(g). Suggeri.mento: aggiungere al linguaggio macchina uniiscruz~one che visual1zz1 una scnnga com inciando da una cena locazione della memori2 dcl
~1 mp~tron. ln ~uella locazione, la prima met della parola co nterr il numero dei cararreri
lnclus1 nella srnnga (owerosia, la sua lung.h.ezza). Ogni mezza parola successiva conterr
un car~rrere ASCII C:Spresso con un v~lore decimale di due cifre. I..: istruzione in lingt.iaggio
~accbina co.nrrollera la l.unghezza e visualizzer la stringa, rraducendo ogni nu 111ero di due
cifre nel caraet~re equJvalence.

7 .30

CA PIT OL O

I ca ra tt er i e le stringhe
Ob iet tiv i

Che cosa far il seguente programma?


#include <stdio.h>

int mystery3 (const char *, const char *) ;

main ()
{

Essere in grad o di utilizzare le funzioni incluse nella libre ria per la


man ipol azio ne dei caratteri (cty pe).
Essere in grad o di ntiliu..are le fi1nzioni per l'inp ut/o utpu t delle strin ghe e dei
caratteri, incluse nella libre ria per l'inp ut/o u.t put star)dard (std io).
Essere in grad o di utilizzare le funzioni per la conversione delle strin ghe,
incluse nella Jibreria di utili t stan dard (std lib).
Essere in grad o di utilizzare le fi1nzioni per l'elaborazione dell e strin ghe,
incluse nella libreria per la man ipol azio ne delle strin ghe (str ing ).
Apprezzare la pote nza insit a nelle librerie di funzioni com e un mezzo per
otte nere la rius abil it del software.

char strin g1[80J, string2[80J;


prin tf( "Ente r two strin gs: ");
scanf('1%s%S, stringl , string2);
prin tf ("The resu lt is %d\n", mystery3(string1, string2)} ;

8.1

return 0I

1n ques to capi tolo pres ente rem le funz ioni incluse nella libreria Stan dard del C che sem -

i nt mystery3(const ohar *sl, const char *s2)


I

for ( ; *s1 I= '\0' && *s2 I= '\0' ; s1++, s2++)


if (*s1 I= *s2)
return 0;
\

Int rod uz ion e

plifi cano l,ela boia zion e delle strin ghe e dei cara tteri . Tali fi1nzioni co nsen tiran no al program ma di elab orar e i cara tteri, le strin ghe, le righ e di cesto e i bloc chi di mem oria .
Il capi tolo disc uter delle cecniche ucilizzate per svilu ppar e gli edic or di tes co, i wor d
processo r, i softw are per !~impaginazione, i siste mi com pute rizz aci .P er la co m posi zio ne
tipo graf ica e alui tipi di softw are per l'ela bora zion e dei tes . Le man ipol azio ni del res to
eseguire dalle fi1nz ioni per rinp ut/o utpu t form attat o, com e prin cf e scan f, potr anno essere
imp leme ntat e utilizzando le funz ioni discusse in ques to capi tolo.

return 1;
}

8.2

I concetti fondamentali delle stringhe


e dei car att eri

I cara tteri sono i m atto ncin i fond ame ntal i per la costrll2one dei program mi sorg enti .
Ogn i prog ram ma form ato da una sequ enza di caratteri che, qual ora sian o raggrupp ati in
mod o sign ifica tivo, sar inte rpre tata dal com pute r com e una serie di istru zion i da utili zzare per svol gere un com pito . Un prog ram ma potr cont ener e delle costanti di carattere. Queste
sono dei valo ri int rapp resen tati da un caranere post o tra apic i sing oli. li valo re della
cost ante di cara ttere co rrisp onde all' inte ro che gli sar stato asso ciato nell ' insi_e me dei
cara tteri della mac chin a. P er.esemp io 'z' rapp rese nc il valore inte ro di z e ' \n' quel lo
del cara ttere new line.

282

CAPITOLO

Una string a u11a serie di caratte ri trattat i come una singola unir. Una stringa potr
includ ere leuere , numer i e vari caratteri speciali com e +, - , *, / , $ e ranci altri. Nel lingua ggio C, le stringhe letterali o costanti di stringa si scrivo no tra virgol erre, co me nei se

guent i esemp i:
"John Q. Doe"
"99999 Main Street "
Walthal'I\, Massa chuset ts"
"(201) 555-12 12"

CARA1TE.RJ E LE STRINGHE

Buona abit11dirle 8.1


Assicuratevi che il vettore di caratteri iri cui immagazzi1zerete le vostre stringhe sia
dimensionato in trlodo tale da poter co11tenere qieella pit lztnga. ne n01'l pone li1niti lllla
li-tnghe:zza delle stringhe immagazzinate. Nei c~~ cl1