fondamenti di informatica
parte 3
appunti per appunti per Nettuno
a.a. 2005-2008 di
anna maria carminelli gregori
[email protected]
Linguaggio C & C++
Fond. Informatica Nettuno par. 3
1
Struttura dei programmi
Come gia’ indicato, ogni programma C o C++ è
composto da funzioni delle quali main() è la principale,
punto di innesco del programma.
Gia’ nei programmi presentati si possono notare parti
differenti, composte da frasi di commento,
dichiarazioni, definizioni (per es. di variabili col loro
nome), comandi esecutivi.
 I commenti servono come documentazione del
programma, essenziale per far capire a chi lo legge cosa
fa il programma e come lo fa;
 le dichiarazioni e definizioni permettono al
compilatore di interpretare e tradurre tutte le frasi del
programma correttamente come appare negli esempi
2
indicati nel seguito. Fond. Informatica Nettuno par. 3
Dichiarazioni e comandi (frasi,
istruzioni) di tipo esecutivo
Le dichiarazioni relative alle funzioni, (cfr. project7)
servono per segnalare al compilatore le funzioni create
dal programmatore e usate nella parte esecutiva del
programma, il loro tipo e quello dei loro argomenti se
presenti. Si tratta di dichiarazioni simili a quelle che
sono nei file header. Con tali indicazioni il compilatore
riconosce e traduce le funzioni che incontra
successivamente.
Con le frasi “esecutive” infine si esprime l’
algoritmo: il compilatore traduce ogni frase nel
numero di istruzioni del linguaggio macchina,
necessario e sufficiente per la sua corretta esecuzione.
3
C++: Definizione di Variabili
Il corpo di ogni funzione ha frasi dichiarative
(che possono porsi nella parte dichiarativa
iniziale) ed esecutive, col significato di
istruzioni, comandi (che producono la parte
esecutiva).
Comunque, in ogni funzione deve essere
presente la dichiarazione (in C++ si dice
definizione) delle variabili usate con il loro
nome (o identificatore) ed il loro tipo,
PRIMA o “contemporaneamente” al loro
uso.
Fond. Informatica Nettuno par. 3
4
Perche’ ?
Le dichiarazione o definizioni di ogni
variabile hanno anche lo scopo di indicare
al compilatore di prenotare spazio in C.M.
Quanto spazio? Dipende dal tipo di dato
che la variabile dovra’ identificare e
contenere.
Il tipo di dato determina la codifica del
dato: fixed, floating, char ...
Fond. Informatica Nettuno par. 3
5
Gli Identificatori del C e C++
sono associati alle entita’ del linguaggio
come: variabili, costanti, funzioni, tipi derivati
(vedere avanti).
Regole di composizione: ogni identificatore
deve iniziare con un carattere alfabetico (o
con l’ underline _ , ma quest’ ultimo e’
pertinente agli identificatori del Sistema);
internamente puo’ contenere caratteri
alfanumerici ed anche l’ underline _ , ma
non lo spazio bianco.
Fond. Informatica Nettuno par. 3
6
Totale liberta’ di scelta ?
… quasi ! In ogni linguaggio esistono alcune
parole riservate (keyword) con significato
preciso per il compilatore del linguaggio e
quindi non usabili come identificatori normali.
Ecco le parole riservate comuni al C e C++
 auto
default
float
register
struct
while
break
do
for
return
switch
case
char
double else
goto
if
short signed
typedef union
const
enum
int
sizeof
unsigned
continue
extern
long
static
void
In C++ ce ne sono ancora altre per es….:
Fond. Informatica Nettuno par. 3
7
keywords
 asm
bool catch class
delete friend
handle inline
new operator private
protected public
template this
throw
try
unsigned virtual volatile … ED ALTRE TIPICHE DI
OGNI COMPILATORE
Nota: non esistono parole riservate come array e
pointer nonostante entrambe le entita’ siano
realizzabili in C e C++ . La loro creazione avviene
usando altri costrutti tipici del linguaggio.
Da qui in poi le keyword saranno scritte in
grassetto.
Fond. Informatica Nettuno par. 3
8
Tipi di dati
Tutti i linguaggi di programmazione hanno alcuni tipi
di dati predefiniti (fondamentali); in C e C++ sono:
int per variabili di tipo intero (di almeno 2 byte);
float “ “
“ “ floating-point (almeno 4byte);
char “ “
“ “ carattere (1byte x car.);
double “ “
“ “ float, ma in doppia precisione
,
ossia di almeno 8 byte.
In C++ esiste anche il tipo bool per indicare una
variabile logica (booleana) che può assumere solo i
valori true(vero) e false (falso)
Questi sono i tipi base standard. Oltre a questi tipi di
dati fondamentali, in C e C++ ci sono gli indirizzi di
variabili (meglio: di posizioni di C.M. dove si trovano i
9
dati identificati dalle variabili).
Il C++ e’ a forte tipizzazione
ossia ad ogni entita’ del linguaggio e’
associato un tipo di dato che ne determina lo
spazio di memoria necessario e il possibile uso
(per es. aritmetica intera o floating-point ? cfr.
Parte 1)
Oltre ai tipi fondamentali predefiniti, in C++ si
possono definire tipi di dato derivati ottenuti
dai tipi fondamentali con vari meccanismi per
elaborare oggetti complessi: matrici, solidi
tridimensionali, numeri complessi ….
Fond. Informatica Nettuno par. 3
10
Definizioni: es. in E:/carmin/
Nettuno2006/programm1-2
Tutte le variabili utilizzate nei C++ program (o
function) in fase di costruzione devono essere
definite per garantirne l’ allocazione in
memoria: non usarle senza definizione !
La definizione puo’ avere la forma seguente:
tipo nomi di variabili separate da virgola: es.
int i, j, k, leo, lilla;
float x, y, z, sup, inf, set1;
Nota: il tipo intero puo’ essere anche indicato
come short int, long int, unsigned.
Fond. Informatica Nettuno par. 3
11
Inizializzazione delle var.
Puo’ avvenire in 3 modi (cfr. fasi traduz. Parte2):
1) alla definizione: es. int a = 7; e’ il
compilatore che pone il valore 7 nella zona di
memoria identificata dalla variab. a (fase di
compilazione);
2) con una frase di assegnazione nella parte
esecutiva del programma eseguita durante l’
esecuzione del programma (fase di esecuzione):
es. a=7; preceduta pero’ dalla frase int a;
3) con le frasi int a; ed una frase di lettura di un
valore da porre in a (ancora fase di esecuzione).
Fond. Informatica Nettuno par. 3
12
Riflessione
Fra le 3 possibilita’ quale scegliere ?
La scelta dipende dalle condizioni, pero’ la
definizione di a come variabile significa che il
suo valore e’ soggetto a cambiare nel corso
del programma (altrimenti cosa sarebbe ???!)
Inizializzarla a 7 significa che al primo giro del
programma il suo valore deve essere 7 e
quindi se e’ il compilatore ad inizializzarla si
risparmia tempo in fase esecutiva.
Fond. Informatica Nettuno par. 3
13
In programm1 project4-5
appaiono le 3 possibilita’ !
I progetti di questi programmi appaiono dalle frasi di
commento dei programma, ma quali sono i loro
diagrammi di flusso ???! Quando la logica e’
sequenziale e gia’ illustrata, diventano superflui !
Si noti nelle visualizzazioni l’ uso delle funz. setw(n) e
setprecision(n) manipolatori di posiz. e precisione del
C++. Altri sono: oct, hex …!
MODIFICHE SUGGERITE: per modificare i contenuti
delle variabili usare gli operatori aritmetici di C e C++:
+ addizione - sottrazione - cambio segno
* moltiplicazione / divisione
%resto
per es. come segue:
Fond. Informatica Nettuno par. 3
14
Modifiche di project4-5 in
programm1: esaminare tutto
Avendo definito: i = 12345;
si puo’ modificare il suo contenuto cosi’:
i = -i;
// in i e’ posto l’ opposto di i che si puo’
visualizzare; oppure:
i = i*2;
//
in i va il prodotto di i per 2 che si puo’
visualizzare ed anche:
i = i+1; // i e’ aumentato di 1 ed anche:
i = i / 3; // “ “ diviso per 3 oppure
i = i % 4; // viene fatta la divisione fra l’ intero
i e l’ intero 4 ed il resto e’ posto in i.
Fond. Informatica Nettuno par. 3
15
Espressioni aritmetiche
 Alla destra dell’ operatore di assegnazione puo’ esserci per
