Info Appunti lezione 6

Informa(ca Appun( della lezione 6 Tipi semplici e built-in!
•  int è un (po numerico semplice e built-­‐in •  char è un (po non-­‐numerico bensì alfabe(co, ma sempre semplice e built-­‐in (i suoi valori vanno sempre scri= tra apici: char c = ‘d’; a differenza delle stringhe che sono struFurate e vogliono le virgoleFe: string s = “ciao”;) •  In memoria, una variabile int occupa 4 byte, mentre una variabile char solo 1 byte •  Altri (pi numerici semplici e built-­‐in sono (con le rispe=ve dimensioni di variabile): short int (2 byte), float (4 byte), double (8 byte) •  Naturalmente, maggiore è la dimensione dedicata a una variabile di un (po, più vasta è la gamma di valori che tale variabile può assumere: una variabile short int può assumere valori tra -­‐32768 e 32767, una variabile int da -­‐2147483648 a 2147483647 Tipi user-defined (1)!
•  Tramite la parola chiave typedef, in C++ è
data al programmatore la possibilità di
definire nuovi tipi, in diversi modi!
•  Ridenominazione (typedef <tipo esistente> <nuovo tipo>)!
"typedef int intero; /*si definisce un nuovo
tipo chiamato “intero” che è esattamente
come int*/!
"intero x = 5;"
Tipi user-defined (2)!
•  Enumerazione (typedef enum {<lista valori>} <nuovo (po>) typedef enum {blu, rosso, verde} colore; /*si definisce un nuovo (po chiamato “colore” le cui variabili possono assumere uno dei valori elenca(*/ colore c = blu; •  Il calcolatore costruisce una corrispondenza implicita tra i valori elenca( e gli interi: blu == 0, rosso == 1, verde == 2 Tipi user-defined (3)!
•  Tipi strutturati user-defined (typedef struct{<descrizione struttura>}
<nuovo tipo>)!
!typedef struct{int giorno;!
! int mese; !!
! ! int anno;} data;!
!/*si crea il tipo “data” le cui variabili
contengono 3 “campi”, chiamati “giorno”,
“mese”, “anno”, che sono tutti di tipo int*/!
La parola chiave struct •  La parola chiave struct sta a indicare l’introduzione alla descrizione di un dato struFurato •  Si può anche usare senza typedef, per dichiarare una singola variabile struFurata •  es.: struct {int sinistro; int destro;} numdop; •  in questo caso numdop non è un (po, ma una variabile struFurata con due campi interi •  la differenza rispeFo a prima è che numdop è unica nel suo genere, per il quale non esiste un nome (ossia, non abbiamo definito un (po) Tipi user-defined (4)!
•  I diversi campi di una struttura possono
essere di tipi diversi, a loro volta strutturati!
•  Per accedere a un campo di una variabile
strutturata si usa la “dot notation” (notazione
col punto)!
!data oggi;!
!oggi.giorno = 15;!
!oggi.mese = 1;!
!oggi.anno = 2010;!
Esercizio •  Definire un (po struFurato “libreFo” che rappresen( il libreFo universitario di uno studente, contenente il suo cognome, nome, matricola e una struFura da( per 20 esami, ciascuno caraFerizzato da un nome e da un voto Soluzione typedef struct { char nome-­‐corso[40]; int voto; } esame; typedef struct { int cont = 0; char cognome[40]; char nome[20]; int matricola; esame carriera[20];} libreFo; Soluzione •  Una variabile di (po libreFo sarà struFurata con 5 campi: –  un array di leFere per il cognome –  un array di leFere per il nome –  un intero per la matricola –  un array chiamato “carriera” di elemen( di (po “esame”, definito come a sua volta una struFura, contenente un array di 40 leFere per il nome del corso e un intero per il voto –  un intero che conta quan( esami sono sta( registra( dentro “carriera” (inizializzato a 0, viene incrementato a ogni scriFura di esame nel libreFo); il contatore serve perché è l’unico indicatore dello stato di riempimento di “carriera” Stringhe!
•  Sono sequenze di caratteri, e C++ fornisce
un tipo (string) per gestirle, includendo (se
il compilatore lo richiede) la libreria
omonima: #include <string>!
•  Esempio di dichiarazione e assegnamento
di valore:!
Mario !string nome;!
!nome = “Mario”;!
!cout << nome;!
Caratteristiche delle stringhe!
•  Le stringhe, a differenza degli interi, vengono inizializzate automa(camente: string s; //s ha già un valore: “ ” (stringa vuota) •  Per l’input di una stringa può servire un altro comando oltre a cin, perché gli spazi vengono considera( come separatori: cin >> s; //se l’input è “molto bene”, s riceve solo “molto” getline(cin,s); //in questo modo, tuFo l’input fino all’enter premuto //dall’utente finisce in s Differenze con gli array!
•  Le stringhe sono sequenze di caratteri, quindi
potrebbero essere paragonate ad array di
caratteri, ma vi sono differenze!
•  Le stringhe possono essere parametro di cin e
cout direttamente, mentre con gli array serve
sempre un ciclo for per fare cin e cout del
contenuto delle loro celle!
•  Gli array hanno una dimensione fissa
predeterminata, mentre le stringhe possono
cambiare dimensione durante l’esecuzione del
programma: le stringhe sono strutture dati
dinamiche!
Funzioni string!
•  concatenazione (+): crea una nuova stringa a
partire da due stringhe unendole in un’unica
sequenza di caratteri!
•  length: restituisce la lunghezza di una
stringa, ossia il numero dei suoi caratteri; si
invoca per mezzo della dot notation!
•  substr: prende due parametri (i, lung) e
restituisce una sottostringa che inizia all’iesima posizione della stringa iniziale ed ha
lung caratteri; anche substr vuole la dot
notation!
Uso di funzioni string!
string n = “mario”;!
mario rossi string c = “rossi”;!
11 io r string nc = n + “ ” + c;!
int x = nc.length();!
string s = nc.substr(3,4);!
cout << nc << “\n” << x << “\n” << s; !
Funzioni (1)!
•  Una funzione è un insieme unitario di istruzioni che ha lo scopo di fornire, appunto, una determinata funzionalità •  Una funzione è caraFerizzata da: • 
• 
• 
• 
nome numero e (po dei parametri in ingresso (po del parametro (unico!) in uscita codice, ossia le istruzioni eseguite dalla funzione Funzioni (2)!
•  Ad esempio, una funzione per calcolare il valore assoluto di un intero è come segue: int abs(int x){ /*nome: abs, 1 parametro in ingresso chiamato x di (po int, 1 parametro in uscita di (po int*/ if (x>=0) return x; else{ x = -­‐x; return x; } } Funzioni (3)!
•  La funzione così definita verrà u(lizzata nel main, a cui la funzione invia il risultato finale tramite l’istruzione return •  Una funzione viene usata nel main semplicemente scrivendo il suo nome seguito dal valore del parametro in ingresso: … int a; cout << “Inserisci un intero\n”; cin >> a; cout << “Il valore assoluto del numero inserito e’: “ << abs(a) << “\n”; … Parametri formali e attuali!
•  Nella scriFura del codice di abs, abbiamo chiamato “x” il parametro di input, ma esso non ha un vero valore: lo usiamo solo per scrivere il codice •  “x” nel codice si chiama “parametro formale” •  Quando abbiamo usato nel main la funzione abs per eseguire un calcolo, abbiamo scriFo abs(a) •  “a” nella chiamata di abs si chiama “parametro aFuale” (da una traduzione errata da actual che in inglese vuol dire reale, effe=vo) Corrispondenza posizionale!
•  Nel caso di abs c’è un solo parametro, quindi la corrispondenza tra “x” e “a” è ovvia •  In funzioni con più parametri la corrispondenza si crea sulla base della posizione dei parametri nella chiamata: es. con la funzione int somma (int x, int y) se si ha nel main la chiamata somma(a,b) al parametro formale “x” viene faFo corrispondere quello aFuale “a” perché occupa la prima posizione, e così per “y” e “b” Passaggio dei parametri per valore!
•  Se non altrimen( specificato, il passaggio dei parametri, ossia l’invio dei parametri di ingresso alla funzione, avviene per valore •  Questo vuol dire che i parametri aFuali forniscono i loro valori, di cui vengono faFe copie su cui operano le istruzioni della funzione per oFenere il risultato da res(tuire al main •  Le copie vengono eliminate al termine dell’esecuzione della funzione Passaggio per valore!
somma(a,b) a 8 somma 8 x 12 y b + 20 return 20 12 I parametri in ingresso “a” e “b” non vengono coinvol( nella funzione Passaggio dei parametri per riferimento!
•  Se si vuole che la funzione operi direFamente sui parametri in ingresso, ques( devono essere passa( per riferimento •  Questo vuol dire che i parametri aFuali non forniscono più i loro valori, bensì il loro indirizzo in memoria, cosicché le istruzioni che ne modificano il valore abbiano un effeFo che permane anche dopo il termine della funzione •  Per indicare che il passaggio è per riferimento basta aggiungere ‘&’ davan( al nome dei parametri formali nella lista Esempio!
dammi un numero int raddoppia (int& a){ 7 il suo doppio e’: 14 a = a*2; return a; } int main(){ int x; cout << “dammi un numero\n”; cin >> x; x = raddoppia(x); cout << “il suo doppio e’: ” << x << “\n”; … } Passaggio per riferimento!
raddoppia(a) return a 14 7 14 a *2 14 raddoppia Il parametro in ingresso “a” viene coinvolto nella funzione Uso di una funzione per trovare
l’mcd di due interi!
#include <iostream> using namespace std; int mcd(int x, int y){ int d; //variabile locale della funzione if (x <= y) d = x; else d = y; while (x%d!=0 || y%d!=0) d-­‐-­‐; return d; } int main(){ int a,b; cout << “Dammi due numeri\n”; cin >> a >> b; cout << “Il loro massimo comun divisore e’: ” << mcd(a,b) << “\n”; system(“PAUSE”); return 0; }