SlideShare a Scribd company logo
1 of 69
Introduzione al C++
Tipi integrali, conversioni di tipo,
costanti ed espressioni costanti,
direttive al preprocessore, inclusione
condizionale
Il concetto di tipo
• Determina i valori che può assumere una variabile e le operazioni
ammissibili su di essa
• Determina la memoria minima necessaria per memorizzare una
variabile
• int: di solito una parola; float: di solito due parole

• Permette al compilatore di rilevare errori nell'uso delle variabili
– un linguaggio è fortemente tipizzato se garantisce:
• correttezza delle istruzioni rispetto al tipo degli operandi, verificabile dal
compilatore
• che non sorgano errori di tipo in esecuzione

• Il C++ persegue la tipizzazione forte
– però è al tempo stesso molto permissivo, poiché ammette molte
conversioni automatiche tra tipi diversi
2
Il sistema dei tipi del C++
• Uno degli obiettivi principali del C++ è
permettere al programmatore di creare tipi
personalizzati e usarli come se fossero offerti
dal linguaggio
• Il sistema dei tipi del C++ comprende
– Tipi predefiniti (predefined)
– Tipi composti (composite)
– Tipi definiti dall’utente (user defined)
– Tipi classe (class types)
Cosa c’è da sapere di ogni tipo
• Che valori ammette
• Come sono rappresentati i valori nel calcolatore
– Sarebbe bello ignorarlo, ma talvolta non si può

• Come rappresentare valori (costanti) di quel tipo nel
programma (anche detti "literal")
• Come dichiarare e inizializzare variabili di quel tipo
• Quali operazioni sono ammesse sulle variabili
• Quali tipi sono “affini”
– Sono definite conversioni automatiche tra tipi affini
Inizializzazione delle variabili
• Le variabili si dichiarano e inizializzano
– La dichiarazione definisce il tipo
– L’inizializzazione definisce il valore iniziale della
variabile neonata
– L’inizializzazione NON è l’assegnamento
• quest’ultimo definisce il valore corrente della variabile
• Alcune cose che si possono fare durante
l’inizializzazione sono vietate nell’assegnamento

int i = 0;
tipo

identificatore inizializzatore
Inizializzazione di default
(tipi predefiniti)
• Una variabile dei tipi predefiniti priva di inizializzatore
viene inizializzata per default
• Il valore di default dipende dal tipo della variabile e
dalla posizione della dichiarazione
– Variabili dei tipi predefiniti definite al di fuori di una
funzione ricevono per default il valore 0
– Variabili dei tipi predefiniti definite all'interno di una
funzione sono uninitialized, cioè il valore NON è definito

• NB: per le variabili di tipo classe, il valore di
inizializzazione per default può essere specificato dal
programmatore
Check this out!
• http://stackoverflow.com/questions/18870547/why-there-isno-difference-between-initialization-and-assignment-for-thebuild-im/articles/article.aspx?p=376876
I tipi predefiniti del C++
• I tipi aritmetici: integral e floating point
Il tipo bool
• Sta per Boolean (booleano)
• Rappresentare il tipo delle espressioni che il
programma usa per prendere decisioni (se…,
fintantoché…)
• Ammette solo due valori: true e false

– false è rappresentato tramite il valore numerico 0
– true è rappresentato da qualunque valore numerico
diverso da 0
bool
bool
bool
bool

b
b
b
b

=
=
=
=

true; // b vale true
23; // b vale true
false; // b vale false
0; // b vale false

• In altre parole bool è un tipo (affine a) intero!
Il tipo char
• Ammette come valore un singolo carattere
• Utilizza il minimo numero di bit necessario a rappresentare
l’insieme dei caratteri standard del calcolatore un byte (di
solito 8 bit per rappresentare i caratteri ASCII)
• I caratteri sono rappresentati internamente da numeri interi e
quindi tra essi è definito un ordinamento
– Esempio: il carattere '1' è rappresentato dall’intero 49, il carattere
'A' dall’intero 65, …
• quindi, nell’ordinamento, risulta '1' < 'A'

– Per le lettere è scelta una codifica tale per cui l’ordinamento dei codici
coincide con l’usuale ordinamento alfabetico: 'A'<'B' ecc.
• Lettere alfabeticamente adiacenti hanno codifiche adiacenti

– Negli insiemi più usati le maiuscole latine sono codificate “prima”
delle minuscole
• Quindi ad esempio 'A'<'a' ma anche 'Z'<'a'
10
Il concetto di insieme di caratteri
• A differenza dei numeri
interi, i caratteri non hanno
una rappresentazione
“naturale” nel calcolatore
• La rappresentazione è
convenzionale e si ottiene
“numerando” i simboli
dell’insieme dei caratteri
che si vuole rappresentare
• Esistono molti insiemi di
caratteri, che coprono un
numero differente di
simboli di lingue diverse

• Gli insiemi di caratteri e
le codifiche più usati
sono
– ASCII
– ISO/IEC 8859
– UNICODE con UTF-8 e
UTF-16
Why character encoding matters

http://en.wikipedia.org/wiki/Mojibake
Insieme di caratteri ASCII
• Lo American Standard Code for Information
Interchange (ASCII ) è una codifica dei caratteri basata
sull’alfabeto inglese che copre 27= 128 caratteri
• Usa 7-bit
• 95 caratteri stampabili: i numeri 0-9, le lettere a-z e AZ, simboli di punteggiatura e lo spazio bianco
• Vari caratteri non stampabili, tra cui alcuni codici di
controllo derivanti dalle Teletype machines
ASCII Table
ISO 8859 (ISO LATIN)
•
•

•
•

I 95 caratteri ASCII stampabili
sono sufficienti per lo scambio di
informazioni in lingua inglese
Molte altre lingue che usano
l'alfabeto latino hanno bisogno di
simboli addizionali, come la ß
(tedesco), la ñ (spagnolo), la å
(svedese e altre lingue
scandinave) o le lettere accentate
italiane (à, è, é, ì, ò, ù)
L'ISO 8859 utilizza l'ottavo bit del
byte, che permette la codifica di
altri 128 caratteri
ISO 8859 è organizzato in diverse
parti: es: ISO 8859-1, Latin-1
Western European

http://en.wikipedia.org/wiki/ISO/IEC_8859
UNICODE, UTF-8, UTF-16
•
•

•

Unicode è un insieme di caratteri
e una sistema di codifica che
comprende oltre 110.000 simboli
Unicode si sovrappone a ISO/IEC
8859-1, ma codifica inoltre i
caratteri di quasi tutte le lingue
vive e in alcune lingue morte,
nonché simboli matematici e
chimici, cartografici, l'alfabeto
Braille, ideogrammi ecc.
I caratteri Unicode sono
rappresentati con le codifiche
UTF-8 e UTF-16

•

•

UTF-8 (8-bit Unicode
Transformation Format) è una
codifica dei caratteri Unicode

– usa un byte per i caratteri
dell’insieme ASCII, che hanno lo
stesso codice sia UTF-8 sia in
ASCII, e fino a 4 bytes per gli altri
caratteri (codifica a lunghezza
variabile)

UTF-16 (16-bit Unicode
Transformation Format) è una
codifica dei caratteri Unicode

– può rappresentare fino a
1,112,064 entità (code points) tra
cui i caratteri UNICODE da 0 a
0x10FFFF
– La codifica è a lunghezza
variabile, con uno o due unità da
16 bit
I tipi int
• Approssima il dominio degli interi
• Normalmente utilizza 1 parola di memoria
• Esistono anche le varianti
– short int, long int e long long int
– tipico: long 32 bit, long long 64 bit, short 16 bit,
e int 16 o 32 (per cui spesso int è grande quanto long
int)

• Lo standard del C++ richiede che
– spazio per short <= spazio per int <= spazio per long
<= spazio per long long
La gestione del segno
• TUTTI i tipi integral, tranne bool, ammettono la
versione “senza segno” (unsigned)
• Il tipo normale permette di rappresentare numeri
interi positivi e negativi
• Il tipo unsigned permette di rappresentare solo
numeri interi positivi, ma utilizza un bit in più (e
quindi può rappresentare di più valori)

– unsigned int: un valore intero positivo di almeno 16
bit, compreso tra 0 e 216-1
– Il prefisso signed si può omettere
– unsigned èquivale a unsigned int
– unsigned char  da 0 a 255
Rapporto tra tipi signed e unsigned
• Tipi signed e unsigned non andrebbero mescolati
• Se si assegna un valore fuori intervallo a una variabile
di tipo unsigned, il risultato è definito come:
– Il resto della divisione del valore per il massimo intero che
il tipo unsigned può rappresentare

• Per esempio, un tipo unsigned char da 8-bit
rappresenta valori da 0 a 255.
• L’assegnamento di un valore fuori intervallo dà come
esito il resto di tale valore diviso per 256
– Assegnare –1 a un unsigned char da 8 bit produce il valore
255!
Check this out
int main() { // Assegna a unsigned valore negativo
unsigned char c;
// va da 0 a 255;
cout << "Inserire un numero negativo: " << endl;
int i;
cin >> i;
cout << "Valore inserito (intero originale): " << i << endl;
c=i; // assegno numero negativo a variabile char
cout << "Valore inserito (char): " << c << endl;
i=c; // recupero il valore intero di c
cout << "Valore inserito (intero dopo la conversione a char): "
<< i << endl;
return 0;
}