esempio un’ espressione aritmetica, formata da variabili e
costanti collegate tra loro da operatori aritmetici che il
compilatore considera con le priorita’ seguenti:
 - (cambio segno) (PRIMO)
* / %
(SECONDO)
+=
ULTIMO ! OSSIA: prima e’ calcolata l’ espressione poi
e’ assegnato il risultato!
 La valutazione di ogni espressione, procede secondo la
priorita’ degli operatori presenti e se essi hanno la stessa
priorita’ da sinistra a destra. Il valore cosi’ ottenuto e’
“assegnato alla variabile posta alla sinistra” dell’ operatore di
assegnazione.
Fond. Informatica Nettuno par. 3
16
Parentesi e Costanti
 Nelle espressioni
 si possono usare parentesi tonde (anche annidate)
per modificare la priorita’ degli operatori … come nelle
espressioni algebriche;
 si possono trovare entita’ fisse del linguaggio che sono le
costanti: per es. “buonasera” e’ una costante tipo testo
(stringa delimitata da “); altra costante di tipo numerico
floating-point e’ 3.1415923 usata in project4-5
(controllare). Ci sono poi costanti di tipo intero in base
10 (per es. 365), in base 8 (per es. 077 col valore ottale
preceduto da zero), in base 16 (per es. 0xff oppure 0Xff
oppure 0XFF col valore esadecimale preceduto da zero e
da X o x).
Fond. Informatica Nettuno par. 3
17
Altre costanti
di tipo carattere delimitate da ‘(per es.’a’ o ‘\n’ =
line feed) Chi e’ line feed ? Nel codice ASCII e’ il
decimo carattere con significato di andare a capo
(in C++ cout<<endl; ha uguale effetto).
Altri caratteri speciali:’\0’ NUL=fine stringa; ‘\g’
BEL=bip; ‘\t’ horizontal tab; altri …
usare il programma project71 in Programm2 per
vedere le codifiche ASCII di tutti i caratteri …
provare anche CTRL Z ...
NOTA: anche una costante puo’ essere identificata
da un identificatore e avere un tipo, preceduto da
Fond. Informatica Nettuno par. 3
18
const.
Altri esercizi
Definire una costante ottale,
una esadecimale
e convertirle in decimale (usando l’
algoritmo noto!);
LEGGERE UN VALORE INTERO DECIMALE
ed usarlo come nuova base per convertirci
le costanti definite…
Fond. Informatica Nettuno par. 3
19
Remember 1
Se una costante serve in una sola frase del
programma non occorre dichiararla come costante;
per es. per calcolare la lunghezza della circonferenza
del cerchio di raggio r, si può scrivere:
float circo, r;
cin >> r;
circo = 2* 3.1415927 *r; cout<< circo;
se invece serve in diverse frasi del programma, (per
es. se occorre calcolare anche l’ area del cerchio) è
MEGLIO definire:
pg=3.1415927; (o anche con #define pg 3.1415927)
e poi usare pg per calcolare area e circonferenza.
Fond. Informatica Nettuno par. 3
20
Remember 2
Le costanti si possono definire anche tramite il
precompilatore con #define (vedere project3 in
programm1)
Le frasi esecutive del programma scritto in un
qualsiasi linguaggio di programmazione come il C++
sono tradotte in istruzioni del linguaggio della
macchina col significato di comandi come Somma,
Trasferisci …
le frasi dichiarative diventano comandi particolari,
diversi dai precedenti, del tipo: riserva una zona di
C.M.
i commenti sono tradotti in binario col codice ASCII,
ossia alla maniera di costanti alfanumeriche (stringhe)
Fond. Informatica Nettuno par. 3
21
Il tipo puntatore a carattere
appare nell’ esempio della stringa di project8.cpp
const char* benvenuto = “sono una stringa
per il main”. In C o C++ una stringa di caratteri
delimitata da 2 virgolette viene memorizzata
con una costante stringa formata da una
successione di caratteri (codice ASCII): essa
termina col carattere ‘\0’ che e’ inserito
automaticamente dal compilatore. Nell’esempio
l’ indirizzo del primo carattere, dal compilatore
e’ posto in benvenuto che diventa il puntatore
alla stringa.
Fond. Informatica Nettuno par. 3
22
Registro P di 4 bit => 16
locazioni (byte) indirizzabili
 CPU = “Ragnetto”
Central Memory
REG. P.
0000
0001
Registro P.= Pointer o

i.C.=Istruction Counter
1111
..........................tanti "millepiedi"
23
Puntatori
La loro importanza specialmente per il C++ e’
notevole.
Il puntatore indica un indirizzo di C.M. ed e’
rappresentato simbolicamente da una freccia.
Una variabile di tipo puntatore e’ destinata a
identificare e contenere solo indirizzi.
Per indicare al compilatore che la variabile e’
di tipo puntatore non si usa una nuova parola
riservata, ma il tipo del valore puntato
seguito da un asterisco e dal nome del
puntatore: es. char* benvenuto
Fond. Informatica Nettuno par. 3
24
Esempi
Scrivendo: int kika = 5; si definisce kika come
una variabile intera e si inizializza con 5. Un
puntatore ad un intero si definisce: int *pk;
col significato che pk puo’ contenere solo
indirizzi di variabili intere; con char *pl; si
definisce pl come un puntatore a carattere (per
es. come benvenuto) e cosi’ via. Pulizia concettuale:
un puntatore definito come puntatore ad un tipo deve
sempre contenere indirizzi di varabili di quel tipo!!!
Inizializzare un puntatore non e’ cosi’ semplice
come inizializzare un intero: per farlo si puo’
usare l’ operatore unario & col significato di
indirizzo di
Fond. Informatica Nettuno par. 3
25
Esempi degli operatori & e *
Avendo: int kika = 5, j; int *pk; si puo’ porre:
pk = & kika; dando cosi’ a pk l’ indirizzo di kika.
(Si può anche prenotare memoria per l’ intero puntato
da pk con la funz. malloc, new… cfr. corso successivo)
Ma posto pk = & kika; pk identifica kika che a
sua volta identifica la zona di memoria
contenente 5: c’e una sorta di catena ! Quindi
per arrivare a 5 si puo’ usare kika, ma anche
usare pk purche’ preceduto dall’ operatore *
che, sui puntatori, attiva un’ operazione di
indirezione come indicato nello schema
successivo da dove si deducono “equivalenti”:
j = kika; j = *pk;  a j e’ assegnato 5 26
1
 1000
 1004
Pk  100416
Kika  100A16
 100A
