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