473
Imparare il C una guida per Linux V. 1.7 Marco Latini - Paolo Lulli 22 novembre 2006

Imparare c

Embed Size (px)

DESCRIPTION

libro sul linguaggio C

Citation preview

ImparareilCuna guida per LinuxV. 1.7Marco Latini - Paolo Lulli22novembre2006Lapresentepubblicazione`eredattaconlamaggiorcurachesi `eresapossibileagliautori;ci`onontogliechepossanoesserepresentierroriesviste,perlequaliringraziamo anticipatamente quanti hanno provveduto o avranno la sensibilit`a diportarceneaconoscenza.Atalescopo, incoraggiamocaldamenteil lettoreafarci pervenireogni tipodi commentoecorrezionecheritengautilefarci. Riteniamoassai utileper lacrescitadelloperaelutilit`adellasuadiusione.Nel faretaleinvito, riportiamoqui di seguitoi nostri recapiti di postaelet-tronica, unitamenteadunaprecisazionechepotrebberisultareassai utilesiaavoi, per trovarelinterlocutoreideale, siaanoi per correggereeventuali errori;ciascunodeidueautorihacuratospecicamentedeicapitolipiuttostochealtri;linformazione su quali di questi capitoli abbia curato ciascuno, `e accuratamenteriportatainunatabellaallanedellopera, inmodotaleche, overiteniatene-cessariofaredelleosservazioni,possiateottenereconmaggiorecelerit`aloscopochevipreggete.Pergli eventuali errori e/osviste,chepure,nonostantelanostradedizione,dovessero aiggere la presente pubblicazione, purtroppo non possiamo assumercialcunaresponsabilit`a, enonpotreteritenerci responsabili innessunmodo, oveesempi di codicequi suggeriti vi recasserounqualchegeneredi dannochetut-taviatendiamoragionevolmenteadescludere.MarcoLatinila.marco@tiscalinet.itPaoloLulliblacksheep@lulli.netImparareilCpag.IIIcopyrightPermission is granted to copy, distribute and/or modify this document under thetermsoftheGNUFreeDocumentationLicense,Version1.1oranylaterversionpublishedbytheFreeSoftwareFoundation; withtheInvariant Sections beingjustGliAutoriwiththefront-CoverTextbeing:ImparareilCunaguidaperLinuxMarcoLatini-PaoloLulliand anything before this section, following the title itself. There are no Back-CoverTexts.AcopyinofthelicenseisincludedintheAppendixentitledGNUFreeDocumentationLicense.Atuttelepersonechelottanoperleproprieidee.Nonsietesoli.MarcoLatiniAtutteledonneliberedallaschiavit` uculturaledegliuomini.Atuttigliuominiliberidallarroganzadel potereedellearmi.PaoloLulliImparareilCpag.VGliautoriMarcoLatiniStudentediIngegneriaInformaticaallUniversit`aLaSapienzadiRoma.Membroattivodel LUGRomasi `eavvicinatoallaprogrammazionedacirca4anni co-minciando, per questioni didattiche da lui indipendenti, col Pascal e col Fortran.Avvicinatosi successivamente al mondo del Free Software ha rivolto la sua atten-zione verso linguaggi certamente pi u utilizzati quali C, C++, Java, PHP restandoestremamentecolpitodallestremaecienzadel primoedallapossibilit`adi in-tervenirepraticamenteovunqueinLinuxtramitetalelinguaggio.`EcoautoredelLateX-PDF-HOWTOedhapartecipatoattivamenteal LinuxDaycurato, nellacapitale,dalLUGRoma.Attualmente `eimpegnatonellampliamentoerevisionedella presente opera e nello studio Programmazione 3D tramite le librerie MESA,naturalmenteinambienteLinux.la.marco@tiscalinet.itPaoloLulliEstudentedi IngegneriaAerospazialepressoluniversit`adi RomaLaSapienza.HaprodottoediusoconlicenzaGNU/FDLdelladocumentazionesul trasferi-mento di dati tra calcolatrici HP e sistemi Linux/Unix; si diletta ad automatizzarein Perl tutto quello che sarebbe troppo noioso fare a mano. Per studio, ha avutomodo di conoscere il Pascal, che non ha mai amato. Di qui, `e nata la ricerca perunlinguaggiochepermettesseunalibert`aespressivail pi upossibileampia,del-laqualenecessita,pi uingenerale,ogni formadi comunicazione.Lespressione`eunbisognofondamentaledelluomo, eperchenondiventi appannaggiodiunaristrettacastasacerdotaledispecialistiaventidiritto,latecnicapropriadei canali di comunicazione deve essere di pubblico dominio; perche non restiprivilegiodipochipoteresprimereil proprioliberopensiero.blacksheeplulli.netVIIndiceI Unprimoapproccio 11 Introduzione 31.1 DueparolesulC . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Ilnecessario . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2.1 Tuttiglistrumenti . . . . . . . . . . . . . . . . . . . 41.3 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Iniziare 72.1 Ilprimoprogramma . . . . . . . . . . . . . . . . . . . . . . . 72.1.1 Icommenti . . . . . . . . . . . . . . . . . . . . . . . . 82.1.2 Gliinclude . . . . . . . . . . . . . . . . . . . . . . . . . 82.1.3 ilMain. . . . . . . . . . . . . . . . . . . . . . . . . . . 92.1.4 printf():unafunzione . . . . . . . . . . . . . . . . . 92.2 Ilsecondoprogramma . . . . . . . . . . . . . . . . . . . . . . 92.2.1 Levariabilieilorotipi . . . . . . . . . . . . . . . . . . 102.2.2 Itipiscalari . . . . . . . . . . . . . . . . . . . . . . . . 112.2.3 Glispecicatoridiformato. . . . . . . . . . . . . . . . 112.3 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14II Lecaratteristichestandarddellinguaggio 153 Operatorieistruzionidicontrollo 173.1 Glioperatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173.1.1 Precisazionisulleoperazionidilogicabooleana. . . . . 193.2 Loperazionedicasting . . . . . . . . . . . . . . . . . . . . . . 203.3 Listruzionecondizionaleif . . . . . . . . . . . . . . . . . . . 213.4 Unalternativascarna:glioperatori? :. . . . . . . . . . . . . 223.5 Sceltemultipleconswitch. . . . . . . . . . . . . . . . . . . . 233.6 Ilciclowhile . . . . . . . . . . . . . . . . . . . . . . . . . . . 253.7 Ilciclodo... while . . . . . . . . . . . . . . . . . . . . . . . 26VIII INDICE3.8 Ilciclofor . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.9 Ilfamigeratogoto . . . . . . . . . . . . . . . . . . . . . . . . 284 Tipididaticomplessi 294.1 Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294.1.1 Passareparametrialmain . . . . . . . . . . . . . . . . 314.2 Struttureeunioni . . . . . . . . . . . . . . . . . . . . . . . . . 324.3 Unautileestensionedellestruct:Icampidibit . . . . . . . . 334.3.1 Lakeywordtypedef . . . . . . . . . . . . . . . . . . . . 355 Ipuntatori 375.1 Alcuneconsiderazioni . . . . . . . . . . . . . . . . . . . . . . . 375.2 Dichiarazionediunpuntatore . . . . . . . . . . . . . . . . . . 375.3 Operatorisuipuntatori . . . . . . . . . . . . . . . . . . . . . . 376 InputeOutputsule 417 Denizioneedusodellefunzioni 457.1 Funzionidenitedallutente . . . . . . . . . . . . . . . . . . . 457.2 Ipuntatoriafunzione . . . . . . . . . . . . . . . . . . . . . . . 477.3 GliheaderstandardANSIelefunzionidilibreria . . . . . . . 507.3.1 assert.h . . . . . . . . . . . . . . . . . . . . . . . . . 507.3.2 ctype.h . . . . . . . . . . . . . . . . . . . . . . . . . . 507.3.3 errno.h . . . . . . . . . . . . . . . . . . . . . . . . . . 507.3.4 float.h . . . . . . . . . . . . . . . . . . . . . . . . . . 517.3.5 limits.h . . . . . . . . . . . . . . . . . . . . . . . . . 517.3.6 locale.h . . . . . . . . . . . . . . . . . . . . . . . . . 517.3.7 math.h. . . . . . . . . . . . . . . . . . . . . . . . . . . 517.3.8 setjmp.h . . . . . . . . . . . . . . . . . . . . . . . . . 527.3.9 signal.h . . . . . . . . . . . . . . . . . . . . . . . . . 527.3.10 stdarg.h . . . . . . . . . . . . . . . . . . . . . . . . . 527.3.11 stddef.h . . . . . . . . . . . . . . . . . . . . . . . . . 527.3.12 stdio.h . . . . . . . . . . . . . . . . . . . . . . . . . . 527.3.13 stdlib.h . . . . . . . . . . . . . . . . . . . . . . . . . 537.3.14 string.h . . . . . . . . . . . . . . . . . . . . . . . . . 547.3.15 time.h. . . . . . . . . . . . . . . . . . . . . . . . . . . 558 Compilazioneseparata 57INDICE ImparareilCpag.IX9 Allocazionedinamicadellamemoria 599.1 Allocazionedinamicadellamemoria. . . . . . . . . . . . . . . 599.2 Lafunzionemalloc() . . . . . . . . . . . . . . . . . . . . . . 609.3 Lafunzionefree(). . . . . . . . . . . . . . . . . . . . . . . . 619.4 Checosasonolestrutturedatieacosaservono . . . . . . . . 619.5 Lepile:LIFO . . . . . . . . . . . . . . . . . . . . . . . . . . . 619.6 Lecode:FIFO . . . . . . . . . . . . . . . . . . . . . . . . . . . 659.7 Leliste. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 689.7.1 Listeaconcatenamentosemplice . . . . . . . . . . . . 6810Tempo 7510.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 7510.2 Tipididato . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7510.3 funzionistandard . . . . . . . . . . . . . . . . . . . . . . . . . 7510.4 funzioniinLinux . . . . . . . . . . . . . . . . . . . . . . . . . 7510.5 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7511Lostandardc99 7711.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 7711.2 C89VSC99. . . . . . . . . . . . . . . . . . . . . . . . . . . . 7711.2.1 Aggiunte. . . . . . . . . . . . . . . . . . . . . . . . . . 7711.2.2 Rimozioni . . . . . . . . . . . . . . . . . . . . . . . . . 7811.2.3 Modiche . . . . . . . . . . . . . . . . . . . . . . . . . 7811.3 inline. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7911.4 restrict . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7911.5 iltipo Bool. . . . . . . . . . . . . . . . . . . . . . . . . . . . 7911.6 Complexed Imaginary . . . . . . . . . . . . . . . . . . . . . 8011.7 Arraydilunghezzavariabile . . . . . . . . . . . . . . . . . . . 8011.8 Arrayessibilicomemembridellestrutture . . . . . . . . . . 8111.9 Aggiuntealpreprocessore . . . . . . . . . . . . . . . . . . . . 8111.9.1 Macroconargomentiinnumerovariabile. . . . . . . . 8211.9.2 Loperatore Pragma . . . . . . . . . . . . . . . . . . . 8211.9.3 Aggiuntadinuovemacro. . . . . . . . . . . . . . . . . 8311.10Iletteralicomposti . . . . . . . . . . . . . . . . . . . . . . . . 8311.11Iltipolonglongint . . . . . . . . . . . . . . . . . . . . . . . . 8411.12Ilcommento// . . . . . . . . . . . . . . . . . . . . . . . . . . 8411.13Dichiarazionediunavariabileinunistruzionefor. . . . . . . 8411.14Amalgamarecodiceedati . . . . . . . . . . . . . . . . . . . . 8411.15Inizializzatoridesignati . . . . . . . . . . . . . . . . . . . . . . 8511.16Usareitipilonglongint . . . . . . . . . . . . . . . . . . . . . 8511.17Identicatoredifunzione func . . . . . . . . . . . . . . . . 85X INDICE11.18Altremodicheedaggiunte . . . . . . . . . . . . . . . . . . . 8611.18.1Nuovelibrerie . . . . . . . . . . . . . . . . . . . . . . . 8611.18.2Notevoleincrementodeilimitiditraduzione . . . . . . 86III ProgrammazioneinambienteLinux/Unix 8912GDB 9112.1 Errorisintatticiederrorilogici . . . . . . . . . . . . . . . . . . 9112.2 Unacompilazionededicata. . . . . . . . . . . . . . . . . . . . 9212.3 GDB:avvio . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9312.3.1 InputedOutputdelprogramma . . . . . . . . . . . . . 9412.4 StepbyStep . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9412.4.1 Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . 9412.4.2 Watchpoints. . . . . . . . . . . . . . . . . . . . . . . . 9712.4.3 Unavoltabloccatalesecuzione. . . . . . . . . . . . . . . 9812.4.4 Andareavanti . . . . . . . . . . . . . . . . . . . . . . . 9912.5 Sessionedesempio . . . . . . . . . . . . . . . . . . . . . . . . 10112.5.1 CodiceC . . . . . . . . . . . . . . . . . . . . . . . . . . 10112.5.2 SessioneGDB. . . . . . . . . . . . . . . . . . . . . . . 10213UsoavanzatodelGDB 10513.1 Modicareilvaloredellevariabili . . . . . . . . . . . . . . . . 10513.2 AnalisidelloStack . . . . . . . . . . . . . . . . . . . . . . . . 10513.2.1 Stackframes . . . . . . . . . . . . . . . . . . . . . . . . 10613.2.2 Backtraces. . . . . . . . . . . . . . . . . . . . . . . . . 10613.2.3 Vagareperiframes:-D. . . . . . . . . . . . . . . . . . 10713.2.4 Ricavareinformazioniriguardantiilframe . . . . . . . 10713.3 Esamiapprofonditidelprogramma . . . . . . . . . . . . . . . 10813.4 Sessionedesempio . . . . . . . . . . . . . . . . . . . . . . . . 10813.4.1 IlCodicesorgente. . . . . . . . . . . . . . . . . . . . . 10813.4.2 Analisidellostackedellamemoria . . . . . . . . . . . 10913.5 GDBancorapi` uvelocemente . . . . . . . . . . . . . . . . . . 11213.6 conclusioni. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11314Inbreve:utilizzodimake 11514.1 makele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11515Gestioneelementaredelcolore 119INDICE ImparareilCpag.XI16Errori 12116.1 Lavariabileerrno . . . . . . . . . . . . . . . . . . . . . . . . . 12116.2 Funzioniperlagestionedeglierrori . . . . . . . . . . . . . . . 12216.2.1 Lafunzionestrerror . . . . . . . . . . . . . . . . . . . . 12216.2.2 Lafunzioneperror. . . . . . . . . . . . . . . . . . . . . 12216.2.3 Lafunzioneerror . . . . . . . . . . . . . . . . . . . . . 12317UtentieGruppi 12517.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 12517.2 UIDeGID . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12617.3 Unprocesso,unapersona . . . . . . . . . . . . . . . . . . . . 12617.4 Cambiarelapersona . . . . . . . . . . . . . . . . . . . . . . . 12817.5 ConosceregliIDdiunprocesso . . . . . . . . . . . . . . . . . 12817.5.1 Lafunzionegetuid . . . . . . . . . . . . . . . . . . . . 12917.5.2 Lafunzionegetgid . . . . . . . . . . . . . . . . . . . . 12917.5.3 Lafunzionegeteuid . . . . . . . . . . . . . . . . . . . . 12917.5.4 Lafunzionegetegid . . . . . . . . . . . . . . . . . . . . 12917.6 Unsempliceesempio . . . . . . . . . . . . . . . . . . . . . . . 12917.7 ModicaregliID . . . . . . . . . . . . . . . . . . . . . . . . . 13117.7.1 Lafunzioneseteuid . . . . . . . . . . . . . . . . . . . . 13117.7.2 Lafunzionesetuid. . . . . . . . . . . . . . . . . . . . . 13117.7.3 Lafunzionesetegid . . . . . . . . . . . . . . . . . . . . 13217.7.4 LafunzioneFunction:intsetgid(gidtNEWGID) . . . . 13217.8 Chistafacendocosa. . . . . . . . . . . . . . . . . . . . . . . . . 13217.8.1 Lafunzionegetlogin . . . . . . . . . . . . . . . . . . . . 13317.9 Unp`odicodice . . . . . . . . . . . . . . . . . . . . . . . . . . 13317.10Luseraccountdatabase . . . . . . . . . . . . . . . . . . . . . 13517.10.1Iltipodidatostructexitstatus . . . . . . . . . . . . . 13517.10.2IltipodidatoDataType:structutmp. . . . . . . . . . 13517.11Funzioniimportanti. . . . . . . . . . . . . . . . . . . . . . . . 13717.11.1Lafunzionesetutent . . . . . . . . . . . . . . . . . . . 13717.11.2Lafunzioneendutent . . . . . . . . . . . . . . . . . . . 13717.11.3Lafunzionegetutent . . . . . . . . . . . . . . . . . . . 13817.11.4Lafunzionegetutentr . . . . . . . . . . . . . . . . . . 13817.11.5Lafunzionegetutid . . . . . . . . . . . . . . . . . . . . 13817.11.6Lafunzionegetutidr . . . . . . . . . . . . . . . . . . . 13917.11.7Lafunzionegetutline . . . . . . . . . . . . . . . . . . . 13917.11.8Lafunzionegetutliner . . . . . . . . . . . . . . . . . . 14017.11.9Lafunzionepututline . . . . . . . . . . . . . . . . . . . 14017.11.10Lafunzioneutmpname . . . . . . . . . . . . . . . . . . 14017.12LoUserDatabase. . . . . . . . . . . . . . . . . . . . . . . . . 141XII INDICE17.12.1Iltipodidato:structpasswd. . . . . . . . . . . . . . . 14117.13Funzioniimportanti. . . . . . . . . . . . . . . . . . . . . . . . 14217.13.1Lafunzionegetpwuid . . . . . . . . . . . . . . . . . . . 14217.13.2Lafunzionegetpwuidr . . . . . . . . . . . . . . . . . . 14217.13.3Lafunzionegetpwnam . . . . . . . . . . . . . . . . . . 14217.13.4Lafunzionegetpwnamr . . . . . . . . . . . . . . . . . 14317.13.5Lafunzionefgetpwent . . . . . . . . . . . . . . . . . . . 14317.13.6Lafunzionefgtpwentr . . . . . . . . . . . . . . . . . . 14317.13.7Lafunzionesetpwent . . . . . . . . . . . . . . . . . . . 14317.13.8Lafunzionegetpwent . . . . . . . . . . . . . . . . . . . 14417.13.9Lafunzionegetpwentr . . . . . . . . . . . . . . . . . . 14417.13.10Lafunzioneendpwent . . . . . . . . . . . . . . . . . . . 14417.13.11Lafunzioneputpwent . . . . . . . . . . . . . . . . . . . 14417.14IlGroupDatabase . . . . . . . . . . . . . . . . . . . . . . . . 14517.14.1Iltipodidato:structgroup . . . . . . . . . . . . . . . . 14517.15Funzioniimportanti. . . . . . . . . . . . . . . . . . . . . . . . 14517.15.1Lafunzionegetgrgid . . . . . . . . . . . . . . . . . . . 14517.15.2Lafunzionegetgrgidr . . . . . . . . . . . . . . . . . . . 14617.15.3Lafunzionegetgrnam. . . . . . . . . . . . . . . . . . . 14617.15.4Lafunzionegetgrnamr . . . . . . . . . . . . . . . . . . 14617.15.5Lafunzionefgetgrent . . . . . . . . . . . . . . . . . . . 14617.15.6Lafunzionefgetgrentr . . . . . . . . . . . . . . . . . . 14717.15.7Lafunzionesetgrent . . . . . . . . . . . . . . . . . . . 14717.15.8Lafunzionegetrent . . . . . . . . . . . . . . . . . . . . 14717.15.9Lafunzionegetrentr . . . . . . . . . . . . . . . . . . . 14717.15.10Lafunzioneendgrent . . . . . . . . . . . . . . . . . . . 14817.16Altridatabase. . . . . . . . . . . . . . . . . . . . . . . . . . . 14817.17Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14818FileSystem 15118.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 15118.2 ConcettidibasedellI/O. . . . . . . . . . . . . . . . . . . . . 15218.3 Streamspi uindettaglio . . . . . . . . . . . . . . . . . . . . . 15318.3.1 Lafunzionefopen. . . . . . . . . . . . . . . . . . . . . 15318.3.2 Lafunzionefreopen. . . . . . . . . . . . . . . . . . . . 15418.3.3 Lafunzione freadable . . . . . . . . . . . . . . . . . . 15418.3.4 Lafunzione fwritable . . . . . . . . . . . . . . . . . . 15418.3.5 Lafunzionefclose . . . . . . . . . . . . . . . . . . . . . 15518.3.6 Lafunzionefcloseall. . . . . . . . . . . . . . . . . . . . 15518.4 Posizionarsiallinternodiunle. . . . . . . . . . . . . . . . . 15518.4.1 Lafunzioneftell . . . . . . . . . . . . . . . . . . . . . . 155INDICE ImparareilCpag.XIII18.4.2 Lafunzionefseek . . . . . . . . . . . . . . . . . . . . . 15518.4.3 Lafunzionerewind . . . . . . . . . . . . . . . . . . . . 15618.5 Directories:funzioniimportanti . . . . . . . . . . . . . . . . . 15618.5.1 Lafunzionegetcwd . . . . . . . . . . . . . . . . . . . . 15618.5.2 Lafunzionechdir . . . . . . . . . . . . . . . . . . . . . 15718.5.3 Lafunzionefchdir . . . . . . . . . . . . . . . . . . . . . 15718.6 Lavorareconledirectory. . . . . . . . . . . . . . . . . . . . . 15818.7 FunzioniImportanti . . . . . . . . . . . . . . . . . . . . . . . 15918.7.1 Lafunzioneopendir . . . . . . . . . . . . . . . . . . . . 15918.7.2 Lafunzionereaddir . . . . . . . . . . . . . . . . . . . . 15918.7.3 Lafunzionereaddirr . . . . . . . . . . . . . . . . . . . 16018.7.4 Lafunzioneclosedir . . . . . . . . . . . . . . . . . . . . 16018.7.5 Unpiccoloesempio . . . . . . . . . . . . . . . . . . . . 16018.7.6 Lafunzionerewinddir . . . . . . . . . . . . . . . . . . . 16118.7.7 Lafunzionetelldir . . . . . . . . . . . . . . . . . . . . . 16118.7.8 Lafunzioneseekdir . . . . . . . . . . . . . . . . . . . . 16118.7.9 Lafunzionescandir . . . . . . . . . . . . . . . . . . . . 16118.8 Alberididirectories. . . . . . . . . . . . . . . . . . . . . . . . 16218.8.1 Tipididato . . . . . . . . . . . . . . . . . . . . . . . . 16218.8.2 Lafunzioneftw . . . . . . . . . . . . . . . . . . . . . . 16318.8.3 Lafunzionenftw . . . . . . . . . . . . . . . . . . . . . 16418.9 Links. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16518.10Funzionirelativeaglihardlinks . . . . . . . . . . . . . . . . . 16518.10.1Lafunzionelink . . . . . . . . . . . . . . . . . . . . . . 16518.11Funzionirelativeaisoftlinks. . . . . . . . . . . . . . . . . . . 16618.11.1Lafunzionesymlink . . . . . . . . . . . . . . . . . . . . 16618.11.2Lafunzionereadlink. . . . . . . . . . . . . . . . . . . . 16718.11.3Lafunzionecanonicalizelename . . . . . . . . . . . . 16718.12Rinominareiles . . . . . . . . . . . . . . . . . . . . . . . . . 16818.12.1Lafunzionecanonicalizelename . . . . . . . . . . . . 16818.13Creazionedidirectories. . . . . . . . . . . . . . . . . . . . . . 16918.13.1Lafunzionemkdir . . . . . . . . . . . . . . . . . . . . . 17018.14Cancellareiles. . . . . . . . . . . . . . . . . . . . . . . . . . 17018.14.1Lafunzioneunlink . . . . . . . . . . . . . . . . . . . . . 17018.14.2Lafunzionermdir . . . . . . . . . . . . . . . . . . . . . 17118.14.3Lafunzioneremove . . . . . . . . . . . . . . . . . . . . 17118.15Gliattributideiles . . . . . . . . . . . . . . . . . . . . . . . 17218.15.1Lastrutturastat . . . . . . . . . . . . . . . . . . . . . 17218.15.2Lafunzionestat . . . . . . . . . . . . . . . . . . . . . . 17418.15.3Lafunzionefstat . . . . . . . . . . . . . . . . . . . . . 17418.15.4Lafunzionelstat . . . . . . . . . . . . . . . . . . . . . 174XIV INDICE18.16Utilizzareleinformazioni . . . . . . . . . . . . . . . . . . . . . 17418.16.1LamacroSISDIR. . . . . . . . . . . . . . . . . . . . . 17518.16.2Lamacro . . . . . . . . . . . . . . . . . . . . . . . . . 17518.16.3LamacroSISBLK . . . . . . . . . . . . . . . . . . . . 17518.16.4LamacroSISREG . . . . . . . . . . . . . . . . . . . . 17518.16.5LamacroSISFIFO . . . . . . . . . . . . . . . . . . . . 17518.16.6LamacroSISLNK . . . . . . . . . . . . . . . . . . . . 17518.16.7LamacroSISSOK . . . . . . . . . . . . . . . . . . . . 17618.16.8LamacroSTYPEISMQ . . . . . . . . . . . . . . . . . 17618.16.9LamacroSTYPEISSEM. . . . . . . . . . . . . . . . . 17618.16.10LamacroSTYPEISSHM. . . . . . . . . . . . . . . . . 17618.17Questionidisicurezza . . . . . . . . . . . . . . . . . . . . . . . 17618.17.1Lafunzionechown . . . . . . . . . . . . . . . . . . . . 17718.17.2Lafunzionefchown . . . . . . . . . . . . . . . . . . . . 17818.17.3Lafunzionechmod . . . . . . . . . . . . . . . . . . . . 18018.17.4Lafunzionefchmod. . . . . . . . . . . . . . . . . . . . 18018.17.5Unpiccoloesempio . . . . . . . . . . . . . . . . . . . . 18118.17.6Lafunzioneaccess . . . . . . . . . . . . . . . . . . . . 18118.18Tempi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18218.18.1Iltipodidatostructutimbuf . . . . . . . . . . . . . . . 18218.18.2Lafunzioneutime. . . . . . . . . . . . . . . . . . . . . 18318.19Dimensioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18318.19.1Lafunzionetruncate . . . . . . . . . . . . . . . . . . . 18318.19.2Lafunzioneftruncate . . . . . . . . . . . . . . . . . . . 18418.20Filesspeciali. . . . . . . . . . . . . . . . . . . . . . . . . . . . 18418.20.1Lafunzionemknod . . . . . . . . . . . . . . . . . . . . 18419Input/OutputdiAltoLivello 18519.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 18519.2 I/OeThreads. . . . . . . . . . . . . . . . . . . . . . . . . . . 18619.2.1 Lafunzioneockle. . . . . . . . . . . . . . . . . . . . 18619.2.2 Lafunzioneftrylockle . . . . . . . . . . . . . . . . . . 18619.2.3 Lafunzionefunlockle . . . . . . . . . . . . . . . . . . 18719.3 funzionidiOutput . . . . . . . . . . . . . . . . . . . . . . . . 18719.3.1 Lafunzionefputc . . . . . . . . . . . . . . . . . . . . . 18719.3.2 Lafunzionefputcunlocked . . . . . . . . . . . . . . . . 18819.3.3 Lafunzioneputc . . . . . . . . . . . . . . . . . . . . . 18819.3.4 Lafunzioneputcunlocked . . . . . . . . . . . . . . . . 18819.3.5 Lafunzioneputchar . . . . . . . . . . . . . . . . . . . . 18819.3.6 Lafunzioneputcharunlocked. . . . . . . . . . . . . . . 18819.3.7 Lafunzionefputs . . . . . . . . . . . . . . . . . . . . . 189INDICE ImparareilCpag.XV19.3.8 Lafunzionefputsunlocked . . . . . . . . . . . . . . . . 18919.3.9 Lafunzioneputs . . . . . . . . . . . . . . . . . . . . . 18919.3.10Lafunzionefwrite. . . . . . . . . . . . . . . . . . . . . 18919.3.11Lafunzionefwriteunlocked. . . . . . . . . . . . . . . . 19019.4 FunzionidiInput . . . . . . . . . . . . . . . . . . . . . . . . . 19019.4.1 Lafunzionefgetc . . . . . . . . . . . . . . . . . . . . . 19019.4.2 Lafunzionefgetcunlocked . . . . . . . . . . . . . . . . 19119.4.3 Lafunzionegetc . . . . . . . . . . . . . . . . . . . . . . 19119.4.4 Lafunzionegetcunlocked . . . . . . . . . . . . . . . . 19119.4.5 Lafunzionegetchar . . . . . . . . . . . . . . . . . . . . 19119.4.6 Lafunzionegetcharunlocked. . . . . . . . . . . . . . . 19119.4.7 Lafunzionefread . . . . . . . . . . . . . . . . . . . . . 19119.4.8 Lafunzionefreadunlocked . . . . . . . . . . . . . . . . 19219.5 EOF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19219.5.1 Lafunzionefeof . . . . . . . . . . . . . . . . . . . . . . 19219.5.2 Lafunzionefeofunlocked. . . . . . . . . . . . . . . . . 19319.5.3 Lafunzioneferror . . . . . . . . . . . . . . . . . . . . . 19319.5.4 Lafunzioneferrorunlocked. . . . . . . . . . . . . . . . 19319.6 Buering. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19319.6.1 Lafunzioneush . . . . . . . . . . . . . . . . . . . . . 19419.6.2 Lafunzioneushunlocked . . . . . . . . . . . . . . . . 19419.6.3 Lafunzione fpurge . . . . . . . . . . . . . . . . . . . . 19519.6.4 Lafunzionesetvbuf . . . . . . . . . . . . . . . . . . . . 19519.6.5 Lafunzione bf . . . . . . . . . . . . . . . . . . . . . 19619.6.6 Lafunzione fbufsize . . . . . . . . . . . . . . . . . . . 19619.6.7 Lafunzione fpending . . . . . . . . . . . . . . . . . . 19620I/Odibassolivello 19720.1 AperturaeChiusuradiunle . . . . . . . . . . . . . . . . . . 19720.1.1 Lafunzioneopen . . . . . . . . . . . . . . . . . . . . . 19720.1.2 Lafunzioneclose . . . . . . . . . . . . . . . . . . . . . 20020.2 Letturaescrittura . . . . . . . . . . . . . . . . . . . . . . . . 20020.2.1 Lafunzioneread . . . . . . . . . . . . . . . . . . . . . 20020.2.2 Lafunzionepread . . . . . . . . . . . . . . . . . . . . . 20120.2.3 Lafunzionewrite . . . . . . . . . . . . . . . . . . . . . 20220.2.4 Lafunzionepwrite . . . . . . . . . . . . . . . . . . . . . 20220.3 Posizionamento . . . . . . . . . . . . . . . . . . . . . . . . . . 20320.3.1 Lafunzionelseek . . . . . . . . . . . . . . . . . . . . . 20320.4 Dabassoadaltolivelloeviceversa . . . . . . . . . . . . . . . 20420.4.1 Lafunzionefdopen . . . . . . . . . . . . . . . . . . . . 20420.4.2 Lafunzioneleno . . . . . . . . . . . . . . . . . . . . . 204XVI INDICE20.5 I/Osupi` ubuer . . . . . . . . . . . . . . . . . . . . . . . . . 20520.5.1 Lastrutturaiovec. . . . . . . . . . . . . . . . . . . . . 20520.5.2 Lafunzionereadv . . . . . . . . . . . . . . . . . . . . . 20520.5.3 Lafunzionewritev . . . . . . . . . . . . . . . . . . . . . 20520.6 Mappareilesinmemoria. . . . . . . . . . . . . . . . . . . . 20620.6.1 Lafunzionemmap . . . . . . . . . . . . . . . . . . . . 20620.6.2 Lafunzionemsync . . . . . . . . . . . . . . . . . . . . 20820.6.3 Lafunzionemremap . . . . . . . . . . . . . . . . . . . 20820.6.4 Lafunzionemunmap . . . . . . . . . . . . . . . . . . . 20921Processi 21121.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 21121.2 Generazioneegestionediprocessi . . . . . . . . . . . . . . . . 21121.2.1 La funzione system() . . . . . . . . . . . . . . . . . 21121.2.2 Lafunzionefork(). . . . . . . . . . . . . . . . . . . . . 21221.3 Impiegodipipeneiprogrammi . . . . . . . . . . . . . . . . . 21621.4 Lefunzionidellaclasseexec . . . . . . . . . . . . . . . . . . . 21721.5 Codedimessaggi . . . . . . . . . . . . . . . . . . . . . . . . . 21821.5.1 inoltrareericevereimessaggi . . . . . . . . . . . . . . 22021.6 Memoriacondivisa . . . . . . . . . . . . . . . . . . . . . . . . 22121.7 NamedpipeeFIFO . . . . . . . . . . . . . . . . . . . . . . . . 22322Segnali 22522.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 22522.2 Generazionedeisegnali . . . . . . . . . . . . . . . . . . . . . . 22622.2.1 Lafunzioneraise . . . . . . . . . . . . . . . . . . . . . 22622.2.2 Lafunzionekill . . . . . . . . . . . . . . . . . . . . . . 22622.3 Gestionedeisegnali . . . . . . . . . . . . . . . . . . . . . . . . 22722.3.1 Lafunzionesignal . . . . . . . . . . . . . . . . . . . . . 22722.3.2 Lafunzionesigaction . . . . . . . . . . . . . . . . . . . 22922.4 Unp`odicodice . . . . . . . . . . . . . . . . . . . . . . . . . . 23122.4.1 Usodisignal(). . . . . . . . . . . . . . . . . . . . . . . 23122.5 BloccareiSegnali . . . . . . . . . . . . . . . . . . . . . . . . . 23222.6 Funzionirelativealbloccodeisegnali . . . . . . . . . . . . . . 23322.6.1 Lafunzionesigemptyset. . . . . . . . . . . . . . . . . . 23322.6.2 Lafunzionesigllset . . . . . . . . . . . . . . . . . . . . 23322.6.3 Lafunzionesigaddset . . . . . . . . . . . . . . . . . . . 23422.6.4 Lafunzionesigdelset . . . . . . . . . . . . . . . . . . . 23422.6.5 Lafunzionesigismemeber . . . . . . . . . . . . . . . . . 23422.6.6 Lafunzionesigprocmask . . . . . . . . . . . . . . . . . 23422.6.7 Lafunzionesigpending . . . . . . . . . . . . . . . . . . 235INDICE ImparareilCpag.XVII22.7 Aspettiimportanti:accessoatomicoaidati. . . . . . . . . . . 23622.8 AttesadiunSegnale . . . . . . . . . . . . . . . . . . . . . . . 23622.8.1 Lafunzionesigsuspend . . . . . . . . . . . . . . . . . . 23623Threads 23723.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 23723.2 Caratteristichedeithreads . . . . . . . . . . . . . . . . . . . . 23723.3 ThreadsVSProcessi . . . . . . . . . . . . . . . . . . . . . . . 23823.4 FunzioniperlaprogrammazioneMultithreading . . . . . . . . 23923.4.1 Lafunzionepthreadcreate . . . . . . . . . . . . . . . . 23923.4.2 Lafunzionepthreadexit . . . . . . . . . . . . . . . . . 24023.4.3 Lafunzionepthreadjoin . . . . . . . . . . . . . . . . . 24023.4.4 Lafunzionepthreadcancel . . . . . . . . . . . . . . . . 24123.5 Unp`odicodice . . . . . . . . . . . . . . . . . . . . . . . . . . 24123.6 Comunicazioneeprimeproblematiche . . . . . . . . . . . . . . 24223.6.1 Meccanismidimutuaesclusione(Mutex) . . . . . . . . 24423.7 FunzioniperlaprogrammazioneMultithreading . . . . . . . . 24423.7.1 Lafunzionepthreadmutexinit . . . . . . . . . . . . . . 24423.7.2 Lafunzioneintpthreadmutexlock . . . . . . . . . . . . 24523.7.3 Lafunzioneintpthreadmutextrylock . . . . . . . . . . 24623.7.4 Lafunzionepthreadmutextimedlock . . . . . . . . . . 24623.7.5 Lafunzionepthreadmutexunlock . . . . . . . . . . . . 24723.7.6 Lafunzionepthreadmutexdestroy . . . . . . . . . . . . 24723.8 Unp`odicodice . . . . . . . . . . . . . . . . . . . . . . . . . . 24723.8.1 Ilproblema. . . . . . . . . . . . . . . . . . . . . . . . . . 24923.8.2 . . . Lasoluzione . . . . . . . . . . . . . . . . . . . . . . 25023.9 Condizioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25123.9.1 Lafunzionepthreadcondinit. . . . . . . . . . . . . . . 25123.9.2 Lafunzionepthreadcondsignal . . . . . . . . . . . . . 25223.9.3 Lafunzionepthreadcondbroadcast . . . . . . . . . . . 25223.9.4 Lafunzionepthreadcondwait . . . . . . . . . . . . . . 25223.9.5 Lafunzionepthreadcondtimedwait . . . . . . . . . . . 25323.9.6 Lafunzionepthreadconddestroy . . . . . . . . . . . . . 25323.10Unp`odicodice . . . . . . . . . . . . . . . . . . . . . . . . . . 25423.11Semafori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25623.11.1Lafunzioneseminit . . . . . . . . . . . . . . . . . . . . 25623.11.2Lafunzionesemwait . . . . . . . . . . . . . . . . . . . 25723.11.3Lafunzioneintsemtrywait . . . . . . . . . . . . . . . . 25723.11.4Lafunzioneintsempost . . . . . . . . . . . . . . . . . 25823.11.5Lafunzioneintsemgetvalue . . . . . . . . . . . . . . . 25823.11.6Lafunzioneintsemdestroy. . . . . . . . . . . . . . . . 258XVIII INDICE24Socket 25924.1 Premessa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25924.2 introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25924.3 ClienteServer . . . . . . . . . . . . . . . . . . . . . . . . . . 25924.4 Micapossofaretuttoio. . . . . . . . . . . . . . . . . . . . . . . 26024.5 Chiamateperlaprogrammazionedisocket . . . . . . . . . . . 26024.5.1 Lachiamatasocket . . . . . . . . . . . . . . . . . . . . 26024.5.2 Lachiamatabind . . . . . . . . . . . . . . . . . . . . . 26224.5.3 Lachiamatalisten . . . . . . . . . . . . . . . . . . . . . 26224.5.4 Lachiamataaccept . . . . . . . . . . . . . . . . . . . . 26324.5.5 Lachiamataconnect . . . . . . . . . . . . . . . . . . . 26324.5.6 Lachiamatasend . . . . . . . . . . . . . . . . . . . . . 26424.5.7 Lachiamatarecv . . . . . . . . . . . . . . . . . . . . . 26524.6 BytesedIndirizzi . . . . . . . . . . . . . . . . . . . . . . . . . 26624.7 Struttureimportanti. . . . . . . . . . . . . . . . . . . . . . . . 26724.7.1 struct inaddr . . . . . . . . . . . . . . . . . . . . . 26724.7.2 sockaddrin . . . . . . . . . . . . . . . . . . . . . . . 26724.7.3 struct sockaddr. . . . . . . . . . . . . . . . . . . . . 26824.8 Unp`odicodice . . . . . . . . . . . . . . . . . . . . . . . . . . 26824.8.1 Serveriterativo . . . . . . . . . . . . . . . . . . . . . . 26824.8.2 Clientdesempio . . . . . . . . . . . . . . . . . . . . . 27024.9 Serverconcorrente . . . . . . . . . . . . . . . . . . . . . . . . 27124.9.1 ilcodice . . . . . . . . . . . . . . . . . . . . . . . . . . 27224.10I/OnonbloccanteeMultiplexing . . . . . . . . . . . . . . . . 27425SocketRaw 27525.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 27525.2 InternetProtocol(IP) . . . . . . . . . . . . . . . . . . . . . . . 27525.2.1 StrutturadelpacchettoIP. . . . . . . . . . . . . . . . 27525.2.2 Vediamolomeglio . . . . . . . . . . . . . . . . . . . . . 27725.2.3 CostruzionediunpacchettoIP . . . . . . . . . . . . . 28025.3 TrasferControlProtocol(TCP) . . . . . . . . . . . . . . . . . 28125.3.1 StrutturadelTCP . . . . . . . . . . . . . . . . . . . . 28125.3.2 Vediamolomeglio . . . . . . . . . . . . . . . . . . . . . 28225.3.3 Lopseudoheader . . . . . . . . . . . . . . . . . . . . . 28425.4 UserDatagramProtocol(UDP) . . . . . . . . . . . . . . . . . 28526Risorsedisistema 28726.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 28726.2 Lastrutturarusage . . . . . . . . . . . . . . . . . . . . . . . . 28726.3 Reperireleinformazioni . . . . . . . . . . . . . . . . . . . . . 289INDICE ImparareilCpag.XIX26.3.1 Lafunzionegetrusage. . . . . . . . . . . . . . . . . . . 28926.4 Limitarelaccesso . . . . . . . . . . . . . . . . . . . . . . . . . 29026.4.1 Limiti . . . . . . . . . . . . . . . . . . . . . . . . . . . 29026.4.2 Struttureimportanti . . . . . . . . . . . . . . . . . . . 29026.5 Funzioniperlagestionedellerisorse . . . . . . . . . . . . . . . 29126.5.1 Lafunzionegetrlimit . . . . . . . . . . . . . . . . . . . 29126.5.2 Lafunzionesetrlimit . . . . . . . . . . . . . . . . . . . 29126.6 Elencorisorse . . . . . . . . . . . . . . . . . . . . . . . . . . . 29126.7 CPU. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29226.7.1 Lafunzionegetnprocsconf . . . . . . . . . . . . . . . 29326.7.2 Lafunzionegetnprocsconf . . . . . . . . . . . . . . . 29326.7.3 Lafunzionegetloadavg . . . . . . . . . . . . . . . . . . 29326.8 Scheduling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29326.8.1 Priorit`adiunprocesso . . . . . . . . . . . . . . . . . . 29426.9 Policydischeduling. . . . . . . . . . . . . . . . . . . . . . . . 29526.9.1 Realtime . . . . . . . . . . . . . . . . . . . . . . . . . 29526.9.2 Schedulingtradizionale. . . . . . . . . . . . . . . . . . 29526.10FunzioniperloschedulingRealTime . . . . . . . . . . . . . . 29626.10.1Lafunzioneschedsetscheduler . . . . . . . . . . . . . . 29626.10.2Lafunzioneschedgetscheduler . . . . . . . . . . . . . . 29726.10.3Lafunzioneschedsetparam. . . . . . . . . . . . . . . . 29726.10.4Lafunzioneschedgetparam . . . . . . . . . . . . . . . 29726.10.5Lafunzioneintschedrrgetinterval . . . . . . . . . . . 29826.10.6Lafunzioneschedyield . . . . . . . . . . . . . . . . . . 29826.11Funzioniperloschedulingtradizionale . . . . . . . . . . . . . 29826.11.1Lafunzionegetpriority . . . . . . . . . . . . . . . . . . 29926.11.2Lafunzionesetpriority . . . . . . . . . . . . . . . . . . . 29927Memoria 30127.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 30127.2 Memoriavirtuale . . . . . . . . . . . . . . . . . . . . . . . . . 30127.3 Allocazionedellamemoria . . . . . . . . . . . . . . . . . . . . 30427.4 Allocazionedinamica . . . . . . . . . . . . . . . . . . . . . . . 30527.5 Funzioniperlallocazionedinamica . . . . . . . . . . . . . . . 30527.5.1 Lafunzionemalloc . . . . . . . . . . . . . . . . . . . . 30527.5.2 Lafunzionecalloc. . . . . . . . . . . . . . . . . . . . . 30627.5.3 Lafunzionerealloc . . . . . . . . . . . . . . . . . . . . 30627.5.4 Lafunzionefree . . . . . . . . . . . . . . . . . . . . . . 30627.6 Lockingdellamemoria . . . . . . . . . . . . . . . . . . . . . . 30627.7 FunzioniperilLockingdellamemoria. . . . . . . . . . . . . . 30727.7.1 Lafunzionemlock. . . . . . . . . . . . . . . . . . . . . 307XX INDICE27.7.2 Lafunzionemlockall . . . . . . . . . . . . . . . . . . . 30827.7.3 Lafunzionemunlock . . . . . . . . . . . . . . . . . . . 30927.7.4 Lafunzionemunlockall . . . . . . . . . . . . . . . . . . 30928Ncurses 31128.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 31128.2 Cominciare . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31229GTKminimalia 313IV SecureProgramming 31730Laprogrammazionesicura 31930.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 31930.2 Pensareallasicurezza. . . . . . . . . . . . . . . . . . . . . . . 32130.2.1 IlPrincipiodelMinimoPrivilegio . . . . . . . . . . . . . 32130.2.2 IlPrincipiodellaSicurezzadiDefault . . . . . . . . . . . 32230.2.3 IlPrincipiodellasemplicit`adeiMeccanismi . . . . . . . . 32230.2.4 IlPrincipiodellOpenDesign . . . . . . . . . . . . . . 32230.2.5 IlPrincipiodelCheckCompleto. . . . . . . . . . . . . 32230.2.6 IlPrincipiodelMinimodeiMeccanismiComuni . . . . 32230.2.7 IlPrincipiodellaSeparazionedeiPrivilegi . . . . . . . 32330.2.8 IlPrincipiodellAccettabilit`aPsicologica . . . . . . . . 32331BuerOverow 32531.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 32531.2 nonloso. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32531.3 Unpiccoloesempio . . . . . . . . . . . . . . . . . . . . . . . . 32631.4 Studiodiuncasosemplicato . . . . . . . . . . . . . . . . . . 32831.4.1 Ilcodiceincriminato . . . . . . . . . . . . . . . . . . . 32831.5 Lattacco . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33031.5.1 Lexploit. . . . . . . . . . . . . . . . . . . . . . . . . . 33031.6 LoShellcode . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33231.6.1 Unuscitapulita . . . . . . . . . . . . . . . . . . . . 33531.7 Unproblema . . . . . . . . . . . . . . . . . . . . . . . . . . . 33631.8 Codica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33731.9 ProteggersidaiBuerOverows. . . . . . . . . . . . . . . . . 33931.9.1 Funzionisicure:pro. . . . . . . . . . . . . . . . . . . . 33931.9.2 Funzionisicure:contro . . . . . . . . . . . . . . . . . . 34031.9.3 Allocazionedinamicadellamemoria. . . . . . . . . . . 340INDICE ImparareilCpag.XXI32Kernelhijacking 34132.1 Premessa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34132.2 introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34132.3 datrovareiltitolo . . . . . . . . . . . . . . . . . . . . . . . . . 34132.4 mettiamoinsiemeunp`odicodice . . . . . . . . . . . . . . . . 34232.5 ilkernel2.6.X. . . . . . . . . . . . . . . . . . . . . . . . . . . 344V KernelProgramming 34533Introduzione 34733.1 SistemiOperativieKernel . . . . . . . . . . . . . . . . . . . . 34733.2 ELinux?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34833.3 Perche? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34833.4 Ilnostroprimomodulo. . . . . . . . . . . . . . . . . . . . . . 34933.5 KernelSymbolTable . . . . . . . . . . . . . . . . . . . . . . . 351VI Appendici 353AAttributideiThreads 355A.1 Gestionedegliattributi . . . . . . . . . . . . . . . . . . . . . . 355A.1.1 Lafunzionepthreadattrinit . . . . . . . . . . . . . . . 355A.1.2 Lafunzionepthreadattrdestroy . . . . . . . . . . . . . 356A.1.3 LafunzionepthreadattrsetATTR . . . . . . . . . . . . 356A.1.4 LafunzionepthreadattrgetATTR . . . . . . . . . . . . 356A.2 Attributipi uimportanti . . . . . . . . . . . . . . . . . . . . . 356BTipidiSegnale 359B.1 Segnalidierrore. . . . . . . . . . . . . . . . . . . . . . . . . . 359B.2 Segnaliditerminazione. . . . . . . . . . . . . . . . . . . . . . 360B.3 Segnalidiallarme. . . . . . . . . . . . . . . . . . . . . . . . . 361B.4 Segnaliasincroni . . . . . . . . . . . . . . . . . . . . . . . . . 361B.5 Segnaliperilcontrollodeiprocessi . . . . . . . . . . . . . . . 362B.6 Errorigeneratidaoperazioni. . . . . . . . . . . . . . . . . . . 362B.7 Vari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363CStilediprogrammazione 365C.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 365C.2 Linuxkernelcodingstyle. . . . . . . . . . . . . . . . . . . . . 366C.3 Indentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366C.4 PlacingBrace . . . . . . . . . . . . . . . . . . . . . . . . . . . 367XXII INDICEC.5 Naming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368C.6 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369C.7 Commenting. . . . . . . . . . . . . . . . . . . . . . . . . . . . 369C.8 DataStructures . . . . . . . . . . . . . . . . . . . . . . . . . . 370DTipidaLinux 371D.1 types.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371D.2 Ilrovesciodellamedaglia. . . . . . . . . . . . . . . . . . . . . 372E RetiNeurali 373E.1 Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . 373E.2 Macos`eunareteneurale? . . . . . . . . . . . . . . . . . . . . 373E.3 Neuronodi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374E.4 unp`odicodice . . . . . . . . . . . . . . . . . . . . . . . . . . 376E.5 Apprendere:errare `esoloumano? . . . . . . . . . . . . . . . . 377E.6 Prendiamolargillaesputiamocisopra . . . . . . . . . . . . . 378E.7 Linput . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379E.8 Signori,luscita `edaquestaparte . . . . . . . . . . . . . . . . 380E.9 Impariamoafarelesomme . . . . . . . . . . . . . . . . . . . . 383E.10Lasoluzione `e. . . . . . . . . . . . . . . . . . . . . . . . . . . . 383E.11Eseguirelemodiche . . . . . . . . . . . . . . . . . . . . . . . 386E.12Testdivalutazione . . . . . . . . . . . . . . . . . . . . . . . . 388E.13Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389E.14Esercizipratici . . . . . . . . . . . . . . . . . . . . . . . . . . 390E.15Eserciziteorici . . . . . . . . . . . . . . . . . . . . . . . . . . . 390F Divertirsiconilcodice:glialgoritmistoricidellacrittograa393F.1 LalgoritmodiCesare. . . . . . . . . . . . . . . . . . . . . . . 393F.2 LalgoritmodiVigen`ere . . . . . . . . . . . . . . . . . . . . . . 397F.3 Ilgrossoguaiodellesostituzionimonoalfabetiche. . . . . . . . 406F.3.1 Osservazionidicaratteregenerale . . . . . . . . . . . . 410GArgomentidalineadicomando 411G.1 ArgceArgv . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411G.2 ConvenzioniPOSIX . . . . . . . . . . . . . . . . . . . . . . . . 412G.3 Parsingdelleopzioni . . . . . . . . . . . . . . . . . . . . . . . 412G.3.1 Lafunzionegetopt . . . . . . . . . . . . . . . . . . . . 413G.3.2 Esempio . . . . . . . . . . . . . . . . . . . . . . . . . . 413G.3.3 Lafunzionegetoptlong. . . . . . . . . . . . . . . . . . 415G.3.4 Esempio . . . . . . . . . . . . . . . . . . . . . . . . . . 415G.4 UtilizzareARGP . . . . . . . . . . . . . . . . . . . . . . . . . 418INDICE ImparareilCpag.XXIIIG.4.1 Lastrutturaargpoption . . . . . . . . . . . . . . . . . 419VII Copyright 421HGNUFreeDocumentationLicense 423I History 439J Ringraziamenti 443KTODO 445ParteIUnprimoapproccioCapitolo1Introduzione1.1 DueparolesulCIl presente documento `e redatto con il proposito di mostrare come il C ANSIsiprestiadessereadoperatocomelinguaggiodidattico,n`epi` u,n`emenodelPascal. Bench`equestosiaeettivamentepi` usicuropercerti aspetti, traivantaggidelCrisiedeevidentementelasuaassolutaportabilit`ama,ancheesoprattutto, l elevatolivellodi integrazionetraUnixedil linguaggio; cosache costituisce un notevole motivo di interesse, dal momento che, con lavven-todiLinux,tuttipossonodisporrediuncompletosistemaUnix-likeacostopressoch`enullo. Conogni probabilit`a, `epi` udicilemantenereprogrammidi grandi dimensioni in C che non in C++; tuttavia, a livello di comprensio-nedi quellocheaccade, il Cproceduralerisultaobbiettivamentepi` uvicinoallamacchina; quindi, anostroparerei assumeunimportanzagrandissimaper scopi didattici, oltre adessere il progenitore nobile di altri linguaggicheaquestosi richiamanoesplicitamentepertuttoil setdelleistruzioni dicontrollo.1.2 IlnecessarioMalgradoleinnumerevoli,nonmenzionabiliedinfamantiguerredireligionetraisostenitoridiciascunodeivarieditorditestodispiccoqualivi,emacs,jedequanti altri... Ci`ocheintendiamofareinquestasede, elimitarci adindicarelastradapi` uagevoleperil neota, acciocchesiaingradodi poteriniziare a programmare e possa disporre agevolmente, e nel minor tempo pos-sibile, degli strumenti che lambiente mette a disposizione per lo svolgimentodeicompitiessenziali.Premettiamoquindicheometteremo,almenoinque-staprimarelease,ditrattarelutilizzodiemacsoaltripurvalidissimieditor4 CAPITOLO1. INTRODUZIONEditesto,tuttaviasegnalandouninsiememinimodicomandidivinecessarioper editareesalvarei les sorgenti. Nonsi esclude, peraltro, cheinbasealle proprie necessit`a, lutente possa poi decidere di adoperare strumenti pi` usosticati, ambienti graci equantaltrosemplicementesi confacciaai suoipersonaligustiedabitudinidivita.1.2.1 TuttiglistrumentiSegue unaveloce rassegnadegli strumenti utili per losviluppo. Per unatrattazioneinprofondit`adegliaspettirelativialdebuggingequantaltro,sirimandasenzaltroalseguitodeldocumento.GccGcceilcompilatore.Peradoperarlo,bastapassarglicomeinput,dallarigadicomando,unopportunosorgenteC,nellaseguentemaniera:$ cc prova.cSupponendo che prova.c sia il nostro sorgente,listruzione sopra generer`aleseguibile a.out Se si vuole dare un nome specico al programma compilato,losipu`ofareusandolopzione-o$ cc prova.c -o provaQuestaistruzioneproducecomerisultatoleseguibileprovaCisonopoialtreopzioniinteressanti,comeperesempiolopzione-S,cheproduce un le corrispondente al sorgente, ma con estensione *.s, contenenteilcodiceassembly;oppure,lopzione-lnomedilibreriaperlinkaredelleli-brerie, ad esempio: -lm necessaria se si vuole collegare la libreria matematica;ma, sevoleteconoscerletutte, il nostroconsiglioe: mangcc Pereseguireilprogrammacos`compilato,bastadigitare,sullarigadicomando:./provaViEleditorditestocheconsigliamoperiniziareperalcunimotiviinpartico-lare:Ha pochi facili comandi di base necessari per editare i sorgenti e salvarli1.2Il necessario ImparareilCpag.5Ha la possibilit`a di sfruttare gli highlight. Ovvero, per i comuni mortali:sintassicolorata.Orelapossibilit`adilanciarecomandidishellsenzausciredalleditorPeraprireunleinscrittura:$ vi miofile.cVidisponeditremodalit`a:1. Modalit`acomandi.2. Modalit`aduepunti.3. Modalit`ainserimento.Quando si entra in Vi, si e in modalit`a comando. Per entrare in modalit`ainserimento,bisognadigitareiequindi inserireil testodesiderato. Si pu`o, inalternativa, digitareaedinserire,quindi,iltestoinmodalit`aappend.Persalvareiltestodigitato,bisognapremereiltastoESC,inmodotaledausciredallamodalit`ainserimento,digitare,appunto:perentrareinmodalit`aduepunti.Diqui,sidigitawpersalvare,oppure:wnomele.cperdareunnomeal lechesi stascrivendo, Invece, perattivaregli hi-ghlight, da modalit`a due punti, basta digitare il comando: syntax on quindi,perusciredalleditor:qeqaPeruscire, eventualmente, senzasalvarenulla. Perlanciarecomandi dishell, basta digitarli, in modalit`a due punti, facendoli precedere da un puntoesclamativo.Esempiopratico:: !cc mioprog.c -o progInoltre,ovesisiapredispostounopportunomakele,sipu`ocompilareilsorgentechesistaeditandofacendo,semplicemente::makoppure::makeComandocheprovvedeachiamareil programmapredenitoperlage-stionedellacompilazione. Inquestocaso(nellamaggiorpartedei sistemi)make.6 CAPITOLO1. INTRODUZIONEMakeMake eunostrumentochesidimostraassaiutilequandosihannoprogram-midistribuitisupi` usorgentiesidovrebberoimpartirecomandinumerosieopzionidiverse.Ceneoccuperemoalmomentoditrattarelacostruzionedieseguibiliapartiredalesseparati.GdbIl debugger; perutilizzarlo, bisognacompilarei sorgenti conlopzione -gche dice al compilatore di generare le informazioni necessarie ad un eventualeprogrammadi debugSi rimandaallasezionespecicaperapprofondimentisullargomento.1.3 Esercizi1. Prendetecondenzaconiprogrammielencati,inparticolarmodoconleditorpresentato. UNabuonacondenzaconalcuni comandi fonda-mentali di vi (ovim)`enecessaria. Leggeteneil manualeoi tutorialspresentiinrete.Buonostudio!Capitolo2Iniziare2.1 IlprimoprogrammaPer prepararsi ad eseguire il primo programma... bisogna disporsi ad editarneil sorgente; questo, ove sia necessario precisarlo, pu`o essere fatto con un qual-siasieditorditestosemplice,noncontenenteformattazione.Sesivolesseuncasoperverso,ondeacquisirebeneilconcettoditestosemplice, `esucienteaprireundocumento*.docconleditorvi..rendendosiconto,oltredellein-formazionichepossonoesservinascoste,dellassurdaridondanzadimarkupnonnecessario.Bene, quandosi editanodei sorgenti, il testodeveesseredavverotestosemplice.Osservatoquesto,qualsiasistrumento `ebuonoperiniziare.Unaltraprecisazionenecessaria:intuttoil documentosi`eusatalaconvenzionedi numerarelerighedeisorgenti posti allattenzione del lettore. Questo per semplicare il commentodelcodicedovesarebbepi` udicilefarlosenzariferimenti.Tuttavia,questa`epuramenteunanostraconvenzionetipograca; nel codicedacompilare,tali cifre nonvannoassolutamente riportate. Questo, adierenzadi altrilinguaggi,sequalcunoricordaunsimileuso,comenelBASIC,dovelerighedicodiceandavanoeettivamentenumerate.Tenute indebito conto tali osservazioni, segue il primo codice che sipu`oprovareacompilare, pervericarechesi siabencompresoil correttofunzionamentodellambiente:123 /* primo.c -- programma desempio -- */458 CAPITOLO2. INIZIARE6 #include78 int main()9 {10 printf("\t Addio, mondo M$ \n");1112 } /* fine main */2.1.1 IcommentiTuttoci`ochecomparetra/*e*/vieneignoratoinfasedi compilazione; quindi, si adoperanoi commentiper rendere pi` ucomprensibile il codice achi si trovaaleggerlo; nonne-cessariamentesonoutili soloapersonediversedachi scriveil codice; anzi,spessosonoutili al programmatorestessopertracciarelordinedi ideechestaseguendonellosvolgerelatramadelprogramma.2.1.2 GliincludeLaseguentedirettiva:#includeserveperindicareal preprocessorelutilizzodi funzioni il cui prototipo`edenitonellopportunoincludele.stdio.hcontieneinfattiladenizionedellafunzioneprintf(), utilizzatanel sorgente; il preprocessorecontrollache la chiamata a tale funzione eettuata nel programma corrisponda al pro-totipo denito nel le include. E da notare che stdio.h contiene i prototipidituttelefunzionidibaseperlinput/outputdelCstandard.Lutentepu`ocrearedei propri leinclude, contenenti denizioni di fun-zioni denitedaquestultimo; inquestocaso, gli includeavrannolaspettoseguente:#include "/home/casamia/miadir/miohd.h"In cui il nome del le va tra virgolette. Tuttavia lintero discorso apparir`api` u chiaro nel prosieguo della trattazione, laddove verr`a trattato nella praticalimpiegodellefunzioni.2.2Il secondoprogramma ImparareilCpag.92.1.3 ilMainOgniprogrammadevecontenerelafunzionemain()int main(){/* Il codice va qui */}sidichiaraintperchepossaritornarealsistemaoperativounvalorein-tero, al nedi operarecontrolli sullariuscitadi unprogramma. Ogni pro-gramma C e, a maggior ragione,in ambiente Unix/Linux, ha associati tre lesaperti: stdinlostandardinput stdoutlostandardoutput stderrlostandarderrorsuiqualiscriveremessaggi,odaiqualiattingeredati.2.1.4 printf():unafunzioneTutto ci`o che si trova tra virgolette come argomento della funzione printf()vienestampatosullostandardoutput.2.2 IlsecondoprogrammaVediamoilcodicechesegue:1 #include2 #include34 int main()5 {6 float a,b;10 CAPITOLO2. INIZIARE7 printf("\t Inserisci a \n");8 scanf("%f", &a);9 b = sin(a);10 printf("\t Il seno di %f vale, %f \n", a, b);1112 } /* fine main */Ilcodicesopracompilaconlaseguenterigadicomando:seno.c -o seno -lmSinotano,innanzitutto,alcunecose:Compaionoduenuovefunzioni:scanf()perlaletturadastdin ,esin()}contenutonellalibreriamatematica.Lastringascanf("%f", &a);dicealprogrammadileggereininputunvaloreditipooat"%f"ememorizzarlonellospaziodimemoriariservatoallavariabilea.Lapresenza,appunto,divariabili.2.2.1 LevariabilieilorotipiDunque, per poter memorizzareunvalorenumerico(ounaltroqualsiasioggetto che necessiti di memoria) , `e necessario, preventivamente, dichiarareunavariabile. Dunque, ci sonobentremodi dierenti per dichiarareunavariabile,ovvero,puntidierentidelprogrammaincuidenirneiltipo:1. Fuoridelmain(variabiliglobali)2. Nelcorpodifunzioni(variabililocali)3. Comeargomentodifunzioni;2.2Il secondoprogramma ImparareilCpag.112.2.2 ItipiscalariItipiammessiinCANSIsono:char singolocarattereASCIIsignedchar carattereASCIIunsignedchar carattereshort tiposhortsignedshort shortconsegnoshortint interoshortsignedshortint interoshortconsegnounsignedshort shortsenzasegnounsignedshortint interoshortsenzasegnoint interosigned tiposignedsignedint Interoconsegnounsignedint Interosenzasegnounsignedlong Longsenzasegnosignedlong Longconsegnolongint interolongsignedlongint longintconsegnounsignedlong longsenzasegnounsignedlongint longintsenzasegnooat valoreinvirgolamobiledouble inprecisionedoppialongdouble nonplusultrabool tipobooleano12.2.3 GlispecicatoridiformatoSeguelalistacompleta:%c Un singolo carattere unsigned%d Numero decimale con segno%i Numero decimale con segno%e Variabile floating point (esponente)%E Variabile floating point (esponente)%f Variabile floating point%F Variabile floating po%nt%g Lascia scegliere il sistema tra%e e%f12 CAPITOLO2. INIZIARE%G Lascia scegliere il sistema tra%E e%F%hd Signed short integer%hi Signed short integer%ho Un unsigned short integer (ottale)%hn Argomento short%hu Unsigned short integer%hx Unsigned short integer (hesadecimale lower case)%hX Unsigned short integer (hexadecimale upper case)%ld Signed long integer%le Double precision variable (exponent)%lf Variabile in doppia precisione%lg Lascia scegliere il sistema tra%le e%lf%li Signed long integer%ln Argomento long%lo Unsigned long integer (ottale)%lu Unsigned long integer%lx Unsigned long integer (hesadecimale lower case)%lX Unsigned long integer (hesadecimale lower case)%LE Variabile in precisione doppia (esponente)%Le Variabile long double (esponente)%LE Variabile long double (esponente)%lF Variabile in precisione doppia%Lf Variabile in precisione doppia%LF Precisione long double%Lg Lascia scegliere il sistema tra%Le e%Lf%lG Lascia scegliere il sistema tra%lE e%lF%LG Lascia scegliere il sistema tra%LE e%LF%n Il numero di caratteri stampati dalla printf()%p Un puntatore generico (e il suo indirizzo)%o Unsigned integer (ottale)%s Puntatore ad una stringa di caratteri2.2Il secondoprogramma ImparareilCpag.13%u Intero decimale senza segno%x Esadecimale senza segno (lower case)%X Esadecimale senza segno (upper case)%% Il carattere %#e Il punto decimale appare anche se non necessario#f Il punto decimale appare anche se non necessario#g Il punto decimale appare anche se non necessario#x Esadecimale con prefisso oxUnaltrasempliceedutiledimostrazionedellutilizzodi specicatori di for-matopotrebbeesserelaseguente:1 # include 2 int main()3 {4 int valore,scelta;5 for(;;){6 printf("\n\t0 per uscire \n");7 printf("\t1 Converte decimale/esadecimale \n");8 printf("\t2 Converte esadecimale/decimale \n");9 scanf("%d",&scelta);1011 if (scelta == 0) break;1213 if (scelta == 1) {14 printf("\tInserisci un numero in base 10\n");15 scanf("%d",&valore);16 printf("\tIn esadecimale: \n");17 printf("\t%x\n",valore);1819 }20 if (scelta == 2){21 printf("\tInserisci un numero in base 16\n");22 scanf("%x",&valore);23 printf("\tIn base 10:\n");24 printf("\t%d\n",valore);25 }2627 }/* for */2829 }14 CAPITOLO2. INIZIAREDove,perlaspiegazionedellasintassidellitsruzionecondizionaleif(),peraltrointuitiva,sirimandaalseguito.2.3 Esercizi1. Scriveteil vostroprimoprogrammaCchestampi avideoqualcosa.Cercatedifarlosenzaaiutarviconladocumentazione,provateacom-pilarlo, risolvete gli eventuali errori. Prendete condenza con la sintassidelCelindentazionedelcodice.2. Cercate inrete unelencodelle funzioni matematiche del Ceduti-lizzatene qualcuna inunvostro programma facendo attenzione aglispecicatoridiformatoeallaprecisionedellevariabilicheutilizzate.3. Utilizzando le funzioni matematiche costruite un programma che calcolilasestapotenzadiunnumero.ParteIILecaratteristichestandarddellinguaggioCapitolo3Operatorieistruzionidicontrollo3.1 GlioperatoriLalistacompletadeglioperatoridelC `elaseguente:= Assegnamento! NOTlogico++ Incremento Decremento/% Operatorimoltiplicativi(moltiplicazione,divisione,modulo)+ Operatoriadditivi OperatoridiShift(Adestraesinistra)= Operatoriperlediseguaglianze==! = UguaglianzaedisuguaglianzaOperatoribitwise& ANDsuBIT^ XORsuBIT| ORsuBIT~ ComplementoadunoOperatorilogici&& ANDlogico|| ORlogico18 CAPITOLO3. OPERATORIEISTRUZIONIDICONTROLLOOperatoricondizionali? :Sonodanotare, inparticolare, gli operatori ++ e-- chepermettonodi incrementare il valore di una variabile basandosi sullopportuna istruzionedi incrementodel proprioprocessore; inaltre parole, giacch`e praticamen-tetutti i processori esistenti deniscono, alivellodi linguaggiomacchina,unoperazionediincremento;operandonellamanieraseguente:int a = 5;a++; /* a vale adesso 6 */siottienecodicesicuramentepi` usnellochenonilseguente:int a = 5;a = a + 1; /* a vale adesso 6 */Tuttoci`oconta,fattesalveeventualiopportuneottimizzazioni,cheven-gonodemandateal particolarecompilatore; eche, grazieaquesteottimiz-zazioni, il compilatorepotrebbecomunqueprodurreil medesimorisultato.Rimaneperaltrobuonanormaadoperareleistruzioni unariedi incrementocherisultano,inpi` u,difacileletturaeveloceutilizzo.Analogheconsiderazionivalgonoperloperatore-- .Sonoinoltredarimarcareladierenzatraglioperatori&&e&validi,ilprimocomeANDlogico,laltrocomeoperatoresubit.Ugualmentedicasiper||e|.Sono inoltre assolutamente da non confondere loperatore di assegnamen-to=conloperatorediuguaglianza== .Inpi` usi pu`o usare, per certe espressioni, una notazione abbreviata;anzichescrivere:a = a +7;siusacorrentemente:3.1Glioperatori ImparareilCpag.19a += 7;cheagisceallostessomodo,eevitandodiinserirecos`unasecondavoltalavariabilea.Talesintassi eadoperabilecontutti gli operatori duali, ovverocheagi-sconosudiunacoppiadiargomenti.3.1.1 PrecisazionisulleoperazionidilogicabooleanaQuella che segue `e la tabella di verit`a dellOR esclusivo (altrimenti noto comeXOR):A operatore B Risultato1 ^ 1 01 ^ 0 10 ^ 1 10 ^ 0 0Loperatoredi XOR`e, comesi `eosservatosopra, il seguente: ^E unoperatorebinario,quindiagiscesuisingolibit.Quantodice latabellasopra, staasignicare: loperazione restituiscevalorevero(uno)Seesoloseunodei dueoperandi`evero. LadierenzadallORsemplice `einquelseesolose.SeguetabelladellORclassico:A operatore B Risultato1 | 1 11 | 0 10 | 1 10 | 0 0Unacuriosapropriet`adelloXORconsistenel fattoche, sequestovieneripetutodue volte sulle stesse variabili, si tornaesattamente al valore dipartenza.Unesempiopratico:operandosullesingolecifrebinarieincolonnate:A = 00110101B = 10101100C= AxorB = 10011001CxorB = 0011010120 CAPITOLO3. OPERATORIEISTRUZIONIDICONTROLLOCxorBequivalea(AxorB)xorB. Ovvero, AxorBduevolte, tornaesattamentelostessovalorediA.PerlAND, latabellavalettainanalogiaaquantosegue: (proposizionevera)E(proposizionefalsa)=proposizionefalsaTabelladiverit`adelloperatoreANDA operatore B Risultato1 & 1 11 & 0 00 & 1 00 & 0 0PerilNOTsubit,sihainvece:(vero)diversoda(vero)==falso(vero)diversoda(falso)==vero...etc.Ovvero:A operatore B Risultato1 ! 1 01 ! 0 10 ! 1 10 ! 0 03.2 LoperazionedicastingIl cast, altrainteressantecaratteristicadel C, consistenellapossibilit`adicostringereunaespressionearitornareunrisultatodi undatotipopiutto-stochediunaltro.Volendofaredirettamenteunesempiopratico,ilcodiceseguente:1 #include23 int main()4 {5 int intero = 3;67 /* Tra parentesi c`e il tipo che si sta "forzando" */83.3Listruzionecondizionaleif ImparareilCpag.219 printf("\t%f\n", (float)intero/2 );11 return 0;12 }Generainoutput:1.500000Invece,selosicorreggenellaseguentemaniera:1 #include23 int main()4 {5 int intero = 3;6789 printf("\t%d\n", intero/2 );10 return 0;10 }Cos`cheloutputrisultantesar`a:1.3.3 ListruzionecondizionaleifLespressioneif()costituisceunmodosemplicepercontrollareilussodelprogramma;ilsuoschemadiesecuzione `edeltipo:22 CAPITOLO3. OPERATORIEISTRUZIONIDICONTROLLOif ( ) /* se condizione restituisce valore "vero" */{......

}else {/* blocco di istruzioni eseguitese la condizione sopra vale "falso" */}Dopolacondizionedi ingressonel bloccoistruzioni, selistruzionedaese-guire`eunasola(allostessomododopolelse), leparentesi graesi posso-noomettere. Inoltreil ramoelsedel ciclo`eopzionaleepu`oquindi essereassente.Unprogrammadesempio1 #include23 int main()4 {5 float b;6 printf("\t Inserisci b \n");7 scanf("%f", &b);8 if ( b > 5) {9 printf("\t b `e maggiore di 5 \n");10 printf("\a"); /* questo codice di escapecausa un segnale sonoro */11 }12 else printf("\t b *non* `e maggiore di 5\n");13 }3.4 Unalternativascarna:glioperatori ? :Il precedenteprogramma, chefacevausodellistruzionecondizionaleif()pu`o essere riscritto facendo uso degli operatori ? e :, nella seguente maniera:3.5Sceltemultipleconswitch ImparareilCpag.231 #include2 int main()3 {4 float a;5 printf("\t Inserisci a \n");6 scanf("%f", &a);7 a > 5 ? printf("\t a e maggiore di 5 \n") : printf("\t8 a *non* e maggiore di 5\n");910 }113.5 SceltemultipleconswitchQuandosi habisognodi vericarecheunavariabileassumaunvaloreinunalistadi opzioni possibili, si pu`oevitaredi scriveredegli ifsuccessivi,adoperando,appunto,ilcostruttoswitch()Questultimosegueilseguenteschema:switch(){case :break;/* blocco di istruzioni */case :break;/* blocco di istruzioni */case :break;/* blocco di istruzioni */...case :24 CAPITOLO3. OPERATORIEISTRUZIONIDICONTROLLObreak;/* blocco di istruzioni */default:/* blocco di istruzioni */}/* fine blocco switch() */Dovedefault: `eseguitodalleistruzionida eseguireladdovenessunodeicasisoprasiverichi.Importante: notareche,sesiomettelistruzionebreak;adesempio,nelblocco2, il programmanonsaltadirettamenteallanedel bloccoswitch,bens` esegue il blocco di istruzioni 3. Questo a dierenza di costrutti analoghiinaltrilinguaggi,comeilCASE...OFdelPascal.Segue un semplice esempio di programma a scopo puramente dimostrati-vo:1 #include2 int main()3 {4 int a;5 printf("\tInserisci un intero da 1 a 6\n");6 scanf("%d",&a);78 switch(a){9 case 1 :10 printf("\t Hai inserito uno\n");11 break;12 case 2:13 printf("\t Hai inserito due\n");14 break;15 case 3:16 printf("\t Hai inserito tre\n");17 break;18 case 4:19 printf("\t Hai inserito quattro\n");20 break;21 case 5:22 printf("\t Hai inserito cinque\n");23 break;3.6Il ciclowhile ImparareilCpag.2524 case 6:25 printf("\t Hai inserito sei\n");26 break;2728 deafult: break;29 }/* fine switch() */303132 }/* main */333.6 IlciclowhileAssumelaforma:while() {/* blocco di istruzioni */}Leistruzioninelcorpodelciclovengonoeseguitentantochelacondi-zionediingressononassumeunvalorefalso.Seguelesempiodirito.1 #include2 int main()3 {4 float miavar =0;56 while( miavar < 10 ) {7 printf("\t %f \n", miavar );8 miavar += 0.5;9 }1011 }26 CAPITOLO3. OPERATORIEISTRUZIONIDICONTROLLO3.7 Ilciclodo... whileQuestultimotipodi ciclodieriscedallaltrowhileinquantoimplicaunacondizione non necessariamente vera per lingresso nel ciclo, che viene quindieseguitoalmenounavolta, comunque. Volendofareunparalleloconil lin-guaggio Pascal, mentre il ciclo while del C corrisponde al WHILE del Pascal, ildo...whilecorrispondeallistruzioneREPEAT...UNTILdiquestultimo.Adognimodo,loschema `eilseguente:do{/* blocco di istruzioni */}while()Ilcodiceseguente:1 #include2 int main()3 {4 float miavar = 0;5 do{6 printf("\t Entro nel ciclo e miavar vale: %f \n", miavar );7 miavar++;8 }9 while ( miavar > 100 );10 }Producecomeoutput:Entro nel ciclo e miavar vale: 0.0000003.8 IlcicloforLimplementazionedelcicloforinC`e,probabilmente,digranlungalapi` uversatilerispettoaciclianaloghiinaltrilinguaggidiprogrammazione;fattisalvi,naturalmente,tuttiqueilinguaggicheereditano,pressoch`esenzamo-diche,leistruzionidicontrollopropriedelC.Stopensando,adesempio,a3.8Il ciclofor ImparareilCpag.27C++,Java,Perl,etc...Talecostrutto `emoltosimileaquellodelFORTRAN,quindiassaiagevoleperfaredellemanipolazioninumeriche,tuttaviaconlapossibilit`adi esseregestitoinmanieraassai pi` uliberadal programmatore,chepu`odecideredifarneunusodeltuttooriginale.Loschemadelciclo `eilseguente:for(;;) {/* Corpo del ciclo */}Dove, , )possonoessereutilizzatecomesegue:1 #include23 int main()4 {5 int miavar;6 for(miavar = 0; miavar eutileperfareriferimentoaglielementidiunastructpuntata;peres.,sesiedenitalastruct:struct indirizzo{char citta[128];char via[128];int civico[5];}struct indirizzo mioind;edunpuntatoreallastruct:struct indirizzo *punt;punt = & mioind;sipu`oaccedereaglielementidellastructfacendo:mia_citta = punt-> citta;mia_via = punt-> via;mia_citta = punt-> civico;Sinoticheloperatore->equivalealladereferenziazionedelpuntatoreastruct,pi` uilpassaggioallelemento;ovvero:(* punt).citta;40 CAPITOLO5. IPUNTATORIequivalea:punt -> citta;Loperatore -> viene spesso utilizzato nelle linked lists per accedere, comepure avremo modo di mostrare nel seguito, ai singoli campi di struct puntatedaappositipuntatori;questisaranno,ovviamente,puntatoriastruct.Capitolo6InputeOutputsulePer salvare i dati prodotti daunprogramma, `e utile salvarli inmanierapermanentesudisco, quindi, scriverli sule. Analogamente, si pu`odoveraccedere a informazioni memorizzate su le. Per fare questo tipo di operazio-ni, bisognadichiarare, allinternodel programma, unpuntatoreale, nellamanierachesegue:FILE *miofile;Per essereutilizzato, unledeveessereaperto; per fareci`o, si utilizzalafunzioneFILE *fopen(const char *nome_file, const char *modalit`a);Dovelamodalit`apu`oessere:r testo,letturaw testo,scritturaa testo,mod.appendrb lettura,mod.binariawb scrittura,mod.binariaab append,mod.binariar+ letturaescritturainmod.binariaw+ letturaescritturainmod.binariar+borb+ letturaescritturainmod.binariaw+bowb+ letturaescritturainmod.binariaa+boab+ letturaescritturainmod.binariaUnesempioutileNellesempiochesegue, si vuoleaprireinletturaun-lecontenenteunsempliceledi testo, adesempiounledi congurazione42 CAPITOLO6. INPUTEOUTPUTSUFILE(nellesempio.bashrc)escrivereinoutput,sudiunopportunole,lostes-sotesto, includendoloinunapaginaHTML; si abbia, adesempio, il testoseguente:#!/bin/bashecho Tempus Fugit...calalias l=ls --color -l|morealias la=ls --color -aalias ls=ls --coloralias vi=vimxexport PS1="\[\033[6;35m\]\u@\h\[\033[36m\]\w\[\033[1;37m\]>\[\033[0;31m\]\$\[\033[0m\] "esivogliaottenere,apartiredaquesto,lapaginaHTMLseguente:File di configurazione

