Perrone - Il Cuore Indurito Del_Faraone. Origene e Il Problema Del Libero Arbitrio @
1 Funzioni e Procedure in C Corso di Informatica A Vito Perrone.
-
Upload
nunziatina-orlando -
Category
Documents
-
view
216 -
download
0
Transcript of 1 Funzioni e Procedure in C Corso di Informatica A Vito Perrone.
1
Funzioni e Procedure in C Funzioni e Procedure in C
Corso di Informatica A
Vito Perrone
2Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
IndiceIndice• Motivazioni• Il concetto di sottoprogramma• Struttura completa di un programma C• Le funzioni
– Esecuzione delle funzioni e passaggio dei parametri
• Le procedure • Il passaggio dei parametri per indirizzo
• Aspetti avanzati nell’uso dei sottoprogrammi
3Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Motivazioni
• Riusabilità (scrivere una sola volta del codice usato più volte)
• Astrazione (esprimere in modo sintetico operazioni complesse)
• Due tipi di sottoprogrammi– Funzioni
– Procedure
4Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Motivazioni: un esempio
#define MaxNumMov 10000typedef struct {
int giorno;int mese;int anno;
} Data;typedef struct {
char causale[100];Data data;float importo;
} Movimento;typedef struct {
int numMovimenti;Movimento dati[MaxNumMov];
} ElencoMovimenti;ElencoMovimenti entrate;ElencoMovimenti uscite;float saldo;
Come calcolare il totale delle entrare e delle uscite?
Come calcolare il totale delle entrare e delle uscite?
5Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Motivazioni: un esempio
POSSIBILE SOLUZIONE….int i;float totEntrate, totUscite;totEntrate = 0;for(i=0; i<entrate.numMovimenti; i++) {totEntrate += entrate.dati[i].importo;}totUscite = 0;for(i=0; i<uscite.numMovimenti; i++) {totUscite += uscite.dati[i].importo;}saldo = totEntrate – totUscite;….
6Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Motivazioni: un esempio
• Ma ci piacerebbe di più scrivere:
saldo = tot(entrate) – tot(uscite);mettendo a fattor comune il codice “simile”
• Ma per fare questo dobbiamo definire un sottoprogramma che calcola “tot”– Si tratta di un programma “asservito” al
programma principale
• Il sottoprogramma deve essere prima di tutto definito e poi può essere invocato (chiamato)
7Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Struttura di un programma C direttive; parte dichiarativa globale
contiene la dichiarazione di tutti gli elementi che sono condivisi dal programma principale e dai sottoprogrammi.
main definizioni di sottoprogrammi funzioni o procedure , a seguire il
programma principale. Il main è un -particolare- sottoprogramma tra gli altri
il main e ciascun sottoprogramma possono usare tutti e soli gli elementi che sono stati dichiarati nella loro propria parte dichiarativa, nonché quelli che sono stati dichiarati nella parte dichiarativa globale
8Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Funzioni (1)• Definizione (semplificata) di una funzione:
testata (header); due parti, racchiuse fra parentesi graffe:
• la parte dichiarativa (detta parte dichiarativa locale);• la parte esecutiva (detta corpo della funzione).
• La testata contiene: – tipo del risultato, – identificatore del sottoprogramma, – lista dei parametri -formali- cui la funzione viene applicata con il
relativo tipo; – (dominio e codominio della funzione)– Ogni parametro formale è un identificatore di tipo seguito da un
identificatore.– Una funzione non può restituire array o funzioni ma può restituire un
puntatore a qualsiasi tipo.
9Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Funzioni (2)
int FatturatoTotale(ElencoFatture par)
boolean Precede(StringaCaratteri par1, StringaCaratteri par2)
boolean Esiste(int par1, SequenzaInteri par2)/* Stabilisce se il primo parametro, di tipo intero, appartiene
all'insieme di interi contenuti nel secondo parametro: una sequenza di interi */
MatriceReali10Per10 *MatriceInversa(MatriceReali10Per10 *par)
10Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Funzioni (3)
int FatturatoTotale (ElencoFatture parametro){
int Totale, Cont;
Totale = 0;for (Cont = 0; Cont < parametro.NumFatture; Cont++)
Totale = Totale + parametro.Sequenza[Cont].Importo;return Totale;
}
11Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Funzioni (4)
int RadiceIntera (int par){
int cont;
cont = 0;while (cont*cont <= par)
cont = cont + 1;return (cont – 1);
}
12Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Chiamata delle funzioni
• x = sin(y) – cos(PiGreco – alfa);• x = cos(atan(y) – beta);• x = sin(alfa);• y = cos(alfa) – sin(beta);• z = sin(PiGreco) + sin(gamma);
• RisultatoGestione = FatturatoTotale(ArchivioFatture) – SommaCosti(ArchivioCosti);
• Det1 = Determinante(Matrice1);• Det2 = Determinante(MatriceInversa(Matrice2));
• TotaleAssoluto = Sommatoria(Lista1) + Sommatoria(Lista2);• ElencoOrdinato = Ordinamento(Elenco);• OrdinatiAlfabeticamente = Precede(nome1, nome2);
13Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
• All’interno di un programma C una funzione può essere chiamata purché risulti definita oppure dichiarata.
• definizione e dichiarazione non sono termini equivalenti
• la dichiarazione di una funzione (prototipo) si limita a richiamarne la testata.
• Utile quando la chiamata di una funzione precede, nel codice, la definizione della funzione, oppure le funzioni utilizzate da un programma sono definite in file propri del sistema C (e.g., le funzioni di libreria).
• Aiuta il compilatore ed è buono stile di programmazione
Prototipo delle funzioni
14Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Esecuzione delle funzionie passaggio dei parametri (1)
/* Programma Contabilità (1) *//* Parte direttiva */
#include <stdio.h>#define MaxNumFatture 1000
/* Parte dichiarativa globale */typedef char String [30];typedef struct { String Indirizzo;
int Ammontare;Data DataFattura;
} DescrizioneFatture;typedef struct { int NumFatture;
DescrizioneFatture Sequenza[MaxNumFatture];} ElencoFatture;
15Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
/* Programma Contabilità (2)*/main() {
ElencoFatture ArchivioFatture1, ArchivioFatture2;int Fatt1, Fatt2, Fatt;
int FatturatoTotale(ElencoFatture parametro);/* Prototipo della funzione FatturatoTotale */
....Fatt1 = FatturatoTotale(ArchivioFatture1);Fatt2 = FatturatoTotale(ArchivioFatture2);Fatt = Fatt1 + Fatt2;....
}/* Fine del main del programma Contabilità */
Esecuzione delle funzionie passaggio dei parametri (2)
16Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
/* Definizione della funzione FatturatoTotale */
int FatturatoTotale (ElencoFatture parametro){
int Totale, Cont;....return Totale;
}
Esecuzione delle funzionie passaggio dei parametri (3)
17Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Ambienti di esecuzione, macchine astratte master e slave
ArchivioFatture1
ArchivioFatture2
Fatt1
Fatt2
Parametro
Totale
Cont
FatturatoTotale
18Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Esecuzione delle funzionie passaggio dei parametri (4)
x = sin(atan(y) – acos(z));
Equivale a :
temp1 = atan(y); temp2 = acos(z);
temp3 = temp1 – temp2
x = sin(temp3);
19Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Procedure (1)
typedef enum {VerdeSinistra, VerdeDestra} TipoStato;typedef struct { TipoStato Stato;
int CodaSinistra; int CodaDestra;} TipoSemaforo;
TipoSemaforo Semaforo;
AggiornaSemaforo :
• Diminuisce di un valore costante il campo CodaSinistra o CodaDestra a seconda che lo stato del semaforo sia VerdeSinistra o VerdeDestra;
• Legge dal terminale i valori NuoviArriviSinistri e NuoviArriviDestri e li somma, rispettivamente, a CodaSinistra e CodaDestra;
• Dà al campo Stato il valore VerdeSinistra se CodaSinistra > Coda Destra e viceversa.
20Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Procedure (2)
/*Programma Contabilità (1)*/
#include<stdio.h>#define MaxNumFatture 1000...typedef struct { String indirizzo;
int ammontare;Data DataFattura;
} DescrizioneFatture;typedef struct { int NumFatture;
DescrizioneFattureSequenza[MaxNumFatture];
} ElencoFatture;
ElencoFatture ArchivioFatture;
21Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
/*Programma Contabilità (2)*/
main(){
Data DataOdierna;DescrizioneFatture Fattura1, Fattura2;void InserisciFattura(DescrizioneFatture
Fattura);boolean Precede(Data Num1, Data Num2);
/*Stabilisce se Num1 precede Num2*/…
/* Sequenza di istruzioni che leggono i datidi una fattura in Fattura1 */
InserisciFattura(Fattura1);...
/* Sequenza di istruzioni che leggono i dati di una fattura in Fattura2 */
if (Precede(Fattura2.DataEmissione, DataOdierna))InserisciFattura(Fattura2);
...}
Procedure (3)
22Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
/*Programma Contabilità (3)*/
void InserisciFattura(DescrizioneFatture Fattura){
if (ArchivioFatture.NumFatture == MaxNumFatture)printf("L'archivio è pieno.\n");
else{
ArchivioFatture.NumFatture = ArchivioFatture.NumFatture + 1;ArchivioFatture.Sequenza[ArchivioFatture.NumFatture–1] =
Fattura;}
}
Procedure (4)
23Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Ambiente globale
ArchivioFatture
Ambiente locale di InserisciFattura
Ambiente di main di Programma Contabilità
DataOdierna Fattura
Fattura1
Fattura2
...
Esecuzione delle procedure
24Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Passaggio parametri per indirizzo (1)
void InserisciFattura( DescrizioneFatture Fattura, ElencoFatture ArchivioFatture)
/*In questa versione della procedura, sia la fattura da inserire sia l'archivio in cui inserirla sono dei parametri */
{
if (ArchivioFatture.NumFatture == MaxNumFatture)
printf("L'archivio è pieno.");
else
{
ArchivioFatture.NumFatture = ArchivioFatture.NumFatture + 1;
ArchivioFatture.Sequenza[ArchivioFatture.NumFatture–1] = Fattura;
}
}
/*Fine della procedura InserisciFattura */
InserisciFattura (Fattura1, ArchivioFatture5); Non funziona! Perché?
25Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Ind(x) = 2034
Parametri attuali Parametri formali
Passaggio per valore
243 243
Ind(y) = 1004Passaggio per indirizzo
y A
413 1004
Passaggio parametri per indirizzo (2)
26Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
In C la modalità di passaggio dei parametri a un sottoprogramma è sempre quella di passaggio per valore. Per simulare il passsaggio per indirizzo:
• utilizzare il costruttore puntatore per la definizione dei parametri formali della funzione;
• usare l’operatore di dereferenziazione di puntatore (operatore * o –>) all’interno del corpo della funzione;
• passare al momento della chiamata della funzione come parametro attuale un indirizzo di variabile (usando l’operatore &).
Passaggio parametri per indirizzo (3)
27Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
/*Programma Contabilità (1)*/...main(){ElencoFatture ArchivioFatture5;
/* Qui ArchivioFatture5 è una variabile locale del main. */Data DataOdierna;DescrizioneFatture Fattura1, Fattura2;
void InserisciFattura ( DescrizioneFatture Fattura,ElencoFatture *PointToArchivioFatture);/* Prototipo della procedura InserisciFattura */
Boolean Precede(Data Num1, Data Num2);/* Prototipo della funzione Precede */
Passaggio parametri per indirizzo (4)
28Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
/*Programma Contabilità (2)*/...
/* Sequenza di istruzioni che leggono i dati di una fattura in Fattura1 */
InserisciFattura(Fattura1, &ArchivioFatture5);/* Chiamata della procedura InserisciFattura: alla procedura viene
passato il valore di Fattura1 e l'indirizzo di ArchivioFatture5 */...
/* Sequenza di istruzioni che leggono i dati di una fattura in Fattura2 */
if (Precede(Fattura2.DataEmissione, DataOdierna)InserisciFattura(Fattura2,&ArchivioFatture5);
/* Nuova chiamata della procedura InserisciFattura: alla procedura viene passato il valore di Fattura2 e -nuovamente- l'indirizzo di
Archivio Fatture5 (ma potrebbe essere un altro) */...
}
Passaggio parametri per indirizzo (5)
29Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
/*Programma Contabilità (3)*/...
/* Definizione della procedura InserisciFattura */void InserisciFattura( DescrizioneFatture Fattura,
ElencoFatture *PointToArchivioFatture);/* In questa versione della procedura, la fattura da inserire e l'indirizzo dell'archivio in cui inserirla
sono dei parametri */{
if (PointToArchivioFatture–>NumFatture == MaxNumFatture)/* PointToArchivioFatture è una variabile che punta a una struttura
avente un campo di nome NumFatture */printf("L'archivio è pieno.\n");
else{
PointToArchivioFatture–>NumFatture = PointToArchivioFatture–>NumFatture +1;PointToArchivioFatture–>Sequenza[PointToArchivioFatture–>NumFatture – 1] =
Fattura;}
}
Passaggio parametri per indirizzo (6)
30Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Aspetti avanzati
31Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
I blocchi
• Un blocco è composto da due parti racchiuse tra parentesi graffe: una parte dichiarativa (facoltativa); una sequenza di istruzioni.
• Diversi blocchi possono comparire internamente al main o alle funzioni che compongono un programma C. I blocchi possono risultare paralleli o annidati
32Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
/* Programma ComplessoInStruttura */#include <stdio.h>
/* Parte dichiarativa globale */int g1, g2;char g3;int f1(int par1, int par2); ...main (){
int a, b; int f2(int par3, int par1); ...
/* blocco1 */ {
char a, c;...
/* blocco2 annidato nel blocco1 */{
float a;...
} /* Fine blocco2 */
} /* Fine blocco1 */
} /* Fine main */
33Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
int f1(int par1, int par2){
int d; ...
/* blocco3 */ { int e;
... }
/* Fine blocco3 *//* blocco4 */
{ int d;
... }
/* Fine blocco4 */}
/* Fine f1 */
34Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
/* Definizione della funzione f2 */int f2(int par3, int par4){
int f; ...
}/* Fine f2 */
35Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
36Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
La durata delle variabili
• variabili fisse o statiche (static): i loro valori vengono mantenuti anche all’esterno del loro ambito di visibilità.
• variabili automatiche (auto): i loro valori non vengono mantenuti all’esterno del proprio ambito di visibilità.
• Sono variabili fisse le variabili globali del programma
37Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
/* Definizione della funzione f1 */
int f1(int par1, int par2)
{
static int d;
/* blocco3 */
{ int e;
...
}
/*Fine blocco3 */
/* blocco4 */
{ int d;
...
}
/* Fine blocco4 */
}
/* Fine f1 */
38Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Parametri di tipo array (1)
• L’indirizzo di base dell’array viene passato “per valore” alla funzione.
typedef double TipoArray[MaxNumElem]
• Le tre testate di funzione riportate di seguito sono equivalenti:
double sum(TipoArray a, int n) /* n è la dimensione dell'array passato */
double sum(double *a, intn)double sum(double a[ ], int n)
39Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Parametri di tipo array (2)double mul(double a[ ], int n)
/* n è la dimensione dell'array passato */{
int i;double ris;
ris = 1.0;for (i=0; i < n; i=i+1)
ris = ris * a[i];return ris;
}
• v array di 50 elementi:
ChiamataValore calcolato e restituito
mul(v, 50) v[0]*v[1]* ... *v[49]
mul(v, 30) v[0]*v[1]* ... *v[29]
mul(&v[5], 7) v[5]*v[6]* ... *v[11]
mul(v+5, 7) v[5]*v[6]* ... *v[11]
40Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Parametri di tipo struttura
• Una struttura può essere passata per valore anche quando contiene un componente di tipo array.
41Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Effetti collaterali (1)
int x; /* Variabile globale */
int PrimoEsempio(int par){
return(par + x)}
• Nel corso del seguente frammento di programma:
x = 1;x = PrimoEsempio(1);x = PrimoEsempio(1);
• La sua chiamata produce, la prima volta, il risultato “2”, la seconda volta “3”.
42Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
int SecondoEsempio(int *par){
*par = *par + 1;return *par;
}
y = SecondoEsempio(&z);
• Assegna alla variabile y il valore di z+1, ma anche z assume lo stesso valore. effetto collaterale (side effect)
Effetti collaterali (2)
43Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
int x; /* Variabile globale */
int TerzoEsempio(int par){
x = par + 2;return (par + 1);
}
• Altro effetto collaterale:
z = TerzoEsempio(4);
• Assegna a z il valore “5”, ma anche il valore “6” a x. A
Effetti collaterali (3)
44Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
DescrizioneFatture EsaminaElimina(Giorno ParGiorno){
DescrizioneFatture FatturaLocale;
FatturaLocale = ArchivioFatture.Sequenza[ArchivioFatture.NumFatture – 1];if (FatturaLocale.DataEmissione.Giorno == ParGiorno)
ArchivioFatture.NumFatture = ArchivioFatture.NumFatture – 1;return FatturaLocale;
}
Effetti collaterali (4)
45Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
Uso interscambiabile di procedure e funzioni
int f(int par1){
...return risultato;
}
• Essa può essere trasformata nella procedura seguente:
void f(int par1, int *par2){
...*par2 = risultato;
}
• Successivamente, una chiamata come:
y = f(x);
verrà trasformata in:
f(x, &y);
46Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
La standard library del C
• Sottoprogrammi di largo uso predefiniti:
– Matematica– I/O– Grafica
• Librerie di sottoprogrammi:
– Predefinite– Costruite dai programmatori applicativi
• Però l’uso di librerie diminuisce la portabilità• A meno che anche le librerie (almeno le
fondamentali) non siano standardizzate• La grande forza del C: la libreria standard
47Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
#include <stdio.h> /* Programma Concatenazione di stringhe */
#include <string.h>#define LunghezzaArray 50main(){
char PrimaStringa[LunghezzaArray], SecondaStringa[LunghezzaArray],
StringaConc[2 * LunghezzaArray];unsigned LunghezzaConc;scanf(“%s”, PrimaStringa);scanf(“%s”, SecondaStringa);if (strcmp(PrimaStringa, SecondaStringa) <= 0){
strcpy(StringaConc, PrimaStringa);strcat(StringaConc, SecondaStringa);
}else{
strcpy(StringaConc, SecondaStringa);strcat(StringaConc, PrimaStringa);
}LunghezzaConc = strlen(StringaConc);printf(“La stringa ottenuta concatenando le due stringhe lette è %s.
Essa è lunga %d caratteri\n”, StringaConc, LunghezzaConc);}
48Funzioni e Procedure in CInformatica A – V. PerroneCopyright © 2004 - The McGraw-Hill
Companies, srl
I file header• Le funzioni della libreria sono disponibili in C come file di codice
compilato.
• È compito del programmatore inserire nel programma i prototipi delle funzioni che verranno usate
• La libreria C comprende alcuni file, chiamati header file, che contengono i prototipi di un insieme di funzioni di libreria.
#include <stdio.h>
e altre #include <xxx.h>
• Il preprocessore copia il contenuto del file stdio.h nel programma, inserendo i prototipi delle funzioni che appartengono al gruppo di cui xxx.h è il file testata.