00000000000001012
C.M.
Schemino dello stato di C.M. dopo:
kika = 5;
pk = &kika; // & estrae l’ indirizzo di una variabile
int o char o float o double,
* estrae il contenuto di un indirizzo ossia il contenuto
dell’ indirizzo contenuto in un puntatore come pk.
& e * sono complementari!
 Addr.16
Fond. Informatica Nettuno par. 3
27
Esempi
delle varie codifiche per tipi diversi sono in project6
di programm2
project6.cpp e’ la versione monoblocco del programma
sulle codifiche ed e’ subito da vedere e capire tramite i
commenti inseriti.
Per introdurre l’ uso di funzioni ci sono i programmi
project7-8 e project71 anche se le funzioni li’
presentate lavorano su variabili globali.
La versione project11 in programm3 è strutturata a
blocchi con l’uso di funzioni che si vedranno piu’
avanti.
Vedere E:/carmin/Nettuno2006/programm2 e
E:/carmin/Nettuno2006/ programm3.
Fond. Informatica Nettuno par. 3
28
Esercizi e ...
Scrivere un programma in C++ in cui la parte
elaborativa consiste nella lettura e somma di 3
valori numerici (letti da Input). Il totale deve
essere visualizzato. I valori numerici possono
essere interi o Floating_point. Scrivere un altro
programma ove, letti 2 valori float, calcoli le
somme per difetto e per eccesso dei 2 valori e
le restituisca al main.
 ….e se i valori numerici fossero 100 ?
….e se il numero dei valori numerici fosse
incognito ?
Fond. Informatica Nettuno par. 3
29
Elaborazione ciclica
(iterativa)
Le domande precedenti servono ad introdurre
le frasi iterative che permettono di realizzare
cicli ossia di ripetere una frase o un blocco di
frasi (nell’ es. precedente: lettura e somma di
valori numerici in numero variabile).
Le frasi sono:
for …; while … ; do … while;
 (del while è già stato presentato un esempio in project71)
Seguono sintassi e diagrammi di while … ; do
… while; e per il for …; quale formato ?
Fond. Informatica Nettuno par. 3
30
La sintassi
di un tipo di frase stabilisce la forma generale,
il costrutto cui occorre attenersi nello scrivere
frasi di quel tipo.
Per il for la sintassi e’ la seguente:
for(<espress.1>;<espress.2>;<espress.3>) <frase>;
dove: <espress.1> inizializza la var. di controllo del
ciclo; <espress.2> condizione di fine ciclo;

<espress.3> incrementa la var. di controllo del
ciclo; <frase> e’ la singola istr. o il blocco di istruzioni
da ripetere. Ogni espressione puo’ mancare ! Esempi
in project6 e project11 di programm2-3 e...
Fond. Informatica Nettuno par. 3
31
Esempio e significato
della frase for:
for (int i=1; i<=3; i=i+1) {cout << endl; … }
cin >> a; ….
1) assegna ad i il valore 1;
2) controlla che risulti i<=3;
3) se la condizione e’ vera: esegui la frase o il
blocco di frasi tra le { } (qui vai a capo), aumenta
i di 1 e riprendi ad operare dal punto 2);
4) altrimenti ( i>3 ) esci dal ciclo ed esegui la
frase successiva al for (qui cin >> a).
Fond. Informatica Nettuno par. 3
32
Il for si usa quando il numero
di ripetizioni e’ noto: esempio
somma =S i=022 3  in C o C++ come segue:
int somma =0, inc =3, max =23, i;
for (i=0; i<max; i=i+1) somma = somma+inc;
cout << “\nla somma e’: “ << somma;
L’ addizione di inc a somma e’ ripetuta max volte
In C e C++ ogni espressione del tipo i=i+1; si
puo’ scrivere con i++; (analogamente i--;) le
espressioni del tipo somma = somma+inc; si
possono scrivere con somma += inc;
(analogamente x*=n; invece di x=x*n; e cosi’
33
pure le altre operazioni.)
La funzione Fattoriale di n
Dato l’ intero n>0, il suo fattoriale n! è definito
dal prodotto 1*2*3*… *n. Per convenzione:
0!=1 ed i fattoriali dei numeri negativi non sono
definiti. La funzione fattoriale indica il numero
delle permutazioni di n oggetti e cresce molto
rapidamente.
 Fare un programma in C++ strutturato in
sottoprogrammi che legga un valore n
(0<n<10), calcoli il suo fattoriale usando la
frase for e lo visualizzi.
Fond. Informatica Nettuno par. 3
34
Altri esercizi
Scrivere un programma in C++ che esegua la
successione dei numeri interi da 1 a 100;
 Scrivere un programma in C++ che esegua la
successione dei numeri interi negativi da -2 a 50;
 e poi quella dei numeri positivi dispari da 1 a
100;….
Fond. Informatica Nettuno par. 3
35
Sintassi e significato del while
Esempi in Programm4 project14-16
while (<Condizione>) <Frase>
fintantoche’ la Condizione e’ vera la Frase
viene eseguita: si esce dal ciclo passando alla
FraseSucc. quando la Condizione diventa falsa;
si utilizza quando non si conosce il numero di
ripetizioni da effettuare, per es. sapendo che
int x >0 ma non quanto vale x si puo’ scrivere:
while (x >0) {cout<<“\nx ancora>0”; x--; }
la Condiz. e’ esaminata prima dell’ esecuzione
della Frase.
Fond. Informatica Nettuno par. 3
36
Sintassi e significato del do ...
While es. in Programm4 project17
do <Frase> while (<Condizione>)
la Frase viene eseguita per tutto il tempo che la
Condizione e’ vera: si esce dal ciclo quando la
Condizione diventa falsa.
si utilizza quando non si conosce il numero di
ripetizioni da effettuare, per es. sapendo che
int x  1 ma non quanto vale si puo’ scrivere:
do{cout<<“\nx ancora>0”; x--; } while (x
>0)
la Condiz. e’ esaminata dopo l’ esecuzione della
frase: ecco perche’ nell’ es. deve essere x  371.
Diagramma di:
while(Condiz.)
{Frase}
Diagramma di:
do{Frase} while
(Condiz.)
Frase
True
False
Condiz.
True
Condiz.
False
Frase
FraseSucc.
FraseSucc.
Esempi in programm4: project14-15
Esempio in programm4: project16
Fond. Informatica Nettuno par. 3
38
Ripensando al ciclo del DOS ...
Operazioni svolte:
1) Accensione & bootstrapping
2) Ricerca e caricamento DOS
3) Esecuzione di autoexec.bat (inizializzazione!)
4) Prompt e attesa di un comando
6) Esecuzione del comando
7) Ritorna a 4)
4) 6) 7) => CICLO INFINITO !!!
Fond. Informatica Nettuno par. 3
39
Ciclo Infinito: tipico della Shell dei S.O.
come si scrive in C o in C++ ? La frase 7)
Ritorna a 4) potrebbe essere scritta con un
goto quattro; con quattro posto come
etichetta della frase 4) ossia cosi’:
quattro: Esegui(prompt); //qui quattro = label

Aspetta(comando);

Esegui(comando);

