Laboratorio di Linguaggi lezione II Marco Tarini Università dellInsubria Facoltà di Scienze...
-
Upload
serafina-antonella -
Category
Documents
-
view
219 -
download
0
Transcript of Laboratorio di Linguaggi lezione II Marco Tarini Università dellInsubria Facoltà di Scienze...
Laboratorio di Linguaggi
lezione II
Marco Tarini
Università dell’Insubria
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 ‧ 2 0 0 6 / 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 e-mail: [email protected]
• ricevimento: Mercoledì dalle 11:00o 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 ‧ 2 0 0 6 / 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: http://vcg.isti.cnr.it/~tarini/linguaggi/
– 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 ‧ 2 0 0 6 / 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 ‧ 2 0 0 6 / 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 <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)
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 ‧ 2 0 0 6 / 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 <stdio.h>#include <stdlib.h>
int main(int argc, char *argv[]){ printf("Ciao Mondo!\n");
return 0; }
COMPILAZIONE
sorgente
?
? ?
?
?
??
??
? ?
???
?
main.exe
binario
ESEGUZIONE
C:\> main.exeC:\> 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 ‧ 2 0 0 6 / 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 ‧ 2 0 0 6 / 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 ‧ 2 0 0 6 / 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 ‧ 2 0 0 6 / 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 ‧ 2 0 0 6 / 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 ‧ 2 0 0 6 / 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 ‧ 2 0 0 6 / 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 compilazionerisultato: 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 ‧ 2 0 0 6 / 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 ‧ 2 0 0 6 / 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, HP9000...) sono definite nell’ambiente.
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 ‧ 2 0 0 6 / 0 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
L’ultima 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 ‧ 2 0 0 6 / 0 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
L’ultima 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 ‧ 2 0 0 6 / 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
fileprecomp.
compilerobject
file"main.o"
in C ancora 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 ‧ 2 0 0 6 / 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 ‧ 2 0 0 6 / 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 ‧ 2 0 0 6 / 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
fileprecomp.
1 compiler
objectfile
"main.o"
pre- complier
fileprecomp.
2 compiler
objectfile
"pippo.o"
pre- complier
fileprecomp.
3 compiler
objectfile
“pluto.o"
eseguibilefinale
"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 ‧ 2 0 0 6 / 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 ‧ 2 0 0 6 / 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*
4*
tipominino valore
assumibilemassimo valore
assumibile
- 128 +127
- 32K +32K (-1)
- 2*K*K*K +2*K*K*K (-1)
(idem) (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 ‧ 2 0 0 6 / 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*
4*
tipominino valore
assumibilemassimo valore
assumibile
+255
+64K (-1)
+4*K*K*K (-1)
(idem)
* Di solito. Dipende dalla macchina. (remember: niente macchine astratte!)
unsignedVariante unsigned int pippo;Esempio:
0
0
0
0
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 ‧ 2 0 0 6 / 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 <descrizione del tipo> <identificatore del tipo>;
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 6 / 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 ‧ 2 0 0 6 / 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: 0123456789ABCDEF
0xFFFF
0xFFFFFFFFFF
0xA000
codifica base 8: 01234567013 0100
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 ‧ 2 0 0 6 / 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 tuttoin 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 ‧ 2 0 0 6 / 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 tuttoin poche righe di codice.)(poche e quindi talvolta criptiche. Usare commenti!)