a = 2

Transcript

a = 2
Fondamenti di
Programmazione
Variabili e memoria
Cos’ è il linguaggio C (1)



Sviluppato a partire dal linguaggio B ideato da
Thompson
Creato all’inizio degli anni ’70 da D. Ritchie ed è
diventato uno standard ANSI (American National
Standard Institute) nel 1983 (terminato nel 1990)
È un linguaggio di programmazione general purpose
imperativo a blocchi. È un linguaggio di uso generale
ma da sempre legato al sistema operativo UNIX, sul
quale è stato sviluppato.
Cos’ è il linguaggio C (2)

È considerato un linguaggio di alto livello ma
non troppo, nel senso che fornisce un
insieme ristretto di costrutti di controllo e di
parole chiave, ma un insieme ricco di
operatori e strutture dati avanzate
–
−
–
Offre al programmatore potenza e
flessibilità
di dimensioni ridotte, può essere
appreso velocemente
I principali vantaggi sono efficienza,
sinteticità e portabilità
Cos’ è il linguaggio C (3)
Il linguaggio non prevede funzionalità
esplicite di I/O, non esistono funzioni READ
e WRITE (devono essere incluse tramite
specifiche chiamate a funzioni di libreria)
Lo standard ANSI ha definito una libreria
standard associata al C la quale specifica le
funzioni (estensione .h) per l’accesso al
sistema operativo (es: leggere e scrivere su
file), l’allocazione di memoria, il trattamento
delle stringhe.

–
Le direttive del processore permettono di
includere porzioni di codice sorgente
esterne ad un dato file
Il lessico
Alfabeto:
utilizzato per scrivere i programmi UNICODE
Parole chiave:
parole riservate che hanno un significato
particolare e non possono essere ridefinite
Parole chiave definite dallo
standard ANSI








auto
break
case
char
const
continue
default
do
•
•
•
•
•
•
•
•
double
else
enum
extern
float
for
goto
if
• int
long
register
return
short
signed
sizeof
static








struct
switch
typedef
union
unsigned
void
volatile
while
Il lessico
Identificatori:
nomi usati per indicare variabili, funzioni etc.
Separatori:
caratteri che permettorno di separare o
raggruppare parti di codice: ( ) { } [ ] ; , .
Operatori:
denotano operazioni
Letterali:
sequenze di caratteri per rappresentari valori
di tipi primitivi : 1234 “questa è una stringa”
Il lessico
Commenti:
devono essere aperti e chiusi attraverso l’uso dei simboli
/* e */
oppure se di una sola riga preceduti da //
Nomi (o identificatori):
−
−
−
−
Il C è un linguaggio case sensitive. Ad esempio il
carattere “A” è diverso dal carattere “a”, sono due
entità diverse e distinte.
Un nome può iniziare con una lettera alfabetica e
continuare con lettere, cifre numeriche, simbolo di
sottolineatura
NON inziare un nome con il simbolo di sottolineatura
(nomi di sistema)
La lunghezza può essere un elemento critico;
generalmente la dimensione max è di 32 caratteri
Note sulla sintassi del
linguaggio (1)

Il C è un linguaggio strutturato e la caratteristica che
più contraddistingue un linguaggio di questo tipo è
rappresentato dai blocchi di codice. Un blocco è un
insieme di istruzioni logicamente collegate delimitato
da parentesi graffe { }
<istruzione>;
{<istruzione>; <istruzione>;}
Ogni istruzione per essere valida deve essere
terminata da un carattere “ ; ”
Norme di buona programmazione



scrivere istruzioni chiare, una per riga
evidenziare
blocchi di istruzioni con le
parentesi graffe anche se consistente di un
solo comando
utilizzare l’indentazione dei diversi blocchi del
programma per una più facile lettura del
codice stesso.
Programmazione

Concetti base:
−
−

Dati:
−
−
−

Dati (numeri interi o “reali”; caratteri alfanumerici; dati
booleani)
Istruzioni (operazioni di input/output, artimetiche o
logiche,strutture di controllo)
Variabili e costanti (variabilità nel tempo)
Tipi (elementari o strutturati)
classi di memoria (visibilità)
Istruzioni:
−
istruzioni base
strutture di controllo
−
moduli
−
Variabili e tipi

Variabile: locazione di memoria a cui è dato un
nome con cui chiamarla ed utilizzarla (contenitore di
dati)


programmatore usa il nome senza necessariamente
sapere che esso faccia riferimento ad una locazione di
memoria
Tipo: ogni variabile ha un tipo che indica che genere
di dati la variabile può contenere

−

una variabile può contenere dati di tipo intero (ad es.,
15 o 2038), oppure dati di tipo carattere (ad es., ‘a’ o
‘£’)
Le dimensioni delle variabili numeriche dipendono
dall’architettura dell’elaboratore sottostante
Classe di memoria: determina la durata di vita
della variabile.
Istruzioni base

