|
|
| << | < | > | >> |IndicePrefazione XV PARTE PRIMA - LE BASI DEL C++: IL LINGUAGGIO C 1 Capitolo 1 - Una panoramica sul linguaggio C 3 1.1 Le origini del linguaggio C 3 1.2 Il C è un linguaggio di medio livello 4 1.3 Il C è un linguaggio strutturato 5 1.4 Il C è un linguaggio per programmatori 7 1.5 L'aspetto di un programma C 9 1.6 La libreria e il linker lO 1.7 Compilazione separata 12 1.8 Le estensioni di file: .c e .cpp 12 Capitolo 2 - Le espressioni 15 2.1 I cinque tipi di dati principali 15 2.2 Modificare i tipi principali 16 2.3 Nomi degli identificatori 18 2.4 Le variabili 19 2.5 I modificatori di accesso 25 2.6 Specificatori di classe di memorizzazione 27 2.7 Inizializzazione delle variabili 34 2.8 Le costanti 35 2.9 Gli operatori 38 2.10 Le espressioni 56 Capitolo 3 - Le istruzioni 61 3.1 La verità e la falsità in C e C++ 62 3.2 Le istruzioni di selezione 62 3.3 Le istruzioni di iterazione 74 3.4 La dichiarazione di variabili nelle istruzioni di selezione e iterazione 85 3.5 Le istruzioni di salto 86 3.6 Le espressioni 92 3.7 I blocchi 93 Capitolo 4 - Gli array e le stringhe 95 4.1 Gli array monodimensionali 95 4.2 La generazione di un puntatore a un array 97 4.3 Come passare un array monodimensionale a una funzione 98 4.4 Le stringhe 99 4.5 Gli array bidimensionali 102 4.6 Gli array multidimensionali 108 4.7 L'indicizzazione dei puntatori 109 4.8 L'inizializzazione degli array 111 4.9 L'esempio del tris (tic-tac-toe) 114 Capitolo 5 - I puntatori 119 5.1 Che cosa sono i puntatori? 119 5.2 Variabili puntatore 120 5.3 Gli operatori per i puntatori 121 5.4 Espressioni con puntatori 122 5.5 Puntatori e array 127 5.6 Indirizzamento multilivello 129 5.7 Inizializzazione di puntatori 131 5.8 Puntatori a funzioni 133 5.9 Le funzioni di allocazione dinamica del C 136 5.10 Problemi con i puntatori 138 Capitolo 6 - Le funzioni 143 6.1 La forma generale di una funzione 143 6.2 Regole di visibilità delle funzioni 144 6.3 Gli argomenti delle funzioni 145 6.4 Gli argomenti di main(): argc e argv 150 6.5 L'istruzione retum 154 6.6 Ricorsione 160 6.7 Prototipi di funzioni 162 6.8 Dichiarazione di elenchi di parametri di lunghezza variabile 165 6.9 Dichiarazione di parametri con metodi vecchi e nuovi 165 6.10 Elementi implementativi 166 Capitolo 7 - Strutture, unioni, enumerazioni e tipi definiti dall'utente 169 7.1 Le strutture 170 7.2 Gli array di strutture 174 7.3 Il passaggio di strutture alle funzioni 175 7.4 I puntatori a strutture 177 7.5 Gli arraye strutture all'interno di altre strutture 181 7.6 I campi bit 182 7.7 Le unioni 185 7.8 Le enumerazioni 188 7.9 Uso di sizeof per assicurare la trasportabi1ità del codice 191 7.10 La parola riservata typedef 193 Capitolo 8 - Operazioni di I/O da console 195 8.1 Un'importante nota applicativa 196 8.2 La lettura e la scrittura di caratteri 196 8.3 La lettura e la scrittura di stringhe 199 8.4 Le operazioni di I/O formattato da console 202 8.5 La funzione printf() 203 8.6 La funzione scanf() 211 Capitolo 9 - Operazioni di I/O da file 219 9.1 Operazioni di I/O C e C++ 219 9.2 Stream e file 220 9.3 Gli stream 220 9.4 I file 221 9.5 Principi di funzionamento del file system 222 9.6 fread() e fwrite() 235 9.7 fseek() e operazioni di I/O ad accesso diretto 237 9.8 fprint() e fscanf() 239 9.9 Gli stream standard 240 Capitolo 10 - Il preprocessore e i commenti 245 10.1 Il preprocessore 245 10.2 La direttiva #define 246 10.3 La direttiva #error 249 10.4 La direttiva #include 250 10.5 Le direttive per compilazioni condizionali 250 10.6 La direttiva #undef 254 10.7 Uso di defined 255 10.8 La direttiva #line 256 10.9 La direttiva #pragma 256 10.10 Gli operatori del preprocessore # e ## 257 10.11 Le macro predefinite 258 10.12 I commenti 259 PARTE SECONDA - IL LINGUAGGIO C++ 261 Capitolo 11 - Panoramica del linguaggio C++ 263 11.1 Le origini del C++ 263 11.2 Che cos'è la programmazione a oggetti 265 11.3 Elementi di base del linguaggio C++ 268 11.4 C++ vecchio stile e C++ moderno 275 11.5 Introduzione alle classi C++ 279 11.6 L'overloading delle funzioni 284 11.7 L'overloading degli operatori 287 11.8 L'ereditarietà 288 11.9 I costruttori e i distruttori 293 11.10 Le parole riservate del C++ 297 11.11 Laforma generale di un programma C++ 297 Capitolo 12 - Le classi e gli oggetti 299 12.1 Le classi 299 12.2 Le strutture e le classi 303 12.3 Le unioni e le classi 305 12.4 Le funzioni friend 307 12.5 Le classi friend 312 12.6 Le funzioni inline 313 12.7 Definizione di funzioni inline all'interno di una classe 316 12.8 I costruttori parametrizzati 317 12.9 I membri static di una classe 320 12.10 Quando vengono eseguiti i costruttori e i distruttori? 327 12.11 L'operatore di risoluzione del campo d'azione 329 12.12 La nidificazione delle classi 330 12.13 Le classi locali 330 12.14 Il passaggio di oggetti a funzioni 331 12.15 La restituzione di oggetti 334 12.16 L'assegnamento di oggetti 335 Capitolo 13 - Gli array, i puntatori, gli indirizzi e gli operatori di allocazione dinamica 337 13.1 Gli array di oggetti 337 13.2 I puntatori a oggetti 341 13.3 Verifiche di tipo sui puntatori C++ 343 13.4 Il puntatore this 343 13.5 I puntatori a tipi derivati 345 13.6 I puntatori ai membri di una classe 348 13.7 Gli indirizzi 351 13.8 Questione di stile 359 13.9 Gli operatori di allocazione dinamica del C++ 360 Capitolo 14 - Overloading di funzioni, costruttori di copie e argomenti standard 371 14.1 Overloading delle funzioni 371 14.2 Overloading delle funzioni costruttore 373 14.3 I costruttori di copie 377 14.4 Ricerca dell'indirizzo di una funzione modificata tramite overloading 381 14.5 L'anacronismo della parola riservata overload 383 14.6 Gli argomenti standard delle funzioni 383 14.7 Overloading di funzioni e ambiguità 390 Capitolo 15 - Overloading degli operatori 395 15.1 Creazione di una funzione operator membro 396 15.2 Overloading di operatori tramite funzioni friend 403 15.3 Overloading di new e delete 409 15.4 Overloading di alcuni operatori particolari 418 15.5 Overloading dell'operatore virgola 425 Capitolo 16 - L'ereditarietà 429 16.1 Controllo dell'accesso alla classe base 429 16.2 Ereditarietà dei membri protected 432 16.3 Ereditarietà da più classi base 436 16.4 Costruttori, distruttori ed ereditarietà 437 16.5 Accesso alle classi 445 16.6 Classi base virtuali 448 Capitolo 17 - Funzioni virtuali e polimorfismo 453 17.1 Le funzioni virtuali 453 17.2 L'attributo virtual viene ereditato 458 17.3 Le funzioni virtuali sono gerarchiche 459 17.4 Le funzioni virtuali pure 462 17.5 Uso delle funzioni virtuali 464 17.6 Il binding anticipato e il binding ritardato 467 Capitolo 18 - I template 469 18.1 Funzioni generiche 469 18.2 Uso delle funzioni generiche 478 18.3 Classi generiche 482 18.4 Le parole riservate typename ed export 493 18.5 La potenza deitemp1ate 494 Capitolo 19 - Gestione delle eccezioni 497 19.1 Principi di gestione delle eccezioni 497 19.2 Gestione delle eccezioni per classi derivate 506 19.3 Opzioni della gestione delle eccezioni 507 19.4 Le funzioni terminate() e unexpected() 513 19.5 La funzione uncaughcexception() 515 19.6 Le classi exception e bad_xception 515 19.7 Applicazioni della gestione delle eccezioni 516 Capitolo 20 - Il sistema di I/0 C++: le basi 519 20.1 Operazioni di I/O C++ vecchie e nuove 520 20.2 Gli stream del C++ 520 20.3 Le classi per stream C++ 520 20.4 Operazioni di I/O formattato 522 20.5 Overloading di « e » 535 20.6 Creazione di funzioni di manipolazione 544 Capitolo 21 - Operazioni di I/0 su file in C++ 549 21.1 L'header |
| << | < | > | >> |Pagina 1In questo volume la descrizione del linguaggio C++ viene suddivisa in due parti. La Parte prima si occupa delle funzionalità che il C++ ha in comune con il suo progenitore, il C. Infatti il linguaggio C rappresenta un sottoinsieme del C++. La Parte seconda descrive le funzionalità specifiche del C++. Insieme, queste due parti, descrivono dunque il linguaggio C++. Come forse molti sanno, il C++ si basa sul linguaggio C. In pratica si può dire che il C++ include l'intero linguaggio C e (tranne lievi eccezioni), tutti i programmi C sono anche programmi C++. Quando fu inventato il linguaggio C++, venne impiegato come base il linguaggio C al quale vennero aggiunte molte nuove funzionalità ed estensioni con lo scopo di garantire il supporto della programmazione orientata agli oggetti (OOP). Questo non significa che gli aspetti che il C++ ha in comune con il C siano stati abbandonati ma, a maggior ragione, il C standard ANSI/ISO costituisce il documento di partenza per lo Standard Internazionale per il C++. Pertanto, la conoscenza del linguaggio C++ implica una conoscenza del linguaggio C. In un volume come questa Guida completa, il fatto di suddividere il linguaggio C++ in due parti (le basi C e le funzionalità specifiche del C++) consente di ottenere tre vantaggi. 1. Si delinea con chiarezza la linea di demarcazione esistente fra C e C++. 2. I lettori che già conoscono il linguaggio C potranno facilmente trovare informazioni specifiche sul linguaggio C++. 3. Viene fornito un modo per discutere quelle funzionalità del linguaggio C++ che sono più legate al sottoinsieme costituito dal linguaggio C. Comprendere la linea di divisione esistente fra C e C++ è importante poiché si tratta in entrambi i casi di linguaggi molto utilizzati e dunque è molto probabile che prima o poi venga richiesto di scrivere o eseguire la manutenzione di codice C e C++. Quando si lavora in C si deve sapere esattamente dove finisce il C e dove inizia il C++. Molti programmatori C++ si troveranno talvolta a scrivere codice che deve rientrare nei limiti stabiliti dal "sottoinsieme C". Questo accade particolarmente nel campo della programmazione di sistemi e della manutenzione di applicazioni preesistenti. Conoscere la differenza fra C e C++ è parte integrante della propria esperienza di programmatore C++ professionale. Una buona comprensione del linguaggio C è insostituibile anche quando si deve convertire del codice C in C++. Per svolgere l'operazione in modo professionale, è necessario conoscere in modo approfondito anche il linguaggio C. Ad esempio, senza una conoscenza approfondita del sistema di I/O del C è impossibile convertire in modo efficiente dal C al C++ un programma che esegua notevoli operazioni di I/O. | << | < | > | >> |Pagina 3Conoscere il C++ significa conoscere le forze che hanno portato alla sua creazione, le idee che gli hanno dato il suo aspetto e i "caratteri" che ha ereditato. Pertanto la storia del C++ non può che partire dal C. Questo capitolo presenta una panoramica del linguaggio di programmazione C, le sue origini, il suo utilizzo e la sua filosofia. Poiché il C++ si basa sul C, questo capitolo presenta anche un'importante prospettiva storica sulle radici del C++. Molti degli elementi che hanno reso il linguaggio C++ quello che è hanno la loro origine nel linguaggio C. 1.1 Le origini del linguaggio C Il C fu inventato e implementato per la prima volta da Dennis Ritchie su un sistema DEC PDP-11 che impiegava il sistema operativo Unix. Il C è il risultato di un processo di sviluppo che è partito da un linguaggio chiamato BCPL. Il BCPL, sviluppato da Martin Richards, influenzò un linguaggio chiamato B, inventato da Ken Thompson. Il B portò allo sviluppo del C negli anni '70.
Per molti anni, lo standard de facto del C fu la versione fornita con il
sistema operativo Unix versione 5. Il linguaggio fu descritto per la prima volta
nel volume
The C Programming Language
di Brian Kernighan e Dennis Ritchie.
Nell'estate del 1983 venne nominato un comitato con lo scopo di creare uno
standard ANSI (American National Standards Institute) che definisse il
linguaggio C una volta per tutte. Il processo di standardizzazione richiese sei
anni (molto più del previsto). Lo standard ANSI C fu infine adottato nel
dicembre del 1989 e le prime copie si resero disponibili all'inizio del 1990. Lo
standard venne anche adottato dall'ISO (Intemational Standards Organization) ed
ora è chiamato Standard C ANSI/ISO. Per semplicità si userà semplicemente il
termine Standard C. Oggi, tutti i principali compilatori C/C++ seguono lo
Standard C. Inoltre, lo Standard C è anche alla base dello Standard C++.
1.2 Il C è un linguaggio di medio livello. Il C è considerato da molti un linguaggio di medio livello. Questo non significa che il C sia meno potente, più difficile da utilizzare o meno evoluto rispetto a un linguaggio ad alto livello come il BASIC o il Pascal, né che il C abbia la natura complicata del linguaggio Assembler (con tutti i problemi derivanti). Piuttosto, significa che il C è un linguaggio che riunisce i migliori elementi dei linguaggi ad alto livello con le possibilità di controllo e la flessibilità del linguaggio Assembler. La Tabella 1.1 mostra la posizione del C nello spettro dei linguaggi per computer. Essendo un linguaggio di medio livello, il C consente la manipolazione di bit, byte e indirizzi, gli elementi su cui si basa il funzionamento di un computer. Nonostante ciò, il codice C è anche molto trasportabile. Con trasportabilità si intende la facilità di adattare su un sistema un software scritto per un altro computer o sistema operativo. Ad esempio, se è possibile convertire con facilità un programma scritto per il DOS in modo che possa essere utilizzato sotto Windows, significa che tale programma è trasportabile. [...] La peculiarità del C consiste nella possibilità di manipolare direttamente i bit, i byte, le word e i puntatori. Questo lo rende adatto alla programmazione di software di sistema, in cui queste operazioni sono molto comuni. Un altro aspetto importante del C è la presenza di solo 32 parole chiave (27 derivanti dallo standard "de facto" Kernighan e Ritchie e 5 aggiunte dal comitato di standardizzazione ANSI), che sono i comandi che formano il linguaggio C. Normalmente i linguaggi di alto livello hanno molte più parole chiave. Come confronto, si può ricordare che la maggior parte delle versioni di BASIC conta più di 100 parole chiave! | << | < | > | >> |Pagina 263Questo capitolo presenta una panoramica dei concetti di base che hanno condotto allo sviluppo del C++. Il C++ è un linguaggio di programmazione a oggetti le cui funzionalità sono strettamente correlate fra loro. In molti casi, questa correlazione rende difficile descrivere una funzionalità del C++ senza menzionarne nel contempo anche altre. In molte situazioni, le funzionalità a oggetti del C++ sono così correlate fra loro che per trattare una funzionalità è necessario che il lettore sia a conoscenza di una o più funzionalità correlate. Per risolvere questo problema, questo capitolo presenta una rapida panoramica degli aspetti più importanti del C++, la sua storia, le sue funzionalità principali e le differenze esistenti fra il C++ tradizionale e quello definito dallo standard. I capitoli successivi di questa parte della guida esaminano più in dettaglio il C++. 11.1 Le origini del C++ Il linguaggio C++ nacque come estensione del C. Le estensioni del C++ sono state inizialmente sviluppate da Bjarne Stroustrup nel 1979 presso i laboratori Bell di Murray Hill nel New Jersey. Inizialmente il nuovo linguaggio fu chiamato semplicemente "C con classi". Nel 1983 questo nome venne cambiato in C++. Anche se il linguaggio C è stato uno dei linguaggi di programmazione professionali più apprezzati e ampiamente utilizzati al mondo, l'invenzione del C++ fu dettata dalla necessità di raggiungere maggiori livelli di complessità. Nel trascorrere degli anni, i programmi per computer sono diventati sempre più estesi e complessi. Anche se il C è un linguaggio di programmazione eccellente, anch'esso ha i propri limiti. In C, quando un programma supera le 25.000 o le 100.000 righe di codice, diviene così complesso che risulta difficile considerarlo nella sua totalità. Il C++ consente di superare questa barriera. L'essenza del C++ è stata quindi concepita con lo scopo di permettere ai programmatori di comprendere e gestire programmi più estesi e complessi. La maggior parte delle funzionalità aggiunte da Stroustrup al C consente il supporto della programmazione a oggetti, chiamata anche OOP (per una breve descrizione della programmazione a oggetti, si consulti la prossima sezione di questo capitolo). Stroustrup asserisce che alcune delle funzionalità a oggetti del C++ sono state ispirate da un altro linguaggio di programmazione a oggetti il Simula67. Pertanto, il C++ rappresenta il punto di unione fra due dei metodi di programmazione più potenti. | << | < | > | >> |Pagina 26511.2 Che cos'è la programmazione a oggettiPoiché la programmazione a oggetti (OOP) ha dato origine al C++, è necessario comprendere i suoi principi fondamentali. La programmazione a oggetti rappresenta un nuovo e potente metodo di programmazione. Le metodologie di programmazione sono cambiate notevolmente dall'invenzione del computer, soprattutto per consentire di aumentare la complessità dei programmi. Ad esempio, quando furono inventati i computer, la programmazione veniva eseguita impostando istruzioni binarie tramite il pannello frontale del computer. Finché i programmi erano composti da poche centinaia di istruzioni, questo approccio ha funzionato. Con la crescita dei programmi è stato sviluppato il linguaggio Assembler con il quale un programmatore poteva realizzare programmi più estesi e complessi, utilizzando rappresentazioni simboliche delle istruzioni in linguaggio macchina. Ma i programmi continuavano a crescere e furono perciò introdotti linguaggi di alto livello che davano al programmatore più strumenti per gestire questa nuova richiesta di complessità. Il primo linguaggio di questo genere fu naturalmente il FORTRAN. Anche se il FORTRAN è stato un notevole passo in avanti rispetto al passato, si trattava di un linguaggio che non incoraggiava la realizzazione di programmi chiari e facili da comprendere. Il 1960 ha dato i natali alla programmazione strutturata. Questo è il metodo seguito da linguaggi come il C e il Pascal. L'impiego di linguaggi strutturati ha reso possibile la realizzazione di programmi piuttosto complessi con una discreta facilità. I linguaggi strutturati sono caratterizzati dal supporto di subroutine indipendenti, variabili locali, costrutti di controllo avanzati e dal fatto di non impiegare GOTO. Tuttavia, anche utilizzando metodi di programmazione strutturata, un progetto può diventare incontrollabile una volta che raggiunga determinate dimensioni. Si consideri questo fatto: ad ogni punto di svolta nel campo della programmazione, sono stati creati strumenti e tecniche che consentivano al programmatore di realizzare programmi più complessi. Ogni passo in questo percorso consisteva nell'utilizzo dei migliori elementi dei metodi precedenti e nel loro sviluppo. Prima dell'invenzione della programmazione a oggetti, molti progetti raggiungevano o superavano il punto in cui l'approccio strutturato non può più essere adottato. La programmazione a oggetti è nata con lo scopo di superare questa barriera.
La programmazione a oggetti ha preso le migliori idee della programmazione
strutturata e le ha combinate con nuovi concetti. Il risultato è
un'organizzazione
completamente nuova dei programmi. In generale un programma può essere
realizzato in due modi: ponendo al centro il codice ("ciò che accade") o ponendo
al centro i dati ("gli attori interessati"). Utilizzando le tecniche della
programmazione strutturata, i programmi vengono tipicamente organizzati attorno
al codice. Questo approccio prevede che il codice operi sui dati. Ad esempio, un
programma scritto con un linguaggio di programmazione strutturato come il C è
definito dalle sue funzioni, le quali operano sui dati usati dal programma. I
programmi a oggetti seguono l'altro approccio. Infatti sono organizzati attorno
ai dati e si basano sul fatto che sono i dati a controllare l'accesso al codice.
In un linguaggio a oggetti si definiscono i dati e le routine che sono
autorizzate ad agire su tali dati. Pertanto sono i dati a stabilire quali sono
le operazioni che possono essere eseguite. I linguaggi che consentono di attuare
i principi della programmazione a oggetti hanno tre fattori in comune:
l'incapsulamento, il polimorfismo e l'ereditarietà.
|