1
Il linguaggio C
Notate che ...
2
Il C è un linguaggio a blocchi
int main (void) {
}
blocco
3
Il C è un linguaggio a blocchi (2)Non è possibile mischiare dichiarazioni e comandi !
int main (void) {
}
Dichiarazione di variabililocali
Comandi
4
Variabili non inizializzateLe variabili non inizializzate non producono nessun errore!!!!
int main (void) {
/* ed esempio …. */
int min, max, out;
min = max * out;
…
}
Controllate sempre di aver inizializzato le variabiliprima del loro uso!
5
E se non me lo esegue?
Se avete cercato di eseguire a.out e non ci riuscite:$$ a.out
6
E se non me lo esegue?(2)Se avete cercato di eseguire un file eseguibile e non ci siete riusciti:
$$ a.out
bash:command not found
Significa che la variabile di ambiente PATH non contiene la directory corrente quindi usate il path completo$$ ./a.out
7
E se non me lo esegue?(3)Se avete cercato di eseguire un file eseguibile e non ci siete riusciti:
$$ a.out
bash:command not found
Per settare il PATH– bash
$$ export PATH=$PATH:.– csh e tcsh
$$ setenv PATH=${PATH}:.
8
Informazioni sulle funzioni di libreria
Usare la sezione 3 dei manuali in linea, es:$$ man 3 printf
9
Informazioni sulle funzioni di libreria (2)
NAME
printf
SYNOPSIS
#include <stdio.h>
int printf(const char* format,…);
DESCRIPTION
…… cosa fa
EXAMPLES
…… esempi di uso
SEE ALSO
… … altre funzioni simili
10
Le FAQAlla pagina
www.di.unipi.it/~susanna/LPS/FAQ.htm
Trovate le domande e risposte più comuni
11
Il linguaggio C
Tipi di dato, costanti, operatori (parte1)
12
I tipi di dato primitivi• Interi : short, int, long,
– 2,4,8,16 byte (dipende dalla implementazione)
– segnaposto •%d rappresentazione decimale•%x,%o rappresentazione esadecimale o ottale
– costanti intere : 1, -2, 4565– La funzione predefinita sizeof() fornisce la lunghezza in byte di un qualsiasi tipo o variabile C
• es. sizeof(int)
13
I tipi di dato primitivi (2)
• Caratteri : – char, 1 byte, cod. ASCII, segnaposto %c– costanti carattere : `a`, `b`, `c`– i caratteri sono visti da C come interi un po’ speciali : è possibile operare sui caratteri con le normali operazioni su interi
– es: char c = `a`;
c++;
putchar(c); /* ???? */
14
I tipi di dato primitivi (3)• Reali :
– float, double, long double– 4,8,16 byte, – rappresentazione in virgola mobile– segnaposto :
• stampa (es. printf()) %f, %lf • lettura (es. scanf()) %f (float) , %lf (double), %Lf (long double),
15
I tipi di dato primitivi (4)• Libreria matematica (libm)
– fornisce tutte le più comuni operazioni matematiche per operare sui reali • es. sqrt()
– per utilizzarla includere il file•#include <math.h>
– compilare con gcc … … … -lm
effettua il link esplicito della libreria
16
I tipi di dato primitivi (5)• Non esistono i tipi byte e bool !!!• Le stringhe sono rappresentate come array di caratteri.• signed/unsigned
– modificatore per i tipi interi e caratteri – permette di scegliere fra la rappresentazione di soli interi positivi (es 0-255 su un byte) o quella in complemento a due (es -128,+127)
• es. unsigned int, signed char
17
I tipi di dato primitivi (6)• limits.h
– contiene macro che definiscono i massimi ed i minimi numeri rappresentabili per tutti i tipi– es. INT_MIN, INT_MAX – per utilizzarli includere il file limits.h
18
I tipi di dato primitivi (7)• Conversioni fra tipi diversi :
– sono automatiche in C
– posso scrivere espressioni con operandi di tipo diversoint a=0; float b, r=3.1;
b = a + r;
– di solito viene convertito tutto nel tipo più accurato, le regole p.115 nel testo KP
– conversioni espliciter =(float) a / b
19
Il linguaggio C
Funzioni
20
Funzioni C• Le funzioni C sono l’unico modo per strutturare i programmi e non si possono annidare• Non esistono le procedure• Non esistono i metodi• Dichiarazione di funzioni :
– descrive il prototipo della funzione ovvero: nome della funzione, il tipo del valore restituito ed il tipo di tutti gli argomenti utilizzati
21
Funzioni C (2)• Dichiarazione di funzioni :
– es: prototipo della funzione di somma di due interi
int somma (int, int);
oppure
int somma (int x, int y);
x, y sono inutili, ma vengono convenzionalmente specificati per documentazione
22
Funzioni C (3)• Definizione di funzioni :
– la definizione di una funzione è divisa fra :• una intestazione (head) che fornisce il prototipo della funzione a i nomi per i parametri formali, ed• un corpo (body) che specifica le azioni da compiere
– es:
int somma (int x, int y) {
return (x + y);
}
intestazione
23
Funzioni C (4)• Definizione di funzioni :
– la definizione di una funzione è divisa fra • una intestazione (head) che fornisce il prototipo della funzione a i nomi per i parametri formali, ed• un corpo (body) che specifica le azioni da compiere
– es:
int somma (int x, int y) {
return (x + y);
}
corpo
24
Funzioni C (5)
• La dichiarazione o la definizione di una funzione deve sempre precedere il suo uso!– Vedimo la tipica struttura di un programma C (unico file):
25
Funzioni C (5.1)/* direttive al preprocessore */
#include …
#define …
/* dichiarazioni di varibili globali*/
int k;
/* dichiarazione di funzioni (prototipi)*/
int somma (int x, int y);
int main (…) {… somma(4,5); … }
/* definizione di funzioni */
int somma (int x, int y) {….}
26
Esempio di funzione#include <stdio.h>
int max (int a, int b);
int main (void){ printf(“Il massimo è %d \n”, max(10,2)); return 0;}
int max (int a, int b) { int tmp; tmp = (a < b)? b : a return tmp; }
27
Funzioni C (6)• Tutti i parametri sono passati per valore
– una copia viene messa sullo stack all’atto della chiamata– la copia viene rimossa qundo la funzione termina e non è più accessibile
• Scope delle variabili:– Il corpo di una funzione contiene le variabili locali
• sono allocate sullo stack,• sono accessibili solo a quella funzione • perdono il valore fra un’invocazione e l’altra
28
Esempio di funzione (.1)
#include <stdio.h>
int max (int a, int b); int main (void){ printf(“Il massimo è %d \n”, max(10,2)); return 0;}
int max (int a, int b) { int tmp; tmp = (a < b)? b : a return tmp; /* definizione */}
Parametri attualicopiati sullo stack
29
Esempio di funzione (.2)
#include <stdio.h>
int max (int a, int b); int main (void){ printf(“Il massimo è %d \n”, max(10,2)); return 0;}
int max (int a, int b) { int tmp; tmp = (a < b)? b : a return tmp; /* definizione */}
Variabili localisullo stack
30
Esempio di funzione: il frame (.3)
printf(“Il massimo è %d \n”, max(10,2));XX: return 0;}
int max (int a, int b) { int tmp; tmp = (a < b)? b : a return tmp; }
stackstack
31
Esempio di funzione: il frame (.4)
printf(“Il massimo è %d \n”, max(10,2));XX: return 0;}
int max (int a, int b) { int tmp; tmp = (a < b)? b : a return tmp; }
2
10
XX
stackstack
32
Esempio di funzione: il frame (.5)
printf(“Il massimo è %d \n”, max(10,2));XX: return 0;}
int max (int a, int b) { int tmp; tmp = (a < b)? b : a return tmp; }
2
10
XX
stackstack
676186815&tmp
33
Esempio di funzione: il frame (.6)
printf(“Il massimo è %d \n”, max(10,2));XX: return 0;}
int max (int a, int b) { int tmp; tmp = (a < b)? b : a return tmp; }
2
10
XX
stackstack
10&tmp
34
Esempio di funzione: il frame (.7)
printf(“Il massimo è %d \n”, max(10,2));XX: return 0;}
int max (int a, int b) { int tmp; tmp = (a < b)? b : a return tmp; }
stackstack
35
Funzioni C (7)• Scope delle variabili (cont.) :
– Le variabili globali sono variabili dichiarate al di fuori delle funzioni • sono accessibili all’interno di tutte le funzioni• sono allocate nell’area dati e vengono deallocate solo alla terminazione del programma
– Le globali sono sconsigliate a meno di casi motivati!• Devono essere sempre adeguatamente documentate
36
Esempio di funzione #2/* un esempio di var globale */#include <stdio.h>int max (int a, int b); int k = 0; /* var globale */
int main (void){ printf(“Il massimo è %d \n”, max(10,2)); printf(“Il valore di k è %d \n”, k); return 0;}
int max (int a, int b) { k = k + 1; /* side effect */ return (a < b)? b : a ;}
37
> maxIl massimo è 10Il valore di k è 1
Esempio di funzione #2 (.1)• Risultato esecuzione
38
Funzioni C (8)• Scope delle variabili (cont.) :
– Le variabili statiche locali (static) • sono accessibili all’interno della funzione che le dichiara• mantengono il valore fra una invocazione e l’altra
39
Esempio di funzione #3/* un esempio di var statica */#include <stdio.h>
int max (int a, int b); int main (void){ printf(“Il massimo è %d \n”, max(10,2)); /*k non è più accessibile fuori da max*/ return 0;}
int max (int a, int b) { static int k = 0; k++; printf(“Il valore di k è %d \n”, k); return (a < b)? b : a ;}
40
> maxIl valore di k è 1Il massimo è 10
Esempio di funzione #3 (.1)• Risultato esecuzione (lo stesso di prima)
41
Funzioni C: commenti• La nostra convenzione per i commenti per dichiarazioni e definizioni
– usa le stesse categorie viste a Metodologie Programmazione, con sintassi un po’ diversa/* @description -- somma due interi
@param x -- significato del parametro
@require -- (opz) condizioni sui parametri es. x positivo)
@return x -- descriz valore restituito (if any)
@modify -- decrizione effetti su variabili globali, array etc*/
42
Funzioni C: commenti (esempio)/* @description -- somma due interi
@param a -- intero
@param b -- intero
@return x -- la somma
@modify -- incrementa k, globale*/
int max (int a, int b) {
k = k + 1;
return (a < b)? b : a ;
}
43
Funzioni C: commenti (esempio) (.1)/* @description -- max di due interi
@param a -- intero
@param b -- intero
@return x -- la somma
@modify -- incrementa k, globale*/
int max (int a, int b) {
extern int k;
k = k + 1;
return (a < b)? b : a ;
}
44
Il linguaggio C
Tipi di dato, costanti, operatori (parte2)
45
I valori booleani• Rappresentazione dei valori booleani in C :
– non esiste il tipo bool!– sono rappresentati con int– 0 rappresenta FALSO, qualsiasi valore != 0 rappresenta VERO
• es. 456 viene interpretato come VERO • es.
if (4) printf(“VERO”);
è un condizionale con condizione legale e sempre vera, che quindi stampa sempre VERO sullo schermo.
46
Gli operatori di confronto• ==, !=, (uguale, diverso)
– definiti sui tipi base e sulle struct– se usati con gli array confrontano solo il puntatore al primo elemento– lo stesso vale con le stringhe
• <, <=, >, >= – definiti sui tipi base (numerici)– per le stringhe si usano funzioni di libreria (es. strcmp(), strncmp())
• restituscono sempre un valore di tipo int
47
Gli operatori booleani• && (and), || (or), ! (not)
– valore : 0 se sono falsi e 1 se sono veri
– restituscono un valore di tipo int
• operatori bit a bit : & (and), | (or), ^ (xor), << (lshift), >> (rshift), ~ (complemento)– es.
1 << 3 // maschera con 1 in terza posizione
a = a & ~ (1 << 3 ) // azzera il quarto bit di a
48
Es operatori bit-a-bit • a = a & ~ (1 << 3 )
0 0 0 0 0 0 0 1
05 4 3 2 167
49
Es operatori bit-a-bit (2)• a = a & ~ (1 << 3 )
0 0 0 0 0 0 0 1
0 0 0 0 1 0 0 0
50
Es operatori bit-a-bit (3)• a = a & ~ (1 << 3 )
0 0 0 0 0 0 0 1
0 0 0 0 1 0 0 0
1 1 1 1 0 1 1 1
51
Es operatori bit-a-bit (4)• a = a & ~ (1 << 3 )
0 1 0 1 1 1 0 1
1 1 1 1 0 1 1 1
52
Es operatori bit-a-bit (5)• a = a & ~ (1 << 3 )
0 1 0 1 1 1 0 1
1 1 1 1 0 1 1 1
1
53
Es operatori bit-a-bit (6)• a = a & ~ (1 << 3 )
0 1 0 1 1 1 0 1
1 1 1 1 0 1 1 1
0 1
54
Es operatori bit-a-bit (7)• a = a & ~ (1 << 3 )
0 1 0 1 1 1 0 1
1 1 1 1 0 1 1 1
0 1 0 1 0 1 0 1Nuovo valore di a
Abbiamo azzerato il bit 3
55
Selezionare l’n-esimo bit di un interoint bitn (int c, int n){
if (((1<<n) & c)!= 0)
return 1;
else
return 0;
}
0 1 0 1 1 1 0 1
0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0
n
1<<n
(1<<n) & c
56
Stampare i K bit meno significativi di un intero
void bitstampa (int c){
int i;
for (i=0; i<K; i++)
if (bitn(c,K-1-i)!= 0)
printf(”1”);
else
printf(”0”);
}
57
Gli array• Aggregati di variabili dello stesso tipo :
– dichiarazione (array statici):
int a[4];
– gli indici partono da 0– non viene effettuato nessun controllo sugli indici nell’accesso : se cerco di accedere a a[15]il compilatore non dà errore ed in fase di esecuzione il risultato dipende dal contenuto della memoria adiacente ad a
1 3 7 8
a[1]
0 1 2 3 posizione
valore
58
Le stringhe• Sono array di caratteri terminati da ´\0´
– dichiarazione :
char parola[8]=“mango”; – permette di memorizzare una qualsiasi parola di al più 7 caratteri (l’ottavo serve per il terminatore)– è inizializzata con la parola “mango”– string.h fornisce tutte le più comuni funzioni per manipolare stringhe
59
Le strutture (record)• Aggregati di variabili di tipo diverso
– dichiarazione di una nuova struttura: struct studente {
char nome[40];
char cognome[40];
double voto;
} ;
– dichiarazione di variabili di tipo struttura :
struct studente x;
struct studente classe[140];
60
Le strutture (record) (2)• Ridenominazione tipi :
typedef tipo nome;– es :
typedef int Intero;
Intero nome[40]; – es :
typedef char stringa40[41];
stringa40 nome;
61
Le strutture (record) (3)• Ridenominazione tipi :
typedef struct { char nome[40];
char cognome[40];
double voto;
} studente ;
– così si può eliminare struct dalle dichiarazioni
studente x;
studente classe[140];
62
Le strutture (record) (4)• Ridenominazione tipi :
typedef struct studente { char nome[40];
char cognome[40];
double voto;
} studente ;
– così si può eliminare struct dalle dichiarazioni
studente x;
studente classe[140];
Opzionale(serve per i tipi ricorsivi)
63
Le strutture (record) (5)• Accesso ai campi :
– tramite l’operatore punto (.)– es :
studente x;
studente classe[140];
classe[i].nome = x.nome;
64
I tipi enumerati• Rappresentano insiemi finiti:
– giorni: lunedi, martedi, …– mesi: gennaio, febbraio, …– bool: true, false.
• Associano un identificatore (costante) ad ogni elemento dell’insieme• Sono rappresentati con degli interi
– .. Ma il compilatore controlla che le funzioni siano chiamate con il tipo giusto (type checking)
65
I tipi enumerati (2)• Esempio:
enum giorni {lun,mar,mer,gio,ven,sab,dom};
enum giorni x; /* dichiarazione */
x = lun;
…
– Si può evitare di ripetere enum con un typedef – I valori interi assegnati partono da 0 :
•lun == 0,mar == 1,mer == 2,…
66
I tipi enumerati (3)• Esempio:
typedef enum {true = 1, false = 0} bool;
bool trovato; /* dichiarazione */
trovato = false;
…
– Si possono scegliere i valori interi assegnati ad ogni elemento
67
I tipi union • Nei tipi union più valori di tipi diversi condividono la stessa zona di memoria
– noti anche come record con varianti – Esempio:
union numero {
int intero;
long double reale;
struct complex complesso;
};
– solo uno dei tre viene memorizzato ogni volta
68
I tipi union (2)union numero {
int intero; /* 4 byte */
long double reale; /* 8 byte */
struct complex complesso; /* 16 byte */
};
union numero n;
• … in memoria ...
&n 16 byte
69
I tipi union (3)union numero {
int intero; /* 4 byte */
long double reale; /* 8 byte */
struct complex complesso; /* 16 byte */
};
union numero n;
/* specifico come interpretare n */
n.intero = 5;
0 0 0 5
&nParte significativa
70
I tipi union (4)• Uso tipico:
– in una struct che contenga (oltre alla union) un campo ‘tipo del valore’
typedef enum {INT,REAL,COMPLEX} numtyp;
struct numero {
numtyp tipo;
union {/* union anonima */
int intero;
long double reale;
struct complex complesso; } };
71
I tipi union (5)• Uso tipico: (cont.)
struct numero x ;
…
switch (x.tipo) {
case INT : ….
x.intero = ...;
case REAL: ….
X.reale = ...;
case COMPLEX: ….
X.complesso = ...;
…..
Top Related