#!/bin/bashecho Tempus Fugit...calalias l=ls --color -l|morealias la=ls --color -aalias ls=ls --coloralias vi=vimxexport PS1="\[\033[6;35m\]\u@\h\[\033[36m\]\w\[\033[1;37m\]>\[\033[0;31m\]\$\[\033[0m\] "

ImparareilCpag.43Eprestodetto:1 #include 23 int app;4 char htmlstart[]="File diconfigurazione";5 char htmlfinish[]="";6 int col, acapo;7 FILE *f_in, *f_out;89 int main( char argc, char *argv[])10 {11 if (argc !=3) {12 printf ("\n\t Converte files di testo in formato HTML\n\n");13 printf("\t utilizzo:\n\t 2html \n");14 exit();15 }1617 if ( ( f_in = fopen ( argv[1] , "r" ) ) &&18 ( f_out = fopen ( argv[2] , "w" ) )19 ) {20 fputs( htmlstart, f_out);2122 while (( app = getc( f_in )) != EOF ) {2324 fputc ( app , f_out );2526 } /* fine while */2728 }29 fputs( htmlfinish, f_out);3031 fclose( f_in );32 fclose( f_out );3334 }4444 CAPITOLO6. INPUTEOUTPUTSUFILECapitolo7Denizioneedusodellefunzioni7.1 FunzionidenitedallutenteNellascritturadi programmi di grandi dimensioni, risultautilespezzareilcodiceinpi ufunzioni,ciascunadellequalisioccupidiunaparticolareope-razione; sar`apoi il main()apreoccuparsi di richiamare ciascunafunzio-ne. Spezzareil codiceinfunzioni (possibilmentedai nomi auto-esplicativi)migliorainoltrelaletturadel codice, equindi rendelavitapi usemplice,nelleventualit`adimodiche.Il codice di una funzione pu`o essere scritto sia prima che dopo del main(),tuttavia quando si voglia postporre limplementazione della funzione, bisognacomunquefornireunprototipodeitipidellafunzione.float potenza_terza ( float x );int main(){float a;...a = potenza_terza(3);}float potenza_terza ( float x )46 CAPITOLO7. DEFINIZIONEEDUSODELLEFUNZIONI{return x*x*x;}PassaggiodeiparametriIl passaggiodi parametri avviene, inquestomodo, per valore; Ovvero, lafunzionepotenza_terza()non conosce lindirizzo in memoria di x, poiche, allatto della chiamata, vienecopiato il valoredella variabile x. Se si volesse passargli lindirizzo, e far s cheeventuali modiche siano ecaci sulla variabile x in memoria, modicando, diconseguenza, il valore chex assume nelmain(), si deve chiamare la funzionepassandocomeparametrolindirizzodellavariabile, ovvero: unpuntatoreallavariabile;1 #include23 int swap (int *a, int *b);45 int main(int argc , char *argv[])6 {7 int a = 7;8 int b = 15;910 swap (&a, &b);11 printf("\t a = %d \n\t b = %d \n", a, b);1213 }/* main */1415 int swap (int *a, int *b)16 {17 int temp;1819 temp = *a;20 *a = *b;21 *b = temp;22 }23Ilcodicesopraproducecomeoutput:7.2Ipuntatoriafunzione ImparareilCpag.47a = 15b = 77.2 IpuntatoriafunzioneAltracaratteristicaassolutamentepeculiaredel C, `elapossibilit`adi usarepuntatoriafunzioni.Caratteristica, questa, assai di rilievo dove ci si trovi a dover implementaredei parser di espressioni, che si trovino a dover richiamare, in maniera snellaedelegante,moltimodulidiversiscrittiseparatamente.Ovvero, manteneredegli arraydi puntatori afunzionepotrebbeessereutile,nellapratica,perscriverelabarradellefunzionidiuneditorditesto,inmododapoter implementare e testare separatamente i vari blocchi dicodice, e poterli poi richiamare in una maniera che somiglia assai ai moderniparadigmidiprogrammazioneadoggetti.Iltuttonellotticadimantenereilpi` ualtogradopossibiledimodularit`a.Dalpuntodivistapratico, `epossibilerealizzareunpuntatoreafunzionesullascortadellaseguenteconsiderazione: vistochemediantei puntatori `epossibile accedere pressoch`e ad una qualsiasi locazione di memoria, e giacch`euna funzione occuper`a una di queste locazioni, basta far s` che esista un pun-tatorechepunti allalocazionecheinteressa, perpoterlanciarelesecuzionedellafunzioneutile.Un puntatore a funzione si dichiara usando la convenzione di racchiuderetraparentesi il nomedellafunzioneefacendoloprecederedaunasterisco,cos`:int (*func)()Esi comporta, per il resto, come unqualsiasi altro tipo di puntato-re, costituendo, di fatto, lamedesimacosa: lindirizzodi unalocazionedimemoriaCome ormai il lettore si sar`a abituato, quanto detto viene messo in praticanelsorgentechesegue:1 /*2 Mostra luso dei puntatori a funzione3 */4 #include56 int sottrazione(int, int);7 int somma (int, int);48 CAPITOLO7. DEFINIZIONEEDUSODELLEFUNZIONI8 int prodotto(int, int);9 int divisione(int, int);101112 int main()13 {14 int a = 48;15 int b = 2;16 int risultato,scelta;17 int (*puntatore)();18 for(;;){19 printf("1\t per la somma\n");20 printf("2\t per la sottrazione\n");21 printf("3\t per il prodotto\n");22 printf("4\t per la divisione\n");23 printf("0\t per uscire\n");2425 scanf("%d", &scelta);26 switch(scelta){27 case 1:28 puntatore = somma;29 break;30 case 2:31 puntatore = sottrazione;32 break;3334 case 3:35 puntatore = prodotto;36 break;3738 case 4:39 puntatore = divisione;40 break;41 case 0:42 exit(0);4344 }4546 risultato = puntatore(a,b);47 printf("Il risultato vale %d", risultato);48 break;7.2Ipuntatoriafunzione ImparareilCpag.494950 }/* fine for */5152 }5354 int somma(int a, int b)55 {56 return a+b;57 }5859 int sottrazione(int a, int b)60 {61 return a-b;62 }6364 int prodotto(int a, int b)65 {66 return a*b;67 }6869 int divisione(int a, int b)70 {71 return (a/b);72 }73Sipu`oriconoscerenellarigaint (*puntatore)();ladichiarazionedi unpuntatoreafunzione; il riferimentoallaparticolarefunzione, viene fatto nel ciclo switch(), nel quale viene assegnato a puntatoreunodeipossibilitipiprevistidalprogramma,conunassegnazionedeltipo:puntatore = prodotto;Acui devecorrispondere, chiaramente, unafunzionedichiaratacomesolitoes.:int prodotto(int a, int b){return a*b;}oppurecorrispondenteadunafunzionedilibreria.50 CAPITOLO7. DEFINIZIONEEDUSODELLEFUNZIONI7.3 Gli header standardANSI elefunzionidilibreriaSegueunsinteticoelencodituttequellechesonolefunzioniANSIstandarddenitenei quindici header ledel suddettostandard. Nonsi intendequifornireunaindicazioneesaustivadei prototipi di tuttelefunzioni; tuttaviapareutilefornire almeno un elenco completo di queste,in modo che lutentepossaconoscere almenoil nome delle funzioni, inmodoche possaessereagevolatonellaricercadi quellechegli occorrono, restandofermalutilit`adellemanpages.7.3.1 assert.hContienelafunzione:void assert(int espressione);7.3.2 ctype.hContienefunzioni pervericheeoperazioni conversionesucaratteri. Seguelalistacompleta:int isalnum(int character);int isalpha(int character);int iscntrl(int character);int isdigit(int character);int isgraph(int character);int islower(int character);int isprint(int character);int ispunct(int character);int isspace(int character);int isupper(int character);int isxdigit(int character);int tolower(int character);int toupper(int character);7.3.3 errno.hContieneladenizionedellavariabileint errno;questahavalorezeroal-linizio del programma; se si vericano condizioni di errore, assume un valorenumericodiversodazero.7.3GliheaderstandardANSIelefunzionidilibreriaImparareilCpag.517.3.4 float.hContiene le denizioni dei valori massimi e minimi per i valori oating-point;7.3.5 limits.hContienelecaratteristichedeitipidivariabile.7.3.6 locale.hContieneladenizioneditipoperlefunzioni:localeconv();setlocale();7.3.7 math.hFunzioniperlamatematica:double acos(double x);double asin(double x);double atan(double x);double atan2(doubly y, double x);double cos(double x);double cosh(double x);double sin(double x);double sinh(double x);double tan(double x);double tanh(double x);double exp(double x);double frexp(double x, int *exponent);double ldexp(double x, int exponent);double log(double x);double log10(double x);double modf(double x, double *integer);double pow(double x, double y);double sqrt(double x);double ceil(double x);double fabs(double x);double floor(double x);double fmod(double x, double y);52 CAPITOLO7. DEFINIZIONEEDUSODELLEFUNZIONI7.3.8 setjmp.hQuestoheader`eutilizzatopercontrollarelechiamatedi bassolivello. Vi`edenitalafunzione:void longjmp(jmp_buf environment, int value);7.3.9 signal.hContienegli strumenti pergestirelinviodi segnali durantelesecuzionediunprogramma.Visonodenitelefunzioni:void (*signal(int sig, void(*func)(int)))(int);int raise(int sig);7.3.10 stdarg.hDenisce molte macro usate per ottenere largomento di una funzione quandononsiconosceilnumerodiquesti.7.3.11 stddef.hContienemoltedenizionistandard.7.3.12 stdio.hDenisce, oltre adalcune macro, le funzioni pi` ufrequenti del linguaggio,quali:clearerr();fclose();feof();ferror();fflush();fgetpos();fopen();fread();freopen();fseek();fsetpos();ftell();fwrite();7.3GliheaderstandardANSIelefunzionidilibreriaImparareilCpag.53remove();rename();rewind();setbuf();setvbuf();tmpfile();tmpnam();fprintf();fscanf();printf();scanf();sprintf();sscanf();vfprintf();vprintf();vsprintf();fgetc();fgets();fputc();fputs();getc();getchar();gets();putc();putchar();puts();ungetc();perror();7.3.13 stdlib.hContieneledenizioniditipodellefunzioni:abort();abs();atexit();atof();atoi();atol();bsearch();calloc();54 CAPITOLO7. DEFINIZIONEEDUSODELLEFUNZIONIdiv();exit();free();getenv();labs();ldiv();malloc();mblen();mbstowcs();mbtowc();qsort();rand();realloc();srand();strtod();strtol();strtoul();system();wcstombs();wctomb();7.3.14 string.hContienetutteledenizioniditipoper:memchr();memcmp();memcpy();memmove();memset();strcat();strncat();strchr();strcmp();strncmp();strcoll();strcpy();strncpy();strcspn();strerror();strlen();7.3GliheaderstandardANSIelefunzionidilibreriaImparareilCpag.55strpbrk();strrchr();strspn();strstr();strtok();strxfrm();7.3.15 time.hFornisce alcune utili funzioni per leggere e convertire lora e la data delsistema.asctime();clock();ctime();difftime();gmtime();localtime();mktime();strftime();time();56 CAPITOLO7. DEFINIZIONEEDUSODELLEFUNZIONICapitolo8CompilazioneseparataQuando i programmi superano certe dimensioni, pu`o essere conveniente sud-dividereil sorgenteinpi ules; alloscopo, bisognadenirelevariabili uti-lizzatedai vari moduli comeextern.Lasoluzionemiglioresi rivelaspessolaseguente: si scriveunheaderlecontenentetutteledichiarazioni perlevariabili elevariabili condivisedai vari moduli. Poi, si includelheaderinciascuno dei moduli che ne fanno uso. Segue un esempio (abbastanza banale):/* file mio_header.h */extern int miavariabile;int mostra(void);Segueillecontenentelimplementazionedellafunzionemostra()1 #include2 #include "mio_header.h"3 /* extern int miavariabile; */4 int mostra()5 {6 printf("\t %d \n" , miavariabile);78 }Inmanierataledapoterleutilizzarenellafunzionemain():1 #include2 #include "mio_header.h"34 int miavariabile;58 CAPITOLO8. COMPILAZIONESEPARATA5 /* int mostra(void); */6 int main()78 {9 printf("\t Inserisci valore per la variabile: \n \t");10 scanf("%d", &miavariabile);11 printf("\t Hai inserito:");12 mostra();1314 }/* main */Capitolo9Allocazionedinamicadellamemoria9.1 AllocazionedinamicadellamemoriaUnadellecaratteristichepi` uimportanti del linguaggioC`esenzadubbiolagestionedellamemoriainmododinamico, cio`epoterutilizzarelamemoriasucientealmomentogiusto.Questacaratteristica, nataassiemeal linguaggioperconsentireal pro-grammatoredievitareinutilisprechi `eper`ounarmaadoppiotaglio,infattiselagestionedellamemorianon`eaccompagnatadaunattentaanalisi deicomportamentidelprogrammapu`oportareallanascitadibachichedicil-mentepossonoesserecorretti.Infattiilcompilatorenonfanessuncontrollosu come viene gestita la memoria, ma lascia al programmatore questo onere.Il motivopercui esistequestacaratteristica`echequandovienescrittounprogrammanonsempresi `eincondizionedipoterprevederequantame-moriasar`anecessariaperil correttofunzionamentodel programmastesso.Si potrebbepuntareadunmassimoprestabilito, maincasi limiteil nostroprogrammapotrebbeaverecattivicomportamenti.Sipensiadesempioadunprogrammachedevememorizzareunnumeroimprecisatodi variabili perpoi doverlerielaboraretutteinsieme. Seil pro-grammauser`aunarraytroppopiccoloallanequalchevariabilepotrebberimanere fuori, se invece il programma avesse bisogno di un numero limitatodi variabili sarebbe usata soltanto una piccola parte dellarray e il resto dellamemoria sarebbe stata sottratta al sistema senza che ve ne sia il necessario bi-sogno. Invece con lallocazione dinamica della memoria il programmatore pu`outilizzareesattamentelaquantit`adi memorianecessariaperlapplicazionechepu`ovariaredivoltainvoltaasecondadeicasi.60 CAPITOLO9. ALLOCAZIONEDINAMICADELLAMEMORIA9.2 Lafunzionemalloc()Perpoter otteneredalsistema unanuova area dimemoria siusa lafunzionemalloc() che restituisce un puntatore ad unarea di memoria delle dimensionirichieste.Lamemoriaallocataviene sottrattadalloheap, unadelle quattrose-zioni incui si suddivide la memoria occupata da unprogramma, creatoappositamenteperconsentirelallocazionedinamicadellamemoria. Questaarea `esucientementegrandedaconsentireilcorrettofunzionamentodiunprogramma, infatti seil programmanecessitadi nuovamemoriail sistemaoperativoamplialareadelloheapinmodotaledapermetterneil correttofunzionamento.Ancheselamemoria`edisponibileingrandi quantit`a, perlomenoneicalcolatori moderni,`esemprebuonanormanonabusaredelloheap, perch`ebisognaricordarechelamemoria`eunarisorsacondivisa`echequindi altriprogramminepotrebberousufruireallostessotempo.Selallocazione `eandataabuonneilpuntatorerestituitodamalloc()puntaallareaeettivamenteottenuta;selallocazionenon`eandataabuonnemalloc()restituisceunpuntatorenullo(NULL).Laletturaoscritturadaoversounpuntatorenullocrealaterminazioneimmediatadelprogramma.Quindiprimadiutilizzareunaqualsiasiareadimemoria allocata dinamicamente `e sempre preferibile vericare che il punte-torenonsiaugualealvalorenullo(NULL).Ilprototipodellafunzionemalloc`e:void malloc(n);Doven `eilnumerodibyterichiestiallamalloc().`Ebuonaregola, pergarantirelaportabilit`adel codicedaunamacchi-naadunaltra, nonesplicitareledimensioni dellamemoriachesi vuoleot-tenere, ma`emegliousareloperatore sizeof()cherestituiscelecorrettedimensioni dellelementoinseritodentroleparentesi. Questo`eutileperch`ediversicompilatoriediversiprocessorimisuranoinmanieradierenteitipidi dati; infatti perunsistemauninteropotrebbeaveredimensione8bytementreperunaltropotrebbeaveredimensione16.Quindi`esempremeglioutilizzare loperatoresizeof() e non esplicitare le dimensioni. (Per ulterioriapprofondimentisiguardiladocumentazionedelpropriocompilatore).Riportoqui di seguitoil codicecheserveperallocarelareadi memorianecessariaacontenereunintero.int *p;p=(int *)malloc(sizeof(int));9.3Lafunzionefree() ImparareilCpag.61if(p==NULL)exit(1);//allocazione fallitaelse *p=213;9.3 Lafunzionefree()Ovviamente quando unarea di memoria non serve pi` u si pu`o liberarla usandolafunzionefree(); per liberarelamemoriabisognapassareafree()unpuntatore indirizzato ad unarea precedentemente allocata; questa area potr`aessere riusata per successive allocazioni. La funzione free() non ritorna alcunvalore.Prototipodellafunzione:void free (puntatore);Eccoilcodicechemostrailfunzionamentodellafunzionefree().int *p;p=(int *)malloc(sizeof(int));...if(p==NULL)exit(1);//allocazione fallitaelse *p=213;free(p);9.4 Checosasonolestrutturedati eacosaservonoIn questa sezione parleremo di come possono essere organizzate queste strut-tureinmododarisolverealcunispeciciproblemichesipresentanoalpro-grammatore.Tralestrutturedatipi` ufamosepossiamoelencare:pile,code,liste,alberi.9.5 Lepile:LIFOSi pu`o pensare ad una pila come un insieme di elementi ammassati uno sopralaltroinmodotalechelultimoarrivatosiail primoadesseredisponibileperluso.Unesempiopraticodipila `equellodeipiatti.Sipensidiaveredeipiatti messi unosopralaltro. Quandooccorreunpiattoil primoadessereusatosar`aquelloincimaalmucchio.Quandoinvecesiposaunpiattonellapila questo diventer`a il primo elemento ad essere disponibile. Le pile vengono62 CAPITOLO9. ALLOCAZIONEDINAMICADELLAMEMORIAcorrentementedetteancheLIFO,che `elacronimodiLastInFirstOut,cio`elultimochearriva `eilprimoaduscire.Applicativi tecnici: dati inarrivooinuscitadaunaqualsiasi periferica,schedulazionedeiprocessiallinternodelsistemaoperativo,ecc.Operazionisullepile:InserimentoCancellazioneVisualizzazionedellelementoincimaallapilaSulle pile sono possibili solo un numero limitato di operazioni che ne per-mettonolalorosemplicegestione. Possiamodenireloperazionedi inseri-mento come lintroduzione nella pila di un nuovo elemento che verr`a posto incimaallapila,echediventer`ailprimoelementodisponibileperlestrazione.Lacancellazione/estrazionedallapiladi unelementoavverr`apuredellaltoverso il basso, nel senso che quando decideremo di eliminare un elemento dallapila sar`a sicuramente lelemento che sta in testa; e bene ricordare che lestra-zionedi unelementodallapilaimplicalasuadistruzione. Comeabbiamovistoentrambeleoperazioni precedenti agisconomodicandolostatodellapila. Lunica operazione che possiamo compiere su una pila senza modicarnelostato `elaletturadellelementochesitrovaincimaadessa.1 #include 2 #include 34 /* definizione dellelememto della pila */5 struct elemento {6 char d;7 struct elemento *next;8 /* puntatore al prossimo elemento della pila */9 };1011 /* definizione del puntatore agli elementi della pila */12 struct pila {13 int numero_elementi;14 /* contiene il numero di elementi presenti nella pila */15 struct elemento *top_elem;16 /* puntatore al primo elemento della pila */17 };1819 void inizializza(struct pila *stack);209.5Lepile:LIFO ImparareilCpag.6321 void ins_new_elem(char c, struct pila *s);2223 char estrazione(struct pila *s);242526 int main(){27 /* stringa che verra inserita nella pila */28 char stringa[]="ciao mondo";29 int i;3031 /* puntatore ad una pila */32 struct pila *p;33 p=(struct pila *)malloc(sizeof(struct pila));34 inizializza (&(*p));35 printf("la stringa da inserire nella pila e: %s\n",stringa);36 for(i=0;stringa[i]!=\0; i++)37 ins_new_elem(stringa[i], &(*p));38 printf("dalla pila arriva: ");39 while(p->numero_elementi!=0)40 putchar(estrazione(&(*p)));41 putchar(\n);42 return 0;43 }4445 /* funzione che inizializza la pila */46 void inizializza(struct pila *stack){47 stack->numero_elementi=0;48 /* azzeramento del contatore */49 stack->top_elem=NULL;50 }5152 /* funzione di inserimento di un nuovo elemento */53 void ins_new_elem(char c, struct pila *s){54 struct elemento *new;55 /* puntatore ad una nuova area di memoria */5657 new = (struct elemento *)malloc(sizeof(struct elemento));58 /* allocazione di una nuova area di memoria */59 if(new==NULL){60 printf("memoria non allocata perfettamente\n");61 exit(1);64 CAPITOLO9. ALLOCAZIONEDINAMICADELLAMEMORIA62 }/* verifica che la memoria sia stata correttamente allocata */63 new->d = c;64 /* copia il valore da inserire nella pila nella nuova memoria ottenuta */65 new->next = s->top_elem;66 /* fa puntare il nuovo elemento al primo della pila */67 s->top_elem = new;68 /* inserisce il nuovo elemento in testa alla pila */69 s->numero_elementi++;70 /* incrementa il valore del contatore */71 }7273 char estrazione(struct pila *s){74 char n;75 /* elemento da restituire alla funzione chiamante */76 struct elemento *tmp;77 /* puntatore temporaneo che puntera allarea di78 memoria da eliminare */7980 n=s->top_elem->d;81 /* assegnazione del valore dellelemento in cima82 alla pila a n */83 tmp = s->top_elem;84 /* ora tmp punta allarea di memoria dellelemento85 in cima alla pila */86 s->top_elem = s->top_elem->next;87 /* il secondo elemento della pila diventa il primo88 vengono scambiati cioe gli indirizzi */89 s->numero_elementi--;90 /* viene decrementato il numero degli elementi nella pila */91 free(tmp);92 /* viene liberata la memoria puntata da tmp */93 return n;94 /* viene restituito il valore */95 }969798 /* funzione che restituisce lelemento in cima alla lista */99 char leggi(struct pila *s){100 return s->top_elem->d;101 }9.6Lecode:FIFO ImparareilCpag.659.6 Lecode:FIFOTutti noi abbiamofattoinvitanostraunacoda. Unacoda`euninsiemedielementichesonoordinaticronologicamente,cio`eilprimoelemento `equelloche `einseritodapi` utemponellacodaechesar`autilizzatoperprimo.Unesempiopraticopu`oesserevistonellalachesi faal caselloauto-stradaleoallosportellodellaposta. Il primochearriva`eservito, gli altriaspettanocheilprimoniscaperessereserviti.LecodesonopurechiamateFIFOche `elacronimodiFirstInFirstOutchesignicailprimochearriva`eilprimoaduscire,unpoilcontrariodellecode.Applicazionitecniche:serverdistampa,datiinarrivodaunterminaleacaratteriecc.Operazionisullecode:inserimentoestrazionevisualizzazionedelprimoelementodellacodaLeoperazioni disponibili sullecodesonolestessedisponibili sullecode,ancheseleoperazioni nominalmentesonouguali praticamenteagisconoinmododierente. Nellinserimento, adesempiopossiamonotarecheil nuovoelemento inserito in una coda diventa lultimo. La cancellazione/estrazione diunelementodallacodaimplicachelelementovengadistruttoecheilpostodaluioccupatoadesso `elibero.Lavisualizzazione,comenellepile, `elunicaoperazionechenonmodicalastrutturadellacoda.1 #include 2 #include 34 struct elemento {5 char d; /* dati contenuti nella coda */6 struct elemento *next; /* puntatore ad un nuovo elemento */7 };89 struct coda {10 /* contatore degli elementi della coda */11 int n;12 struct elemento *p;13 struct elemento *u;14 };151617 void inizializza(struct coda *q);66 CAPITOLO9. ALLOCAZIONEDINAMICADELLAMEMORIA1819 void inserisci(char c,struct coda *q);2021 char leggi(const struct coda *q);2223 char estrai(struct coda *q);2425 int main(){26 char str[]="Ciao mondo!";27 int i;28 char d;29 struct coda *c;3031 /* allocazione della memoria per l il nuovo elemento */32 c=(struct coda *)malloc(sizeof(struct coda));33 inizializza(c);34 if(c->n !=0 || c->p !=NULL || c->u !=NULL)35 {36 printf("errore nellinizializzazione\n");37 exit(1);38 }39 /* verifica che linizializzazione sia avvenuta correttamente */40 printf("la stringa che viene inserita nella coda e: %s\n",str);41 for(i=0; str[i]!=\0; i++)42 inserisci(str[i], c);4344 while(c->n!=0){45 d=leggi(c);46 printf("%c",d);47 estrai(c);48 }4950 printf("\n");51 return 0;52 }535455 /* inserisce un nuovo elemento nella coda */56 void inserisci(char c, struct coda *q){57 struct elemento *new;58 /* puntatore ad un nuovo elemento della coda */9.6Lecode:FIFO ImparareilCpag.675960 new=(struct elemento *)malloc(sizeof(struct elemento));61 /* allocazione della memoria */6263 new->d=c; /* copia il parametro */64 new->next=NULL; /* inizializza il puntatore */6566 if(q->n!=0){ /* se la coda non e vuota */67 q->u->next=new;68 /* fa puntare il vecchio ultimo elemento al nuovo ultimo */69 q->u=new; /* inserisci il nuovo elemento alla fine */70 }71 else /* se la coda e vuota */72 q->p=q->u=new;73 /* fa puntare il p e u allo stesso elemento */7475 q->n++; /* incrementa il contatore degli elementi */76 }777879 /* funzione che estrae il primo elemento della coda e */80 /* lo rimpiaza con il secondo */81 char estrai(struct coda *q){82 char pr;83 struct elemento *tmp;8485 pr=q->p->d; /* salva d il primo elemento della coda in pr */8687 tmp=q->p; /* adesso p punta al primo elemento della coda */8889 q->p=q->p->next;90 /* adesso il primo elemento della coda e lelemento */91 /* puntato da next */9293 q->n--; /* decrementa il contatore degli elementi della coda */9495 free(tmp);96 /* libera larea di memoria occupata dal vecchio primo elemento della coda */97 return pr;98 }9968 CAPITOLO9. ALLOCAZIONEDINAMICADELLAMEMORIA100 /* funzione che legge lelemento in te