Laboratorio di Linguaggi lezione II Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in Informatica Anno Accademico 2006/07
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Laboratorio di Linguaggi docente: Marco Tarini ricevimento: Mercoledì dalle 11: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
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Laboratorio di Linguaggi link utile: –guida essensiale di alcuni emementi di C v = argomanto già trattato
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Prima di andare avanti in questi lucidi (e nell'ambiente DevC++) le reserved words sono in blu! –non si possono usare per gli identificatori –ma, ricordiamoci, il C è case sensitive " " non si è un nome lecito per una nuova var, ma " " si. int potenza (int b, int e) { int res=1, i; for (i=1; i<=e; i++) { res = res * b; } return res; } 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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Un programma completo il cosidetto "hello world" #include 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) dichiaria che verranno usate due librerie standard: standard Input Output e Standard Library
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Compilazione (o "build", o "make") file main.c #include int main(int argc, char *argv[]) { printf("Ciao Mondo!\n"); return 0; } COMPILAZIONE sorgente ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? main.exe binario ESEGUZIONE C:\> main.exe C:\> Ciao Mondo! C:\>
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Risassumendo Compilazione (build, make) (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)
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Precompilatore Sostituzioni delle macro (costanti simboliche) –puramente sintattiche! #define LIMIT 10 int main() {... if (x < LIMIT) {... } else {... }... } # = istruzione per il preprocessore:d'ora in poi, quando scrivo LIMIT, fai finta che abbia scritto 10
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Precompilatore Sostituzioni delle macro (costanti simboliche) –puramente sintattiche! #define LIMIT 10 int main() {... if (x < LIMIT) {... } else {... }... } precompliler int main() {... if (x < 10) {... } else {... }... }
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Precompilatore Sostituzioni delle macro (costanti simboliche) –puramente sintattiche! #define LIMIT x int main() {... if (LIMIT < 10) {... } else {... }... } precompliler int main() {... if (x < 10) {... } else {... }... }
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Precompilatore 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; } precompliler int fattoriale(int a) { int res=1; printf("valore di a:%d \n",a); while (a>1) { res*= (a--); } return res; }
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Precompilatore 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; } precompliler int fattoriale(int a) { int res=1; while (a>1) { res*= (a--); } return res; }
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Precompilatore Costrutti condizionali statici –perchè é una tale furbata? #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 DEBUG = 0; 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! la guardia viene controllata durante ogni esecuzione! risultato: programma inefficiente!
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Precompilatore Costrutti condizionali statici –due forme sintattiche equivalenti #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; } #define DEBUG 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#if defined (DEBUG)
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Precompilatore 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... questo tipo di flags (SUN, HP ) sono definite nellambiente. Il compilatore lo sa. Non vanno specificate a mano nel codice
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Lultima fatica del Precompilatore precompliler const int LIRE_PER_EURO = 1955; int da_euri_a_lire (int euri) { return euri * LIRE_PER_EURO; } Inclusione file di header file cambi.h const int LIRE_PER_EURO = 1955; file main.c #include "cambi.h" int da_euri_a_lire (int euri) { return euri * LIRE_PER_EURO; }
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Lultima fatica del Precompilatore precompliler const int LIRE_PER_EURO = 1955; pernacchia :P prrrrrr int da_euri_a_lire (int euri) { return euri * LIRE_PER_EURO; } Inclusione file di header file cambi.h const int LIRE_PER_EURO = 1955; pernacchia :P prrrrrr file main.c #include "cambi.h" int da_euri_a_lire (int euri) { return euri * LIRE_PER_EURO; } pura, meccanica, manipolazione sintattica !
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Cosa è successo esattamente quando "compliamo" il progetto? Source File "main.c" precompiler file precomp. compiler object file "main.o" in Cancora in C (quasi) linguaggio macchia
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Compilazione (o "build", o "make") file main.c [ codice in C ] file main.h [ altro codice ] COMPILAZIONE ("BUILD") ("MAKE") sorgenti main.exe binario
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Compilazione (build) file main.c [ codice in C ] file main.h [ altro codice ] file zap.c [ altro codice ] COMPILAZIONE ("BUILD") ("MAKE") sorgenti main.exe binario file pippo.c [ altro codice ] Progetto con più file sorgenti !
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Cosa è successo esattamente "compliamo" il progetto? Source File 1 "main.c" Source File 2 "pippo.c" Source File 3 pluto.c" pre- complier file precomp. 1 compiler object file "main.o" pre- complier file precomp. 2 compiler object file "pippo.o" pre- complier file precomp. 3 compiler object file pluto.o" eseguibile finale "prova.exe" linker libreria A libreria B
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Tipi Base tipi base: –intero –floating point –booleano tipi derivati: –enumerazione –strutture –arrays int x;... if (x) a(); else b(); esegue b se e solo se x è zero. esegue a in tutti gli altri casi (anche se x è negativo) vale anche per i tipi non interi...
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Tipi Base : interi int long short char dimensione (in bytes) 1 2* 4* tipo minino valore assumibile massimo valore assumibile K +32K (-1) - 2*K*K*K +2*K*K*K (-1) (idem) * Di solito. Dipende dalla macchina. (remember: niente macchine astratte!)
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Tipi Base : interi int long short char dimensione (in bytes) 1 2* 4* tipo minino valore assumibile massimo valore assumibile K (-1) +4*K*K*K (-1) (idem) * Di solito. Dipende dalla macchina. (remember: niente macchine astratte!) unsigned Variante unsigned int pippo; Esempio: con questa variante, si risparmia il bit del segno.
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Definiamo un nuovo tipo Byte a,b,c; int main(){ Byte pippo=21, panco;... } typedef unsigned char Byte; (ricordiamoci la filosofia del C: linguaggio scarno, ma estendibile!) typedef unsigned char Byte; typedef ;
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Literals interi Molti modi per scriverle… const int PIPPO = 12; int a,c = 16, b; int main(){ char pippo= 67; if (pippo + a > 21) {... } else { b = 4;... }
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Literals interi Molti modi per scriverle… const int PIPPO = 12; int a,c = 0x10, b; int main(){ char pippo= 'C'; if (pippo + a > 025) {... } else { b = 4;... } codifica base 16: ABCDEF 0xFFFF 0xFFFFFFFFFF 0xA000 codifica base 8: codifica ASCII (per caratteri). 'A' 'a' 'B' =97 =65=66 'b' =98 '+' =43 '?' =67 etc. (256 "caratteri" in tutto)
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Piccoli trucchi con i chars Caratteri ASCII e numeri di un byte sono proprio lo stesso tipo! char c0, c1;... if (c0<c1) { /* c0 viene prima di c1 in ordine alfabetico */... } else { /* c0 viene dopo di c1 in ordine alfabetico, o c0==c1 */... } (ricordiamoci la filosofia del C: linguaggio che permette di dire tutto in poche righe di codice.) (poche e quindi talvolta criptiche. Usare commenti!)
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 / 0 7 U n i v e r s i t à d e l l I n s u b r i a Piccoli trucchi con i chars Caratteri ASCII e numeri di un byte sono proprio lo stesso tipo! /* restituisce 1 se il carattere e' una lettera minuscola, o 0 altrimenti */ int is_minuscolo(char c){ if ( (c>=a') && (c<=z') ) return 1; return 0; } /* restituisce la versione minuscola di un carattere dato*/ char minuscolo(char c){ if ( (c>='A') && (c<='Z') ) return c-'A'+'a'; else return c; } (ricordiamoci la filosofia del C: linguaggio che permette di dire tutto in poche righe di codice.) (poche e quindi talvolta criptiche. Usare commenti!)