Università dell’Insubria
Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese
Corso di Laurea in Informatica
Anno Accademico 2004/05
Laboratorio di Linguaggi
lezione II
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
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 (e nell'ambiente DevC++)
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.
2004/05 ‧ Università dell’Insubria
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...
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Tipi Base : interi
tipo
dimensione minino valore
assumibile
(in bytes)
massimo valore
assumibile
char
1
- 128
+127
short
2*
- 32K
+32K (-1)
int
4*
- 2*K*K
2*K*K (-1)
long
4*
(idem)
(idem)
* Di solito. Dipende dalla macchina. (remember: niente macchine astratte!)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Tipi Base : interi
Variante unsigned
Esempio: unsigned int pippo;
con questa variante, si risparmia il bit del segno.
tipo
dimensione minino valore
assumibile
(in bytes)
massimo valore
assumibile
char
1
0
+255
short
2*
0
+64K (-1)
int
4*
0
+4*K*K (-1)
long
4*
0
(idem)
* Di solito. Dipende dalla macchina. (remember: niente macchine astratte!)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Facciamo un nuovo tipo
typedef <descrizione del tipo>
<identificatore del tipo>;
typedef unsigned char Byte;
Byte a,b,c;
int main(){
Byte pippo=21, panco;
...
}
(ricordiamoci la filosofia del C: linguaggio scarno, ma estendibile!)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Costanti (literals) intere
• Molti modi per scriverle…
int a,c = 16, b;
int main(){
char pippo= 67;
if (pippo + a > 21) {
...
} else {
b = 4;
...
}
}
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Costanti (literals) intere
• Molti modi per scriverle…
codifica base 16:
0123456789ABCDEF
0xFFFF
int a,c = 0x10, b;
0xA000
0xFFFFFFFFFF
int main(){
codifica ASCII
char pippo= 'C';
if (pippo + a > 025) {
...
} else {
b = 4;
...
}
}
Marco Tarini ‧ Laboratorio di Linguaggi ‧
(per caratteri).
'A' =65
'B' =66
'a' =97
'b' =98
'+' =43
'?' =67
etc. (256 "caratteri" in tutto)
codifica base 8:
01234567
013
0100
2004/05 ‧ Università dell’Insubria
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!)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
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 maiuscola,
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';
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!)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Tipi Base : virgola mobile
tipo
minino/massimo
cifre decimali
dimensione
valore
esprimibili (circa)
(in bytes)
assumibile
float
4*
10∓38
6
double
8*
10∓308
15
long double
8*
(idem)
(idem)
* Di solito. Dipende dalla macchina. (remember: niente macchine astratte!)
* float è più efficiente in spazio, ma sorprendentemente può essere persino
meno efficiente in tempo (es. su molti processori INTEL).
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Literals in virgola mobile
5.32
5.32f
un double (un float a precisione doppia) che vale 5,32
un float che vale 5,32
5.32e12
un double che vale 5,32 x 1012
5.32e-12
un double che vale 5,32 x 10-12
5.32e-12f
un float che vale 5,32 x 10-12
esempi: double avogadro = 6.022e23; /* N molecole x mole */
double epsilon = 1e-18;
che è meglio (più chiaro, meno orrendo) di:
double epsilon = 0.000000000000000001;
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Tipo delle espressioni
• viene indovinato dal compilatore…
int x = 10, y;
x = x / 3;
double x = 10, y;
y = x / 3;
equivalente a:
double x = 10.0, y;
y = x / 3.0;
float x = 10.0f, y;
double x = 10.0, y;
y = x / 3;
equivalente a: y = x / 3.0;
in sostanza, nelle operazioni miste viene convertito tutto al tipo più preciso.
(double più preciso di float, float di int).
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Tipo delle espressioni
• si può anche cambiare esplicitamente:
double x = 10.0;
y = (int)(x) / 3; /* y = 3.0 */
• si tratta di un type-cast
– sintassi: (<tipo di destinazione>) <espressione>
– altri esempio:
int numerone1, numerone2, media;
...
media= (numerone1 + numerone2) /2;
media= (unsigned int) (numerone1 + numerone2) /2;
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
La dimensione dei vari tipi
• Si può chiedere al compilatore.
• Costrutto "sizeof"
– sintassi: sizeof( <tipo> )
• ad esempio, sizeof( int )
è una espressione (costante) che vale 4.
– nota: non è una funzione (che restituisce 4):
non c'è nessuna invocazione di funzione,
il valore di "sizeof" è risolto staticamente
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Tipi costruiti: il tipo enum.
• esempio:
enum
{ LUN, MAR, MERC, GIOV, VEN, SAB, DOM } giorno;
("giorno" è una var che vale uno dei valori listati)
• meglio definire un tipo:
typedef
enum { LUN, MAR, MERC, GIOV, VEN, SAB, DOM }
GiornoSettimana;
GiornoSettimana ieri, oggi;
("GiornoSettimana" è il tipo delle variabili che possono
assumere i valori listati, e "ieri" e "oggi" sono due variabili di
tale tipo)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Tipi costruiti: il tipo enum.
semplicemente delle
nuove costanti, che
valgono 0, 1, 2 , 3, 4, 5, 6
typedef
enum { LUN, MAR, MERC, GIOV, VEN, SAB, DOM }
GiornoSettimana;
GiornoSettimana ieri, oggi;
• sono implementati come interi, a tutti gli effetti.
if ( (oggi > MERC) && (oggi <= VEN ) ) ...
if ( oggi == DOM ) oggi = LUN; else oggi++;
• come si fanno passare 5 giorni?
oggi = ( oggi + 5 ) % 7;
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Tipi composti: il tipo struct
definizione del tipo.
MA NON E' UNA
CLASSE:
tutto "public"
niente metodi
niente costruttore…
typedef
struct {
char giorno;
Mese mese;
short anno;
}
Data;
dichiarazione di
alcune variabili
Data oggi, mio_compleanno;
con inizializzatore
(nota la sintassi del
literal, a dx del '=')
Data data_esame = { 28, OTTOBRE, 2004 };
accesso ai campi
(come per le classi)
int main(){
data_esame.mese = DICEMBRE;
...
};
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Tipi composti: il tipo struct
typedef
struct {
char giorno;
Mese mese;
short anno;
}
Data;
• si può chiedere
la dimensione
del nuovo tipo "Data": sizeof(Data)
• che sarà uguale a:
sizeof(char)+sizeof(Mese)+sizeof(short)
• in fatti, in memoria, una struct e' codificata come
la semplice concatenzaione delle codifiche dei suoi campi :
codifica di giorno
codifica di mese
Marco Tarini ‧ Laboratorio di Linguaggi ‧
codifica di anno
2004/05 ‧ Università dell’Insubria
Tipi composti: il tipo struct
typedef
struct {
char giorno;
Mese mese;
short anno;
}
Data;
typedef
struct {
Data partenza;
Data arrivo;
int numero_stanza;
}
Prenotazione;
Prenotazione p = {
{ 28, OTTOBRE, 2004 },
{ 2, NOVEMBRE, 2004 },
23
};
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Gli array
• simile a java…
/* cartella della tombola, contiene 15 numeri*/
int cartella[15];
deve essere una costante!
(il comp. deve sapere quanti elementi allocare)
• come prima, si può definire il tipo
senza dichiarare nessuna variabile
typedef int Cartella[15];
• in ogni caso…
int main(){
Cartella mia, sua;
mia[2]=31;
}
si usano solo tipi interi per indicizzare. (qui: da 0 a 14)
NB: no range checking !
Segmentation faults sempre in agguato.
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Gli array: inizializzazione
• Inizializzazione di array (opzionale, come sempre)
int cartella[15]={
10,21,33,13,4,
12,4, 53, 1,78,
2,54,31,86,78,
};
l'ultima virgola è
tollerata
se si inizializza un
int cartella[]={
10,21,33,13,4,
12,4, 53, 1,78,
2,54,31,86,78,
};
Marco Tarini ‧ Laboratorio di Linguaggi ‧
array, allora non è
necessario
specificare il numero
di elementi
(li conta il
compilatore per noi)
2004/05 ‧ Università dell’Insubria
Gli array: inizializzazione
• Inizializzazione di array:
– gli array di caratteri godono di un inizializzatore speciale:
– questa inizializzazione:
char nome[]={'m','a','r','c','o',' ','t','a','r','i','n','i',0};
– si può scrivere equivalentemente così:
char nome[]= "marco tarini";
la costante char 0.
Si può scrivere anche
così:
'\0'
nome[ 5]
nome[ 6]
nome[12]
vale
vale
vale
' '
't'
'\0'
Marco Tarini ‧ Laboratorio di Linguaggi ‧
Per convenzione, è
usato come terminatore
delle stringhe:
2004/05 ‧ Università dell’Insubria
Gli array: storaggio
• Importante:
– in memoria, gli elementi di un array sono memorizzati
in una serie di celle contigue
– ogni cella ha la stessa grandezza
– per questo gli array sono random access!
int cartella[5]={
10,21,33,13,4,
};
indirizzo
base
di "cartella"
dimensione
cella (=4)
10
indirizzo di
21
33
13
4
cartella[3] = (indirizzo base) + 3 x (dimensione cella)
cartella[3]
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Problema
• Cosa succede, se non si sa a priori quanti
elementi dovremo allocare?
– (a tempo di esecuzione)
• Necessità allocazione dinamica di array.
• Per la soluzione di questo problema, useremo i
puntatori
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: intro
• Una tipo variabile che contiene
un indirizzo di una locazione di memoria:
– l'indirizzo di un'altra variabile!
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: sintassi della dichiarazione
int* pippo;
" pippo " è una var di tipo int*,
cioè puntatore ad intero
o se preferite:
int *pippo;
" *pippo "
(cioè il valore puntato da pippo)
è una var di tipo intero
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: sintassi dell'uso
pippo;
*pippo;
il valore del puntatore.
il valore dell'oggetto puntato.
entrambi possono essere sia letti che assegnati
(possono comparire da entrambi i lati di un assegnamento)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: preambolo
Cosa succede normalmente…
int pippo = 0xA0;
Inoltre, riserva quei
quattro byte per la
variabile pippo.
0x612A0214 00 00 00 FF
0x612A0218 01 22 00 AB
0x612A021C 21 2A 02 2C
0x612A0220 12 23 D2 FF
0x612A0224 FF 02 41 A4
RAM
Ad esempio, la
locazione 0x612A22C
0x00000000
spazio degli indirizzi logici
il compilatore assegna
alla variabile pippo
una locazione di memoria.
0x612A0228 21 00 00 00
0x612A022C 00 00 00 A0
0x612A0230 12 33 A3 D0
0xFFFFFFFF
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: preambolo
Cosa succede normalmente…
Ad esempio, la
locazione 0x612A22C
Inoltre, riserva quei
quattro byte per la
variabile pippo.
variabile
pippo
tipo locazione
Inoltre
int 0x612A22C
STORE 0x0612A22C 0x00AABB00
0x00000000
0x612A0214 00 00 00 FF
0x612A0218 01 22 00 AB
0x612A021C 21 2A 02 2C
0x612A0220 12 23 D2 FF
0x612A0224 FF 02 41 A4
RAM
il compilatore assegna
alla variabile pippo
una locazione di memoria.
dopo la complazione
spazio degli indirizzi logici
int pippo = 0xA0;
pippo = 0x00AABB00;
0x612A0228 21 00 00 00
00 BB
00 00
A0
0x612A022C 00 AA
0x612A0230 12 33 A3 D0
0xFFFFFFFF
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Scarica

lucidi