Università dell’Insubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in Informatica Anno Accademico 2007/08 Laboratorio di Linguaggi lezione II Marco Tarini Laboratorio di Linguaggi • docente: Marco Tarini e-mail: [email protected] • ricevimento: Mercoledì 11:00 - 13:00 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 - 2007/08 - Università dell’Insubri Laboratorio di Linguaggi • Pagina del corso: http://vcg.isti.cnr.it/~tarini/?57 – (oppure: google for "Marco Tarini" => "Teaching" => "Linguaggi-07") Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Laboratorio di Linguaggi • piccola guida pratica di C – guida essensiale di alcuni emementi di C v = argomanto già trattato Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Prima di andare avanti int potenza (int b, int e) { int res=1 , i; for (i=1; i<=e; i++) { res = res * b; } return res; } • in questi lucidi le reserved words sono in blu! – non si possono usare per gli identificatori – ma, ricordiamoci, il C è case sensitive • " int " non si è un nome lecito per una nuova var , ma " Marco Tarini - Laboratorio di Linguaggi - Int " si. 2007/08 - Università dell’Insubri 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 - 2007/08 - Università dell’Insubri Commenti • Usare /* e */ per delimitare i commenti commento stile C++ facile che non vada bene per il vs compilatore C non ANSI ! 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 - 2007/08 - Università dell’Insubri Commento sui Commenti • Usetali ! /* funzione potenza: dati due numeri interi B e E restituisce (B elevato 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 - 2007/08 - Università dell’Insubri Un programma completo • il famigerato "hello world" 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[]) { printf("Ciao Mondo!\n"); return 0; } printf = scrivi sullo STANDARD OUTPUT (esempio di funzione che NON fa parte del core del lingauggio, è definito in stdio.h) Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Compilazione (build) sorgente binario ? file “main.c“ #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { printf("Ciao Mondo!\n"); return 0; } ? ?? ? ? ? COMPILAZIONE main.exe ESECUZIONE ?? ?? ? ? ? ? C:\> main.exe C:\> Ciao Mondo! C:\> Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Cosa è successo esattamente quando abbiamo "complilato" il progetto? in C (quasi) linguaggio macchia ancora in C Source File "main.c" precompilatore file precomp. • Solo operazioni sintattiche: compiler object file "main.o" • La compilazione vera e propria – inclusioni di files di “header” – risoluzioni delle “macro” – codici alternativi • per esempio, per le varie piattaforme Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Cosa fa il precompilatore 1/3 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; } precompilator Marco Tarini - Laboratorio di Linguaggi - int da_euri_a_lire (int euri) { return euri * LIRE_PER_EURO; } 2007/08 - Università dell’Insubri Cosa fa il precompilatore 1/3 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; } precompilator int da_euri_a_lire (int euri) { return euri * LIRE_PER_EURO; } pura, meccanica, manipolazione sintattica ! Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Cosa fa il precompilatore 2/3 • 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 - 2007/08 - Università dell’Insubri Cosa fa il precompilatore 2/3 • Sostituzioni delle macro (costanti simboliche) – puramente sintattiche! #define LIMIT 10 int main() { ... if (x < LIMIT) { ... ... } else { ... ... } ... } precompilator Marco Tarini - Laboratorio di Linguaggi - int main() { ... if (x < 10) { ... ... } else { ... ... } ... } 2007/08 - Università dell’Insubri Cosa fa il precompilatore 2/3 • Sostituzioni delle macro (costanti simboliche) – puramente sintattiche! #define LIMIT x int main() { ... if (LIMIT < 10) { ... ... } else { ... ... } ... } precompilator Marco Tarini - Laboratorio di Linguaggi - int main() { ... if (x < 10) { ... ... } else { ... ... } ... } 2007/08 - Università dell’Insubri Cosa fa il precompilatore 3/3 • 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; precompilator Marco Tarini - Laboratorio di Linguaggi - printf("valore di a:%d \n",a); while (a>1) { res*= (a--); } return res; } 2007/08 - Università dell’Insubri Cosa fa il precompilatore 3/3 • 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; precompilator Marco Tarini - Laboratorio di Linguaggi - while (a>1) { res*= (a--); } return res; } 2007/08 - Università dell’Insubri Cosa fa il precompilatore 3/3 • 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 durante ogni esecuzione! risultato: programma inefficiente! 2007/08 - Università dell’Insubri Cosa fa il precompilatore 3/3 • 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) 2007/08 - Università dell’Insubri Cosa fa il precompilatore 3/3 • 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 2007/08 - Università dell’Insubri Compilazione (build): 1 files sorgente solo? in C Source File "main.c" (quasi) linguaggio macchia ancora in C precompiler file precomp. Marco Tarini - Laboratorio di Linguaggi - compiler object file "main.o" 2007/08 - Università dell’Insubri Compilazione (build): più files sorgenti binario file “main.c“ [ codice in C ] file “main.h“ COMPILAZIONE (BUILD) [ altro codice ] Marco Tarini - Laboratorio di Linguaggi - main.exe 2007/08 - Università dell’Insubri Compilazione (build): più files sorgenti binario file “main.c“ [ codice in C ] file “main.h“ COMPILAZIONE (BUILD) [ altro codice ] main.exe file “zap.c“ [ altro codice ] file “pippo.c“ Progetto con più file sorgenti ! [ altro codice ] Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Building a project Source File 1 "main.c" Source File 2 "pippo.c" precompil. file precomp. compiler 1 precompil. file precomp. compiler 2 object file "main.o" object file "pippo.o" Header File 1 linker eseguibile finale "prova.exe" “caio.h" Source File 3 “pluto.c" precompil. file precomp. compiler 3 Marco Tarini - Laboratorio di Linguaggi - object file “pluto.o" 2007/08 - Università dell’Insubri Il ruolo delle librerie Source File 1 "main.c" Source File 2 "pippo.c" Source File 3 “pluto.c" precompil. file precomp. compiler 1 precompil. file precomp. compiler 2 precompil. file precomp. compiler 3 Header File 1 "main.o" object file "pippo.o" object file “pluto.o" linker eseguibile finale "prova.exe" libreria A “stdlib.a” “caio.h" Header Lib File 1 “stdlib.h" Marco Tarini object file libreria B - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Risassumendo • Compilazione (build) (TRE FASI) 1. Precompliazione • • (di ogni file sorgente ".c") (utilizzando anche i file headers ".h") 2. Compilazione (vera e propria) • (per ogni file sorgente ".c" risultante) 3. Linking • • (di tutti i ".o" risultanti insieme) (utilizzando anche i file di libreria) Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri