Università dell’Insubria
Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese
Corso di Laurea in Informatica
Anno Accademico 2004/05
Laboratorio di Linguaggi
Marco Tarini
Laboratorio di Linguaggi
• docente: Marco Tarini
e-mail: [email protected]
• ricevimento: Martedì 14:30 - 17:30
o anche su appuntamento
• libro di testo consigliato:
Kelley Al, Pohl Ira:
"C Didattica e Programmazione" ("A Book on C")
quarta edizione - anche la terza va bene
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Laboratorio di Linguaggi
• link utile: http://vcg.isti.cnr.it/~tarini/linguaggi/
– guida essensiale di alcuni
emementi di C
v = argomanto
già trattato
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Linguaggio C: cenni storici
• 1972: nasce il C,
– by Brian Kernighan & Dennis M.Richie, AT&T Bell Labs
– scopo: poter riscrivere in un linguaggio a più alto livello il
codice del sistema operativo UNIX
– evoluzione del B
• Anni 80: si sviluppa il C tradizionale
• 1983: comincia la definizione dello standard ANSI C,
– (ANSI = American National Standards Institute)
• 1990: nascita ufficiale dello "ANSI C"
– (o "ANSI ISO/C")
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Caratteristiche del Linguaggio C
• Linguaggio imperativo
– con numerosi tipi di dato e strutture di controllo
• "Medio" livello
–
–
–
–
cioè più basso di Java!
gestione memoria diretta
gestione files diretta
puntatori…
• Focalizzato su efficienza e compattezza di codice
• Linguaggio scarno, ma estendibile
– esistono molte librerie per operazioni non definite dal linguaggio…
• Possibile sviluppare progetti modulari
– composti da più files sorgente (source files) compilabili separatamente
– molto utile per progetti complessi
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Caratteristiche del Linguaggio C
• Il C è un linguaggio tipizzato
– cioè: il tipo di ogni espressione è del tutto noto
al momento della compilazione
x = y + z ;
int
int
int
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Caratteristiche del Linguaggio C
• Il C usa il Binding statico!
viene definita la variabile
globale intera "a",
(che vale 5)
viene definita la
procedura "proc" che…
…scrive il
valore di a
viene definita un altra
variabile locale intera "a",
(che vale 10)
viene invocata la
procedura "proc"
int a=5;
void proc()
{
printf("%d",a);
}
void main()
{
int a=10;
proc();
}
Marco Tarini ‧ Laboratorio di Linguaggi ‧
bindind statico:
il programma
scrive "5"
se bindind fosse
dinamico,
il programma
scriverebbe "10" !
2004/05 ‧ Università dell’Insubria
C e Java a confronto...
• i costrutti sono simili
ma
i++
...
if (x<0) x=-x;
...
è più elegante
dell’ l’equivalente
i=i+1
int x=1, i;
for (i=1; i<=10; i=i+1) {
x = x * i;
}
int log2=0, x=100;
while (x>1) {
x = x / 2;
log2++;
}
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
C e Java a confronto...
• ma scordatevi...
– la programmazione ad oggetti (le classi)
• in C niente metodi* !
– (* member functions che si applicano all’oggetto che le chiama)!
• solo funzioni globali
• ...se volete pensatele come metodi statici
– macchine astratte (“java runtime environment”)
• il C è molto, molto concreto
• gestione diretta della macchina
• puramente compilato, non compilato-poi-interpretato
– gestione delle eccezioni...
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Un programma in C
• Un programma è un’insieme di
– funzioni, e
– variabili.
• La funzione main
– funzione speciale, è l’inizio del programma
– deve esistere
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Le variabili
• Dichiarazioni (semplici)
tipo (delle variabili x, y, z, w):
int (intero)
opzionalmente,
le variabili possono essere
inizializzate
qui, il valore iniziale di z è 5
int x , y , z = 5, w;
float ratio, ratio_bis ;
tipo (delle variabili ratio e ratio_bis):
float (intero)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Le funzioni
int potenza (int b, int e)
{
int res=1 , i;
for (i=1; i<=e; i++) {
res = res * b;
}
return res;
}
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Le funzioni
tipo del risultato: intero
(output della funzione)
corpo della
funzione
“cosa fa”
un blocco
delimitato
da {}
nome
(identificatore)
della funzione:
“potenza”
lista dei parametri formali,
ciascuno preceduto dal tipo
(input della funzione)
int potenza (int b, int e)
{
int res=1 , i;
for (i=1; i<=e; i++) {
res = res * b;
}
return res;
}
variabili locali
• qui, due
• visibili solo
nel corpo
della
funzione.
• dichiarate
all’inizio!
comando “return”:
restituzione del
risultato, e uscita dalla
funzione
ci deve essere!
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Le procedure
• Sono funzioni...
...solo, non restituiscono nessun valore
tipo del risultato:
“void” (nessuno)
void saluta_n_volte (int n)
{
int i;
for (i=1; i<=n; i++) {
printf("ciao ");
}
}
nota:
niete comando “return” nel corpo.
(ma si può usare “return”, senza
valore, per uscire dalla funzione)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Chiamare le funzioni
int potenza (int b, int e)
{
int res=1 , i;
for (i=1; i<=e; i++) {
res = res * b;
};
return res;
}
int main(){
int base=10, milione;
milione = potenza( base, 6);
...
}
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Errori comuni di C...
• le variabili locali si possono definire
solo all’inizio di una funzione!
{
{
int x=1;
for (int i=1; i<=10; i=i+1) {
x = x * i;
};
int
z =
int
w =
NO
}
}
{
{
int x=1, i;
for (i=1; i<=10; i=i+1) {
x = x * i;
}
x=2, z, k=5;
x+k;
h=4, w;
w+h;
int x=2, z,w, k=5, h=4;
z = x+k;
w = w+h;
SI
}
}
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Errori comuni di C...
• Vietato annidare funzioni!
– le funzioni in C sono tutte allo stesso livello
int funzione_uno (int b, int e)
{
int x, y;
int funzione_due( int a) {
...
}
funzione annidata
(nested function)
male, male...
(non compilerà)
...
}
–(ma, è vero, si può fare ad esempio in Pascal)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Passaggio di parametri
• Sempre per copia
– mai per riferimento !
– esempio...
void raddoppia (int x)
{
x = x*2;
}
int main(){
int incassi = 5;
raddoppia( incassi );
...
};
–...di errore
–nota: compila perfettamente!
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Commenti
• Usare /* e */ per delimitare i commenti
commento stile C++
facile che non vada
bene per il vs
compilatore C
non ANSI !
non va bene a me
int main(){
/* commento ansi C */
int x=10,y;
while (x<6) { ... };
/* commento ansi C
lungo due righe
*/
y = x / 2;
// tentativo di commento
}
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Commento sui Commenti
• Usetali !
/*
funzione potenza:
dati due numeri interi B e E
restituisce B alla E
*/
int potenza (int b, int e)
{
int res=1 , i;
for (i=1; i<=e; i++) {
res = res * b;
};
return res;
}
int main(){
int base=10, milione;
/* modo scemo di calcolare un milione */
milione = potenza( base, 6);
/*resto del codice ... */
};
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Strumento: Dev-CPP
•
•
•
•
un Ambiente Integrato di Sviluppo per C (e C++)
Web: http://www.bloodshed.net/dev/devcpp.html,
Free Software (GNU General Public License).
L’installatore è scaricabile da:
http://prdownloads.sourceforge.net/devcpp/devcpp4990setup.exe
cioè
software “libero”,
non “gratis”
(lo sapevate, vero?)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Come Usare Dev-CPP
• Installare, eseguire
• File → New → Project…
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Come Usare Dev-CPP
• Installare, eseguire
• File → New → Project…
• Selezionare:
1) "Console
Application"
2) "C Project"
3) Immette
un nome
per il progetto
Marco Tarini ‧ Laboratorio di Linguaggi ‧
4) ok!
2004/05 ‧ Università dell’Insubria
Come Usare Dev-CPP
• Immettere il path
per un maggior
ordine, meglio
creare una
directory
per il nuovo
progetto.
NOTA: a ricevimento
se avete domande
su un progetto
potete portarmi
una copia
della directory
creata
(per esempio in un floppy)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Come Usare Dev-CPP
• Abbiamo un nuovo "progetto"
premere questo
piccolo "+"
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Come Usare Dev-CPP
• Abbiamo un nuovo "progetto"
codice
dentro
"main.cpp"
unico file
del progetto
(per ora):
"main.c"
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Come Usare Dev-CPP
• Abbiamo un nuovo "progetto"
questa piccola [*] significa che
"main.c" non è ancora stato
salvato...
…salviamolo
premendo su
questa icona
(ci verrà chisto
che nome di file
usare. Confermare pure
il default)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Come Usare Dev-CPP
• Abbiamo un nuovo "progetto"
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Come Usare Dev-CPP
• Abbiamo un nuovo "progetto": compiliamolo
– "Execute → Complile"
oppure premere
su questa icona
…oppure Ctrl-F9
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Come Usare Dev-CPP
• Abbiamo un nuovo "progetto": compiliamolo
nessun
errore!
Marco Tarini ‧ Laboratorio di Linguaggi ‧
nessun
"warining"!
2004/05 ‧ Università dell’Insubria
Come Usare Dev-CPP
• Ora eseguiamo il progetto
– "Execute → Run"
oppure premere
su questa icona
…oppure Ctrl-F10
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Come Usare Dev-CPP
• Ora eseguiamo il progetto
– Risultato dell'esecuzione
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Come Usare Dev-CPP
• In seguito, per ritornare sullo stesso progetto…
– "Execute → Open Project or File…"
…e selezionare
il file ".dev"
col nome
corrispondente
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Cosa fa il programma di prova?
• non molto…
dichiaria che verranno usate due librerie standard:
“standard Input Output” e “Standard Library”
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
system("PAUSE");
return 0;
}
“press any key to continue”
utile per permettere di visualizzare l’output del
programma prima che la finestra si chiuda
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Cosa fa il programma di prova?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
aggiungiam
o
printf("Ciao Mondo!\n");
system("PAUSE");
return 0;
}
• ricompliamo & rieseguiamo
– abbiamo ottenuto il nostro primo programma “hello world”
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Cosa è successo esattamente
quando abbiamo "complilato" il progetto?
in C
(quasi)
linguaggio
macchia
ancora in C
Source
File
"main.c"
preprocessor
file
precomp.
• Solo operazioni sintattiche:
compiler
object
file
"main.o"
• La compilazione vera
e propria
– risoluzioni delle “macro”
– inclusioni di files di “header”
– codici alternativi
• per esempio, per le varie piattaforme
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Cosa è successo esattamente
quando abbiamo "complilato" il progetto?
Source
File 1
"main.c"
Source
File 2
"pippo.c"
Source
File 3
“pluto.c"
preprocess.
file
precomp. compiler
1
preprocess.
file
precomp. compiler
2
preprocess.
file
precomp. compiler
3
object
file
"main.o"
object
file
"pippo.o"
object
file
“pluto.o"
linker
eseguibile
finale
"prova.exe"
libreria A
libreria B
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Preprocessore
• Sostituzioni delle macro (costanti simboliche)
– puramente sintattiche!
#define LIMIT
10
•
•
# = istruzione per il preprocessore:
≪d'ora in poi, quando scrivo LIMIT,
fai finta che abbia scritto 10≫
int main()
{
...
if (x < LIMIT) {
...
...
} else {
...
...
}
...
}
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Preprocessore
• Sostituzioni delle macro (costanti simboliche)
– puramente sintattiche!
#define LIMIT
10
int main()
{
...
if (x < LIMIT) {
...
...
} else {
...
...
}
...
}
preprocessor
Marco Tarini ‧ Laboratorio di Linguaggi ‧
int main()
{
...
if (x < 10) {
...
...
} else {
...
...
}
...
}
2004/05 ‧ Università dell’Insubria
Preprocessore
• Sostituzioni delle macro (costanti simboliche)
– puramente sintattiche!
#define LIMIT
x
int main()
{
...
if (LIMIT < 10) {
...
...
} else {
...
...
}
...
}
preprocessor
Marco Tarini ‧ Laboratorio di Linguaggi ‧
int main()
{
...
if (x < 10) {
...
...
} else {
...
...
}
...
}
2004/05 ‧ Università dell’Insubria
Preprocessore
• Costrutti condizionali
– statici, fatti prima del compilatore!
#define DEBUG 1
int fattoriale(int a)
{
int res=1;
#if DEBUG
printf("valore di a:%d \n",a);
#endif
while (a>1) {
res*= (a--);
}
return res;
}
int fattoriale(int a)
{
int res=1;
preprocessor
Marco Tarini ‧ Laboratorio di Linguaggi ‧
printf("valore di a:%d \n",a);
while (a>1) {
res*= (a--);
}
return res;
}
2004/05 ‧ Università dell’Insubria
Preprocessore
• Costrutti condizionali
– statici, fatti prima del compilatore!
#define DEBUG 0
int fattoriale(int a)
{
int res=1;
#if DEBUG
printf("valore di a:%d \n",a);
#endif
while (a>1) {
res*= (a--);
}
return res;
}
int fattoriale(int a)
{
int res=1;
preprocessor
Marco Tarini ‧ Laboratorio di Linguaggi ‧
while (a>1) {
res*= (a--);
}
return res;
}
2004/05 ‧ Università dell’Insubria
Preprocessore
• Costrutti condizionali statici
– perchè é una tale furbata?
#define DEBUG 0
int DEBUG = 0;
int fattoriale(int a)
{
int res=1;
#if DEBUG
printf("valore di a:%d \n",a);
#endif
while (a>1) {
res*= (a--);
}
return res;
}
int fattoriale(int a)
{
int res=1;
if (DEBUG) {
printf("valore di a:%d \n",a);
}
while (a>1) {
res*= (a--);
}
return res;
}
VS.
la guardia viene controllata
solo durante la compilazione
risultato: programma efficiente!
Marco Tarini ‧ Laboratorio di Linguaggi ‧
la guardia viene controllata solo
durante ogni esecuzione!
risultato: programma inefficiente!
2004/05 ‧ Università dell’Insubria
Preprocessore
• Costrutti condizionali statici
– due forme sintattiche equivalenti
#define DEBUG 1
#define DEBUG
int fattoriale(int a)
{
int res=1;
#if DEBUG
printf("valore di a:%d \n",a);
#endif
while (a>1) {
res*= (a--);
}
return res;
}
int fattoriale(int a)
{
int res=1;
#ifdef DEBUG
printf("valore di a:%d \n",a);
#endif
while (a>1) {
res*= (a--);
}
return res;
}
–si possono anche usare
#ifndef DEBUG
#undef DEBUG
Marco Tarini ‧ Laboratorio di Linguaggi ‧
#if defined (DEBUG)
2004/05 ‧ Università dell’Insubria
Preprocessore
• Costrutti condizionali statici
– altro tipico uso:
• specializzazione del codice per architetture specifiche
– (remember: niente macchine virtuali in C)
...
#if defined (HP9000) || defined(SUN)
/*
codice funzionante SOLO per le sun
o per le HP9000
*/
...
#else
/*
codice buono per le altre architettutre
*/
...
#endif
...
Marco Tarini ‧ Laboratorio di Linguaggi ‧
questo tipo di flags
(SUN, HP9000...) sono
definite nell’ambiente.
Il compilatore lo sa.
Non vanno specificate
a mano nel codice
2004/05 ‧ Università dell’Insubria
L’ultima fatica del Preprocessore
Inclusione file di header
file “cambi.h“
const int
LIRE_PER_EURO = 1955;
file “main.c“
const int
LIRE_PER_EURO = 1955;
#include "cambi.h"
int da_euri_a_lire (int euri)
{
return euri * LIRE_PER_EURO;
}
preprocessor
Marco Tarini ‧ Laboratorio di Linguaggi ‧
int da_euri_a_lire (int euri)
{
return euri * LIRE_PER_EURO;
}
2004/05 ‧ Università dell’Insubria
L’ultima fatica del Preprocessore
Inclusione file di header
file “cambi.h“
const int
LIRE_PER_EURO = 1955;
pernacchia :P prrrrrr
$£!@&&
const int
LIRE_PER_EURO = 1955;
file “main.c“
pernacchia :P prrrrrr
$£!@&&
#include "cambi.h"
int da_euri_a_lire (int euri)
{
return euri * LIRE_PER_EURO;
}
preprocessor
int da_euri_a_lire (int euri)
{
return euri * LIRE_PER_EURO;
}
pura, meccanica, manipolazione sintattica !
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Scarica

lucidi