• Non ci sono risultati.

Programmazione Procedurale in Linguaggio C++

N/A
N/A
Protected

Academic year: 2021

Condividi "Programmazione Procedurale in Linguaggio C++"

Copied!
25
0
0

Testo completo

(1)

G. Mecca – Università della Basilicata – mecca@unibas.it

Programmazione Procedurale in Linguaggio C++

Sottoprogrammi Parte 7 Conclusioni

versione 2.1

Questo lavoro è concesso in uso secondo i termini di una licenza Creative Commons (vedi ultima pagina)

Sommario

m

Ricapitolazione

m

Convenzioni di Stile

m

Alcune Tecniche Notevoli

ðUtilizzo delle Costanti Numeriche ðGenerazione di Numeri Casuali

m

Errori Frequenti

Sottoprogrammi: Conclusioni >> Sommario

(2)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 3

Ricapitolazione

m

Sottoprogrammi

ðuna funzionalità essenziale dei linguaggi di programmazione procedurale

ðconsentono di dividere un’applicazione in moduli (programma principale e

sottoprogrammi)

ðche comunicano attraverso il passaggio dei parametri (meccanismo fondamentale)

Sottoprogrammi: Conclusioni >> Ricapitolazione

Ricapitolazione

m

Due categorie

ðfunzioni: blocchi di istruzioni per il calcolo di un valore

ðprocedure: blocchi di istruzioni che realizzano opportune operazioni

m

In entrambi i casi

ðpossono essere predefiniti (parte di una libreria di sistema)

ðoppure definiti dall’utente

Sottoprogrammi: Conclusioni >> Ricapitolazione

(3)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 5

Ricapitolazione

m

Definizione di un sottoprogramma

ðintestazione e corpo

m

Intestazione

ðtipo del risultato o void ðnome

ðelenco dei parametri (tipo e nome)

m

Corpo

ðblocco di istruzioni

Sottoprogrammi: Conclusioni >> Ricapitolazione

Ricapitolazione

m

Utilizzo di un sottoprogramma

ðchiamata

ðnome e argomenti

m

Utilizzo delle funzioni

ðall’interno di espressioni per calcolare un valore

m

Utilizzo delle procedure

ðcome istruzioni a sé stante

Sottoprogrammi: Conclusioni >> Ricapitolazione

(4)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 7

Ricapitolazione

m

Parametri

ðspazi nella memoria

m

Parametri standard (o “per valore”)

ðvengono usati come dati ordinari del modulo

m

Parametri per riferimento (“per variabile”)

ðsono intermediari tra il proc. e un altro dato ðpossono essere utilizzati per modificare il

corrispondente argomento

Sottoprogrammi: Conclusioni >> Ricapitolazione

Ricapitolazione

m

Programmazione modulare

ðapproccio alla programmazione procedurale basato sui sottoprogrammi

m

Idea

ðindividuare i passi (le funzionalità) fondamentali dell’applicazione

ðcostruire un opportuno sottoprogramma per ciascuna funzionalità

ðmetodologia incrementale

Sottoprogrammi: Conclusioni >> Ricapitolazione

(5)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 9

Ricapitolazione

m

Funzionalità avanzate

ðpossibilità offerte dalla prog. modulare

m

Utilizzo di dati globali

ðutile per definire costanti globali ðregole di visibilità

m

Compilazione separata

ðcreazione di librerie (file di intestazioni) ðriuso del codice

Sottoprogrammi: Conclusioni >> Ricapitolazione

La Metodologia di Sviluppo

m Analisi delle specifiche

ðeliminazione delle ambiguità ðdati di ingresso e dati di uscita

m Scelta dell’algoritmo

ðstrategia per la rappresentazione dei dati ðstrategia per le operazioni

m Scrittura del codice

m Compilazione e collegamento

m Esecuzione e verifica

Sottoprogrammi: Conclusioni >> Ricapitolazione

approccio integrato e incrementale

(6)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 11

La Metodologia di Sviluppo

Sottoprogrammi: Conclusioni >> Ricapitolazione

Analisi dei Requisiti

Scelta dell’Algoritmo e Scrittura del Programma

Compilazione e Collegamento

Esecuzione e Verifica

Uso e Manutenzione errori

sintattici

errori logici codice

sorgente

codice eseguibile - eliminazione