Assegnazioni ed espressioni:
−
comandi per assegnare un valore ad una
variabile direttamente o come valutazione
di sequenze di operatori e operandi

esempio: interest = amount * 0.07;
Moduli


I programmi sono spesso abbastanza complessi da
dover essere scomposti in “pezzi” più maneggevoli
Un modulo consiste di istruzioni per svolgere un
certo compito raggruppate insieme in un’unità a cui è
dato un nome


il nome può essere usato come sostituto dell’intero insieme di
istruzioni
Vantaggi:

risparmio di scrittura, organizzazione, riutilizzo
Creare un programma
eseguibile

Editor
−

Compilatore
−

Codice oggetto scritto in linguaggio assembler
(nome_file.obj)
Linker
−

Scrittura del programma sorgente
(nome_file.c)
Collega tra loro i moduli che costituiscono il
programma e produce il codice eseguibile
(nome_file.exe)
Loader (fase di caricamento)
L'inizio del programma


main (non Main o MAIN) è una funzione speciale che
indica l’inizio dell’esecuzione del programma e deve
pertanto essere presente in ogni programma.
Le parentesi vuote dopo main significano che la funzione
non prende nessun parametro in input.
Creazione di variabili


Tutte le variabili devono essere dichiarate prima di poterle
utilizzare
Una dichiarazione di variabile associa un nome alle locazioni
di memoria ad essa corrispondenti e specifica il tipo di dati
che la variabile conterrà:
Tipo Variabile_1, Variabile_2, …;

Per esempio, per creare tre variabili che memorizzino il numero
di cesti, il numero di uova per cesto ed il numero totale di uova:
int numberOfBaskets, eggsPerBasket, totalEggs;
Tipi fondamentali

Rappresentano un singolo valore numerico

Tipo
Descrizione
•
•
•
•
char
int
float
double
singolo carattere
intero
virgola mobile a singola precisione
virgola mobile a doppia precisione
• char<= int <= float <= double

Tipo
•
•
•
•
•
char
int
float
double
void

Bit occupati
8
16
32
64
0
• Intervallo
0 – 255
-32768 – 32767
3.4E-38 – 3.4E+38
1.7E-308 – 1.7E+308
indefinito
Esempio: definire una
variabile
Inizializzazione di una
variabile

Operatore di assegnamento è: =
int total;
total=0;


Oppure
int total=0;
il compilatore non segnala errore se si
inizializza una variable con un valore fuori
range
La parola chiave typedef
typedef int integer;


crea integer sinonimo di int
non crea un nuovo tipo!
Costanti






Una costante è una locazione di
memoria di un dato
Il valore immagazzinato non può
variare durante l’esecuzione di un
programma
Costanti carattere : ‘A’
Costanti intere : 23
Costanti con virgola (double) :123.456 ,
1.23e2, 100.
Costanti stringa: “cane”
Costanti simboliche


Una costante simbolica è una costante
che è rappresentata da un nome
Una variabile con valore fissato
const float PI=3.14159265;
#define PI 3.14159265
Variabili e costanti
a = 2;
b = 3.5;
c = 2.;
0xffffa000
0xffffa001
Nota: per brevità
0xffffa002
le variabili intere
sono rappresentate
0xffffa003
usando solo 8 bit
0xffffa004
0xffffa005
????????
????????
00000010
????????
????????
????????
Variabili e costanti
a = 2;
b = 3.5;
c = 2.;
0xffffa000
0xffffa001
0xffffa002
00000010
0xffffa003
01000000
0xffffa004
11100000
0xffffa005
00000000
3.5 = (1 + 0.75)*21
NOTA: l’esponente è 0xffffa006
rappresentato in
eccesso (cap.1,p.19) 0xffffa007
00000000
a = 2;
b = 3.5;
c = 2.;
2. = (1 + 0)*21
0xffffa002
0xffffa003
0xffffa004
0xffffa005
0xffffa006
0xffffa007
0xffffa008
0xffffa009
0xffffa00a
00000010
01000000
11100000
00000000
00000000
01000000
10000000
00000000
00000000
a
b
c
d
=
=
=
=
2;
3.5;
2.;
‘f’;
f ↔ 102 (6616)
0xffffa003
0xffffa004
0xffffa005
0xffffa006
0xffffa007
0xffffa008
0xffffa009
0xffffa00a
0xffffa00b
01000000
11100000
00000000
00000000
01000000
10000000
00000000
00000000
01100110
Modificatori di tipo