goto quattro;
...ma il goto NON E’ una frase BEN VISTA dai...
“Programmatori Strutturati” ! Meglio usarla
solo per andare a segnalare errori …. e allora?
Fond. Informatica Nettuno par. 3
40
CICLO INFINITO: possibilita’ ed … altro
1) For (;;)
2) while (1) { ... }
3) do { ... } while (1)
… ma perche’ ?? RIFLETTERE !…
e poi avendo alcuni cicli infiniti nel
proprio progr. invece di ripetere per ogni
ciclo una delle 3 frasi cosa si puo’ fare ?
Ricordare #define ….
Fond. Informatica Nettuno par. 3
41
Esempio di un ciclo infinito
Es. #define forever For (;;)
Una volta cosi’ definito si puo’
usare nel proprio programma
forever invece di For (;;) …
cosi’ per il ciclo del DOS:
forever
{Esegui(prompt);
Aspetta(comando);
Esegui(comando);}
Un altro esempio in Programm4
project17 qui di seguito
…
Fond. Informatica Nettuno par. 3
42
/* PROGRAM provo_while infinito; INIZIO DOCUMENTAZIONE:
Il programma in versione monoblocco deve solo mostrare
l'uso di un while infinito per la
ripetizione di una stampa
interrotta quando e‘ True la condizione nella frase if. La condizione
e' True se la funzione kbhit() NON restituisce 0. Cio' si verifica solo
alla pressione di un tasto.
Fare il programma in versione strutturata a moduli con la funzione
tastosi che attiva kbhit(). */
#include "iostream.h" // Libreria: Standard I/O del C++
#include "conio.h" /* Libreria: Conform.I/O del C */
main ()
{ /* Inizio Modulo principale */
clrscr();
while (1)
{
cout<<"\ndammi un carattere:";
if (kbhit()) break;
}
cout<< "\nFINE";
43
return 0;} /* Fine Modulo principale */

Elaborazione condizionale
La condizione che appare nella frase while e’
tipica delle scelte che intervengono nello
svolgimento di programmi.
La scelta di una condizione permette di
interrompere la sequenzialita’ delle operazioni:
in base al valore della condizione un blocco di
frasi puo’ essere eseguito o no; tra 2 blocchi
puo’ essere scelto uno per l’esecuzione e
saltato l’ altro; ci puo’ anche essere un
annidamento di scelte…
Scelta essenziale per trovare i numeri dispari e
44
divisibili per 3! Fond. Informatica Nettuno par. 3
Scelte e frase if … sintassi,
significato ed esempi
if (< condizione >) frase1;
se la condizione e’ vera esegui la frase1 che puo’
essere semplice o composta; es. di frase semplice:
if (j>0) cout << “j e’ positivo”;
if (< condizione >) Frase1; else Frase2;
se la condizione e’ vera esegui Frase1, altrimenti
esegui Frase2; poi prosegui con la Frase in sequenza,
come indicato nel diagramma seguente.
es. if (j>0) cout << “j e’ positivo”; else cout
<< “j e’ minore o =0”;
Fond. Informatica Nettuno par. 3
45
Diagramma: if(condiz.) {Frase1}
else {Frase2}
Condiz.
False
True
Frase1
Frase2
Frase

 L’ else puo’ mancare: se manca l’ else, la freccia da Frase1
porta a Frase2. Project14 in program4 ha vari else…(fra 2
diapo)
Fond. Informatica Nettuno par. 3
46
Frasi if annidate: selezione
multlipla, ma ...
if (< condizione 1>) <frase 1>;
else if (< condizione 2>) <frase 2>;
else if (< condizione 3>) <frase 3>;
…..
else if (< condizione n>) <frase n>;
else frase n+1; // qui puo’ andare male …
Ricordare che <frase i> e’ una singola istr. o
in generale un blocco di istruzioni: segue
esempio … ma usare con cautela if annidati !!!
Fond. Informatica Nettuno par. 3
47
Esempio con operatori !=
(diverso), == (uguale)e >maggiore
{// ricordare: EOF = CTRL-Z
char c;
while ((c=getchar()) != EOF)
 if (c==‘a’) cout<< “ primo carattere\n”;
 else if (c==‘b’) cout<< “secondo car.\n”;
 else if (c==‘c’) cout<< “terzo car. \n”;
 else if (c>‘c’) cout “carattere imprevisto\n”;
} //vedere prg. project14 in programm4, ma
meglio usare switch.
Fond. Informatica Nettuno par. 3
48
Operatori relazionali
== il primo operando e’ uguale al
secondo
!= “ “
“
“ diverso dal
“
> “ “
“
“ maggiore del “
>= “ “
“
““
o uguale al “
< “ “
“
“ minore del
secondo
<= “ “
“
““
o uguale al “
ATT.ne operatore di uguaglianza ==: NON
confonderlo con l’ operatore di assegnazione!!
Fond. Informatica Nettuno par. 3
49
Ma sono tutte accessibili le
variabili e le costanti?
Quando la definizione delle variabili (o costanti)
viene fatta all’ esterno di tutte le funzioni, le
variabili sono dette globali: ad esse si puo’
accedere con qualunque istruzione di una
qualsiasi funzione componente l’ intero
programma C o C++.
Invece se le variabili sono definite all’ interno di
una funzione sono dette locali alla funzione:
ad esse si puo’ accedere solo dall’ interno della
funzione.
Fond. Informatica Nettuno par. 3
50
L’ esempio in project8 (program2)
mette in luce anche la globalita’ e la localita’ dell’
ambiente di una funzione o programma.
L’ ambiente locale si intende formato da tutte le entita’
dichiarate e definite dentro la funzione.
In project8.cpp l’ ambiente locale al main si compone
della sola const char* benvenuto che e’ usabile,
visibile solo all’ interno del main, mentre la const
char* bene e le var. car e num esterne al main e a
tutte le altre funzioni formano l’ ambiente globale e
sono visibili e usabili in ogni funzione.
Fond. Informatica Nettuno par. 3
51
/*Variabili e costante Gobali usabili in tutti i MOduli*/

int num; char car;
const char* bene= "Sono bene una costante globale";

/* Dichiarazione dei Prototipi dei MODULI usati */