• Il compilatore non può rilevare l’errore
• Non sa predire che valore inserisce l’utente
• NB:
Rapporto tra char e int
• In molti linguaggi di programmazione, char e int sono
tipi non solo diversi, ma incompatibili
• C e C++ considerano i caratteri come “una particolare
interpretazione” dei numeri interi
• La convertibilità tra char e int può portare a
programmi difficili da comprendere
• Usare char solo quando serve davvero una variabile
che contenga un carattere, per esempio per
– Cercare/contare/sostituire tutte le occorrenze di un
carattere in un testo
Da char a int
• Determinare il codice di una lettera minuscola
• Cosa serve
– Una variabile char
– Una variabile int

• Algoritmo

1. Leggi il prossimo carattere
2. Se è una lettera maiuscola
1.
2.
3.

Convertilo in un intero
Stampa il risultato della conversione
Torna al punto uno

3. Termina
Da char a int
int main() {
// Legge un carattere e stampa il codice ASCII
char c;
// se è una minuscola; altrimenti termina
int i;
cout << "Scrivi un car. minuscolo (maiusc. x finire)" << endl;
cin >> c;
while (c >= 'a' && c <= 'z') { // minuscolo?
i = c; // assegna il valore del carattere a un intero
cout << "Valore ASCII per " << c << " è" << i << endl;
cout << "Scrivi car. minuscolo (maiusc. x finire)" << endl;
cin >> c;
}
return 0; // termina
}

NB: notare la ripetizione delle istruzioni che richiedono
l'input
Iterazione e condizione
• while (c >= 'a' && c <= 'z') {..
Corpo del ciclo..}
• Se la condizione è vera

• esegue le istruzioni all’interno del corpo

• Quando la condizione è falsa
• termina il ciclo (esce dal ciclo)

• (c >= 'a' && c <= 'z')
•
•
•
•

Esprime la condizione di permanenza nel ciclo
E’ un’espressione con valore di tipo bool, cioè vero o falso
&& Operatore logico AND
‘a’ è un valore costante (literal) di tipo carattere
Da int a char
int main() {
// Stampa il codice carattere
char c;
// corrispondente ai 128 codici ASCII
for (int i=0; i<128; ++i) {
c = i; // assegna il valore intero al carattere
cout << "Il carattere corrispondente a " << i
<< " è: " << c << endl;
}
return 0;
}
Iterazione a conteggio
• for (int i=0; i<128; ++i)
• Quando una iterazione deve essere svolta un
numero preciso di volte si può usare un “ciclo for”
• Il ciclo incrementa una variabile apposita (contatore)
per tener traccia del numero di interazioni
– int i=0; dichiarazione del contatore
– i<128; condizione di permanenza
– ++i avanzamento del contatore
Ciclo while e ciclo for
char c;
for (int i=0; i<128; i++) {
c = i;
cout << “Il carattere
corrispondente a " << i
<< " è: " << c << endl;
}

int i = 0;
char c;
while (i<128) {
c = i;
cout << “Il carattere
corrispondente a " << i
<< " è: " << c << endl;
i++;
}
I tipi float e double
• Approssimano i numeri razionali
• I valori si possono rappresentare con due notazioni
– 315.779
– 3.73E-5

• double di solito occupa più memoria di float
– tipicamente 4 byte per float e 8 byte per double
• (...esistono anche i long double, che devono occupare almeno
tanto spazio quanto i double)

• Lo standard prescrive la precisione minima, cioè il
minimo numero di cifre significative
28
Come rappresentare valori dei tipi
predefiniti

• Il valore 10 ha un tipo diverso da 10.0
• 10L è un valore di tipo long int
Cautele
• Attenzione ai confronti tra float
float a, b;
...
if (a == b) ...

• non ha senso, a causa delle approssimazioni nella
memorizzazione!!
diff = A - B;
if ((diff < EPSILON) && (-diff <
EPSILON));

• EPSILON costante definita in std::numeric_limits
Check this out
• http://stackoverflow.com/questions/17333/m
ost-effective-way-for-float-and-doublecomparison
Quali tipi scegliere
• Usare tipi unsigned quando si è certi che servono
solo valori positivi
• Usare int per valori aritmentici (short di solito
non basta)
• Se servono valori molto grandi usare long long
• Non usare char e bool in espressioni aritmentiche
– Se proprio proprio serve un intero piccolo usare signed
char o unsigned char

• Usare double per le operazioni in virgola mobile (di
solito float ha precisione insufficiente e le
operazioni sui double sono comunque veloci)
Conversioni di tipo
• Se un operando non è del tipo atteso e il compilatore
non ha informazioni sul tipo desiderato interviene
una conversione automatica di tipo
– È detta anche cast implicito
– Si opera la conversione anziché segnalare l'errore
• A volte è accompagnata da un “avvertimento” (warning)

• Esempio
– int i; float f;
– la valutazione dell’espressione i + f effettua prima la
conversione di i in float e poi la somma
La "scaletta" delle conversioni
Conversioni di tipo: esempi
int n, m;

float x,y;

n = 3.541 + 3; // il risultato è 6!
x = n;
x = n +
n = x;
n = n /
n = n /
x = n /
x = n /

n da “int” è promosso a “float”
x; // n è promosso a “float” e poi sommato a x
// x è troncato, ne sopravvive la parte intera
m; // il risultato della divisione tra interi è intero
x; /* n è convertito in “float”, poi si esegue la
divisione, il risultato è troncato a int */
x; //come sopra ma il risultato resta float
m; // attenzione: la divisione tra int tronca
//
Conversioni con il tipo bool
• Il tipo bool ha valore true o false
• I valori interi vengono convertiti a bool come segue
– 0 viene convertito a false
– ogni altro valore intero viene convertito a true

• Vale anche la conversione inversa (promozione a int)
bool b=false; int i; // inizializzazione
i = b; // i vale 0
b=true;
i = b; // i ora vale 1!
Conversioni con tipi un/signed
• Ecco perché è meglio non mescolare
unsigned u = 10;
int i = -42;
cout << i + i << endl; // prints -84
cout << u + i << endl; // if 32-bit ints, prints
4294967264

• Il valore di i (-42) viene convertito a unsigned
prima dell’addizione
unsigned u1 = 42, u2 = 10;
cout << u1 - u2 << endl; // ok: result is 32
cout << u2 - u1 << endl; // ok: but the result is… ?
Quando avvengono le conversioni
automatiche
• Nelle espressioni, i valori di tipi aritmetici piccoli vengono
solitamente promossi a int
char c, int i;
i=c+i; // da evitare

• Nelle condizioni, tipi non bool sono convertiti a bool
– while (33) equivale a while (true) !

• Nell’inizializzazione, il valore dell’inizializzatore è convertito al
tipo della variabile inizializzata
– int i = 3.14; // i inizializzato a 3 !

• Nelle espressioni aritmetiche, gli operando sono convertiti a
un tipo comune
• Nelle chiamate di funzione (che vedremo)
Altri esempi
bool b = 42; // b is true
int i = b; // i has value 1
i = 3.14; // i has value 3
double pi = i; // pi has value 3.0
// assuming 8-bit chars
unsigned char c = -1; // c has value 255
Conversione (cast) esplicita
• Quando una conversione utile non verrebbe
eseguita, la si può richiedere esplicitamente
• Es: divisione tra interi con risultato double
x = (double) n / m;

• ES: troncamento esplicito del risultato
cout << (int) x / y;

• C++11 introduce una sintassi più precisa
ATTENZIONE
• Il cast (implicito o esplicito che sia) non modifica il
tipo della variabile o delle variabili coinvolte, ma solo
il tipo associato al valore dell'espressione
• Le variabili in memoria continuano a essere del tipo
dichiarato staticamente nella parte dichiarativa del
programma
• Il cambio del tipo della variabile può portare al
cambio del valore dell’espressione dove la variabile è
usata
Le espressioni
•

Espressione: applicazione di operatori a
operandi
– Ha un valore e un tipo
– Condizione: espressione con tipo booleano

•

Cosa bisogna sapere sulle espressioni
1. Ordine di valutazione
2. Proprietà degli operandi (precedenza,
associatività)
3. Tipo degli operatori e del risultato, conversioni
Espressioni base
Le espressioni base si compongono di:
• Variabili
– Il tipo è noto in base alla dichiarazione, e NON cambia

• Valori (detti anche costanti o literal)
– Il tipo è deducibile da come sono “scritte”
•
•
•
•
•
•
•

3 : int (il più piccolo tra int, long, long long in cui il valore ci sta)
03 : int in notazione ottale
0x3 : int in notazione esadecimale
3.0 : float
3.0L : long
'3' : char
"3" : stringa (sequenza di caratteri di lunghezza variabile)
Constanti di tipo stringa
"Hello World!" // string literal
•Ha un tipo composto che vedremo in seguito
– Array di const char