delle ambiguità - analisi dei dati

di ingresso e uscita

- strategia di rappresentazione - strategia di

operazioni

Convenzioni di Stile

m

Ulteriori convenzioni di stile

ðorganizzazione del file e spazi bianchi ðnomi delle costanti

ðnomi dei sottoprogrammi

m

Si aggiungono a quelle precedentemente definite

Sottoprogrammi: Conclusioni >> Convenzioni di Stile

(7)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 13

Organizzazione del File

m Commento iniziale

ðlinea vuota

m Direttive import

ðlinea vuota

m Definizione delle costanti globali

ðlinea vuota

m Prototipi

ðlinea vuota

m main

ðlinea vuota

m Codice delle procedure e delle funzioni

Sottoprogrammi: Conclusioni >> Convenzioni di Stile

>> morraCinese4.cpp

Convenzioni di Stile

m

Nome delle costanti

ðmaiuscolo

ðes: VINCEILCOMPUTER

m

Nome dei sottoprogrammi

ðnotazione “cammello”

ðlettere minuscole (come le variabili) ðes: schermoIniziale

Sottoprogrammi: Conclusioni >> Convenzioni di Stile

(8)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 15

Alcune Tecniche Notevoli

m

La Morra Cinese

ðdue tecniche notevoli

m

Oggetto da giocare ed esito della mano

ðutilizzo di costanti simboliche intere

ðper migliorare la leggibilità del codice

m

Giocata del computer

ðgenerazione di numeri casuali

ðtecnica frequentemente usata nei giochi

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

Utilizzo di Costanti Simboliche Intere

m

Nel programma

ðè necessario gestire dati con valori particolari ðinsieme finito e limitato di valori possibili

m

Finora

ðdati tradizionali; es: raggio di una circonferenza, coordinata di un punto

ðpossono assumere un insieme molto ampio di valori che variano con continuità

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

(9)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 17

Utilizzo di Costanti Simboliche Intere

m

Oggetti della giocata

ðvalori possibili: carta, forbici, sasso

m

Esito della giocata

ðvalori possibili: vince il computer, vince il giocatore, pareggio

m

Dati particolari

ðdati discreti con valori “enumerabili”

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

Utilizzo di Costanti Simboliche Intere

m

Dati di tipo enumerabile

ðo “enumerazioni”

ðdati che possono assumere un insieme limitato di valori discreti

ði valori possono essere elencati

m

Altri esempi

ðgiorni della settimana, mesi dell’anno ecc.

m

Come rappresentarli nel programma ?

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

(10)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 19

Utilizzo di Costanti Simboliche Intere

m Soluzione 1: stringhe

ðidea: descrivo ciascun valore con una stringa ðstring giocata; es: “carta”, “forbici”, “sasso”

ðstring esitoMano; es: “pareggio”, “vince il computer”

m Vantaggi

ðmodo naturale per rappresentare i valori

m Svantaggi

ðmanipolare le stringhe è poco naturale (es: il giocatore deve digitare ogni volta il nome dell’oggetto che vuole giocare)

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

Utilizzo di Costanti Simboliche Intere

m Soluzione 2: numeri interi

ðidea: associo un valore intero a ciascun valore ðint giocata; es: 1=carta, 2=forbici, 3=sasso

ðint esitoMano; es: 1=vince il computer, 2=vince il giocatore, 3=pareggio

m Vantaggi

ðmanipolare i numeri è più naturale

m Svantaggi

ðbisogna ricordarsi il significato dei valori (quale numero è associato a ogni valore)

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

(11)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 21

Utilizzo di Costanti Simboliche Intere

m

Una soluzione di compromesso

ðutilizzare costanti globali intere

m

Esempio

const int CARTA=1;

const int FORBICI=2;

const int SASSO=3;

const int VINCEILCOMPUTER=1;

const int VINCEILGIOCATORE=2;

const int PAREGGIO=3;

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

Utilizzo di Costanti Simboliche Intere

m

Questa soluzione

ðha i vantaggi dell’utilizzo dei numeri interi ði dati sono più semplici da utilizzare delle

stringhe

ðsenza gli svantaggi

ðil nome della costante consente di disinteressarsi del valore intero scelto

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

(12)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 23

Esempio: Esito di una Mano