I tipi di dato primitivi possono essere
estesi con l’uso di alcuni modificatori:
−
−
Di dimensione: short, long
Di “valutazione”: unsigned
Operatori ed Espressioni
Espressioni
Una espressione è una combinazione
valida di costanti, variabili e operatori.
Ha un valore numerico e un tipo.
• 2+5; /*somma tra costanti*/
• x=a+10; /* assegnazione di una
somma tra una costante e una
variabile*/
Operatori


Un operatore è un simbolo che istruisce
C di eseguire una operazione su uno o
più operandi.
Esistono tre classi di operatori:
−
−
−
aritmetici (o matematici)
logici e relazionali
bit a bit.
Operatori aritmetici binari
<op1> + <op2>
<op1> - <op2>
<op1> * <op2>
Somma i due operandi
Sottrae dal primo il secondo
operando
Moltiplica gli operandi
<op1> / <op2>
Divide il primo con il secondo
operando
<op1> % <op2>
Resto della divisione tra il primo e il
secondo operando
L’operatore % non può essere applicato ai tipi float,double
Assegnazione+operatore
aritimetico
•
•
•
•
•
<op1>
<op1>
<op1>
<op1>
<op1>
+=
-=
*=
/=
%=
<op2>
<op2>
<op2>
<op2>
<op2>
<op1>=<op1>+<op2>
<op1>=<op1>-<op2>
<op1>=<op1>*<op2>
<op1>=<op1>/<op2>
<op1>=<op1>%<op2>
Ad es. int a=5, b=7;
a+=2;
b/=3;
equivale a:
equivale a:
a=a+2; (nota: a vale 7)
b=b/3; (nota: b vale 2)
Operatori matematici
int a=2;
float b=3.5,c;
c = a + b;
Nota: nel registro
della CPU il numero 2
viene “promosso” a
float
0xffffa002
0xffffa003
0xffffa004
0xffffa005
0xffffa006
0xffffa007
0xffffa008
0xffffa009
0xffffa00a
00000010
01000000
11100000
00000000
00000000
01000000
10000000
00000000
00000000
Operatori matematici
c = a + b;
0xffffa002
0xffffa003
0xffffa004
0xffffa005
0xffffa006
0xffffa007
0xffffa008
0xffffa009
0xffffa00a
00000010
01000000
11100000
00000000
00000000
?
?
?
?
Operatori matematici
c = a + b;
5.5 = (1 + 0.375)*22
0xffffa002
0xffffa003
0xffffa004
0xffffa005
0xffffa006
0xffffa007
0xffffa008
0xffffa009
0xffffa00a
00000010
01000000
11100000
00000000
00000000
01000001
00110000
00000000
00000000
Nota : conversioni
int c;
int a=2;
float b=3.5;
c=a+b;
c vale 5


Usare le parentesi per rendere chiaro
l’ordine di valutazione dell’espressione
Non sovraccaricare l’espressione
−
−
Spezzare un espressione complessa in
più espressioni
Soprattutto se si utilizzano gli operatori (+
+) o (--)
Assegnazione: priorità
• x=(25-2*(10+(8/2)));
• i=j=k=0;


= ha priorità più bassa rispetto agli altri
operatori ed associa da destra a sinistra
Poiché anche l’assegnazione è un
operatore si possono scrivere
contrazioni:
• z=(x=1)+(y=2);
Operatori speciali
a = 2;
b = ++a;
0xffffa002
00000010
0xffffa003
????????
Operatori speciali
a = 2;
b = ++a;
0xffffa002
00000011
0xffffa003
00000011
Operatori speciali
a = 2;
b = ++a;
a = 2;
b = a++;
0xffffa002
00000011
0xffffa003
00000011
0xffffa002
00000010
0xffffa003
????????
Operatori speciali
a = 2;
b = ++a;
a = 2;
b = a++;
0xffffa002
00000011
0xffffa003
00000011
0xffffa002
00000011
0xffffa003
00000010
Precedenze
++, --
massima
*, /, %
intermedia
+,
-
minima
Espressioni con operatori dello stesso livello
sono valutati da sinistra verso destra
w*x/y*z;
w*x/y+z/y;
w*x/++y+z/y;
z-(a+b/2)+w*y
Problema: conversione di
gradi Fahrenheit in Celsius
Dobbiamo studiare le diverse temperature
rilevate in periodi diversi alcune delle quali
sono espresse in Fahrenheit, mentre altre in
Celsius. Vorremmo avere tutte le temperature
in gradi Celsius.
Analisi: Conversione da gradi Fahrenheit a
Celsius
Dati in ingresso: temperatura in Fahrenheit (tf)
Risultato: temperatura in Celsius (tc)
Formula: tc=(tf-32)x5/9
Algoritmo (da raffinare):

“Acquisisci” i dati

Calcola la conversione