•Il compilatore appende al valore un carattere
speciale "terminatore" ('0')
•La dimensione reale del valore è 1 + la dimensione
apparente (c'è anche il carattere "terminatore")
•Attenzione: "a" ha tipo e dimensione diversi da 'a'
Espressioni e operatori
• Operatori unari: sia applicano a un operando
– -2

• Operatori binari: sia applicano a due operandi
– a+b

• Il valore di un'espressione dipende da
precedenza e associatività degli operatori e può
dipendere dall'ordine di valutazione delle sottoespressioni
– Quanto vale : 5 + 10 * 20/2 ?

• Nella valutazione intervengono anche le
conversioni di tipo
Precedenza e associatività
•
•
•

•
•

Un'espressione con due o più operatori di dice composta
La sua valutazione richiede di assegnare gli operandi agli operatori
Si usano le regole di precedenza tra operatori diversi e le regole di
associatività per operatori con la stessa precedenza
– Precedenza: 3+4*5 vale 23, non 35
– Associatività: 20-15-3 vale 2, non 8 (associatività a sinistra)

Le parentesi possono cambiare le regole
– (3+4)*5 vale 35
– 20-(15-3) vale 8

Non solo operatori aritmetici:
–
–
–
–

cin >> v1 >> v2; // read into v1 and then into v2
L'operatore >> è associativo a sinistra
Il valore dell'espressione cin >> v1 è cin !
Equivale a (cin >> v1) >> v2;
Ordine di valutazione operandi
• In generale l'ordine di valutazione di sotto-espressioni con
la stessa priorità NON è definito
– int i = f1() + f2(); // f1, f2 sono funzioni

• Non si sa quale tra le funzioni f1() e f2() venga valutata per
prima
• Non si devono fare ipotesi indebite
– int i = 0;
– cout << i << " " << ++i << endl; // undefined
– ++i espressione che incrementa i e "torna" il nuovo valore

– Potrebbe stampare 1 1 oppure 0 1 o qualsiasi altra cosa

• Ci sono 4 operatori per cui invece è stabilito l'ordine di
valutazione delle sotto-espressioni

– AND logico (&&) OR logico (||) operatore condizionale (? :),
operatore virgola (,)
Operatori aritmetici
• Precedenza e associatività (tutti associativi a sinistra)
• PS: % indica il resto delle divisione tra due interi
– Se m e n sono interi e n è diverso da 0,
• (m/n)*n + m%n = m

– Non si applica a tipi in virgola mobile
precedenza
Operatori logici e relazionali
• Sono usati per costruire condizioni, cioè espressioni
con valore di tipo bool

precedenza
La regola del cortocircuito
• Gli operatori AND e OR in C e C++ hanno un ordine di
valutazione prefissato (a differenza delle pure
espressioni della logica)
– Prima l’operando di sinistra POI quello di destra

• Vale una regola detta del cortocircuito che evita di
valutare inutilmente l’operando di destra
– AND: se l’operando di sinistra vale false
– OR: se l’operando di sinistra vale true

• La regola del corto circuito ha applicazioni
interessanti, per esempio quando si ispezionano
sequenze di dati (lo vedremo in seguito)
L’operatore di assegnamento
• Anche = è un operatore!
• L’operando di sinistra deve essere una variabile (più
precisamente un lvalue), quello di destra un’espressione (più
precisamente un rvalue)
• Modifica lo stato del programma: assegna il valore
dell’operando di destra all’operando di sinistra
–
–
–
–

i=3 è un’espressione, il cui valore è l’operando di sinistra, cioè i!
i=3; è un’istruzione! Per via del ;
L’operatore = è associativo a destra
x=y=3 equivale a x=(y=3)

• Si assegna il valore 3 a y, il risultato dell’espressione è y
• Si effettua l’assegnamento x=y che copia il valore di y in x, anche x vale 3

• L’inizializzazione NON è un assegnamento (mai ribadito
abbastanza)
Esempi
int i = 0, j = 0, k = 0; // initializations, not
// assignment
1024 = k; // error: literals are rvalues
i + j = k; // error: arithmetic expressions are rvalues
k = 0; // result: type int, value 0
k = 3.14159; // result: type int, value 3
ATTENZIONE
• Possiamo usare assegnamenti come condizioni e viceversa?
• Si, perché = è un operatore, proprio come ==
• Di solito però… succede quando si sta commettendo un
errore...!
– x = y == 3;
– while ( 3 = x )

• Ma soprattutto...

// Assegna a x il valore 0 o 1 e non modifica
// Errore di sintassi (3 non è una variabile)

– while(x = 3) ... È SEMPRE VERO!!! (per ogni valore precedente di x)
– while (x = 0) ... È SEMPRE FALSO!!! (per ogni valore precedente di x)
– while (x = y) ... equivale a scrivere
• x = y;
• while ( y != 0 ) ...

• Ancora peggio...

– while (! (x = 0)) ... NON TERMINA MAI !!!!
I costruttori di tipi
• A partire dai tipi predefiniti si possono creare
nuovi tipi, che aggiungono proprietà speciali ai
tipi predefiniti
–
–
–
–

const
reference
pointer
array

• A questi si aggiungono costruttori di tipi definiti
interamente dall'utente
– class
– struct (eredità del C, poco usato in C++)
Il qualificatore const
• Talora serve definire una variabile che non cambi valore
• Per farlo si premette const alla dichiarazione

– const int modelloauto = 159; // tipo const int
– const float pigreco = 3.14159265; // tipo const float

• Un tipo const è diverso dal corrispondente tipo base
• Una variabile const
– Si dichiara e inizializza obbligatoriamente
– Non ammette assegnamento
•
•
•
•
•

int i = 42;
const int ci = i; // ok: the value in i is copied into ci
ci = 43; // error, no assignment
const int k; // error: k is uninitialized const
int j = ci; // ok: the value in ci is copied into j
Visibilità delle variabili const
• const float pigreco = 3.14159265;

• Il compilatore sostituisce pigreco con il valore
associato
• Il compilatore deve conoscere il valore
dell'inizializzatore
• Se il programma è diviso in più file, la variabile
const viene (ri)definita in ciascun file
• Alternativamente, la variabile const può essere
definita in un solo file e dichiarata come esterna
nei file che ne fanno uso
extern const
• Per definire una variabile const una sola volta, si usa la keyword
extern sia nella definizione che nelle dichiarazioni
// file_1.cc definisce e inizializza una variabile const
extern const float pigreco = 3.14159265;
// file_1.h
extern const float pigreco; // stessa const di file_1.cc

• file_1.cc definisce e inizializza pigreco. Siccome la dichiarazione
comprende un inizializzatore è una definizione. Però, siccome
pigreco è const, si specifica extern per farla usare in altri file.
• La dichiarazione in file_1.h è anch'essa extern. Significa che pigreco
non è locale a tale file ma definita altrove
• Altri file possono includere il file file_1.h e importare la definizione
di pigreco
Definizione di macro: #define
• Esiste anche un altro modo di definire un valore una volta per tutte
– la direttiva #define

• #define PIGRECO 3.141592

– #define è una direttiva al preprocessore (come #include)
– Non è terminata dal punto e virgola
• una direttiva al precompilatore non è un’istruzione C++

– Non causa allocazione di memoria

• PIGRECO è una "costante simbolica"

– Il simbolo PIGRECO viene sostituito nel codice con il valore 3.14 …
prima che il programma sia compilato
– Si dice che PIGRECO è una macro-definizione (o semplicemente una
MACRO)
– Per convenzione, le costanti definite tramite macro sono interamente
maiuscole (es: TIPICA_COSTANTE)
Definizione di macro: #define
• #define MIGLIO 1609.34
• #define YARDA
0.9144
• Si possono costruire MACRO a partire da altre
MACRO, e una macro può anche usare uno o
più parametri:
– #define AREACERCHIO(X) (PIGRECO∗(X)∗(X))
– area = AREACERCHIO(4);
– Diventa ⇒ area = (3.141592∗(4)∗(4));
– ma è un valore fisso !!
Altre direttive al precompilatore
• Abbiamo già visto:
#include <nome_libreria>
– Serve a richiamare librerie
– comanda al preprocessore di leggere anche da un altro file
sorgente

• Altra direttiva usata frequentemente:
#undef VERO
– Serve ad annullare la definizione di una MACRO
– Da quel punto in poi la costante VERO non è più definita
Esempio di programma multifile
/* File contenente funzioni di utilità sui cerchi
* dichiarazione e definizione di una costante
* riusabile : pigreco.cpp */
extern const float pigreco = 3.14159265;
float area(float r){
return r*r*pigreco;
}
float perimeter(float r){
return 2*r*pigreco;
}
File di intestazione della libreria
/*
*
*
*
*

File contenente solo le dichiarazioni delle
funzioni di utilità sui cerchi
e della costante riusabile: pigreco.h
Usato dal compilatore per controllare la
correttezza del programma */

extern const float pigreco;
float area(float r);
float perimeter(float r);
Programma principale
#include <iostream>
#include "pigreco.h"
using namespace std;
int main() {
float radius;
cout << "Insert the value of the radius: " << endl;
cin >> radius;
cout << "Value of pigreco: " << pigreco << endl;
cout << "Perimeter of circle: " << perimeter(radius) <<
cout << "Area of the circle: " << area(radius) << endl;
return 0;
}

endl;
I tipi definiti dall'utente
• La ragione principale del successo di C++ è che
consente di estendere il sistema dei tipi in
modo assai potente
• La novità introdotta dal C++ è che i tipi definiti
dall'utente si possono usare (quasi) come
quelli predefiniti
Requisiti
• Si vuole costruire un programma che gestisca le
vendite di libri
• Ogni libro è caratterizzato da un codice ISBN
• Il programma deve gestire per ogni libro il numero
totale di copie vendute, il ricavo totale e medio
• L'utente inserisce sequenzialmente i dati di vendita per
i diversi libri, il programma aggrega i dati per ciascun
codice ISBN e stampa il dato aggregato
• Deve quindi essere possibile:
– Inserire e stampare i dati di un libro
– Sommare più dati di vendita relativi allo stesso libro
– Stampare i dati di vendita aggregati relativi a un libro
Progettazione
• Inizializza il totale vendite a 0
• Leggi dati 1° transazione e aggiorna il totale
• Finché ci sono transazioni

– Leggi un'altra transazione;
– Se la transazione letta è dello stesso libro di prima
• sommala al totale corrente;

– Altrimenti

• stampa il totale corrente; // è cambiato il libro
• inizializza il totale corrente del nuovo libro coi dati della
transazione letta;

•

Stampa il totale di vendita dell'ultimo libro (perché
serve??)
Suddivisione del programma
• Un file di libreria (Sales_item.h) conterrà la
definizione del tipo che rappresenta il dato di
vendita: Sales_item
• Sales_item è un tipo classe, cioè un tipo
definito dall'utente che comprende dati e
operazioni relativi al dato di vendita
• Il programma principale (Booksales.cpp)
importa e usa Sales_item come se fosse un
tipo predefinito
– Sales_item item; // dichiara una var. di tipo Sales_item !
Un primo esempio di main()
#include <iostream>
#include "Sales_item.h"
int main()
{
Sales_item book;
// read ISBN, number of copies sold, and sales price
std::cin >> book;
// write ISBN, # of copies sold, total revenue, and average price
std::cout << book << std::endl;
return 0;
}