int controllaEsito(int giocataComp, int giocataGioc) { int esito = VINCEILCOMPUTER;

if (giocataGioc == giocataComp) { esito = PAREGGIO;

} else if ((giocataGioc == CARTA) && (giocataComp == SASSO)) { esito = VINCEILGIOCATORE;

} else if ((giocataGioc == FORBICI)&&(giocataComp == CARTA)) { esito = VINCEILGIOCATORE;

} else if ((giocataGioc == SASSO)&&(giocataComp == FORBICI)) { esito = VINCEILGIOCATORE;

}

return esito;

}

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

Utilizzo di Costanti Simboliche Intere

m

Annotazione

ðil sottoprogramma precedente è scritto secondo una tecnica particolare, detta

“ipotesi e verifica”

m

Ipotesi e Verifica

ðper semplificare il controllo formulo un’ipotesi iniziale (es: ha vinto il computer)

ðpoi verifico solo se l’ipotesi è vera o meno ðquesto mi evita di scrivere vari if in più

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

(13)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 25

Generazione di Numeri Casuali

m

Molto spesso nei programmi

ðè necessario effettuare scelte casuali ðprogrammi che simulano il mondo reale

m

Soluzione tipica

ðviene generato un numero a caso

ðal numero a caso viene associata la scelta ðcon una tecnica simile a quella appena

discussa

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

Generazione di Numeri Casuali

m

Generazione di numeri casuali in C++

ðbasata su sottoprogrammi predefiniti ðun processo a due passi

m

Primo passo: inizializzazione

ðscegliere un valore casuale iniziale per

“inizializzare” l’algoritmo di generazione

m

Secondo passo: generazione dei numeri

ðutilizzare la funzione predefinita rand() per

generare la sequenza di numeri casuali

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

(14)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 27

Generazione di Numeri Casuali

m

Primo passo: inizializzazione

ðdeve essere effettuato una sola volta,

all’inizio dell’applicazione, prima di generare il primo numero casuale

ðserve a fornire al calcolatore una “base”

(“seme”) da cui partire per generare tutti gli altri numeri della serie

ðaltrimenti il calcolatore genererebbe sempre gli stessi numeri (comportamento

“deterministico”)

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

Generazione di Numeri Casuali

m

Problema

ðcome scegliere un valore iniziale (o “seme”) davvero casuale che vari tra un’esecuzione all’altra del programma ?

m

Risposta

ðè possibile utilizzare l’orologio di sistema (ora in millisecondi)

ðil valore cambia sicuramente da esecuzione a esecuzione

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

(15)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 29

Generazione di Numeri Casuali

m

I sottoprogrammi necessari

ðint time(): funzione che restituisce il valore dell’orologio di sistema

ðvoid srand(int valore): procedura che

inizializza la generazione di numeri casuali con il valore iniziale specificato

m

Esempio

int seme = time(NULL);

srand(seme);

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

Generazione di Numeri Casuali

m

Secondo passo: generazione dei numeri

ðgenerare i numeri usando la funzione

predefinita int rand()

ðogni volta che la funzione viene chiamata, restituisce un numero intero diverso

uniformemente distribuito tra 0 e una

costante RAND_MAX (normalmente 32767)

m

Nota: apparentemente...

ðcomportamento diverso dalle altre funzioni

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

(16)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 31

Generazione di Numeri Casuali

m

Esempio:

ðsupponendo di avere inizializzato il generatore di numeri casuali

cout << rand();

cout << rand();

cout << rand();

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

I esecuzione 29

123 76

II esecuzione 12

333 3245

Generazione di Numeri Casuali

m

In generale

ðserve ottenere numeri compresi tra 1 ed n ðes: Morra Cinese: tra 1 e 3

m

Per ottenere numeri tra 1 ed n

rand()% n + 1

m

Esempio

cout << rand() % 3 + 1;

cout << rand() % 3 + 1;

cout << rand() % 3 + 1;

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

il modulo restituisce valori tra 0 e n-1

2 76

1 123

3 29

rand() % 3 + 1 rand()

(17)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 33

Generazione di Numeri Casuali

void inizioGioco(string& nome) { int seme = time(NULL);

srand(seme);

schermoIniziale(nome);

return;

}

int generaGiocataComputer() { int giocata;

giocata = rand() % 3 + 1;

return giocata;

}

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