void leggi();
void scrivi();
void elabora();
void attendi();
 main()
 { /* Inizio Modulo principale e dichiarazioni: ambiente
locale del main */

const char* benvenuto= "Sono benvenuto
costante locale al main";
/* INIZIO Parte esecutiva */
 clrscr();
 cout<<"\n Costanti locale benvenuto, bene globale)";
 cout << "\n" << benvenuto;
 cout << "\n" <<Fond.
bene;
....
Informatica Nettuno par. 3
52

…..
void scrivi() /*Intestazione delle funzione scrivi */
 /* Visualizza le costanti ed il carattere <> 0 col suo
valore numerico:
 variabili globali utilizzate: car, num */
 { /* Inizio scrivi */
 cout << "\nsono in scrivi posso scrivere bene, ma
benvenuto ?";
 cout << "\n" << bene <<endl;
 // cout << "\n" << benvenuto <<endl;
cout << "\n";
cout<< "Carattere letto e Valore numerico
corrispondente: "<< car<<" "<< num;
 } /* Fine scrivi*/ …..
Fond. Informatica Nettuno par. 3
53
Printf: un esempio delle
funzioni di libreria del C
E’ gia’ stata usata e come appare evidente dal
suo uso ed effetto, si tratta di una funzione
della libreria Lib del C ossia di un segmento
di codice (che permette di usare il video per
visualizzazioni) e quindi puo’ essere eseguito
piu’ volte nel corso del programma. Questo
segmento di codice e’ stato isolato dai
Sistemisti della Borland ed il suo prototipo e’
disponibile nel file “header” <stdio.h> del C.
Fond. Informatica Nettuno par. 3
54
Primi esempi di funzioni void
scritti come esempi di funzioni per strutturare
bene i PROGRAMMI sono in programm2
project7-8. Sono le funzioni: void leggi(), void
elabora() void scrivi(), void attendi().
Si tratta di funzioni create dall' utente che
lavorano su variabili globali (uso dell’ ambiente
globale): non hanno ne’ tipo (sono indicate
come void), ne’ argomenti.
Si tratta di un uso improprio delle funzioni e dei
sottoprogrammi in generale, adottato nei prim
esempi soltanto per evidenziare le
componenti funzionali di un programma.
Fond. Informatica Nettuno par. 3
55
Scope di un’ entita’
Scope puo’ essere tradotto con raggio d’
azione e significa l’ insieme di codice in cui una
variabile o una costante e’ visibile e quindi
usabile in modo corretto.
=> lo scope dell’ ambiente globale
comprende il main, le funzioni, tutto il codice
che sta sullo stesso file del main;
=> lo scope dell’ ambiente locale si esaurisce
nella funzione di appartenenza;
=> lo “scope” del precompilatore e’ tutto il file
in cui si richiamaFond.
! Informatica Nettuno par. 3
56
( … ma a chi giova la
modularita’ dei programmi ?
Il problema della globalita’ e della localita’ delle
variabili di un programma non esisterebbe se il
programma non fosse strutturato a moduli, ma
monoblocco: pero’ questo modello non va.
 Esempi di programmi monoblocco sono i primi in
program1..
Dagli esempi elementari appare poco la convenienza
della modularita’ che diventa essenziale se
aumenta la complessita’ dei programmi.
Di tutto cio’ si parlera’ +avanti.
Fond. Informatica Nettuno par. 3
57
Una pausa di riflessione
Uno degli scopi del corso e’ imparare a
programmare usando il linguaggio C++.
Ossia l’ accento va su imparare a programmare.
Per questo e’ necessario capire come deve
essere fatto un programma e la lettura e analisi
di programmi scritti da altri aiuta a capirlo.
L’ organizzazione a moduli dei programmi vuole
evidenziare le funzionalita’ di ogni programma:
lettura dati, loro elaborazione, stampa risultati.
Di cio’ bisogna ricordarsi quando si scrive un
programma.
Fond. Informatica Nettuno par. 3
58
La riflessione termina con un
nuovo programma in C++
da fare usando alcune frasi finora presentate.
Progetto logico: il prg. deve leggere 2 valori interi da
assegnare alle variabili Base e Altezza e visualizzarli;
calcolare le aree del rettangolo, triangolo (Base *
Altezza/2), del quadrato costruito sulla Base e del
quadrato costruito sull’ Altezza, del cerchio di raggio =
Base, Altezza o con un valore del raggio da leggere;
visualizzare le aree.
 Fare un programma monoblocco ed uno strutturato a
moduli (funzioni appena saranno presentate.)
Fond. Informatica Nettuno par. 3
59
RICORDARE!!!
 Ogni frase compiuta del C o C++ termina con il ;
 for è una parola riservata usata per iniziare un ciclo. La
sintassi del for è:
 for ( iniziazione_var_controllo; condizione_prosegui_ciclo;
variazione_var_controllo)<frase_C++>;
 Il ; va dopo la frase del C++. Messo dopo la ) significa che la
frase del C++ è vuota!!
 La variazione_var_controllo può essere un incremento come
i= i+3 che diventa i+=3, o un decremento come i = i-1 che
diventa i--.
 La forma del for può essere modificata, ma rispettando la
sua sintassi. Per es. per realizzare col for un ciclo infinito non
si può scrivere a casaccio, ma si deve ricordare che ci sono
tra le parentesi 3 espressioni. Ogni espressione può essere
vuota, ma indicata dal ; quindi un ciclo infinito sarà:
 for(;;)< frase>; oppure
 for (;1;)< frase>; indicando con 1 che la condizione prosegui
60
ciclo è sempre vera! Fond. Informatica Nettuno par. 3
Variabili globali
L’ambiente globale si puo’ schematizzare come
lo strato piu’ esterno di un sistema ad anelli
concentrici.
Tutte le funzioni rappresentate dagli anelli
interni lo possono vedere e usare, ma ne
diventano dipendenti.
Fond. Informatica Nettuno par. 3
61
Variabili locali
Per rendere indipendente ogni funzione
occorre sganciarla dall’ ambiente globale e
comunicarle i dati su cui lavorare ad ogni sua
attivazione.
Lo schema che si puo’ considerare e’ quello di 2
entita’ (scatole) che comunicano tra loro: la
prima attiva la seconda inviandole i dati su cui
lavorare e questa le restituisce il risultato che
ha calcolato (per esempio con una sua variabile
. 1
locale).
2
Fond. Informatica Nettuno par. 3
62
Indipendenza delle funzioni
La funzione o sottoprogramma in genere e’ lo
strumento che ha permesso lo sviluppo di
quantita’ enormi di software (esempio tipico le
librerie) e deve lavorare indipendentemente
dall' ambiente globale e dal programma che lo
attiva.
Per essere indipendente, il sottoprogramma ha
bisogno di variabili e strutture dati in generale,
per identificare i dati su cui deve lavorare al suo
interno.
Fond. Informatica Nettuno par. 3
63
Sottoprogrammi parametrici
Il sottoprogramma per identificare e scambiare dati
con l’esterno usa il meccanismo degli argomenti
(dichiarati nella sua intestazione) che prendono il
nome di parametri formali. Le frasi componenti il
suo corpo utilizzano questi parametri formali.
Quando il sottoprogramma e’ attivato per es. dal main
i parametri formali diventano il veicolo di trasporto
delle informazioni che il main vuole comunicare al
sottoprogramma e/o ricevere da questo.
(Nel corpo del sottoprogramma possono essere usate
anche altre variabili e strutture dati con compiti
provvisori e circoscritte al solo sottoprogramma:
queste appartengono all’ ambiente LOCALE del
sottoprogr. definito e usabile solo al suo interno.)
Fond. Informatica Nettuno par. 3
64
… ma, perche’ sottoprogrammi ?
La motivazione del nome sta nel loro uso. Si
tratta in generale di programmi (software) che
vanno in esecuzione solo se vengono attivati o
richiamati da altri programmi.
Anche il main program va in esecuzione solo se
qualcuno lo chiama, ma costui puo’ essere solo
l’ utente o il S.O. non una qualsiasi funzione
definita ad un livello a lui sottostante.
Invece qualsiasi sottoprogramma sottostante il
main, puo’ attivare gli altri ed anche se’
stesso, (ricorsione =definizione di un oggetto
con versioni più semplici dell’ oggetto stesso)
ma non il main!
Fond. Informatica Nettuno par. 3
65
Compiti dei sottoprogrammi
Il programma che chiama o attiva un
sottoprogramma perche’ effettui il compito per
cui e’ stato costruito (per es. visualizzare una
variabile), deve fornire al sottoprogramma i dati
da elaborare (per es. la variabile da
visualizzare).
Cio’ viene effettuato nella frase di attivazione
specificando, dopo il nome del sottoprogramma
e tra parentesi tonde, i nomi dei dati al posto
dei parametri formali: questi si dicono
parametri effettivi e sostuiscono i parametri
formali tramite un meccanismo Hard-Soft.
Fond. Informatica Nettuno par. 3
66
I motivi per l' introduzione
dei sottoprogrammi.
1)
1) Si inserisce una sola volta il codice del
sottoprogramma (per es. la printf e’ un pezzo
di codice di circa 1000 istruzioni che se si
dovessero scrivere al posto del richiamo printf
.... porterebbero i programmini di stampa a
lunghezze grandiose!) Cio provoca:
RIDUZIONE di CODICE sorgente ed
eseguibile con conseguente maggior
velocita’ di esecuzione.
Fond. Informatica Nettuno par. 3
67
I motivi per l' introduzione
dei sottoprogrammi.
2) 3)
2) Il proprio sottoprogramma una volta
scritto in modo appropriato, risulta
indipendente da qualsiasi programma e
puo’ essere utilizzato tante volte e da tanti
programmi. (INDIPENDENZA)
3) Un sottoprogramma realizzato da
professionisti ad alto livello (e quindi in modo
ottimale !!) puo’ venire usato da milioni di
utenti e milioni di volte. (OTTIMALITA’)
Fond. Informatica Nettuno par. 3
68
I motivi per l' introduzione
dei sottoprogrammi.
4)
4) I meccanismi di attivazione e le rigide regole
di utilizzo del sottoprogramma, di cui solo il
nome ed i tipi dei parametri formali sono
visibili all' esterno, permettono PULIZIA
CONCETTUALE E SOSTANZIALE nella
costruzione di software: cio’ significa che con
l'uso corretto dei sottoprogrammi si ottiene un
codice di buona qualita’, facile interpretazione
ed uso. E' il primo passo verso la chiarezza e
facilita’ di documentazione che sono gli obiettivi
dell' Ingegneria del Software.
Fond. Informatica Nettuno par. 3
69
Meccanismi Hardware
L' importanza di questi benefici ha fatto si’ che
tutti gli elaboratori, fin dalla prima generazione,
contengano istruzioni macchina per eseguire l'
attivazione , il richiamo di un sottoprogramma.
Questo in linguaggio macchina e’ realizzato
tramite un salto dal MODULO chiamante a
quello chiamato lasciando pero’ MEMORIA del
punto di ritorno a cui diventa possibile tornare
dopo aver eseguito il modulo attivato. Queste
istruzioni pero’ riguardano il linguaggio
macchina che non sara’ trattato in questo
corso.
Fond. Informatica Nettuno par. 3
70
Frasi di “va e torna”
Semplificando si tratta di istruzioni macchina di
salto al sottoprogramma chiamato e di
ritorno al (sotto)programma chiamante. Ma
nei linguaggi avanzati come il C, C++, Fortran,
Pascal l’ attivazione di sottoprogrammi ha frasi
diverse. Qui interessano le frasi del C e C++
per la definizione dei moduli e la loro
attivazione che il Compilatore traduce nelle
opportune istruzioni macchina di salto a e
ritorno da sottoprogramma.
Fond. Informatica Nettuno par. 3
71
Regole del C e C++ (gia’ viste !)
Un sottoprogramma (subroutine) non puo’
essere attivato se non e’ stato dichiarato all’
inizio: la dichiarazione si effettua indicando il
seguente prototipo del sottoprogramma:
[type] subroutine name (arguments type );
NOTA: tipi (non nomi degli argomenti) separati
da virgola!! es. int elabora (char, int); oppure
void calcola(int, float*, float);
I tipi degli argomenti indicati nel prototipo
sono condizionanti: i parametri effettivi e
formali del sottoprogr. devono corrispondere a
72
loro in numero, tipo e ordine.
Attivazione in C e C++
Chi attiva il sottoprogramma? qualsiasi altro
[sotto]programma: il main per es. ma non
solo il main, anche le altre funzioni si possono
attivare tra loro.
Come si attiva un sottoprogramma? scrivendo
nel programma chiamante il nome del
sottoprogramma seguito dai parametri effettivi
separati da virgola e racchiusi tra parentesi
tonde: es. calcola (100, p*, 3.14);
Da RICORDARE però che il prototipo di calcola
DEVE essere inserito tra le dichiarazioni
Fond. Informatica Nettuno par. 3
73
GLOBALI
In C e C++, dopo aver inserito il
prototipo di una funzione
la sua definizione inizia con l’ intestazione (prima
frase) dove arguments list e’ la sequenza dei
parametri formali separati da virgola (tipo e nome);
segue il corpo come qui sotto indicato:
type function name (arguments list)
{declarations;
 function body with the use of the arguments
 return(expression);
/* type function name = type expression */
}
Il sottoprogram. che NON usa il suo nome per
restituire valori e’ di tipo void (  procedura), le
74
funzioni sono di tipo int, float, … ecc.
Funzioni & Procedure
In C e C++ se il sottoprogramma e’ una
funzione il risultato di uscita e’ affidato al
nome della funzione stessa. Ossia in ogni
Funzione il NOME e’ il veicolo di attivazione e
di trasporto del risultato in essa calcolato.
Se il sottoprogramma e’ piu’ generale (tipo
procedura Pascal) il NOME e’ il veicolo di
attivazione, ma i risultati di uscita possono
essere posti nei parametri formali purche’ sia
usato il passaggio per indirizzo (cfr.+avanti).
Fond. Informatica Nettuno par. 3
75
funzioni e procedure: esempi
Le funzioni del C o C++ sono monodrome ossia
restituiscono un singolo valore, come in
matematica y=log(x), e quindi il nome della
funzione (che e’ un identificatore come quello
di ogni variabile) identifica anche il risultato.
Le procedure del C o C++ iniziano e sono
attivabili analogamente alle funzioni col loro
nome, ma restituiscono alcuni valori ad es.
somma, media e varianza di un gruppo di dati:
3 valori che non possono essere identificati da
una sola entita’, (il nome!!!) ma da 3 che
quindi devono essere poste tra i parametri di
Fond. Informatica Nettuno par. 3
76
scambio.
Es. funzione con nome elabora
in project9.cpp di Programm3
int elabora (char carattere)
/*in questa intestaz. -preceduta dal prototipo int
elabora(char)- la lista degli argomenti e’ di un solo
argomento se no sarebbero separati da virgole */
{ int n; // n e’ variabile locale di elabora
 n=(int) carattere; // function body ...
 return(n); /* oppure return n che e’ int
come elabora: il nome elabora diventa il veicolo
per restituire il valore calcolato. Invece per
funzioni di tipo void niente return cfr. esempio
diapo seg.*/
}
Fond. Informatica Nettuno par. 3
77
void scrivi()
/* Visualizza il carattere <> 0 col suo valore numerico:
variabili globali utilizzate: car, num */
{ /* Inizio scrivi */
cout << "\nCarattere letto e Valore numerico corrispondente: ";
cout << car <<" "<< num;
} /* Fine scrivi senza return !!!*/
int elabora(char carat)
/* Esegue la conversione di carat (parametro) nel
valore numerico corrispondente secondo il codice ASCII
e lo restituisce al programma chiamante nel nome elabora */
{ /* Inizio elabora */
int n; /* var. locale di elabora */
n = (int) carat;
return (n); /* il valore di n viene restituito al main */
/* affidandolo al nome elabora=veicolo di trasmissione */
}
Fond. Informatica Nettuno par. 3
78
Funzionamento
Quando l'istruzione contenente l’ attivazione
(per es. int me= elabora(carattere);) viene
eseguita, il controllo delle operazioni passa dal
programma chiamante al programma chiamato
che viene eseguito
o fino alla fine
o fino al primo return. (....ce ne possono essere
piu’ di uno!)
In C, C++ (a differenza di altri linguaggi come
il Pascal) le funzioni non possono essere
innestate una dentro l' altra: sono tutte allo
stesso livello che si puo’ considerare
sottostante il livello del main. => E’ impossibile
attivare il main da un suo sottoprogramma! 79
Funzionamento e regole
Al main il controllo delle operazioni arriva all'
inizio (per es. dal S.O.); dal main passa al
primo sottoprogramma chiamato; da questo
puo’ passare ad un altro sottoprogramma o
tornare al main per effetto di un return o della
fine del sottoprogramma stesso, e cosi’ via.
Gli argomenti presenti nell’ intestazione del
sottoprogramma (i parametri formali) sono
nomi di variabili separati da virgole e preceduti
dal tipo. Per scrivere il corpo del sottoprogr. si
usano i suoi parametri formali. I parametri
effettivi devono corrispondere in numero,
ordine e tipo ai parametri formali che all’
attivazione sostituiscono.
Fond. Informatica Nettuno par. 3
80
/* INIZIO parte dichiarativa */
#include "stdio.h" /* Libreria richiesta: Standard Input-Output */
#include "conio.h" /* Libreria richiesta: I/O confor.*/
#include "iostream.h" // "
"
I/O del C++
/* Dichiarazione dei Prototipi dei MODULI usati */
void scrivi(char,int);
int elabora(char); ….