•book è trattata come una variabile di un tipo predefinito
•Si applicano gli stessi operatori di I/O che a una variabile di tipo int
•Gli operatori sono definiti nel tipo classe Sales_item
L'esempio completo
int main()
{
Sales_item total; // variable to hold data for the next transaction
// read the first transaction and ensure that there are data to process
if (cin >> total) {
Sales_item trans; // variable to hold the running sum
// read and process the remaining transactions
while (cin >> trans) {
// if we're still processing the same book
if (total.isbn() == trans.isbn())
total += trans; // update the running total
else {
// print results for the previous book
cout << total << endl;
total = trans; // total now refers to the next book
}
}
cout << total << endl; // print the last transaction
} else {
// no input! warn the user
cerr << "No data?!" << endl;
return -1; // indicate failure
}
return 0;
}

if(cin >> x)
while(cin >> x)
La condizione è
soddisfatta se
l'acquisizione dell'input
non ha dato errori
Per terminare, basta
premere CTRL-Z
(carattere end of file)

More Related Content

What's hot

13 Puntatori E Memoria Dinamica
13   Puntatori E Memoria Dinamica13   Puntatori E Memoria Dinamica
13 Puntatori E Memoria Dinamicaguest60e9511
 
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...UltraUploader
 
Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)STELITANO
 
11 - Programmazione: Tipi di dato strutturati pt. 2
11 - Programmazione: Tipi di dato strutturati pt. 211 - Programmazione: Tipi di dato strutturati pt. 2
11 - Programmazione: Tipi di dato strutturati pt. 2Majong DevJfu
 
2011.02.19 Introducing F#
2011.02.19 Introducing F#2011.02.19 Introducing F#
2011.02.19 Introducing F#Marco Parenzan
 
Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)STELITANO
 
Gestione della memoria in C++
Gestione della memoria in C++Gestione della memoria in C++
Gestione della memoria in C++Ilio Catallo
 
10 - Programmazione: Tipi di dato strutturati
10 - Programmazione: Tipi di dato strutturati10 - Programmazione: Tipi di dato strutturati
10 - Programmazione: Tipi di dato strutturatiMajong DevJfu
 
C# e la Framework Class Library
C# e la Framework Class LibraryC# e la Framework Class Library
C# e la Framework Class LibraryManuel Scapolan
 
Dai delegati a LINQ con C#
Dai delegati a LINQ con C#Dai delegati a LINQ con C#
Dai delegati a LINQ con C#Manuel Scapolan
 
05 - Programmazione: Funzioni
05 - Programmazione: Funzioni05 - Programmazione: Funzioni
05 - Programmazione: FunzioniMajong DevJfu
 

What's hot (20)

13 Puntatori E Memoria Dinamica
13   Puntatori E Memoria Dinamica13   Puntatori E Memoria Dinamica
13 Puntatori E Memoria Dinamica
 
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
 
Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)
 
11 - Programmazione: Tipi di dato strutturati pt. 2
11 - Programmazione: Tipi di dato strutturati pt. 211 - Programmazione: Tipi di dato strutturati pt. 2
11 - Programmazione: Tipi di dato strutturati pt. 2
 
2011.02.19 Introducing F#
2011.02.19 Introducing F#2011.02.19 Introducing F#
2011.02.19 Introducing F#
 
2006 Py03 intermedio
2006 Py03 intermedio2006 Py03 intermedio
2006 Py03 intermedio
 
Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)
 
Gestione della memoria in C++
Gestione della memoria in C++Gestione della memoria in C++
Gestione della memoria in C++
 
Lezione 3
Lezione 3Lezione 3
Lezione 3
 
Corso c++
Corso c++Corso c++
Corso c++
 
10 - Programmazione: Tipi di dato strutturati
10 - Programmazione: Tipi di dato strutturati10 - Programmazione: Tipi di dato strutturati
10 - Programmazione: Tipi di dato strutturati
 
C# e la Framework Class Library
C# e la Framework Class LibraryC# e la Framework Class Library
C# e la Framework Class Library
 
2006 Py02 base
2006 Py02 base2006 Py02 base
2006 Py02 base
 
Dai delegati a LINQ con C#
Dai delegati a LINQ con C#Dai delegati a LINQ con C#
Dai delegati a LINQ con C#
 
2008 python
2008 python2008 python
2008 python
 
Lezione 1: I/O in Java
Lezione 1: I/O in JavaLezione 1: I/O in Java
Lezione 1: I/O in Java
 
Pillole di C++
Pillole di C++Pillole di C++
Pillole di C++
 
Inferno Limbo Italian
Inferno Limbo ItalianInferno Limbo Italian
Inferno Limbo Italian
 
Array in C++
Array in C++Array in C++
Array in C++
 
05 - Programmazione: Funzioni
05 - Programmazione: Funzioni05 - Programmazione: Funzioni
05 - Programmazione: Funzioni
 

Similar to 05 2 integrali-conversioni-costanti-preproc-inclusione

Lezione 20 (2 maggio 2012) seconda parte
Lezione 20 (2 maggio 2012) seconda parteLezione 20 (2 maggio 2012) seconda parte
Lezione 20 (2 maggio 2012) seconda parteSTELITANO
 
Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)STELITANO
 
Lezione 10 (21 marzo 2012)
Lezione 10 (21 marzo 2012)Lezione 10 (21 marzo 2012)
Lezione 10 (21 marzo 2012)STELITANO
 
Le Espressioni Regolari e gli Automi
Le Espressioni Regolari e gli AutomiLe Espressioni Regolari e gli Automi
Le Espressioni Regolari e gli AutomiGiuseppe Luciano
 
Lezione 10 (21 marzo 2012)
Lezione 10 (21 marzo 2012)Lezione 10 (21 marzo 2012)
Lezione 10 (21 marzo 2012)STELITANO
 
Lezione 20 (2 maggio 2012) prima parte
Lezione 20 (2 maggio 2012) prima parteLezione 20 (2 maggio 2012) prima parte
Lezione 20 (2 maggio 2012) prima parteSTELITANO
 

Similar to 05 2 integrali-conversioni-costanti-preproc-inclusione (13)

Lezione 20 (2 maggio 2012) seconda parte
Lezione 20 (2 maggio 2012) seconda parteLezione 20 (2 maggio 2012) seconda parte
Lezione 20 (2 maggio 2012) seconda parte
 
Variabili
VariabiliVariabili
Variabili
 
Corso java base
Corso java baseCorso java base
Corso java base
 
Java 2 IO
Java 2 IOJava 2 IO
Java 2 IO
 
Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)
 
Java Lezione 1
Java Lezione 1Java Lezione 1
Java Lezione 1
 