“Visualizza” il risultato
Programmi e variabili
main() {
float tc, tf = 90., conv;
float offset = 32.;
conv = 5./9.;
tc = (tf – offset) * conv;
}
?
90.
?
tc
tf
conv
Programmi e variabili
main() {
float tc, tf = 90., conv;
float offset = 32.;
conv = 5./9.;
tc = (tf – offset) * conv;
}
?
90.
?
32.
tc
tf
conv
offset
Programmi e variabili
main() {
float tc, tf = 90., conv;
float offset = 32.;
conv = 5./9.;
tc = (tf – offset) * conv;
}
?
90.
tc
tf
0.555
conv
32.
offset
Programmi e variabili
main() {
float tc, tf = 90., conv;
float offset = 32.;
conv = 5./9.;
tc = (tf – offset) * conv;
}
32.22
tc
90.
tf
0.555
conv
32.
offset
Test


Cosa accade se eseguo il programma?
Nulla, perché non ci sono istruzioni di
output!
Input/Output
scanf(“%lf”, &tf);
Input/Output
scanf(“%f”, &tf);
90
Input/Output
scanf(“%lf”, &tf);
90 = (1+0.40625)26
010000101011010000000000...
(1/4 + 1/8 + 1/32)
Input/Output
scanf(“%lf”, &tf);
90 = (1+0.40625)26
010000101011010000000000...
90.
Input/Output
printf(“%f F = %f C\n”, tf, tc);
Input/Output
printf(“%f F = %f C\n”, tf, tc);
Input/Output
printf(“%f F = %f C\n”, tf, tc);
90.000000 F = ...
Input/Output
printf(“%f F = %f C\n”, tf, tc);
90.000000 F = 32.222222 C...
Input/Output
printf(“%f F = %f C\n”, tf, tc);
90.000000 F = 32.222222 C
>
Emissione dei dati
attraverso printf()

Questa funzione permette di formattare l’output
int printf(<stringa-formato>[,<espressione>]… )
 Emette la stringa indicata nel 1o parametro
 Se il 1o parametro contiene metavariabili, queste formattano
ordinatamente i parametri successivi
printf(“Totale fatturato:%d\n” ,12345);
 Restituisce il numero di caratteri emessi
Ancora su printf()



La stringa di formato può essere
costituita da tre componenti:
(obbligatoria) una costante stringa ;
(opzionali) metavariabili e sequenze di
escape
Opzioni di visualizzazione di
caratteri
Principali caratteri di conversione
%c
Singolo carattere
%d
Intero decimale con segno
%f
Decimale in virgola mobile
%e
Notazione scientifica
%s
Costante stringa
%u
Decimale intero senza segno
%o
Ottale
%e
Esadecimale
Codice di escape
\ooo
\xhh
\\
\0
\a
\b
\f
\n
\t
Descrizione
Notazione ottale*
Notazione esadecimale**
Singola barra obliqua (\)
Il codice NUL
Il codice bell (alert)
Il codice backspace
Il codice formfeed
Il codice newline
Tabulazione oriz.
Tabulazione vert.
Acquisizione dei dati
attraverso scanf()

Questa funzione permette di immettere da tastiera
l’input
int scanf(<stringa-formato>,&var1,[lista
destinazioni])
 Copia ordinatamente in memoria i valori digitati da tastiera
nelle variabili contenute in lista destinazioni
 Le variabili nella lista delle destinazioni devono essere
precedute da & che ne indica l'indirizzo
scanf(“%d%lf”,&count,&average);
 Restituisce il numero di dati acquisiti
scanf()
ATTENZIONE:
Se si inseriscono spazi o invio
nell'immissione di più caratteri (tra un
carattere e un altro) è necessario inserire
anche questi nella stringa di formato tra i
segnaposto %c
Importanza della
rappresentazione
tf =(tc – offset) * 5./ 9.;
(tc – offset) * 5./ 9;
(tc – offset) * 5 / 9;
tf = 5 / 9 * (tc – offset);
Imprecisioni numeriche
Errore di arrotondamento:
0.1 non ha una rappresentazione finita in
binario
0.00011001100110011001100110011001100
11001100110011...
Underflow e overflow
– Tentativo di rappresentare un numero
fuori dal range di valori possibili
Errore di cancellazione:
– a+b vale a, se a>>b
Direttive al preprocessore
Preprocessore: programma che “esegue”
istruzioni dette direttive di inclusione e
definizione
#include
Consente di includere il contenuto di un altro
file
#define
Definisce un simbolo (Attenzione!!!)
#ifdef, #ifndef, #else
Compilazione condizionale
#include

#include <stdio.h>
per input/output

#include <stdlib.h>
allocazione dinamica della memoria,
generazione numeri casuali, exit, time

#include <math.h>
libreria matematica
− sin(x), cos(x), sqrt(x), exp(x), pow(x,y),
log(x), fabs(x), iabs(x)