………
main()
{int num; char car;
…..// LETTURA DI car
num=elabora(car); scrivi (car,num);
….
void scrivi(char c, int n)
/* Visualizza il carattere <> 0 col suo valore numerico:
parametri utilizzati: c, n */
{ /* Inizio scrivi */
cout << "\nCarattere letto e Valore numerico corrispondente: ";
cout << c <<" "<< n;
} /* Fine scrivi senza return !!!*/
Fond. Informatica Nettuno par. 3
81
Dove mettere i sottoprogrammi?
 Un programma composto da diversi moduli è memorizzato in un file sequenziale
dove si trovano: il main(), il sottoprogramma ics(float,int), il sottopprogramma
ipsilon(int), la funzione int pippo(int) ….
 L’ ordine con cui i sottoprogrammi sono scritti, non ha importanza: essi vanno in
esecuzione quando sono richiamati o attivati dal main() o da qualsiasi altro
sottoprogramma. Nel main() qui sotto per es. l’ ordine di attivazione può essere:
 main()









{int m, j; float f1, f2;
…..// LETTURA DI m
ics(f1,m);
j=pippo (m); // VISUALIZZAZIONE DI m, j, f1, f2 …
…. //altre frasi con attivazione delle procedura ipsilon, ics, e ancora pippo
} // Fine main
void ipsilon (int r)
{ …. } // Fine ipsilon
void ics (float a, int b)
{ ….. } // Fine ics
L’ ordine di scrittura non ha
alcuna importanza:
importante é l’ ordine di
attivazione!

 int pippo (int param)
 {int mio=987;
 return(mio*mio*param*param);
 } // Fine pippo …..altri moduli di LETTURA e VISUALIZZAZIONE …
82
Visibilita’
SOLO il NOME del sottoprogramma ed il TIPO
dei suoi parametri formali sono VISIBILI nel
prototipo ossia all’ esterno del
sottoprogramma: rappresentano l'
INTERFACCIA del sottoprogramma !
INVISIBILI all' esterno del sottoprogr. sono i
NOMI delle variabili locali e dei parametri
formali del sottoprogramma: meccanismo di
PROTEZIONE. Conseguenza:=>Variabili del
sottoprogram. con lo stesso nome di quelle del
main sono diverse.
Fond. Informatica Nettuno par. 3
83
Il passaggio_informazioni tra
moduli non si basa sul nome
dei parametri formali, ma sulla loro posizione !!
Il passaggio dei parametri effettivi da
chiamante a chiamato puo’ avvenire:
1) per valore: non sono le variabili ad essere
trasferite, ma il loro CONTENUTO che e’
copiato nel parametro formale corrispondente.
Da cio’ segue che i valori delle variabili del
programma chiamante non vengono modificati
dall' attivita’ del sottoprogram. che lavora sui
suoi parametri formali contenenti una copia dei
parametri effettivi. E’ il passaggio standard,
Fond. Informatica Nettuno par. 3
84
ma...
Il passaggio per valore e’ un
MECCANISMO pulito, ma sprecone: duplica i
valori delle variabili ! Se venisse applicato
anche a tabelle (array) di 10000 e piu’ elementi
ci sarebbe uno spreco enorme di memoria… Si
ottiene nel modo descritto dall’ esempio:
es. prototipo: int elabora (char);
 intestazione (prima frase del sottoprogramma):