Arduino base
Arduino baseArduino base
Arduino base
 
Informatica 2.pptx
Informatica 2.pptxInformatica 2.pptx
Informatica 2.pptx
 
Lezione 10 (21 marzo 2012)
Lezione 10 (21 marzo 2012)Lezione 10 (21 marzo 2012)
Lezione 10 (21 marzo 2012)
 
Modulo 1 - Lezione 1
Modulo 1 - Lezione 1Modulo 1 - Lezione 1
Modulo 1 - Lezione 1
 
Le Espressioni Regolari e gli Automi
Le Espressioni Regolari e gli AutomiLe Espressioni Regolari e gli Automi
Le Espressioni Regolari e gli Automi
 
Lezione 10 (21 marzo 2012)
Lezione 10 (21 marzo 2012)Lezione 10 (21 marzo 2012)
Lezione 10 (21 marzo 2012)
 
Lezione 20 (2 maggio 2012) prima parte
Lezione 20 (2 maggio 2012) prima parteLezione 20 (2 maggio 2012) prima parte
Lezione 20 (2 maggio 2012) prima parte
 

More from Piero Fraternali

Multimedia on the mountaintop: presentation at ACM MM2016
Multimedia on the mountaintop: presentation at ACM MM2016Multimedia on the mountaintop: presentation at ACM MM2016
Multimedia on the mountaintop: presentation at ACM MM2016Piero Fraternali
 
presentation at European Utility Week, Vienna, Nov. 2015
presentation at European Utility Week, Vienna, Nov. 2015presentation at European Utility Week, Vienna, Nov. 2015
presentation at European Utility Week, Vienna, Nov. 2015Piero Fraternali
 
Fraternali concertation june25bruxelles
Fraternali concertation june25bruxellesFraternali concertation june25bruxelles
Fraternali concertation june25bruxellesPiero Fraternali
 
Crowsourcing (anche) per le aziende del settore tessile e della moda
Crowsourcing (anche) per le aziende del settore tessile e della modaCrowsourcing (anche) per le aziende del settore tessile e della moda
Crowsourcing (anche) per le aziende del settore tessile e della modaPiero Fraternali
 
05 3 istruzioni-selezione-iterazione-condizioni
05 3 istruzioni-selezione-iterazione-condizioni05 3 istruzioni-selezione-iterazione-condizioni
05 3 istruzioni-selezione-iterazione-condizioniPiero Fraternali
 
Human computation and participatory systems
Human computation and participatory systems Human computation and participatory systems
Human computation and participatory systems Piero Fraternali
 
Better society: Meet us at #ICT2013eu for #trustedsocialmedia http://bit.ly/1...
Better society: Meet us at #ICT2013eu for #trustedsocialmedia http://bit.ly/1...Better society: Meet us at #ICT2013eu for #trustedsocialmedia http://bit.ly/1...
Better society: Meet us at #ICT2013eu for #trustedsocialmedia http://bit.ly/1...Piero Fraternali
 
Human and social computation
Human and social computation Human and social computation
Human and social computation Piero Fraternali
 
Web technologies: Model Driven Engineering
Web technologies: Model Driven EngineeringWeb technologies: Model Driven Engineering
Web technologies: Model Driven EngineeringPiero Fraternali
 
Web technologies: recap on TCP-IP
Web technologies: recap on TCP-IPWeb technologies: recap on TCP-IP
Web technologies: recap on TCP-IPPiero Fraternali
 
Web technologies course, an introduction
Web technologies course, an introductionWeb technologies course, an introduction
Web technologies course, an introductionPiero Fraternali
 

More from Piero Fraternali (20)

Multimedia on the mountaintop: presentation at ACM MM2016
Multimedia on the mountaintop: presentation at ACM MM2016Multimedia on the mountaintop: presentation at ACM MM2016
Multimedia on the mountaintop: presentation at ACM MM2016
 
presentation at European Utility Week, Vienna, Nov. 2015
presentation at European Utility Week, Vienna, Nov. 2015presentation at European Utility Week, Vienna, Nov. 2015
presentation at European Utility Week, Vienna, Nov. 2015
 
Fraternali concertation june25bruxelles
Fraternali concertation june25bruxellesFraternali concertation june25bruxelles
Fraternali concertation june25bruxelles
 
Crowsourcing (anche) per le aziende del settore tessile e della moda
Crowsourcing (anche) per le aziende del settore tessile e della modaCrowsourcing (anche) per le aziende del settore tessile e della moda
Crowsourcing (anche) per le aziende del settore tessile e della moda
 
07 2 ricorsione
07 2 ricorsione07 2 ricorsione
07 2 ricorsione
 
07 1 funzioni
07 1 funzioni07 1 funzioni
07 1 funzioni
 
06 2 vector_matrici
06 2 vector_matrici06 2 vector_matrici
06 2 vector_matrici
 
05 3 istruzioni-selezione-iterazione-condizioni
05 3 istruzioni-selezione-iterazione-condizioni05 3 istruzioni-selezione-iterazione-condizioni
05 3 istruzioni-selezione-iterazione-condizioni
 
03 2 arit_bin
03 2 arit_bin03 2 arit_bin
03 2 arit_bin
 
03 1 alg_bool
03 1 alg_bool03 1 alg_bool
03 1 alg_bool
 
02 algo programmi
02 algo programmi02 algo programmi
02 algo programmi
 
Human computation and participatory systems
Human computation and participatory systems Human computation and participatory systems
Human computation and participatory systems
 
Better society: Meet us at #ICT2013eu for #trustedsocialmedia http://bit.ly/1...
Better society: Meet us at #ICT2013eu for #trustedsocialmedia http://bit.ly/1...Better society: Meet us at #ICT2013eu for #trustedsocialmedia http://bit.ly/1...
Better society: Meet us at #ICT2013eu for #trustedsocialmedia http://bit.ly/1...
 
So human presentation
So human presentationSo human presentation
So human presentation
 
Human and social computation
Human and social computation Human and social computation
Human and social computation
 
Web technologies: Model Driven Engineering
Web technologies: Model Driven EngineeringWeb technologies: Model Driven Engineering
Web technologies: Model Driven Engineering
 
Common Gateway Interface
Common Gateway InterfaceCommon Gateway Interface
Common Gateway Interface
 
Web technologies: HTTP
Web technologies: HTTPWeb technologies: HTTP
Web technologies: HTTP
 
Web technologies: recap on TCP-IP
Web technologies: recap on TCP-IPWeb technologies: recap on TCP-IP
Web technologies: recap on TCP-IP
 
Web technologies course, an introduction
Web technologies course, an introductionWeb technologies course, an introduction
Web technologies course, an introduction
 