Generazione di Numeri Casuali

m

Nota

ðnonostante la funzione rand() abbia

apparentemente un funzionamento diverso da quello delle altre funzioni, non è così ðanche rand() è basata su un algoritmo

preciso, ovvero a parità di valore del seme, genera sempre la stessa sequenza

ðquello che cambia è il valore del seme

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

(18)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 35

Generazione di Numeri Casuali

m

Un esempio

Sottoprogrammi: Conclusioni >> Tecniche Notevoli

#include <iostream.h>

void main() { srand(100);

cout << rand() << endl;

cout << rand() << endl;

cout << rand() << endl;

}

I esecuzione 11548 3973 4846

II esecuzione 11548 3973 4846

Errori Frequenti

m

Alcuni errori frequenti

m

Errori sintattici

ðerrori nelle chiamate

ðerrori nella definizione e nei prototipi

m

Errori logici

ðerrori nell’uso delle proc. e delle funzioni ðerrori di duplicazione del codice

ðerrori nell’uso dei parametri

Sottoprogrammi: Conclusioni >> Errori Frequenti

(19)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 37

Errori Sintattici

m Nome scorretto del sottoprogramma

ðes: d = discriminate(a1, b1, c1);

ðError E2268 prova.cpp 10: Call to undefined function 'discriminate' in function main()

m Errore nel numero dei parametri

ðes: d = discriminante(a1, b1);

ðError E2193 prova.cpp 10: Too few parameters in call to 'discriminante(float,float,float)' in function main()

Sottoprogrammi: Conclusioni >> Errori Frequenti

Errori Sintattici

m

Errore nel tipo dei parametri

ðes: float a1, b1; string c1;

ðd = discriminante(a1, b1, c1);

ðError E2034 prova.cpp 10: Cannot convert 'char *' to 'float' in function main()

ðError E2342 prova.cpp 10: Type mismatch in parameter 'c' (wanted 'float', got 'char *') in function main()

Sottoprogrammi: Conclusioni >> Errori Frequenti

(20)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 39

Errori Sintattici

m

Attenzione

ðutilizzando i prototipi, a volte si verificano errori se viene modificato il sottoprogramma e non il prototipo

m

Esempio:

void sceltaMenu(int &scelta);

void main() {...}

int schermoSceltaMenu(string nome) { ...

}

Sottoprogrammi: Conclusioni >> Errori Frequenti

prototipo e intestazione sono disallineati (nome, parametri,

tipo di ritorno)

Errori Sintattici

m Caso n.1

ðse le chiamate rispecchiano il prototipo, la compilazione si verifica senza problemi ðma c’è un errore a tempo di collegamento ðError: Unresolved external ‘sceltaMenu(int&)'

referenced from E:\TMP\PROVA.OBJ

m Caso n.2

ðse le chiamate rispecchiano l’intestazione

ðError E2268 prova.cpp 10: Call to undefined function

‘schermoSceltaMenu' in function main()

Sottoprogrammi: Conclusioni >> Errori Frequenti

(21)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 41

Errori Logici

m

Errore principale

ðutilizzare le funzioni come se fossero procedure