int elabora (char carattere)
con carattere = parametro formale di elabora;
attivazione (nel prg. chiamante):
 num=elabora (car); con car e num = variabili
definite da: char car; int num; nel prg. chiamante.
Fond. Informatica Nettuno par. 3
85
Il passaggio per valore nella
funzione elabora avviene
nel modo seguente: il compilatore
dal prototipo capisce che deve lavorare su un
carattere passato per valore e restituire nel
nome dalla funzione un valore intero;
quando incontra la frase: num=elabora (car);
copia il valore di car (qualunque sia: ‘a’, o ‘f’, o
…) nel parametro formale di elabora, - vedere
intestaz. di elabora int elabora (char carattere) -,
esegue il corpo di elabora e restituisce il
risultato in elabora che poi assegna a num
Fond. Informatica Nettuno par. 3
86
Il passaggio per valore di un
parametro
ad una funzione permette di:
visualizzare il valore passato;
usarlo per calcolare un risultato, che può essere
restituito al programma chiamante nel nome della
funzione.
NON ALTRO!
Per trasferire più di un valore al programma chiamante
NON SI PUO’ usare il passaggio per valore che
trasmette solo la copia dei parametri effettivi !!!
Bisogna usare un altro “marchingegno” ossia
trasmettere l’ indirizzo di tali parametri effettivi in
modo da poterli modificare. Si chiama:
Fond. Informatica Nettuno par. 3
87
Il passaggio di parametri
2) per indirizzo: non sono trasferiti i valori
delle variabili, ma il loro INDIRIZZO che e’
copiato nel parametro formale corrispondente.
Da cio’ segue: il sottoprogramma lavora sempre
sui suoi parametri formali, ma questi ora
contengono gli indirizzi delle variabili e quindi
l' attivita’ del sottoprogram. puo’ modificare le
var. originali e/o inserirci dati! ogni modifica si
riflette sull' originale! E’ un meccanismo meno
pulito, ma non sprecone! In C e C++ e’
obbligatorio per vettori, array e strutture.
Fond. Informatica Nettuno par. 3
88
Il passaggio per indirizzo
 deve essere riconosciuto dal compilatore e perciò
essere diverso dal passaggio per valore. Il compilatore lo
riconosce perché, come parametri, vengono indicati puntatori
a variabili e non variabili!
 Si usa talvolta nelle procedure di lettura come qui descritto:
 es. prototipo: void leggi ( int *); // l’ argom. e’ di tipo
puntatore a intero
 intestazione: void leggi ( int *pu) //il parametro formale pu e’
un puntatore a int, *pu è l’ intero!
 corpo { cin>>* pu; }
 attivazione: leggi (&num);
 con la var num definita nel prg. chiamante da:
 int num; e con &num indirizzo di num, indirizzo copiato nel
param. pu di tipo puntatore a int. Il dato letto è così
posizionato nella RAM all’ indirizzo pu ossia &num !!!
Fond. Informatica Nettuno par. 3
89
Altro esempio di passaggio per
indirizzo che
 si ottiene come qui descritto per la funz. cambia che oltre alla
convesione di car in valore numerico può cambiare anche car
 es. prototipo: int cambia ( char *); // l’ argom. e’ di tipo
puntatore a carattere
 intestazione: int cambia (char * puntacar) // il parametro
formale puntacar e’ un puntatore a char
 attivazione: num = cambia(&car); con le var. car e num definite
nel prg. chiamante da: char car; int num; e con &car indirizzo d
car indirizzo copiato nel param. puntacar di tipo puntatore a
char. In int cambia (char *puntacar) si può scrivere:
{int n; /* var. locale di cambia */ n =(int) (*puntacar);
 *puntacar= ‘z’; return (n); }
 In C++ c’e’ anche il passaggio per riferimento concettualmente
