laboratorio di linguaggi lezione x marco tarini università dellinsubria facoltà di scienze...
TRANSCRIPT
Laboratorio di Linguaggi
lezione X
Marco Tarini
Università dell’Insubria
Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese
Corso di Laurea in Informatica
Anno Accademico 2004/05
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "main.c" file "auxiliary.c"
Progetti a piu' files
#include "auxiliary.h"
int main(){ int x; ... x = funz1(5, 6); }
#include "auxiliary.h"
int funz1(int b,int e){ ...}
file "auxiliary.h"
int funz1(int,int);
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "main.c"
file "auxiliary.c"
Progetti a piu' files: schema base
#include "auxiliary.h"double d;int main(){ int x; ... x = funz1(5, 6); ... funz2( &d ); ...}
#include "auxiliary.h"
int funz1(int b,int e){ ... /* corpo di funz1 */}
void funz2(double*){ ... /* corpo di funz1 */}
file "auxiliary.h"int funz1(int,int);void funz2(double*);
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
int funz1(int b,int e){ ... /* commento implementativo */ ... }
void funz2(double*){ ... }
file "main.c"
Ricordarsi di commentare!
#include "auxiliary.h"double d;int main(){ int x; ... x = funz1(5, 6); ... funz2( &d ); ...}
file "auxiliary.h"/* funzione 1: blah blah */ int funz1(int,int);
/* funzione 2: blah blah */void funz2(double*);
commenti ad alto livello!
(su cosa fanno -in totale- e come si usano le funzioni)
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Progetti a piu' files: schema base
main.c
auxiliary.c
auxiliary.h
pre- process.
fileprecomp.
1 compiler
objectfile
main.o
pre- process.
fileprecomp.
3 compiler
objectfile
auxiliary.o
eseguibilefinale
exec.exe linker
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
int funz1(int b,int e){ ... /* corpo di funz1 */}
void funz2(double*){ ... /* corpo di funz1 */}
file "main.c"
Progetti a piu' files: esempio di errore
#include "auxiliary.h"double d;int main(){ int x; ... x = funz1(5, 6); ... funz2( &d ); ...}
file "auxiliary.h"int funz1(int,int);void funz2(double*);
...niente funz 2
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Progetti a piu' files: esempio di errore
eseguibilefinale
exec.exe linker linker
main.c
auxiliary.c
auxiliary.h
pre- process.
fileprecomp.
1 compiler
objectfile
main.o
pre- process.
fileprecomp.
3 compiler
objectfile
auxiliary.o
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
void funz_pippo(int x){ ...}
int funz1(int b,int e){ ... funz_pippo( b + 1); ...}
void funz2(double*){ ...}
file "main.c"
Funzioni "interne"
#include "auxiliary.h"double d;int main(){ int x; ... x = funz1(5, 6); ... funz2( &d ); ...}
file "auxiliary.h"int funz1(int,int);void funz2(double*);
void funz_pippo(int x){ ...}
la funzione "funz_pippo" non e' dichiarata nell'header.
Sarà visibile al compilatoresolo nel file in cui vienedefinita.
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
void funz_pippo(int x){ ...}
int funz1(int b,int e){ ... funz_pippo( b + 1); ...}
void funz2(double*){ ...}
file "main.c"
Progetti a piu' files: collisioni
#include "auxiliary.h"
double d;int main(){ int x; ... x = funz1(5, 6); ... funz2( &d ); ...}
file "auxiliary.h"int funz1(int,int);void funz2(double*);
void funz_pippo(int x){ ...}
int funz_pippo(){ ...}
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Progetti a piu' files: collisioni
eseguibilefinale
exec.exe linker
main.c
auxiliary.c
auxiliary.h
pre- process.
fileprecomp.
1 compiler
objectfile
main.o
pre- process.
fileprecomp.
3 compiler
objectfile
auxiliary.o
linkerfunz_pippo
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
void funz_pippo(int x){ ...}
int funz1(int b,int e){ ... funz_pippo( b + 1); ...}
void funz2(double*){ ...}
file "main.c"
Progetti a piu' files: funzioni "interne"
#include "auxiliary.h"
double d;int main(){ int x; ... x = funz1(5, 6); ... funz2( &d ); ...}
file "auxiliary.h"int funz1(int,int);void funz2(double*);
void funz_pippo(int x){ ...}
int funz_pippo(){ ...}
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
void funz_pippo(int x){ ...}
int funz1(int b,int e){ ... funz_pippo( b + 1); ...}
void funz2(double*){ ...}
file "main.c"
Progetti a piu' files: funzioni "interne"
#include "auxiliary.h"...double d;int main(){ int x; ... x = funz1(5, 6); ... funz2( &d ); ...}
file "auxiliary.h"int funz1(int,int);void funz2(double*);
static void funz_pippo(int x){ ...}
la funzione "funz_pippo" ora non è visibile (all'esterno)
nemmeno dal linker !
morale della favola:le funzioni "interne" megliodichiararle static
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Progetti a piu' files
•Condivisione di...–funzioni–variabili–costanti–macros–tipi di dato
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
int funz1(int b,int e){ pippo = 16; ... }
file "main.c"
Progetti a piu' files: condivisione variabili
#include "auxiliary.h" int main(){ int x; x = funz1(5, 6); ... if (pippo) ...; ...}
file "auxiliary.h"/* funzione 1: blah blah */ int funz1(int,int);
int pippo = 2;
collisione!
multiple definition ofvariable "pippo"
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
int pippo=2;
int funz1(int b,int e){ pippo = 16; ... }
file "main.c"
Progetti a piu' files: condivisione variabili
#include "auxiliary.h" int main(){ int x; x = funz1(5, 6); ... if (pippo) ...; ...}
file "auxiliary.h"/* funzione 1: blah blah */ int funz1(int,int);
extern int pippo;extern
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Progetti a piu' files: condivisione variabili
definizione di una var:1. alloca dello spazio di memoria per un nuovo
intero2. (opzionale) inizializza: scrivi "3" in quello spazio3. d'ora in poi, pippo si riferira' a quello spazio
extern int pippo;
int pippo = 3;
dichiarazione di una var:1. "prometto che da qualche parte sara' definita
una variabile che si chiama pippo, e sara' un intero"
2. pippo si riferira' allo spazio di quella variabile
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
int pippo=2;
int funz1(int b,int e){ pippo = 16; ... }
file "main.c"
Progetti a piu' files: condivisione variabili
#include "auxiliary.h" int main(){ int x; x = funz1(5, 6); ... if (pippo) ...; ...}
file "auxiliary.h"/* funzione 1: blah blah */ int funz1(int,int);
/* pippo: blah blah */extern int pippo;
al solito,i commenti di spiegazione...
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
int pippo=2;int i=0;
int funz1(int b,int e){ pippo = 16; ... }
file "main.c"
Progetti a piu' files: variabili "interne"
#include "auxiliary.h" int main(){ int x; x = funz1(5, 6); ... if (pippo) ...; ...}
file "auxiliary.h"la variabile "i" non e' dichiarata nell'header.
Sarà visibile (al compilatore)solo nel file in cui vienedefinita.
/* funzione 1: blah blah */ int funz1(int,int);
/* pippo: blah blah */extern int pippo;
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
int pippo=2;int i=0;
int funz1(int b,int e){ pippo = 16; ... }
file "main.c"
Progetti a piu' files: variabili "interne"
#include "auxiliary.h"int i=0;int main(){ int x; x = funz1(5, 6); ... if (pippo) ...; ...}
file "auxiliary.h"/* funzione 1: blah blah */ int funz1(int,int);
/* pippo: blah blah */extern int pippo;
collisione!
multiple definition ofvariable "i"
solito probelma...
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
int pippo=2;static int i=0;
int funz1(int b,int e){ pippo = 16; ... }
file "main.c"
Progetti a piu' files: variabili "interne"
#include "auxiliary.h"int i=0;int main(){ int x; x = funz1(5, 6); ... if (pippo) ...; ...}
file "auxiliary.h"/* funzione 1: blah blah */ int funz1(int,int);
/* pippo: blah blah */extern int pippo;
solita soluzione:
Dichiarare staticle variabili "interne".
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
I due significati diversi di
1. se riferito a var locali : "variabili che hanno lo scope di var. localima sono per tutto il resto var. globali" (vedi lez. 8)
2. se riferito a var globali :"variabili non visibili all'esterno del source corrente, neanche dal linker (= vars che il linker deve ignorare)"
static
o funzioni...
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Progetti a piu' files
•Condivisione di...–funzioni–variabili–costanti–macros–tipi di dato
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
int pippo=2;static int i=0;
int funz1(int b,int e){ ... pippo ...}
file "main.c"
Progetti a piu' files: condividere costanti
#include "auxiliary.h" int main(){ int x; x = funz1(5, 6); ... if (pippo) ...; ...}
file "auxiliary.h"/* funzione 1: blah blah */ int funz1(int,int);
/* pippo: blah blah */extern int pippo;
/* MAXN: il numero max... blah blah */const MAXN = 100;
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
int pippo=2;static int i=0;
int funz1(int b,int e){ ... pippo ...}
file "main.c"
Progetti a piu' files: condividere macro
#include "auxiliary.h" int main(){ int x; x = funz1(5, 6); ... if (pippo) ...; ...}
file "auxiliary.h"/* funzione 1: blah blah */ int funz1(int,int);
/* pippo: blah blah */extern int pippo;
/* MAXN: il numero max... blah blah */#define MAXN 100
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file "auxiliary.c"#include "auxiliary.h"
int pippo=2;static int i=0;
int funz1(int b,int e){ ... pippo ...}
file "main.c"
Progetti a piu' files: condividere macro
#include "auxiliary.h" int main(){ int x; x = funz1(5, 6); ... if (pippo) ...; ...}
file "auxiliary.h"/* MAXN: il numero max... blah blah */#define MAXN 100
typedef enum { ...} TipoStrano;
/* funzione 1: blah blah */ int funz1(int, int);
/* pippo: blah blah */extern int pippo;
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
file " TipoStrano.c"#include "auxiliary.h"
int pippo=2;static int i=0;
int funz1(int b,int e){ ... pippo ...}
file "main.c"
Progetti a piu' files: condividere macro
#include "auxiliary.h" int main(){ int x; x = funz1(5, 6); ... if (pippo) ...; ...}
file "TipoStrano.h"/* MAXN: il numero max... blah blah */#define MAXN 100
typedef enum { ...} TipoStrano;
/* funzione 1: blah blah */ int funz1(TipoStrano,int);
/* pippo: blah blah */extern int pippo;
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Progetti a piu' files
•Condivisione di...–funzioni–variabili–costanti–macros–tipi di dato
M a r c o T a r i n i ‧ L a b o r a t o r i o d i L i n g u a g g i ‧ 2 0 0 4 / 0 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Progetti a piu' files: perchè?
• Scopi:– Modularità del progetto software
•dividere il progetto in aree concettualmente separate
•mantenibilita', chiarezza...– Separazione interfaccia / implementazione– Riutilizzabilità del codice– Parallelizzazione dello sviluppo software– Riduzione tempo di ri-compilazione
•(sempre meno)•(ma, storicamente, tra le motivazioni principali)