05 2 integrali-conversioni-costanti-preproc-inclusione

  • 1. Introduzione al C++ Tipi integrali, conversioni di tipo, costanti ed espressioni costanti, direttive al preprocessore, inclusione condizionale
  • 2. Il concetto di tipo • Determina i valori che può assumere una variabile e le operazioni ammissibili su di essa • Determina la memoria minima necessaria per memorizzare una variabile • int: di solito una parola; float: di solito due parole • Permette al compilatore di rilevare errori nell'uso delle variabili – un linguaggio è fortemente tipizzato se garantisce: • correttezza delle istruzioni rispetto al tipo degli operandi, verificabile dal compilatore • che non sorgano errori di tipo in esecuzione • Il C++ persegue la tipizzazione forte – però è al tempo stesso molto permissivo, poiché ammette molte conversioni automatiche tra tipi diversi 2
  • 3. Il sistema dei tipi del C++ • Uno degli obiettivi principali del C++ è permettere al programmatore di creare tipi personalizzati e usarli come se fossero offerti dal linguaggio • Il sistema dei tipi del C++ comprende – Tipi predefiniti (predefined) – Tipi composti (composite) – Tipi definiti dall’utente (user defined) – Tipi classe (class types)
  • 4. Cosa c’è da sapere di ogni tipo • Che valori ammette • Come sono rappresentati i valori nel calcolatore – Sarebbe bello ignorarlo, ma talvolta non si può • Come rappresentare valori (costanti) di quel tipo nel programma (anche detti "literal") • Come dichiarare e inizializzare variabili di quel tipo • Quali operazioni sono ammesse sulle variabili • Quali tipi sono “affini” – Sono definite conversioni automatiche tra tipi affini
  • 5. Inizializzazione delle variabili • Le variabili si dichiarano e inizializzano – La dichiarazione definisce il tipo – L’inizializzazione definisce il valore iniziale della variabile neonata – L’inizializzazione NON è l’assegnamento • quest’ultimo definisce il valore corrente della variabile • Alcune cose che si possono fare durante l’inizializzazione sono vietate nell’assegnamento int i = 0; tipo identificatore inizializzatore
  • 6. Inizializzazione di default (tipi predefiniti) • Una variabile dei tipi predefiniti priva di inizializzatore viene inizializzata per default • Il valore di default dipende dal tipo della variabile e dalla posizione della dichiarazione – Variabili dei tipi predefiniti definite al di fuori di una funzione ricevono per default il valore 0 – Variabili dei tipi predefiniti definite all'interno di una funzione sono uninitialized, cioè il valore NON è definito • NB: per le variabili di tipo classe, il valore di inizializzazione per default può essere specificato dal programmatore
  • 7. Check this out! • http://stackoverflow.com/questions/18870547/why-there-isno-difference-between-initialization-and-assignment-for-thebuild-im/articles/article.aspx?p=376876
  • 8. I tipi predefiniti del C++ • I tipi aritmetici: integral e floating point
  • 9. Il tipo bool • Sta per Boolean (booleano) • Rappresentare il tipo delle espressioni che il programma usa per prendere decisioni (se…, fintantoché…) • Ammette solo due valori: true e false – false è rappresentato tramite il valore numerico 0 – true è rappresentato da qualunque valore numerico diverso da 0 bool bool bool bool b b b b = = = = true; // b vale true 23; // b vale true false; // b vale false 0; // b vale false • In altre parole bool è un tipo (affine a) intero!
  • 10. Il tipo char • Ammette come valore un singolo carattere • Utilizza il minimo numero di bit necessario a rappresentare l’insieme dei caratteri standard del calcolatore un byte (di solito 8 bit per rappresentare i caratteri ASCII) • I caratteri sono rappresentati internamente da numeri interi e quindi tra essi è definito un ordinamento – Esempio: il carattere '1' è rappresentato dall’intero 49, il carattere 'A' dall’intero 65, … • quindi, nell’ordinamento, risulta '1' < 'A' – Per le lettere è scelta una codifica tale per cui l’ordinamento dei codici coincide con l’usuale ordinamento alfabetico: 'A'<'B' ecc. • Lettere alfabeticamente adiacenti hanno codifiche adiacenti – Negli insiemi più usati le maiuscole latine sono codificate “prima” delle minuscole • Quindi ad esempio 'A'<'a' ma anche 'Z'<'a' 10
  • 11. Il concetto di insieme di caratteri • A differenza dei numeri interi, i caratteri non hanno una rappresentazione “naturale” nel calcolatore • La rappresentazione è convenzionale e si ottiene “numerando” i simboli dell’insieme dei caratteri che si vuole rappresentare • Esistono molti insiemi di caratteri, che coprono un numero differente di simboli di lingue diverse • Gli insiemi di caratteri e le codifiche più usati sono – ASCII – ISO/IEC 8859 – UNICODE con UTF-8 e UTF-16
  • 12. Why character encoding matters http://en.wikipedia.org/wiki/Mojibake
  • 13. Insieme di caratteri ASCII • Lo American Standard Code for Information Interchange (ASCII ) è una codifica dei caratteri basata sull’alfabeto inglese che copre 27= 128 caratteri • Usa 7-bit • 95 caratteri stampabili: i numeri 0-9, le lettere a-z e AZ, simboli di punteggiatura e lo spazio bianco • Vari caratteri non stampabili, tra cui alcuni codici di controllo derivanti dalle Teletype machines
  • 15. ISO 8859 (ISO LATIN) • • • • I 95 caratteri ASCII stampabili sono sufficienti per lo scambio di informazioni in lingua inglese Molte altre lingue che usano l'alfabeto latino hanno bisogno di simboli addizionali, come la ß (tedesco), la ñ (spagnolo), la å (svedese e altre lingue scandinave) o le lettere accentate italiane (à, è, é, ì, ò, ù) L'ISO 8859 utilizza l'ottavo bit del byte, che permette la codifica di altri 128 caratteri ISO 8859 è organizzato in diverse parti: es: ISO 8859-1, Latin-1 Western European http://en.wikipedia.org/wiki/ISO/IEC_8859
  • 16. UNICODE, UTF-8, UTF-16 • • • Unicode è un insieme di caratteri e una sistema di codifica che comprende oltre 110.000 simboli Unicode si sovrappone a ISO/IEC 8859-1, ma codifica inoltre i caratteri di quasi tutte le lingue vive e in alcune lingue morte, nonché simboli matematici e chimici, cartografici, l'alfabeto Braille, ideogrammi ecc. I caratteri Unicode sono rappresentati con le codifiche UTF-8 e UTF-16 • • UTF-8 (8-bit Unicode Transformation Format) è una codifica dei caratteri Unicode – usa un byte per i caratteri dell’insieme ASCII, che hanno lo stesso codice sia UTF-8 sia in ASCII, e fino a 4 bytes per gli altri caratteri (codifica a lunghezza variabile) UTF-16 (16-bit Unicode Transformation Format) è una codifica dei caratteri Unicode – può rappresentare fino a 1,112,064 entità (code points) tra cui i caratteri UNICODE da 0 a 0x10FFFF – La codifica è a lunghezza variabile, con uno o due unità da 16 bit
  • 17. I tipi int • Approssima il dominio degli interi • Normalmente utilizza 1 parola di memoria • Esistono anche le varianti – short int, long int e long long int – tipico: long 32 bit, long long 64 bit, short 16 bit, e int 16 o 32 (per cui spesso int è grande quanto long int) • Lo standard del C++ richiede che – spazio per short <= spazio per int <= spazio per long <= spazio per long long
  • 18. La gestione del segno • TUTTI i tipi integral, tranne bool, ammettono la versione “senza segno” (unsigned) • Il tipo normale permette di rappresentare numeri interi positivi e negativi • Il tipo unsigned permette di rappresentare solo numeri interi positivi, ma utilizza un bit in più (e quindi può rappresentare di più valori) – unsigned int: un valore intero positivo di almeno 16 bit, compreso tra 0 e 216-1 – Il prefisso signed si può omettere – unsigned èquivale a unsigned int – unsigned char  da 0 a 255
  • 19. Rapporto tra tipi signed e unsigned • Tipi signed e unsigned non andrebbero mescolati • Se si assegna un valore fuori intervallo a una variabile di tipo unsigned, il risultato è definito come: – Il resto della divisione del valore per il massimo intero che il tipo unsigned può rappresentare • Per esempio, un tipo unsigned char da 8-bit rappresenta valori da 0 a 255. • L’assegnamento di un valore fuori intervallo dà come esito il resto di tale valore diviso per 256 – Assegnare –1 a un unsigned char da 8 bit produce il valore 255!
  • 20. Check this out int main() { // Assegna a unsigned valore negativo unsigned char c; // va da 0 a 255; cout << "Inserire un numero negativo: " << endl; int i; cin >> i; cout << "Valore inserito (intero originale): " << i << endl; c=i; // assegno numero negativo a variabile char cout << "Valore inserito (char): " << c << endl; i=c; // recupero il valore intero di c cout << "Valore inserito (intero dopo la conversione a char): " << i << endl; return 0; } • Il compilatore non può rilevare l’errore • Non sa predire che valore inserisce l’utente • NB:
  • 21. Rapporto tra char e int • In molti linguaggi di programmazione, char e int sono tipi non solo diversi, ma incompatibili • C e C++ considerano i caratteri come “una particolare interpretazione” dei numeri interi • La convertibilità tra char e int può portare a programmi difficili da comprendere • Usare char solo quando serve davvero una variabile che contenga un carattere, per esempio per – Cercare/contare/sostituire tutte le occorrenze di un carattere in un testo
  • 22. Da char a int • Determinare il codice di una lettera minuscola • Cosa serve – Una variabile char – Una variabile int • Algoritmo 1. Leggi il prossimo carattere 2. Se è una lettera maiuscola 1. 2. 3. Convertilo in un intero Stampa il risultato della conversione Torna al punto uno 3. Termina
  • 23. Da char a int int main() { // Legge un carattere e stampa il codice ASCII char c; // se è una minuscola; altrimenti termina int i; cout << "Scrivi un car. minuscolo (maiusc. x finire)" << endl; cin >> c; while (c >= 'a' && c <= 'z') { // minuscolo? i = c; // assegna il valore del carattere a un intero cout << "Valore ASCII per " << c << " è" << i << endl; cout << "Scrivi car. minuscolo (maiusc. x finire)" << endl; cin >> c; } return 0; // termina } NB: notare la ripetizione delle istruzioni che richiedono l'input
  • 24. Iterazione e condizione • while (c >= 'a' && c <= 'z') {.. Corpo del ciclo..} • Se la condizione è vera • esegue le istruzioni all’interno del corpo • Quando la condizione è falsa • termina il ciclo (esce dal ciclo) • (c >= 'a' && c <= 'z') • • • • Esprime la condizione di permanenza nel ciclo E’ un’espressione con valore di tipo bool, cioè vero o falso && Operatore logico AND ‘a’ è un valore costante (literal) di tipo carattere
  • 25. Da int a char int main() { // Stampa il codice carattere char c; // corrispondente ai 128 codici ASCII for (int i=0; i<128; ++i) { c = i; // assegna il valore intero al carattere cout << "Il carattere corrispondente a " << i << " è: " << c << endl; } return 0; }
  • 26. Iterazione a conteggio • for (int i=0; i<128; ++i) • Quando una iterazione deve essere svolta un numero preciso di volte si può usare un “ciclo for” • Il ciclo incrementa una variabile apposita (contatore) per tener traccia del numero di interazioni – int i=0; dichiarazione del contatore – i<128; condizione di permanenza – ++i avanzamento del contatore
  • 27. Ciclo while e ciclo for char c; for (int i=0; i<128; i++) { c = i; cout << “Il carattere corrispondente a " << i << " è: " << c << endl; } int i = 0; char c; while (i<128) { c = i; cout << “Il carattere corrispondente a " << i << " è: " << c << endl; i++; }
  • 28. I tipi float e double • Approssimano i numeri razionali • I valori si possono rappresentare con due notazioni – 315.779 – 3.73E-5 • double di solito occupa più memoria di float – tipicamente 4 byte per float e 8 byte per double • (...esistono anche i long double, che devono occupare almeno tanto spazio quanto i double) • Lo standard prescrive la precisione minima, cioè il minimo numero di cifre significative 28
  • 29. Come rappresentare valori dei tipi predefiniti • Il valore 10 ha un tipo diverso da 10.0 • 10L è un valore di tipo long int
  • 30. Cautele • Attenzione ai confronti tra float float a, b; ... if (a == b) ... • non ha senso, a causa delle approssimazioni nella memorizzazione!! diff = A - B; if ((diff < EPSILON) && (-diff < EPSILON)); • EPSILON costante definita in std::numeric_limits
  • 31. Check this out • http://stackoverflow.com/questions/17333/m ost-effective-way-for-float-and-doublecomparison
  • 32. Quali tipi scegliere • Usare tipi unsigned quando si è certi che servono solo valori positivi • Usare int per valori aritmentici (short di solito non basta) • Se servono valori molto grandi usare long long • Non usare char e bool in espressioni aritmentiche – Se proprio proprio serve un intero piccolo usare signed char o unsigned char • Usare double per le operazioni in virgola mobile (di solito float ha precisione insufficiente e le operazioni sui double sono comunque veloci)
  • 33. Conversioni di tipo • Se un operando non è del tipo atteso e il compilatore non ha informazioni sul tipo desiderato interviene una conversione automatica di tipo – È detta anche cast implicito – Si opera la conversione anziché segnalare l'errore • A volte è accompagnata da un “avvertimento” (warning) • Esempio – int i; float f; – la valutazione dell’espressione i + f effettua prima la conversione di i in float e poi la somma
  • 34. La "scaletta" delle conversioni
  • 35. Conversioni di tipo: esempi int n, m; float x,y; n = 3.541 + 3; // il risultato è 6! x = n; x = n + n = x; n = n / n = n / x = n / x = n / n da “int” è promosso a “float” x; // n è promosso a “float” e poi sommato a x // x è troncato, ne sopravvive la parte intera m; // il risultato della divisione tra interi è intero x; /* n è convertito in “float”, poi si esegue la divisione, il risultato è troncato a int */ x; //come sopra ma il risultato resta float m; // attenzione: la divisione tra int tronca //
  • 36. Conversioni con il tipo bool • Il tipo bool ha valore true o false • I valori interi vengono convertiti a bool come segue – 0 viene convertito a false – ogni altro valore intero viene convertito a true • Vale anche la conversione inversa (promozione a int) bool b=false; int i; // inizializzazione i = b; // i vale 0 b=true; i = b; // i ora vale 1!
  • 37. Conversioni con tipi un/signed • Ecco perché è meglio non mescolare unsigned u = 10; int i = -42; cout << i + i << endl; // prints -84 cout << u + i << endl; // if 32-bit ints, prints 4294967264 • Il valore di i (-42) viene convertito a unsigned prima dell’addizione unsigned u1 = 42, u2 = 10; cout << u1 - u2 << endl; // ok: result is 32 cout << u2 - u1 << endl; // ok: but the result is… ?
  • 38. Quando avvengono le conversioni automatiche • Nelle espressioni, i valori di tipi aritmetici piccoli vengono solitamente promossi a int char c, int i; i=c+i; // da evitare • Nelle condizioni, tipi non bool sono convertiti a bool – while (33) equivale a while (true) ! • Nell’inizializzazione, il valore dell’inizializzatore è convertito al tipo della variabile inizializzata – int i = 3.14; // i inizializzato a 3 ! • Nelle espressioni aritmetiche, gli operando sono convertiti a un tipo comune • Nelle chiamate di funzione (che vedremo)
  • 39. Altri esempi bool b = 42; // b is true int i = b; // i has value 1 i = 3.14; // i has value 3 double pi = i; // pi has value 3.0 // assuming 8-bit chars unsigned char c = -1; // c has value 255
  • 40. Conversione (cast) esplicita • Quando una conversione utile non verrebbe eseguita, la si può richiedere esplicitamente • Es: divisione tra interi con risultato double x = (double) n / m; • ES: troncamento esplicito del risultato cout << (int) x / y; • C++11 introduce una sintassi più precisa
  • 41. ATTENZIONE • Il cast (implicito o esplicito che sia) non modifica il tipo della variabile o delle variabili coinvolte, ma solo il tipo associato al valore dell'espressione • Le variabili in memoria continuano a essere del tipo dichiarato staticamente nella parte dichiarativa del programma • Il cambio del tipo della variabile può portare al cambio del valore dell’espressione dove la variabile è usata
  • 42. Le espressioni • Espressione: applicazione di operatori a operandi – Ha un valore e un tipo – Condizione: espressione con tipo booleano • Cosa bisogna sapere sulle espressioni 1. Ordine di valutazione 2. Proprietà degli operandi (precedenza, associatività) 3. Tipo degli operatori e del risultato, conversioni
  • 43. Espressioni base Le espressioni base si compongono di: • Variabili – Il tipo è noto in base alla dichiarazione, e NON cambia • Valori (detti anche costanti o literal) – Il tipo è deducibile da come sono “scritte” • • • • • • • 3 : int (il più piccolo tra int, long, long long in cui il valore ci sta) 03 : int in notazione ottale 0x3 : int in notazione esadecimale 3.0 : float 3.0L : long '3' : char "3" : stringa (sequenza di caratteri di lunghezza variabile)
  • 44. Constanti di tipo stringa "Hello World!" // string literal •Ha un tipo composto che vedremo in seguito – Array di const char •Il compilatore appende al valore un carattere speciale "terminatore" ('0') •La dimensione reale del valore è 1 + la dimensione apparente (c'è anche il carattere "terminatore") •Attenzione: "a" ha tipo e dimensione diversi da 'a'
  • 45. Espressioni e operatori • Operatori unari: sia applicano a un operando – -2 • Operatori binari: sia applicano a due operandi – a+b • Il valore di un'espressione dipende da precedenza e associatività degli operatori e può dipendere dall'ordine di valutazione delle sottoespressioni – Quanto vale : 5 + 10 * 20/2 ? • Nella valutazione intervengono anche le conversioni di tipo
  • 46. Precedenza e associatività • • • • • Un'espressione con due o più operatori di dice composta La sua valutazione richiede di assegnare gli operandi agli operatori Si usano le regole di precedenza tra operatori diversi e le regole di associatività per operatori con la stessa precedenza – Precedenza: 3+4*5 vale 23, non 35 – Associatività: 20-15-3 vale 2, non 8 (associatività a sinistra) Le parentesi possono cambiare le regole – (3+4)*5 vale 35 – 20-(15-3) vale 8 Non solo operatori aritmetici: – – – – cin >> v1 >> v2; // read into v1 and then into v2 L'operatore >> è associativo a sinistra Il valore dell'espressione cin >> v1 è cin ! Equivale a (cin >> v1) >> v2;
  • 47. Ordine di valutazione operandi • In generale l'ordine di valutazione di sotto-espressioni con la stessa priorità NON è definito – int i = f1() + f2(); // f1, f2 sono funzioni • Non si sa quale tra le funzioni f1() e f2() venga valutata per prima • Non si devono fare ipotesi indebite – int i = 0; – cout << i << " " << ++i << endl; // undefined – ++i espressione che incrementa i e "torna" il nuovo valore – Potrebbe stampare 1 1 oppure 0 1 o qualsiasi altra cosa • Ci sono 4 operatori per cui invece è stabilito l'ordine di valutazione delle sotto-espressioni – AND logico (&&) OR logico (||) operatore condizionale (? :), operatore virgola (,)
  • 48. Operatori aritmetici • Precedenza e associatività (tutti associativi a sinistra) • PS: % indica il resto delle divisione tra due interi – Se m e n sono interi e n è diverso da 0, • (m/n)*n + m%n = m – Non si applica a tipi in virgola mobile precedenza
  • 49. Operatori logici e relazionali • Sono usati per costruire condizioni, cioè espressioni con valore di tipo bool precedenza
  • 50. La regola del cortocircuito • Gli operatori AND e OR in C e C++ hanno un ordine di valutazione prefissato (a differenza delle pure espressioni della logica) – Prima l’operando di sinistra POI quello di destra • Vale una regola detta del cortocircuito che evita di valutare inutilmente l’operando di destra – AND: se l’operando di sinistra vale false – OR: se l’operando di sinistra vale true • La regola del corto circuito ha applicazioni interessanti, per esempio quando si ispezionano sequenze di dati (lo vedremo in seguito)
  • 51. L’operatore di assegnamento • Anche = è un operatore! • L’operando di sinistra deve essere una variabile (più precisamente un lvalue), quello di destra un’espressione (più precisamente un rvalue) • Modifica lo stato del programma: assegna il valore dell’operando di destra all’operando di sinistra – – – – i=3 è un’espressione, il cui valore è l’operando di sinistra, cioè i! i=3; è un’istruzione! Per via del ; L’operatore = è associativo a destra x=y=3 equivale a x=(y=3) • Si assegna il valore 3 a y, il risultato dell’espressione è y • Si effettua l’assegnamento x=y che copia il valore di y in x, anche x vale 3 • L’inizializzazione NON è un assegnamento (mai ribadito abbastanza)
  • 52. Esempi int i = 0, j = 0, k = 0; // initializations, not // assignment 1024 = k; // error: literals are rvalues i + j = k; // error: arithmetic expressions are rvalues k = 0; // result: type int, value 0 k = 3.14159; // result: type int, value 3
  • 53. ATTENZIONE • Possiamo usare assegnamenti come condizioni e viceversa? • Si, perché = è un operatore, proprio come == • Di solito però… succede quando si sta commettendo un errore...! – x = y == 3; – while ( 3 = x ) • Ma soprattutto... // Assegna a x il valore 0 o 1 e non modifica // Errore di sintassi (3 non è una variabile) – while(x = 3) ... È SEMPRE VERO!!! (per ogni valore precedente di x) – while (x = 0) ... È SEMPRE FALSO!!! (per ogni valore precedente di x) – while (x = y) ... equivale a scrivere • x = y; • while ( y != 0 ) ... • Ancora peggio... – while (! (x = 0)) ... NON TERMINA MAI !!!!
  • 54. I costruttori di tipi • A partire dai tipi predefiniti si possono creare nuovi tipi, che aggiungono proprietà speciali ai tipi predefiniti – – – – const reference pointer array • A questi si aggiungono costruttori di tipi definiti interamente dall'utente – class – struct (eredità del C, poco usato in C++)
  • 55. Il qualificatore const • Talora serve definire una variabile che non cambi valore • Per farlo si premette const alla dichiarazione – const int modelloauto = 159; // tipo const int – const float pigreco = 3.14159265; // tipo const float • Un tipo const è diverso dal corrispondente tipo base • Una variabile const – Si dichiara e inizializza obbligatoriamente – Non ammette assegnamento • • • • • int i = 42; const int ci = i; // ok: the value in i is copied into ci ci = 43; // error, no assignment const int k; // error: k is uninitialized const int j = ci; // ok: the value in ci is copied into j
  • 56. Visibilità delle variabili const • const float pigreco = 3.14159265; • Il compilatore sostituisce pigreco con il valore associato • Il compilatore deve conoscere il valore dell'inizializzatore • Se il programma è diviso in più file, la variabile const viene (ri)definita in ciascun file • Alternativamente, la variabile const può essere definita in un solo file e dichiarata come esterna nei file che ne fanno uso
  • 57. extern const • Per definire una variabile const una sola volta, si usa la keyword extern sia nella definizione che nelle dichiarazioni // file_1.cc definisce e inizializza una variabile const extern const float pigreco = 3.14159265; // file_1.h extern const float pigreco; // stessa const di file_1.cc • file_1.cc definisce e inizializza pigreco. Siccome la dichiarazione comprende un inizializzatore è una definizione. Però, siccome pigreco è const, si specifica extern per farla usare in altri file. • La dichiarazione in file_1.h è anch'essa extern. Significa che pigreco non è locale a tale file ma definita altrove • Altri file possono includere il file file_1.h e importare la definizione di pigreco
  • 58. Definizione di macro: #define • Esiste anche un altro modo di definire un valore una volta per tutte – la direttiva #define • #define PIGRECO 3.141592 – #define è una direttiva al preprocessore (come #include) – Non è terminata dal punto e virgola • una direttiva al precompilatore non è un’istruzione C++ – Non causa allocazione di memoria • PIGRECO è una "costante simbolica" – Il simbolo PIGRECO viene sostituito nel codice con il valore 3.14 … prima che il programma sia compilato – Si dice che PIGRECO è una macro-definizione (o semplicemente una MACRO) – Per convenzione, le costanti definite tramite macro sono interamente maiuscole (es: TIPICA_COSTANTE)
  • 59. Definizione di macro: #define • #define MIGLIO 1609.34 • #define YARDA 0.9144 • Si possono costruire MACRO a partire da altre MACRO, e una macro può anche usare uno o più parametri: – #define AREACERCHIO(X) (PIGRECO∗(X)∗(X)) – area = AREACERCHIO(4); – Diventa ⇒ area = (3.141592∗(4)∗(4)); – ma è un valore fisso !!
  • 60. Altre direttive al precompilatore • Abbiamo già visto: #include <nome_libreria> – Serve a richiamare librerie – comanda al preprocessore di leggere anche da un altro file sorgente • Altra direttiva usata frequentemente: #undef VERO – Serve ad annullare la definizione di una MACRO – Da quel punto in poi la costante VERO non è più definita
  • 61. Esempio di programma multifile /* File contenente funzioni di utilità sui cerchi * dichiarazione e definizione di una costante * riusabile : pigreco.cpp */ extern const float pigreco = 3.14159265; float area(float r){ return r*r*pigreco; } float perimeter(float r){ return 2*r*pigreco; }
  • 62. File di intestazione della libreria /* * * * * File contenente solo le dichiarazioni delle funzioni di utilità sui cerchi e della costante riusabile: pigreco.h Usato dal compilatore per controllare la correttezza del programma */ extern const float pigreco; float area(float r); float perimeter(float r);
  • 63. Programma principale #include <iostream> #include "pigreco.h" using namespace std; int main() { float radius; cout << "Insert the value of the radius: " << endl; cin >> radius; cout << "Value of pigreco: " << pigreco << endl; cout << "Perimeter of circle: " << perimeter(radius) << cout << "Area of the circle: " << area(radius) << endl; return 0; } endl;
  • 64. I tipi definiti dall'utente • La ragione principale del successo di C++ è che consente di estendere il sistema dei tipi in modo assai potente • La novità introdotta dal C++ è che i tipi definiti dall'utente si possono usare (quasi) come quelli predefiniti
  • 65. Requisiti • Si vuole costruire un programma che gestisca le vendite di libri • Ogni libro è caratterizzato da un codice ISBN • Il programma deve gestire per ogni libro il numero totale di copie vendute, il ricavo totale e medio • L'utente inserisce sequenzialmente i dati di vendita per i diversi libri, il programma aggrega i dati per ciascun codice ISBN e stampa il dato aggregato • Deve quindi essere possibile: – Inserire e stampare i dati di un libro – Sommare più dati di vendita relativi allo stesso libro – Stampare i dati di vendita aggregati relativi a un libro
  • 66. Progettazione • Inizializza il totale vendite a 0 • Leggi dati 1° transazione e aggiorna il totale • Finché ci sono transazioni – Leggi un'altra transazione; – Se la transazione letta è dello stesso libro di prima • sommala al totale corrente; – Altrimenti • stampa il totale corrente; // è cambiato il libro • inizializza il totale corrente del nuovo libro coi dati della transazione letta; • Stampa il totale di vendita dell'ultimo libro (perché serve??)
  • 67. Suddivisione del programma • Un file di libreria (Sales_item.h) conterrà la definizione del tipo che rappresenta il dato di vendita: Sales_item • Sales_item è un tipo classe, cioè un tipo definito dall'utente che comprende dati e operazioni relativi al dato di vendita • Il programma principale (Booksales.cpp) importa e usa Sales_item come se fosse un tipo predefinito – Sales_item item; // dichiara una var. di tipo Sales_item !
  • 68. Un primo esempio di main() #include <iostream> #include "Sales_item.h" int main() { Sales_item book; // read ISBN, number of copies sold, and sales price std::cin >> book; // write ISBN, # of copies sold, total revenue, and average price std::cout << book << std::endl; return 0; } •book è trattata come una variabile di un tipo predefinito •Si applicano gli stessi operatori di I/O che a una variabile di tipo int •Gli operatori sono definiti nel tipo classe Sales_item
  • 69. L'esempio completo int main() { Sales_item total; // variable to hold data for the next transaction // read the first transaction and ensure that there are data to process if (cin >> total) { Sales_item trans; // variable to hold the running sum // read and process the remaining transactions while (cin >> trans) { // if we're still processing the same book if (total.isbn() == trans.isbn()) total += trans; // update the running total else { // print results for the previous book cout << total << endl; total = trans; // total now refers to the next book } } cout << total << endl; // print the last transaction } else { // no input! warn the user cerr << "No data?!" << endl; return -1; // indicate failure } return 0; } if(cin >> x) while(cin >> x) La condizione è soddisfatta se l'acquisizione dell'input non ha dato errori Per terminare, basta premere CTRL-Z (carattere end of file)