simile a quello per indirizzo.
90
Altro esempio di passaggio per
indirizzo che
si ottiene come qui descritto per la funz. cambia
 es. prototipo: int cambia ( char *); // l’ argom.
e’ di tipo puntatore a carattere
 intestazione: int cambia (char * puntacar) // il
parametro formale puntacar e’ un puntatore a char
 attivazione: num = cambia(&car);
con le var. car e num definite nel prg. chiamante da:
char car; int num; e con &car indirizzo di car, indirizzo
copiato nel param. puntacar di tipo puntatore a char.
 In C++ c’e’ anche il passaggio per riferimento
concettualmente simile a quello per indirizzo.
Fond. Informatica Nettuno par. 3
91
I/O di un sottoprogramma
Il passaggio di parametri evidenzia il ruolo dei
parametri stessi: un sottoprogramma per lavorare deve
ricevere in ingresso i dati da elaborare e deve
restituire in uscita i risultati prodotti. (NOTARE CHE
questo principio vale per ogni tipo di programma o
sottoprogramma ! Vedrete che anche il main ha possibili
argomenti.)
Tra i parametri si distinguono dunque quelli di ingresso
e quelli di uscita, di Input e di Output: i primi sono i
valori dati e sono passati di norma per valore, i secondi
per indirizzo: sono i risultati …ma talora i parametri
sono di Input e di Output insieme (cfr. project12 in programm3 e
diapo seg.)
92
void scambia(int *x, int *y)
/* Esegue lo scambio del valore numerico puntato da x
con il valore puntato da y */
{ /* Inizio scambia */
int com; /* variabile LOCALE di comodo per fare lo
scambio: sempre necessaria per scambiare valori*/
com = *x; // pone il valore puntato da x in com
*x = *y; /* sovrappone il valore numerico puntato da
y nel posto di memoria puntato da x .....! */
*y = com; /* sovrappone il valore numerico in com nel
posto di memoria puntato da y: scambio effettuato! */
} // Fine scambia NON SI PERDONO INFORMAZIONI!!!
Fond. Informatica Nettuno par. 3
93
Attivazione di scambia
Come si fa ?
Semplicemente scrivendo il suo nome seguito dai
parametri effettivi. Per es. volendo scambiare 10 con
100 si può scrivere
scambia (10,100) ?
NO!!! i parametri devono corrispondere al tipo
dichiarato nel prototipo che indica 2 puntatori come
parametri: quindi occorre porre x=10; y=100; e poi
scrivere scambia(&x,&y);
…e se scambia fosse una funzione che restituisce un
char (S per scambio fatto, N per scambio saltato) ?
char scambia(…) va attivata con char c =scambia(…)
che ritorna un carattere da assegnare a c.
Fond. Informatica Nettuno par. 3
94
REMEMBER
In ogni Funzione il NOME e’ il veicolo
della sua attivazione e di trasporto del
risultato in essa calcolato.
In ogni Procedura il NOME e’ il veicolo
della sua attivazione: il trasporto dei risultati
in essa calcolati e’ generalmente affidato a
parametri passati per indirizzo.
Esempi in programm3: project9-13
Fond. Informatica Nettuno par. 3
95
Riflessione
Quando si usera’ una procedura con prototipo
come void calcola(int, float*, float*)
e quando si usera’ una procedura con prototipo
come float valcalcol(int, int*, float*)
e quando si usera’ una procedura con prototipo
come int valori(int*, float*,float, float)
???
(Vedere anche gli esercizi proposti nella diapo 29)
Fond. Informatica Nettuno par. 3
96
A proposito delle funzioni
A qualcuno piace scrivere in C o C++ i
programmi alla maniera dei programmi Pascal
dove la funzione principale (ossia il main) si
pone alla fine dell’ intero programma facendola
precedere dalle altre funzioni. In tal modo, con
alcuni compilatori (per es. TURBOC) si possono
omettere le dichiarazioni delle funzioni dato che
il compilatore le riconosce via via che le
incontra. E’ conveniente ? Lo SEMBRA, ma e’
meglio NON seguire questo metodo.
Perche’ ?
Fond. Informatica Nettuno par. 3
97
Impostazione da evitare per
2 motivi
Il primo motivo e’ che ogni funzione puo’
attivare anche funzioni definite
successivamente e quindi, se non dichiarate,
ignote al compilatore che non le sa riconoscere;
il secondo riguarda la modularita’ tipica del C,
C++ che permette di compilare separatamente
le varie funzioni (per es. su file diversi come le
funzioni di libreria). Cio’ si puo’ realizzare meglio
se si dichiarano inizialmente al compilatore le funzioni
che il programma richiede.
Fond. Informatica Nettuno par. 3
98
Selezione multipla e frase
switch: sintassi ed esempio
switch (<espressione>)
{ case <costante 1>: <frase 1>; break;
 case <costante 2>: <frase 2>; break;
 ...
case <costante n>: <frase n>; break;
default: <frase>
}
Ricordare che <frase i> e’ una singola istr.
o in generale un blocco di istruzioni
Fond. Informatica Nettuno par. 3
99
Significato anche di default e
break: programm4 project18-21
E’ calcolata (<espressione>) che ha la funzione
di selettore e deve essere integrale (int o char)
se il risultato e’ il valore <costante i> viene
eseguita la <frase i> associata e quindi break
fa uscire dal blocco di switch; se mancasse
break verrebbero eseguite tutte le frasi
seguenti la i-esima: un perdi-tempo assurdo !
Invece se il risultato non corrisponde ad alcuna
<costante i> viene eseguita la frase associata a
default e si esce dal switch: questa e’ una
clausola opzionale,
ma comoda.
Fond. Informatica Nettuno par. 3
100
Break e altro
La frase break si può usare anche in cicli while,
do… while,
for: vedere project 20 - 22 di programm4 dove si esce con un
break da un ciclo infinito come qui riportato più semplicemente
con la funzione (prototipo) int leggo(); Come scriverla?
forever
 { num = leggo(); // il valore digitato è assegnato a num

scriv_inter(num); // passaggio per valore

switch (num)

{

case 1: cout <<"\nnumero 1 e ris: "; ris =
elabora(num); cout <<ris; break;

case 2: cout <<"\nnumero 2 e ris: "; ris =
elabor1(num); cout <<ris; break;

default: cout <<"\n intero non previsto\n";

}

if (num==999)break;
}
Fond. Informatica Nettuno par. 3
101
Esercizi
Utilizzando la frase break rifare il programma
project14.cpp inserendola opportunamente;
Utilizzando la frase switch …. case e break
rifare il programma richiesto alla diapo 59 con
le funzioni scritte per calcolare le aree di alcune
figure geometriche inserendo pero’ anche una
funzione di scelta che chieda all’ utente quale
area vuole e restituisca al main l’ indicazione
ottenuta. Il main deve quindi attivare solo la
funzione che calcola l’area voluta e
visualizzarla.
Fond. Informatica Nettuno par. 3
102
Altri Esercizi proposti
Ora che le frasi più importanti del C e C++ sono
state
 presentate, utilizzatele per costruire
programmi che risolvano i problemi matematici
incontrati nei vostri studi.
Esempi:
Risoluzione di un’ equazione di secondo grado;
calcolo del M.C.D. tra due interi e del loro m.c.m.
studio di funzioni quadratiche e/o di altro tipo
trovando per esempio le zone del piano ove sono
le radici…
Fond. Informatica Nettuno par. 3
103
Scarica

Fond3 - UniNa STiDuE