ðes: void main() {

float a1, b1, c1;

leggiEquazione(a1, b1, c1);

discriminante(a1, b1, c1);

...

ðquesto tipo di chiamata non ha senso: non viene utilizzato il valore della funzione

Sottoprogrammi: Conclusioni >> Errori Frequenti

Errori Logici

m

Un altro errore frequente

ðduplicazione del codice

m

Obiettivi dei sottoprogrammi

ðguidare il processo di scrittura del codice (ogni passo un sottoprogramma)

ðevitare di riscrivere il codice più volte

m

Di conseguenza

ðdurante la scrittura bisogna evitare di riscrivere due volte lo “stesso” sottoprog.

Sottoprogrammi: Conclusioni >> Errori Frequenti

(22)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 43

Errori Logici

m Esempi

ð“acquisire dalla tastiera i dati di due rettangoli nel piano e analizzarli”

ð“acquisire da un file i dati di una serie di giocate del totocalcio e calcolare i punteggi”

ð“acquisire i dati di un triangolo, stamparli, modificare i vertici e stampare i dati del nuovo triangolo” (un solo sottoprogramma di stampa)

m In tutti questi casi

ðgli stessi sottoprogrammi possono essere utilizzati con argomenti diversi (vedi equazioni)

Sottoprogrammi: Conclusioni >> Errori Frequenti

Errori Logici

m

Altri errori nell’uso dei parametri

ðnumero eccessivo di parametri per un

sottoprogramma (parametri inutili) – già discusso

ðscambiare parametri standard e parametri per riferimento – già discusso

Sottoprogrammi: Conclusioni >> Errori Frequenti

(23)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 45

Esempio di Parametro Inutile

float discriminante (float a, float b, float c float d) {

d = b*b-4*a*c;

return d;

}

void main() {

float a1, b1, c1;

float a2, b2, c2;

float d;

...

if (discriminante(a1, b1, c1, d) >= 0 ...

Sottoprogrammi: Conclusioni >> Errori Frequenti

d dovrebbe essere una variabile locale

void nuovaMano( string nome, int& punteggioComputer, int& punteggioGiocatore, int& pareggi int giocataComputer ) {

int giocataGiocatore;

int esito;

giocataComputer = generaGiocataComputer();

giocataGiocatore = schermoMenuMano(nome);

esito = controllaEsito(giocataComputer, giocataGiocatore);

schermoEsitoMano(nome,esito,giocataComputer,giocataGiocatore);

if (esito == 1)

punteggioComputer++;

else if (esito == 2) punteggioGiocatore++;

else

pareggi++;

return;

}

Esempio di Parametro Inutile

Sottoprogrammi: Conclusioni >> Errori Frequenti

giocataComputer dovrebbe essere

una variabile locale

(24)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 47

Esempio di Errore

le1. void leggiEquazione

(float a, float &b, float &c) { le2. cout << “Coefficienti ? ";

le3. cin >> a;

le4. cin >> b;

le5. cin >> c;

le6. return;

le7. }

m1. void main() {

m2. float a1, b1, c1;

m3. float a2, b2, c2;

m4. float x1, y1, x2, y2;

m5. leggiEquazione(a1, b1, c1);

m6. leggiEquazione(a2, b2, c2);

m7. if (...)

Sottoprogrammi: Conclusioni >> Errori Frequenti

Al termine dell’esecuzione - il primo valore acquisito dalla tastiera nella procedura viene perso

- il valore di a1 e di a2 non è cambiato

Riassumendo

m

Ricapitolazione

m

Convenzioni di Stile

m

Alcune Tecniche Notevoli

ðUtilizzo delle Costanti Numeriche ðGenerazione di Numeri Casuali

m

Errori Frequenti

Sottotitolo >> Sommario

(25)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 49

Termini della Licenza

m This work is licensed under the Creative Commons Attribution- ShareAlike License. To view a copy of this license, visit

http://creativecommons.org/licenses/by-sa/1.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

Termini della Licenza

m Questo lavoro viene concesso in uso secondo i termini della licenza “Attribution-ShareAlike” di Creative Commons. Per ottenere una copia della licenza, è possibile visitare

http://creativecommons.org/licenses/by-sa/1.0/ oppure inviare una lettera all’indirizzo Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

Riferimenti

Documenti correlati

Concetti Introduttivi: Linguaggi &gt;&gt; Ciclo di Vita di un Programma.. Mecca - Programmazione Procedurale in Linguaggio

Strutture di Controllo: Conclusioni &gt;&gt; Convenzioni di Stile.. Mecca - Programmazione Procedurale in Linguaggio C++ 11. Convenzioni

il sottoprogramma lavora su tre dati di tipo float chiamati a,b,c attraverso cui è possibile modificare i corrispondenti argomenti. istruzione

Sottoprogrammi: Metodologia di Sviluppo &gt;&gt; Tecniche di Test e

ðDefinizione di Funzioni ðDefinizione di Procedure ðChiamata di Funzioni ðChiamata di Procedure ðPassaggio dei Parametri ðProgrammazione Modulare. Termini

Strutture di Dati: Lista &gt;&gt; Rappresentazione con Record e Array. ATTENZIONE ai

Strutture di Dati: Lista &gt;&gt; Inserimenti e Cancellazioni. Mecca - Programmazione Procedurale in Linguaggio

Strutture di Dati: Lista &gt;&gt; Gestione dei File. i conta il numero di valori prelevati dal