Sintesi
Sintesi
Fondamenti di Programmazione
Linguaggio c, strutture dati e algoritmi elementari, c++
Indice
Introduzione 1
1 Rappresentazione 3
1.1 Il linguaggio c . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.1 Sintesi . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Testi di approfondimento 11
3
Introduzione
1
Negli anni mi è capitato di tenere il corso in diversi formati. Attualmente lo
presento in un corso di 80-90 ore per 9 Crediti Formativi Universitari (CFU) al
primo semestre del primo anno.
Il nucleo caratterizzante è costituito dalle sezioni ?? dove si fornisce un’intro-
duzione intuitiva al linguaggio, ?? dove si introducono gli elementi di grammatica
che servono ad una trattazione compatta, 1.1 dove si descrive in modo quasi com-
pleto il linguaggio c, e ?? dove se ne dimostra un uso avanzato in riferimento alla
rappresentazione delle liste e dove si introducono vari concetti tra cui dato astrat-
to e rappresentazione, iterazione e ricorsione. Tutto questo richiede tipicamente
3+3+18+9 ore di lezione a cui convenientemente se ne aggiungono altre 6-12 di
esercitazione teorica e pratica con cui si arriva a un totale di 4-5 CFU.
La parte sugli algoritmi nelle sezioni ??, ??, ?? e ?? consolida in qualche
misura l’uso del linguaggio ma soprattutto introduce in modo concreto elementi
essenziali in un corso di Fondamenti di Informatica, tra cui in particolare i concetti
di problema, algoritmo, complessità, correttezza. Tipicamente questo richiede
altre 3+3+15+3 ore a cui se ne aggiungono bene altre 3-6 di esercitazione e se
ne sottraggono bene 6 rimandando a un corso successivo lo HeapSort e il costo
medio del QuickSort. Complessivamente il tutto corrisponde a 2-3 CFU.
La sezioni iniziali ?? e ??, sulla rappresentazione dei dati e sulla rappresen-
tazione e esecuzione di istruzioni su un calcolatore, servono a creare una base che
motivi limiti e caratteristiche del linguaggio. In un corso al primo semestre del
primo anno servono anche a dare un’intuizione concreta sul principio di funziona-
mento di un calcolatore. Complessivamente richiedono circa 18 ore che corrispon-
dono ad ulteriori 2 CFU, ma sarebbe tranquillamente possibile saltare questa parte
e partire direttamente dalla trattazione del linguaggio c.
Le sezioni ?? sugli alberi e 3 sulla transizione dal c al c++ da diversi anni ho
rinunciato a farle. Complessivamente richiederebbero almeno altre 9+9 ore per
altri 2CFU. La parte sugli alberi non è in effetti essenziale per un primo corso di
Informatica e trova posto più adeguatamente in un successivo corso su Strutture
Dati e Algoritmi. Ho qualche maggiore rimpianto per la transizione da c a c++,
che peraltro nel nostro corso di laurea è sviluppata con maggiore ampiezza e
profondità, e con ottimi risultati, in un modulo di laboratorio immediatamente
successivo.
2
Capitolo 1
Rappresentazione
3
1.1 Il linguaggio c
In questo capitolo viene definito il linguaggio c.
La trattazione fa leva congiuntamente sui capitoli precedenti, con diversi gradi
di dipendenza: la descrizione informale del frammento di linguaggio c nel capitolo
?? aiuta la comprensione fornendo una visione di insieme, ma è completamente
coperta da quanto viene ora esposto; la trattazione dei capitoli ?? e ?? circa
il modo in cui un programma c può essere compilato in assembler, tradotto in
linguaggio macchina ed eseguito su un processore mostra un razionale per alcune
caratteristiche del linguaggio, ma può essere anche omessa; gli elementi di teoria
dei linguaggi forniti nel capitolo ?? sono invece usati diffusamente e risultano
strettamente necessari per la comprensione.
4
1.1.1 Sintesi
Ricapitoliamo in questa sezione la sintassi e la semantica generale delle categorie
introdotte nella descrizione del linguaggio c.
Tipi
<type> ::= char|[unsigned][short|long]int|float|double|void
<type expr> ::= <type>|struct<identifier>*|<type expr>*
<type decl> ::= <type>|struct<identifier>
<struct def> ::= struct<identifier>{ { <declaration> } };
Vincoli contestuali: in <type expr> e <type decl>, il nome <identifier> deve
comparire in una <struct def> visibile.
La semantica di un tipo <type> consiste di un insieme di valori rappresentati e
un insieme di operazioni sui valori. La stessa semantica si applica a <type expr>
e <type decl>, che costituiscono estensioni diverse strumentali a catturare le
limitazioni imposte sul tipo del valore restituito da un’espressione.
Dichiarazioni
<declaration> ::= <type decl><decl>;
<decl> ::= <identifier>|*<decl>|<decl>[<const>]|
(<decl>)|<decl>(<formal parameter list>)
<formal parameter list> ::= void|<type decl><decl>{,<type><decl>}
Vincoli contestuali: il tipo di una funzione deve appartenere a <type expr>.
La semantica di una dichiarazione <declaration> consiste nell’associare un nome
e un tipo a un’entità referenziabile, che può essere una variabile, un’array, una
funzione.
Riferimenti a variabile
<var>::=<identifier>|(<var>)|*<expr addr>|<expr addr>[<expr int>]|
<var s>.<identifier field>|<expr s>-><identifier field>
Vincoli contestuali: <identifier> deve essere il nome identificato in una
<declaration> visibile; <expr addr> deve restituire un indirizzo; <expr int>
deve restituire un intero; <var s> deve essere un riferimento a variabile di tipo
strutturato; <expr s> deve restituire l’indirizzo di una variabile di tipo strutturato;
<identifier field> deve essere il nome identificato in una <declaration>
contenuta in una <struct def> visibile.
La semantica di un riferimento a variabile <var> consiste nell’identificare una
variabile, ovvero una locazione di memoria e un tipo.
5
Espressioni
Istruzioni
<statement> ::= <expr>;|
<statement1><statement2>|{<statement1>}|
if(<expr>)<statement1> [else<statement2>]|
for(<expr init>;<expr guard>;<expr inc>)
<statement>|
while(<expr guard>)<statement>|
do<statement>while(<expr guard>);|
return[<expr>];|goto<label>;|break;|continue;|
switch(<expr>)
{ {case <const>:<statement>}
[default:<statement>]
}
6
Programma
Un programma è costituito da una sequenza di direttive, di definizioni di strutture
e di tipi, di dichiarazioni di funzioni o variabili, e di definizioni di funzione ciascuna
costituita da una sequenza di dichiarazioni e statements.
<program> ::= { <directive>|
typedef <type> <identifier>;|
<declaration>|
<function definition>
}
<function definition> ::= <type><decl>(<formal parameter list>)
{ {declaration}
<statement>
}
<directive>::=#include<filename.h>|#define<identifier><any>|...
7
8
Capitolo 2
9
10
Capitolo 3
11
12
Testi di approfondimento
Architettura dei calcolatori:
• D.A.Patterson, J.L.Hennessy, “Struttura e progetto dei calcolatori,” Zanichel-
li, Bologna, 1995.
• G.Bucci, “Architettura e organizzazione dei calcolatori elettronici - fonda-
menti ,” McGraw-Hill Italia, Milano, 2001.
Linguaggio c:
• H.Schildt, “c, the complete reference,” McGraw-Hill, 2000.
• E.Yourdon, L.Constantine, “Structured design: fundamentals of a discipline
of Computer programming and system design,” Prentice Hall, 1986.
Linguaggio c++:
• E.Gamma, R.Helm, R.Johnson, J.Vlissides, “Design Patterns: elements of
reusable object oriented software,” Addison Wesley, 1995.
• M.Fowler, “UML distilled,” Addison Wesley, 2000.
• H.Schildt, “c++, the complete reference,” McGraw-Hill, 2002.
• J.Arlow, I.Neustadt, “UML e Unified Process,” McGraw Hill, 2003.
• K.Beck, “Embracing change with eXtreme Programming,” IEEE Computer,
Vol.32, No.10, 1999.
13