




























































































Studia grazie alle numerose risorse presenti su Docsity
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Prepara i tuoi esami
Studia grazie alle numerose risorse presenti su Docsity
Prepara i tuoi esami con i documenti condivisi da studenti come te su Docsity
Trova i documenti specifici per gli esami della tua università
Preparati con lezioni e prove svolte basate sui programmi universitari!
Rispondi a reali domande d’esame e scopri la tua preparazione
Riassumi i tuoi documenti, fagli domande, convertili in quiz e mappe concettuali
Studia con prove svolte, tesine e consigli utili
Togliti ogni dubbio leggendo le risposte alle domande fatte da altri studenti come te
Esplora i documenti più scaricati per gli argomenti di studio più popolari
Ottieni i punti per scaricare
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Breve Corso Linguaggio C - Laboratorio di programmazione e Calcolo
Tipologia: Dispense
1 / 107
Questa pagina non è visibile nell’anteprima
Non perderti parti importanti!





























































































versione 3.1, Ottobre 2006
Corso di “Laboratorio di Programmazione e Calcolo” Corso di Laurea in Matematica Università di Roma “La Sapienza” A.A. 2006-
“How do we convince people that in programming simplicity and clarity - in short: what mathematicians call ‘elegance’- are not a dispensable luxury, but a crucial matter that decide between success and failure?”
“Come convincere la gente che, nella programmazione, semplicità e chiarezza - in breve: quello che i matematici chiamano ‘eleganza’ - non sono un lusso , ma un fatto cruciale che fa la differenza tra successo e insuccesso?”
(E.W. Dijkstra, Selected writings on computing: a personal perspective,1982)
- Il C è un linguaggio procedurale moderno che permette
una notazione molto compatta ed efficace
- E’ portabile su molte architetture - Permette al programmatore un controllo molto elevato
sulla memoria della macchina, consentendo di ottimizzare il codice
- E’ molto versatile (multi-purpose) e viene correntemente
utilizzato per scrivere sistemi operativi, librerie scientifiche e grafiche molti altri pacchetti applicativi.
- Insieme alla sua versione C++ orientata alla
programmazione ad oggetti, è uno dei linguaggi più diffusi nel mondo del calcolo scientifico e nell’industria.
Altri linguaggi sono più adatti a risolvere problemi in
specifiche aree di applicazione:
Linguaggio Applicazione tipica
Fortran 77 e Fortran 90 calcolo scientifico
Pascal insegnamento
APL calcolo simbolico, calcolo scientifico
Cobol contabilità, gestione
Assembler primitive di librerie (grafiche ad esempio)
DB3 gestione di banche dati (data-base)
BASIC giochi
VISUAL BASIC giochi, calcolo, gestione
I chip di memoria contengono bits di informazione.
Un bit ha unicamente due valori possibili, 0 oppure 1. Questa forte limitazione è superata dal fatto che un insieme di bit contigui può essere utilizzato per distinguere moltissime possibilità.
Ad esempio, 8 bits (= 1 byte ) possono distinguere tra
28 =256 differenti casi (sono tutte le possibili combinazioni di 8 valori 0 e 1). Il numero di queste possibilità è sufficiente a individuare ogni carattere presente sulla tastiera del vostro computer.
Un insieme di bytes, che siano contigui in memoria, può essere utilizzato per descrivere un numero, intero o in virgola mobile.
In C e C++, ogni insieme di bytes in memoria per essere usato dal vostro programma deve essere dichiarato ed assegnato ad un tipo di dato ( data type ). Il tipo di dato scelto indica in che modo i bits devono essere interpretati per individuare il numero, il carattere o un altro tipo di dato.
Ogni byte di memoria ha un posizione precisa nel chip di memoria, tale posizione è individuata da un numero (il suo indirizzo ). Questo indirizzo non va confuso con il contenuto dell’informazione contenuta nel byte (che è il suo valore ).
C e C++ permettono di accedere sia all’indirizzo che al valore di un byte o di un insieme di bytes contingui in memoria.
int
Occupazione di memoria : 2 bytes (=16 bits) Ogni intero n, tale che -32768 < n < + Se l’intero è fuori da quell’intervallo si verifica un integer overflow.
I qualificatori short e long si applicano a int e corrispondono a due lunghezze diverse di interi (in termini di cifre). Vengono interpretati in modo diverso a seconda della macchina e del compilatore, l’unica certezza è che short int ha meno cifre di long int.
In molti casi una delle due versioni coincide con il tipo int, ad esempio in Turbo C int=short int.
Un numero long int occupa 4 bytes (= 32 bits).
Un altro qualificatore per gli interi è unsigned, gli interi unsigned sono sempre positivi.
Esempio int i; long int n; unsigned int m;
corrispondono alle dichiarazioni di un intero (i), un intero esteso (n) e di un intero positivo (m).
L'overflow intero (integer overflow) non viene dichiarato ma il risultato non è quello voluto.
Esempio: L’operazione 1000*100/ non dà come risultato 2000 ma dà integer overflow (cioè
32768 ) perché le operazioni vengono eseguite da sinistra a
destra.
Le parentesi invertono l’ordine di esecuzione, dunque
1000*(100/50)
fornisce il risultato corretto.
Attenzione!
Se sui reali si verifica un errore di:
overflow causa l'arresto del programma
underflow il risultato viene posto = 0, ma il programma prosegue l’esecuzione.
a=exp(100) va in overflow con arresto del programma (runtime error)
b=exp(-100) va in underflow, il programma continua l’esecuzione
(in bit)
int 16 da -32.768 a 32. unsigned int 16 da 0 a 65535 long int 32 da -2.147.483. a 2.147.483. float 32 da 3.4 E-38 a 3.4 E double 64 da 1.7 E- a 1.7 E+
char
Occupazione di memoria: 1 byte Carattere nell'ambito dei caratteri ascii (sono 255).
Anche le stringhe (=sequenze di caratteri e spazi bianchi) sono variabili di tipo char
Ad esempio, si può assegnare una intera frase del tipo
“Il risultato dell’integrale e’:”
ad una variabile di tipo char.
In C il tipo booleano non è predefinito. Di solito una variabile booleana viene sostituita con una variabile intera che può valere solo 1 (true) oppure 0 (false). In C++ invece esiste il tipo bool , a variabili di questo tipo si applicano solitamente gli operatori logici (AND, OR, NOT,..)
In particolare, nelle espressioni aritmetiche la sequenza delle
trasformazioni di tipo viene eseguita esattamente in questo
ordine:
double;
viene convertito in double e il risultato dell’operazione è un
double;
convertito in long e il risultato dell’operazione è long;
viene convertito in unsigned e il risultato dell’operazione è
unsigned;
Nei casi in cui la conversione di tipo non venga effettuata
implicitamente dal compilatore oppure quando si vuole
evitare un risultato indesiderato si può forzare una
conversione di tipo (cast) mettendo tra ( ) il tipo desiderato
prima del nome della variabile.
Esempio
(float) media/n /* con media ed n int*/
(double) minimo+idx /con minimo, dx float e i int*/
impongono il tipo float al valore della divisione media/n ed
il tipo double al risultato dell’espressione minimo+i*dx.
Un caso tipico in cui occorre imporre il tipo del risultato è
nella divisione di due numeri interi. Infatti, se non venisse
fatto un cast il risultato della divisione sarebbe intero e si
perderebbero tutte le cifre dopo la virgola.
Le variabili possono anche essere di tipo puntatore.
Una variabile di tipo puntatore conterrà l’indirizzo di memoria di un’altra variabile di tipo int, char, float,...
Non è possibile definire una variabile puntatore “universale”, cioè che “punti” indifferentemente ad una variabile intera, reale, character,... Di conseguenza, a fianco del puntatore bisogna sempre indicare qual’è il tipo di variabile cui “punta”.
Per indicare che una variabile è un puntatore, nella sua dichiarazione occorre mettere * prima del nome.
Esempio int pn,pm; float px,py, x;
definiscono rispettivamente 2 puntatori ad interi (pn,pm), 2 puntatori a reali (px,py) e 1 variabile reale x.
Ci sono due operatori particolarmente importanti per lavorare con i puntatori: & e *.
L’operatore & applicato ad una variabile restituisce il suo indirizzo di memoria (puntatore alla variabile).
L’operatore * applicato ad un indirizzo di memoria (puntatore) restituisce il valore contenuto in quell’indirizzo.
Esempio Se a è una variabile e pa il suo puntatore avremo &a=pa *pa=a