|
|
|
| << | < | > | >> |Indice
Prefazione 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à.
|