Upload
dokhuong
View
215
Download
0
Embed Size (px)
Citation preview
04/05/2005 LP2-04/05 - Appunti di C 1
Appunti sul linguaggio C
Diapositive adattate dalle omonime create dalla Dottoressa di Ricerca Giovanna Melideo per il corso di Laboratorio di Algoritmi e Strutture Dati
04/05/2005 LP2-04/05 - Appunti di C 2
Il processo di compilazione
Il comando di compilazione dunque richiama:• Il preprocessore modifica una copia del file sorgente (secondo le direttive
contenute in esso) producendo una “unità di traduzioneunità di traduzione” • Il compilatore traduce la “unità” in codice oggettocodice oggetto se non rileva errori
(tipicamente errori sintattici)• Il linker Crea il file eseguibilefile eseguibile dal codice oggetto prodotto dal
compilatore ed il codice oggetto disponibile nelle librerie di sistema
• Attenzione agli errori logici, non rilevabili in fase di compilazione !
04/05/2005 LP2-04/05 - Appunti di C 3
Struttura di un programmaUn programma C è costituito da:
• Inclusione di librerie e definizione di costanti tramite le direttive al preprocessore #include e #define
• Definizione di variabili globali
• Dichiarazioni di funzioni (o prototipi)
• Definizione di funzioni
• Una funzione main() da cui ha inizio l’esecuzione del programma
04/05/2005 LP2-04/05 - Appunti di C 4
Direttive al preprocessore• Mediante la direttiva #include è possibile indicare le
librerie da “caricare”:
–– una copia del file header è inclusa nel codice prima una copia del file header è inclusa nel codice prima della compilazionedella compilazione
• La direttiva #include può indicare l’inclusione di:
– file header standard (#include <stdio.h>), oppure
– file header definiti dall’utente (#include “myfile.h”)
04/05/2005 LP2-04/05 - Appunti di C 5
Direttive al preprocessore• Mediante la direttiva #define è possibile definire
le costanti simboliche
Es.: #define PI 3.1415 ogni occorrenza di “PI” è sostituita dal ogni occorrenza di “PI” è sostituita dal
preprocessore con 3.1415preprocessore con 3.1415, ad eccezione delle occorrenze nelle stringhe racchiuse da virgolette e nei commenti
04/05/2005 LP2-04/05 - Appunti di C 6
Dichiarazioni di variabili• Una variabile rappresenta un’associazione tra un nome ed un
valore. Per “tipo” si intende un insieme di valori ed un insieme di operazioni definite su di essi
• In C, come per ogni linguaggio che possiede il controllo dei tipi, ogni variabile deve essere dichiarata prima del suo utilizzo per permettere il controllo della consistenza
• Le variabili dichiarate al di fuori delle funzioni (variabili globali) hanno una validità globale sull’intero programma e possono essere utilizzate da tutte le funzioni.
• L’uso di variabili globali contribuisce a diminuire la portabilità e la riutilizzabilità delle funzioni ed è pertanto sconsigliato
04/05/2005 LP2-04/05 - Appunti di C 7
Dichiarazione di funzioni
• La possibilità di definire funzioni consente di frammentare il programma in tanti moduli
• se la suddivisione rispecchia la frammentazione del problema in sotto-problemi più semplici ed elementari il programma assume una architettura modulare e il riuso delle funzioni è più semplice
04/05/2005 LP2-04/05 - Appunti di C 8
La funzione main()• La funzione main() è una particolare funzione che
viene eseguita automaticamente dal programma quando questo viene lanciato
Ømain() è il punto di inizio del programma
• Il valore restituito dalla funzione main() (un intero, come richiesto dallo standard ANSI-C) può essere utilizzato come codice di controllo da un eventuale programma chiamante
04/05/2005 LP2-04/05 - Appunti di C 9
Regole sintattiche principali• Il linguaggio C è casecase--sensitivesensitive: il compilatore distingue fra lettere
minuscole e maiuscole.
• Ogni istruzione è terminata da un punto-e-virgola (“;”).
• I blocchi di istruzioniblocchi di istruzioni sono racchiusi da parentesi graffe (“{” e “}”) e contengono una parte opzionale di dichiarazioni seguita da una sequenza di istruzioni.
• I commenti commenti sono racchiusi tra “/*” e “*/” .
• I nomi nomi delle funzioni e delle variabili sono costituiti solo da caratteri alfa-numerici e dal simbolo di sottolineatura (underscore: “_”) e non devono iniziare con un carattere numerico. Es.: “B”, “ciao”, “CiAo”, “_nome”, “Nome17” .
• Convenzione: usare nomi con minuscole per variabili e funzioni, maiscole per le costanti
04/05/2005 LP2-04/05 - Appunti di C 10
Regole sintattiche principali• Una dichiarazione di variabilidichiarazione di variabili avviene riportando il tipo di dato seguito
dall’elenco dei nomi di variabile separati da virgole “,”. Nella dichiarazione le variabili possono essere inizializzate. Es: char x, _pi2=‘a’, A123b;
• Non è possibile definire funzioni all’interno del corpo di altre funzioni.• I parametri parametri ““formaliformali”” di una funzione vengono specificati tra parentesi
tonde e separati tra loro mediante la virgola.• Una funzione viene attivata mediante la chiamata, che provvede al
passaggio degli eventuali parametri parametri ““attualiattuali”” che devono corrispondere in numero, ordine e tipo con quelli formali specificati nella dichiarazione.
• La chiamata di funzioni con dominio nullo deve comunque essere effettuata riportando le parentesi tonde dopo il nome della funzione. Es.: “saluti();” .
04/05/2005 LP2-04/05 - Appunti di C 11
Esempio#include <stdio.h> /* direttive al */#define PI 3.1415 /* preprocessore */
float area(int); /* prototipo */
int main (void){ float y; /* float: tipo dei razionali */ y=area(5); /* chiamata di funzione */return 0;
}
float area(int raggio) {/* fine definizione */
return (raggio* raggio * PI);} /* fine definizione */
04/05/2005 LP2-04/05 - Appunti di C 12
• Il C fornisce al programmatore tipi di dato elementari con cui definire variabili e funzioni:
caratteri alfanumericicharCaratteri
reali in precisione singolareali in precisione doppia
floatdouble
Numeri razionali
interi relativiintNumeri interi
p La parola chiave void denota l’insieme vuoto.p Per dichiarare il tipo delle variabili si deve riportare il nome del tipo
seguito dai nomi delle variabili separati da virgole. Es: int _A2b, x4;
Tipi di dato elementari
04/05/2005 LP2-04/05 - Appunti di C 13
• L’insieme dei valori è costituito da numeri interi compresi tra i valori INT_MIN e INT_MAX definiti nella libreria standard <limits.h>
• INT_MAX è il massimo intero rappresentabile in una parola di macchina: in una architettura a 32 bit, un int occupa 4 byte e INT_MAX vale 231-1=2.147.483.647
• I principali operatori tra valori interi sono gli operatori aritmetici (+, -, *, /) e l’operatore di modulo (%) descritti in seguito.
Tipo di dato int
04/05/2005 LP2-04/05 - Appunti di C 14
• Com’è noto, i numeri reali, come definiti in matematica, non sono rappresentabili sui calcolatori
• I tipi in virgola mobile assumono valori in un sottoinsieme dei razionali detto insieme dei numeri di macchina (perché dipende strettamente dalla macchina su cui è implementato il compilatore). Nella libreria <float.h> sono definiti i valori:
Ø FLT_MIN,FLT_MAX (risp. DBL_MIN,DBL_MAX): minimo valore positivo e massimo valore float (double) rappresentabile
Ø FLT_EPSILON (risp. DBL_EPSILON): la precisione di macchina, ovvero il minimo float (double) ε tale che 1+ ε ≠ε
Ø In una architettura a 32 bit FLT_EPSILON vale 10-7 e DBL_EPSILON vale 10-15
• I principali operatori tra valori reali sono gli usuali operatori aritmetici
• Le costanti si indicano con il punto decimale e/o l’esponente (1.2e-2)
Tipi di dato float e double
04/05/2005 LP2-04/05 - Appunti di C 15
• L’insieme dei valori è costituito dai caratteri normalmente visibili su schermo più alcuni caratteri speciali.
• I valori costanti “stampabili” sono rappresentati fra apici singoli (es: ‘a’, ‘G’, ‘3’, ‘&’).– Si noti che ‘G’ è diverso da ‘g’ e che ‘3’ è diverso dall’intero 3.
• I caratteri speciali possono essere rappresentati in forma simbolica mediante backslash “\” seguito da un carattere o dal codice ottaledel carattere. Ad es:– costante null;– ‘\007’ è ‘\’’ è l’apice e ‘\”’ è il doppio apice;– ‘\n’ è il carattere di controllo newline (a capo);– ‘\t’ è il carattere di tabulazione;– ‘\0’ è la il bel (segnale acustico)– ‘\x20’ è il carattere di codice esadecimale 20 (32 in decimale)
Tipo di dato char
04/05/2005 LP2-04/05 - Appunti di C 16
• Secondo la codifica ASCII:
Ø I codici delle cifre da ‘0’ e ‘9’ sono consecutivi;Ø lettere dalla ‘A’ alla ‘Z’ sono consecutive;Ø lettere dalla ‘a’ alla ‘z’ sono consecutive;Ø La differenza tra il codice di una lettera maiuscola e quello della
lettera minuscola corrispondente è 32. • Il tipo char è a tutti gli effetti un tipo intero di solito rappresentato
da un singolo byte e su cui si possono effettuare le operazioni previste sugli interi. Ad es.:Ø è lecito scrivere ‘a’+4 per rappresentare il quarto carattere che
segue ‘a’.
Ø ‘a’-’A’ vale 32
Tipo di dato char
04/05/2005 LP2-04/05 - Appunti di C 17
Costanti di enumerazioneSono un modo comodo per assegnare nomi alle costanti. Esempi:• enum boolean { NO, YES }; /*assegna NO a 0 e YES a 1*/• enum numeri { zero, uno, due };• enum numeri_grandi { cento = 100, centouno, centodue };• enum numeri_magici { INTREQ = \x9c, DMACON = \x96,
BEAMCON0 = \x1dc, AUD0PER = \xa6 };
04/05/2005 LP2-04/05 - Appunti di C 18
I modificatori• Il C permette di definire varianti dei tipi aritmetici mediante l’uso dei
modificatori short, long, signed, unsigned, che possono precedere il tipo nelle dichiarazioni di variabili
• I modificatori variano l’occupazione di memoria o il campo dei valori ammissibili:– short tipicamente diminuisce l’occupazione;– long tipicamente aumenta l’occupazione;– signed denota l’esistenza del segno– unsigned denota l’uso del bit di segno, per cui l’intervallo di
rappresentazione è tutto positivo• Non è vero che a tutte le combinazioni corrispondono
rappresentazioni distinte. Es.: signed int equivale a int• Il risultato dell’applicazione di short e long dipende
dall’implementazione
04/05/2005 LP2-04/05 - Appunti di C 19
Valori di verità e valori stringa• In C89 non esiste un tipo specifico per i valori di verità “vero” e
“falso” come il tipo boolean del Pascal. Nel C99 è stato introdotto il tipo _Bool composto da 0 (interpretato come “falso” nella valutazione di una condizione) e 1 (“vero”). La convenzione adottata in C89 è che 0 rappresenta “falso” e un qualunque intero diverso da 0 rappresenta “vero”
• Il C non prevede il tipo di dato stringa: questo significa che non èpossibile dichiarare una stringa come si dichiara un carattere o un valore numerico
• Una costante stringa è rappresentata come una sequenza di caratteri racchiusa da doppi apici. Es: “sono una stringa”
04/05/2005 LP2-04/05 - Appunti di C 20
• Operatori aritmetici
“+”, “-”, “*”, “/”, “%” (operatore di modulo, solo per interi)
Ø Conversione implicita di tipo: se un operatore è applicato ad operandi di tipo diverso il C effettua la conversione verso il tipo più generale (es: 3/2 vale 1; 3.0/2=1.5)
Ø Gli operatori “+” e “-” sono applicabili anche ad operandi di tipo char (es: lett+’a’-’A’)
• Operatori logici di confronto
“==“, “!=“, “<“, “>”, “<=”, “>=”
Ø Applicabili anche ad operandi di tipo char (es: ‘a’<‘b’)
Operatori
04/05/2005 LP2-04/05 - Appunti di C 21
Operatori• Operatori booleani “!” (not), “&&” (and), “||” (or)Ø Per convenzione è falsa ogni espressione che vale 0,
vera ogni altra.Ø Le espressioni logiche sono valutate da sinistra verso
destra e la valutazione si interrompe non appena è possibile stabilire un valore con certezza aritmetici
• Operatore di assegnamentoØ forma estesa: a=b*c; x=-234.5;Ø forma contratta: x <op>= y; (<op>=+,-,*,/), che
equivale a x=x <op> y;Ø operatore come espressione: a=b=c=d+1; Equivale
alla sequenza: c=d+1; b=c; a=b;
04/05/2005 LP2-04/05 - Appunti di C 22
Operatori legati ai tipi• Type-casting
l’operatore cast permette la modifica esplicita dei tipi
(<tipo>) <espr> Es: (int) 5.4
• Conversioni automatiche:
n_intero=(int) n_float; /* assegna la parte intera di un “reale” */
n_intero=(int) lettera; /* assegna il codice ASCII del carattere*/
n_float=(float) n_intero /* converte in “reale” l’intero*/
04/05/2005 LP2-04/05 - Appunti di C 23
Operatori legati ai tipi• Operatore-funzione sizeof()
sizeof(<tipo>) (equivalentemente: sizeof(<var>))
sizeof(T) restituisce l’occupazione in byte di una variabile di tipo T
La dimensione dei tipi fondamentali può variare da una macchina ad un’altra. Comunque vale quanto segue:
sizeof(char) vale 1 sizeof(short) ≤ sizeof(int) ≤ sizeof(long) sizeof(signed) = sizeof(unsigned) = sizeof(int) sizeof(float) ≤ sizeof(double) ≤ sizeof(long
double)
04/05/2005 LP2-04/05 - Appunti di C 24
Altri operatori• Operatore condizionale
– operatore ternarioternario i cui operandi sono un’espressione logica e due espressioni di tipo qualsiasi:
<espr-logica> ? <espr1> : <espr2>;
– Il valore è restituito dall’espressione condizionale è:
• il valore restituito da <espr1> se l’espressione logica ha valore “vero” (!= 0)
• il valore restituito da <espr2> altrimenti.
04/05/2005 LP2-04/05 - Appunti di C 25
Altri Operatori• Operatori per manipolare i bit
– “&” AND bit a bit
– “|” OR inclusivo bit a bit
– “^” OR esclusivo bit a bit
– “~” NOT bit a bit
– “<<“ shift a sinistra
– “>>” shift a destra
• Esempi
– \x0f & \xab == \x0b, \x55 | \xaa == \xff, \x0f == (~\xf0)
– \x2b >> 1 == \x15, \x2b << 2 == \xa8
04/05/2005 LP2-04/05 - Appunti di C 26
Esempiofloat max(float a, float b) {
float x;x=(a>b) ? a : b;return x;
}float max(float a, float b {/* assegnamento contestuale alla
dichiarazione della var */float x=(a>b) ? a : b;return x;
}
float max(float a, float b {return (a>b) ? a : b;}
Il calcolo del massimo tra due numeri in virgola mobile
04/05/2005 LP2-04/05 - Appunti di C 27
Altri operatori• Operatore di incremento “++” e decremento “--”Ø int x=3; x++; /* x vale 4 */
Ø char x=‘a’; ++x; /* x vale ‘b’ */
• è importante sottolineare che un'istruzione del tipo x++; è più veloce della corrispondente x=x+1;
• Attenzione all’interno di espressioni:
– se postposti, l’incremento/decremento viene effettuato dopo la valutazione dell’espressione
– Se preposti, l’incremento/decremento viene effettuato prima della valutazione dell’espressione
04/05/2005 LP2-04/05 - Appunti di C 28
n Esempio 1int x,z=2; x=(++z)-1; /* A questo punto x=2 e z=3 */ x=(z++)-1; /* A questo punto x=1 e z=3 */
n Esempio 2Ø x=((++z)-(w--))%100;
equivale alle seguenti istruzioni:z++;x=(z-w)%100;w--;
Esempi
04/05/2005 LP2-04/05 - Appunti di C 29
La precedenza tra operatori• Una espressione complessa si presta ad essere interpretata in modi
diversi.
• Le ambiguità sorgono su:
Ø L’ordine di applicazione degli operatori. Esempio: l’espressione 3+2*5 dovrebbe essere intesa come 3+(2*5) e non (3+2)*5
Ø L’associatività degli operatori. Esempio: l’espressione 9/3/2 va intesa come (9/3)/2 o 9/(3/2) ?
• Il C fissa univocamente sia la precedenza che l’associatività degli operatori
04/05/2005 LP2-04/05 - Appunti di C 30
• Di seguito vengono riportati in ordine decrescente di precedenzatutti gli operatori incontrati con la loro associativitàØ ++, --, (<tipo>), * (da destra a sinistra)Ø *, /, % (da sinistra a destra)Ø +, - (da sinistra a destra)Ø <, <=, >, >= (da sinistra a destra)Ø ==, != (da sinistra a destra)Ø & (da sinistra a destra)Ø ! (da sinistra a destra)Ø && (da sinistra a destra)Ø || (da sinistra a destra)Ø ? : (da destra a sinistra)Ø =, <op>= (da destra a sinistra)
Priorità altaPriorità alta
Priorità bassaPriorità bassa
Ordine di precedenza tra operatori