1
ALCUNE INFORMAZIONI PRELIMINARI
Docente: E. Burattini
e-mail: [email protected]
Libri di testo:
Deitel H.M., Deitel P.J. – C++ Fondamenti di programmazione, ed. Apogeo
Chianese A. , Picariello A. , Moscato V. - Alla scoperta dei fondamenti
dell’informatica. Un viaggio nel mondo dei BIT - ed. Liguori, 2008
Programma:
•Strutture e file binari
•Ricorsione
•Puntatori
•Liste legate
•Alberi
•Cenni di programmazione a oggetti
Il compilatore dev C++, utilizzato per gli esercizi può essere scaricato all’indirizzo
http://www.toggle.com/lv/group/view/kl39865/Dev-C%2B%2B.htm
2
SVOLGIMENTO DEL CORSO
LEZIONI
PROVA INTERCORSO
valida solo per chi sostiene l’esame nella sessione di giugno
PROVA SCRITTA
ESAME ORALE
I lucidi del corso si possono rinvenire sul sito:
http//:people.na.infn.it/~ernb/programmacioneBC/index.php
Oppure su
www.federica.unina.it
3
4
Questo corso fa seguito al corso di Programmazione I.
Si danno, quindi, per note tutte le conoscenze trasmesse in quel
corso in particolare:
Tipi di dati in C++
Espressioni numeriche e booleane
Function
Array
Algoritmi di ordinamento
In alcuni casi esse saranno esplicitamente richiamate
5
Si richiamano alcune nozioni fondamentali introdotte in
Programmazione I
Interfacciamento: fase durante la quale avviene il passaggio dei
parametri effettivi del processo chiamante ai parametri formali
della function.
Il passaggio dei parametri avviene attraverso due modalità:
Passaggio per valore: al parametro formale è assegnata una copia del
valore del parametro effettivo. La function può quindi anche
modificarne il valore senza che nessuna delle variabili del processo
chiamante ne risulti modificata.
6
Passaggio per riferimento ( per indirizzo): al parametro formale, che
deve essere un riferimento, è passato l’indirizzo della
corrispondente variabile del parametro effettivo. Il parametro
formale si comporta come un sinonimo o alias del corrispondente
parametro effettivo. Ogni modifica apportata al parametro formale
è in realtà una modifica apportata al corrispondente parametro
effettivo.
Al termine della function ed al ritorno nel processo chiamante solo le
variabili di quest’ultima corrispondenti ai parametri effettivi
passati per indirizzo risulteranno modificati.
Per questi motivi tutto ciò che serve ad una procedura per poter
effettuare i suoi calcoli, cioè i parametri di input, deve essere
passato per valore, mentre tutte le variabili dichiarate nel
processo chiamante che la procedura deve modificare o
inizializzare , ovverosia i parametri di input-output ed i
parametri di output devono essere passati per riferimento.
7
Regola
Scrivere una function che ritorna un valore solo se si tratta di una
funzione, cioè quando tutti suoi parametri devono essere passati
per valore.
In tutti gli altri casi scrivere una procedura.
L’uso del for è fortemente sconsigliato
8
TIPI STANDARD
Ricapitoliamo i tipi di dati introdotti in Programmazione I
int ------- numeri interi ----------------- 435
float --- numeri reali semplice precisione----- 3.1416
double --- numeri reali doppia precisione------- 7.1416934523
char ------- caratteri ----------------- a
boolean ----- valori vero o falso ------------ true
array ----- insieme di valori di un prefissato tipo ---string ----- insieme di caratteri ------enumerated ----- insieme finito di valori -----9
Le strutture
I dati che riguardano situazioni reali sono composti da elementi
formati da tipi distinti.
Ad esempio:
i dati relativi ad uno studente sono costituiti da nome e cognome
(stringhe), numero di matricola (numero), data di nascita (tre numeri
interi), reddito (numero reale);
i dati relativi ad un libro sono formati da titolo e autore (stringhe),
anno di edizione (intero), prezzo (reale) e così via.
Un array, pur essendo un dato complesso, è comunque formato da
elementi dello stesso tipo, quindi non adatto a descrivere situazioni
reali del tipo di quella sopra descritta relativa ad uno studente.10
Le strutture
Il tipo struct
Per superare tale ostacolo è stato introdotto un tipo di dato detto
strutturato denominato record o struttura e identificato dalla parola
riservata struct.
11
RECORD O STRUCT
Studente
Anagrafe
Nascita
Matricola
Reddito
Cognome Nome Giorno Mese Anno
Studente
Anagrafe
Nascita
Matricola Reddito
Cognome Nome Giorno Mese Anno
Rossi
Ugo
Bianchi Carlo
3
12
5
2
1972 8796
1971 8746
23000
15000
12
Studenti e libri dell’esempio precedente possono essere definiti come
dati strutturati.
La sintassi di una struttura è data dalla parola riservata struct seguita
da un identificatore, che rappresenta l’introduzione del nuovo tipo, e da
una coppia di parentesi graffe al cui interno è contenuta la lista dei suoi
componenti; l’ultima parentesi graffa termina con il simbolo “;” .
Esempio
struct Tpdata {
int giorno;
int mese;
int anno;
};
Il Tpdata è un tipo che contiene
i campi giorno, mese, anno;
esso rappresenta un nuovo tipo
definito dall’utente, per cui
sono lecite dichiarazioni come
Tpdata oggi, domani;
13
Le componenti della struttura, detti anche campi, possono essere tipi
elementari ( int, float, char, bool ), array o altre strutture.
Definiamo, per esempio, un tipo persona, Tpersona, contenente i dati
essenziali di una persona, cognome, nome, luogo e data di nascita:
struct TPersona {
char cognome[20];
char nome[20];
Tpdata nascita;
char luogo[20];
};
struct Tstudente {
Tpersona anagrafe;
int matricola;
int esami[4];
};
struct Tpdata {
int giorno;
int mese;
int anno;
};
struct Tlibro {
char titolo[40];
TPersona autore;
int annoedizione;
Tpdata dataAcq;
char editore[20];
float prezzo;
};
e le due strutture, Tstudente e Tlibro, che si avvalgono dei tipi
Tpersona e Tpdata. Si noti che il tipo studente ha, tra i suoi 14
campi, anche un array.
Osserviamo che, pur creando un nuovo tipo, la definizione della
struttura con la parola riservata struct, non crea spazio di per sé.
Lo spazio viene creato quando la variabile viene dichiarata.
Per poter assegnare dei valori ad una struct è necessario definire una
variabile di quel tipo. In questo caso diciamo che abbiamo creato una
istanza del tipo.
Il computer provvede a creare lo spazio necessario la cui grandezza in
byte possiamo conoscerla applicando la function sizeof(tipo-struttura).
15
Per esempio, creiamo tre variabili di diverso tipo: studente, persona,
libro:
struct Tpdata {
Tstudente studente;
TPersona persona;
Tlibro libro;
struct TPersona {
char cognome[20];
char nome[20];
Tpdata nascita;
char luogo[20];
};
struct Tstudente {
Tpersona anagrafe;
int matricola;
int esami[4];
};
int giorno;
int mese;
int anno;
};
struct Tlibro {
char titolo[40];
TPersona autore;
int annoedizione;
char editore[20];
float prezzo;
};
Notiamo innanzitutto che il Tpdata viene utilizzato nella definizione
della struct Tstudente (tipostudente), mentre il tipo persona è ripreso
nel Tlibro: una struttura complessa come la struct si può servire di
altre strutture complesse (ancora struct) oppure array.
16
Tstudente studente;
TPersona persona;
Tlibro libro;
struct TPersona {
char cognome[20];
char nome[20];
Tpdata nascita;
char luogo[20];
};
struct Tstudente {
Tpersona anagrafe;
int matricola;
int esami[4];
};
struct Tlibro {
char titolo[40];
TPersona autore;
int annoedizione;
char editore[20];
float prezzo;
};
Per poter accedere al campo nome della variabile persona della
struct TPersona, dobbiamo porre un punto tra i due dati;
l’istruzione
cout<<persona.nome
mostrerà sul video il dato contenuto nella struttura persona, campo
nome.
17
Per accedere al nome dell’autore della struct libro dobbiamo
scrivere:
cout<<libro.autore.nome
L’operatore punto (.) rappresenta la specifica di campo, per cui in
libro.autore.nome
libro richiama la struct di tipo Tlibro
autore richiama il campo autore che, a sua volta, è una struct di tipo
Tpersona
nome richiama il campo del tipo Tpersona
la variabile libro.autore.nome è un array di char avente una
lunghezza massima in caratteri predeterminata.
18
Poiché le struct definiscono un nuovo tipo, è possibile dichiarare ed
utilizzare anche array di struct con le dichiarazioni:
Tlibro libri[100]; // viene dichiarato un array di record libri
contenente al massimo 100 libri
Tpdata festivi[30]; // viene dichiarato un array festivi contenente al
massimo 30 date corrispondenti a giorni festivi
struct Tlibro {
char titolo[40];
TPersona autore;
int annoedizione;
char editore[20];
float prezzo;
};
struct Tpdata {
int giorno;
int mese;
int anno;
};
19
Per leggere una data da tastiera possiamo introdurre le seguenti
istruzioni, dopo aver definito la variabile data1 di tipo Tpdata:
Tpdata data1
do
cout<<”Introduci giorno mese anno separati da spazi: ”;
cin >> pers1.nascita.giorno>>pers1.nascita.mese
>>pers1.nascita.anno;
while (!(data_corretta(pers1)));
20
La funzione data_corretta(data1) potrebbe essere definita come
segue:
bool data_corretta(Tpersona persona)
{
return ((persona.nascita.giorno>0) &&
(persona.nascita.giorno<=31)&&
(persona.nascita.mese >0) &&
(persona.nascita.mese<=12));
}
Questa funzione è richiamata nel programma tante volte finché il
giorno della data non è compreso tra 1 e 31 ed il mese tra 1 e 12.
Esercizio: scrivere una funzione che tenga conto anche dei mesi con
numero di giorni diversi (Apr, Giu, Sett, Nov, 30gg, Feb 28/29 (se
anno bisestile) tutti gli altri 31 gg.)
21
Se abbiamo un’altra variabile data2 di tipo Tpdata possiamo scrivere
data2=data1
ed il compilatore assegnerà opportunamente i valori
(data1.giorno viene scritto in data2.giorno, data1.mese in data2.mese
e data1.anno in data2.anno).
22
Se l’operazione di assegnazione consente di trattare le struct come
una struttura unica, gli operatori di confronto necessitano invece
un’analisi più dettagliata delle componenti.
Scrivere, ad esempio, if (data1==data2)…. provocherà un errore del
compilatore, per cui è opportuno scrivere una funzione del tipo
bool confrontadata (Tpdata data1, Tpdata data2)
{
confrontadata= (data1.giorno == data2.giorno) && (data1.mese
== data2.mese) && (data1.anno ==
data2.anno);
}
23
Osservazioni sulle struct.
1. All’interno di una struttura NON si può utilizzare il tipo string
perché è un tipo che non ha grandezza fissa ma varia in modo
dinamico: servirsi sempre di array di caratteri come negli esempi.
2. Nelle chiamate di funzioni, per eliminare il tempo necessario per
la copia, passare le strutture per riferimento.
3. Nelle chiamate di funzioni, se la struttura non deve essere variata
aggiungere la clausola const.
4. I membri di una struttura possono essere di tipo diverso; essa,
comunque, NON può avere un’istanza di se stessa.
Eser record
24
Esercizio.
Scrivere una funzione
int confrontadata (Tpdata data1, Tpdata data2)
che restituisca
0 se le due date sono uguali
-1 se data1 è minore di data2
+1 se data1 è maggiore di data2
25
Scrivere le strutture necessarie alla gestione di un rivenditore di
moto.
es.
Venditore
Compratore
Descrizione estetica
Descrizione tecnica
Prezzo
Modalità di pagamento
Magazzino
26
Scarica

ppt