1. 2 puntatori e function così come il nome di un array rappresenta l’indirizzo del suo primo...
TRANSCRIPT
![Page 1: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/1.jpg)
1
![Page 2: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/2.jpg)
2
Puntatori e function
Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo di partenza del suo codice.
Un puntatore a function contiene l’indirizzo di memoria della function; esso può essere passato o restituito da un’altra function e può essere assegnato ad un altro puntatore a function.
Il puntatore a function è molto utile quando è necessario, nel corso di un programma, scegliere tra più function.
STACK Stack: zona di memoria che costituisce un’area di appoggio temporaneo
CODICE Codice: contiene il codice macchina del programma
HEAP Heap: zona di memoria libera di essere utilizzata sul momento
DATI Dati: contiene tutte le variabili e le costanti definite nel programma
![Page 3: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/3.jpg)
3
STACK Stack: zona di memoria che costituisce un’area di appoggio temporaneo
CODICE Codice: contiene il codice macchina del programma
HEAP Heap: zona di memoria libera di essere utilizzata sul momento
DATI Dati: contiene tutte le variabili e le costanti definite nel programma
Puntatori e function
Supponiamo di avere due function, funz1 e funz2 del tipoint funz1(char) e int funz2(char)
ed un’altra function funzvoid funz(int, int)
A seconda delle varie opportunità, ci si vuole servire di funz1 o di funz2: il primo intero int può essere il risultato della prima (funz1), il secondo di funz2 o viceversa. Come possiamo scrivere il codice in maniera tale che la function funz possa richiamare l’una o l’altra tra funz1 o funz2?
![Page 4: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/4.jpg)
4
Utilizzando i puntatori a function possiamo scrivere il prototipo di funz in questo modo:
void funz(int (*)(char), int)
il primo parametro int da assegnare alla function deve essere il risultato di una function che ha un parametro char (potrebbe essere funz1 o funz2 o qualsiasi altra function che ha le stesse caratteristiche: stessa tipologia di parametri formali e stesso tipo di valore restituito).
L’implementazione della function funz deve avere un’intestazione del tipo
void funz(int (*puntafunz)(char), int n)
mentre la function funz può essere richiamata con una delle seguenti modalità
funz(funz1, m) funz(funz2, m)
![Page 5: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/5.jpg)
5
ESEMPIO
Un esempio di utilizzo dei puntatori a function concerne l’ordinamento.
Supponiamo di voler ordinare un array A di interi. Possiamo decidere di ordinarli sia in modo crescente che decrescente.
A questo scopo supponiamo di avere due function, chiamate crescente e decrescente, che restituiscono un valore booleano.
Come organizzare il programma in modo tale da passare la function che serve allo scopo?
Il puntatore a function risolve il problema.
![Page 6: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/6.jpg)
6
Di seguito è riportato il codice che permette di scegliere fra il realizzare un ordinamento crescente o decrescente dei dati contenuti in un array di interi.
Le function interessate sono:
void ordinaB (int vet[], int N, bool (*confronta)(int,int))
bool crescente(int x, int y)
bool decrescente(int x, int y)
void scambia (int &x1, int &x2)
![Page 7: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/7.jpg)
7
#include <iostream>#include <cstdlib>#include "InsertArray.h"using namespace std;
// PROTOTIPI
void ordinaB(int[ ], int, bool(*)(int,int));bool crescente(int, int);bool decrescente(int, int); void scambia (int&, int&);
int main () { char ch; int a[100], n; cout<<" Lunghezza vettore="; cin>>n; LeggeVettore ( a, n, 'a'); do { cout<<" CRESCENTE "<<endl; ordinaB(a,n,crescente); StampaVettore (a, n,'a'); cout<<"\n DECRESCENTE "<<endl; ordinaB(a,n,decrescente); StampaVettore (a, n,'a');
cout<<"\n f per terminare ";cin>>ch;
} while (ch!='f'); return 0; }
![Page 8: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/8.jpg)
8
// implementazione delle procedure e functionvoid scambia (int &x1, int &x2) { int s; s=x1; x1=x2; x2=s;}void ordinaB (int vet[], int N, bool (*confronta)(int,int)) { int j, k; for (k=0; k<N-1; k++) for (j=k+1; j<N; j++) if ((confronta)(vet[k], vet[j]))
{ scambia (vet[k],vet[j]);
} } bool crescente(int x, int y) { return (x>y); }bool decrescente(int x, int y) { return (x<y); }
Allegato: funzPuntatori
![Page 9: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/9.jpg)
9
Esercizio
Con i puntatori a funzione scrivere una function che valuti il valore massimo contenuto in un vettore di interi, il minimo e la somma di tutti gli elementi del vettore.
Con i puntatori a funzione scrivere una function che verifichi se assegnata una matrice di interi essa è unitaria, oppure simmetrica oppure con elementi tutti non negativi.
funzMinMax.cpp
funzMatrixPunt
![Page 10: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/10.jpg)
10
Variabili dinamiche
Nel caso delle variabili statiche la memoria viene allocata nel momento in cui la variabile è definita; per esempio le variabili
int x, a[10];impegnano la memoria nel momento stesso in cui vengono definite, mentre vengono deallocate nel momento in cui il programma termina, se la variabile è globale; se, invece, la variabile è locale (cioé definita in una function) allora viene deallocata quando termina la function.
In molti casi, però, è più comodo avere un controllo completo sulla allocazione di memoria cioè decidere quando allocare o deallocare la variabile in un qualsiasi punto del programma.
![Page 11: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/11.jpg)
11
Questo è il concetto chiave di gestione dinamica della memoria.
Il C++ mette a disposizione del programmatore due istruzioni:
new che serve per allocare memoria per una certa variabile durante l’esecuzione del programma
delete che serve a deallocare memoria (libera la zona di memoria occupata dall’oggetto definito con new).
![Page 12: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/12.jpg)
12
Volendo definire due variabili dinamiche, ad esempio un intero ed un array di 100 interi, si procede in questo modo:
si definiscono due puntatori ad interi, int *P1, *P2;
si usa l’operatore new per indicare che è una variabile dinamica
sia per l’intero P1=new int
che per l’arrayP2=new int [100]
Se l’operatore new fallisce, ritorna il puntatore nullo NULL: ciò indica che, per qualche ragione, non è stato possibile allocare altra memoria.
![Page 13: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/13.jpg)
13
Il programma può utilizzare i puntatori P1 e P2 nei suoi
calcoli; può, inoltre, deallocarli in un qualsiasi momento
con l’istruzione delete:
delete P1; // cancella dalla memoria heap l’intero di cui P1 contiene l’indirizzo
delete [ ] P2; // cancella dalla memoria heap l’array di cui P2 contiene l’indirizzo-base
Vediamo l’utilizzo delle variabili dinamiche per un algoritmo di selection sort
![Page 14: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/14.jpg)
14
#include <iostream>#include <cstdlib>#include "InsertArraypunt.h"using namespace std;// PROTOTIPIvoid SortSel(int*, const int);void Scambia (int*, int*);// questa function usa puntatori
che puntano ad interi NON ad array
// MAIN int main() { int N, *ap; //viene definito un puntatore ad un array ap=new int[30]; // ap è un puntatore ad un array: è
una variabile dinamica con al più 30 interi if (ap==NULL) { //se ap è NULL allora non è possibile
allocare memoria cout<<"Non è possibile allocare memoria"<<endl; return -1; } //il programma termina cout<<”Numero valori da caricare in a ="; cin>>N; LeggeVettore(ap,N,'a'); // in questa e nelle chiamate
successive si passa il puntatore ap all'array SortSel(ap,N); StampaVettore(ap,N,'a'); delete [ ] ap; //si libera la memoria a cui punta ap system("pause"); }
ESEMPIO
Dal main si evince che viene creato lo spazio e caricato un array con N interi (Legge Vettore), successivamente vengono ordinati (SortSel) e stampati (StampaVettore) i dati e quindi viene liberato lo spazio di memoria
![Page 15: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/15.jpg)
15
// DEFINIZIONIvoid SortSel(int *vet, const int Nv) { int minp; for ( int i=0; i<Nv-1; i++) { minp=i; for ( int j=i+1; j<Nv; j++) { if (*(vet+j) < *(vet+minp)) minp=j; } Scambia((vet+minp), (vet+i)); // Attenzione! La procedura Scambia richiede puntatori!! } }
void Scambia (int *x, int *y) { int z; z=*x; *x=*y; *y=z; }
Allegato: SortPuntatori2
ESEMPIO
Si noti che gli elementi del vettore vengono individuati tramite i puntatori.
![Page 16: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/16.jpg)
16
Esercizi
Assegnato un array A scrivere una funzione booleana ricorsiva che, operando con i puntatori, determini se i valori disposti nell’array sono simmetrici rispetto al centro.
Assegnato un array A scrivere una procedura ricorsiva che, operando con i puntatori, ordini l’array con l’algoritmo dell’inserction sort.
6 8 7 8 9
![Page 17: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/17.jpg)
17
/*Assegnato un array A[10] scrivere una funzione booleana ricorsiva che, operando con i puntatori, determini se i valori disposti nell’array sono simmetrici rispetto al centro. */#include <iostream>#include <cstdlib>#include "InsertArraypunt.h"
using namespace std;//void StampaVettore(ap,N,'a');bool simm(int*,int,int); int main(){ int *array; int *lng; array=new int[50]; lng= new int; cout<<" Numero dati= ";cin>>*lng;cout<<"\n"<<endl; for(int i=0;i<*lng;i++) { cout<<"A["<<i<<"]="; cin>>array[i]; } cout<<"\n CONTROLLO...\n"<<endl; StampaVettore(array,*lng,'a'); if (simm(array,*lng-1,0)) cout<<"\n L'ARRAY E' SIMMETRICO\n"<<endl; else cout<<"\n L'ARRAY NON E' SIMMETRICO\n"<<endl; system("pause");}
arraySimmetrico
bool simm (int *array,int lng, int pos){ if(lng <= pos) return true; else { if(array[lng]==array[pos]) return simm (array,lng-1,pos+1); else return false; }}
![Page 18: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/18.jpg)
18
Consideriamo il tipo
struct TPersona {char cognome[20];char nome[20];Tdata nascita;char luogo[20];double reddito;}
Definiamo due variabili
TPersona* puntP;
TPersona persona;
La variabile puntP non ha un nome in quanto il suo nome coincide con l’indirizzo;Le variabili di questo tipo sono dette anonime; il loro contenuto può essere perso se non ne conosciamo più l’indirizzo.
I puntatori e i record
STACK
CODICE
HEAP
DATI
![Page 19: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/19.jpg)
19
Per memorizzare il contenuto cui punta puntP dobbiamo:
Usare new per allocare lo spazio nello HeappuntP=new Tpersona
Inserire i daticout<<“Cognome=“; cin>>puntP.cognome;
cout<<“Nome=“; cin>>puntP.nome;
cout<<“Data Nascita=“; cin>>puntP.nascita.giorno >>puntP.nascita.mese >>puntP.nascita.anno;
cout<<“Luogo Nascita=“; cin>>puntP.luogo;
cout<<“Reddito=“; cin>>puntP.reddito;
Una volta inseriti i dati questi si trovano nella memoria heap a cui è possibile accedere solo attraverso puntP e l’operatore “.”
![Page 20: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/20.jpg)
20
AbateLuca21 9 1976Napoli12000
ZurloAldo1 8 1966Milano37000
puntP puntP1
Supponiamo siano assegnate due variabili
Se poniamo puntP1=puntP si avrà
AbateLuca21 9 1976Napoli12000
puntP
puntP1
La zona di memoria a cui puntavapuntP1 resta occupata ma irraggiungibilein quanto ne abbiamo perso l’indirizzo.
Si crea così garbage o spazzatura e nonserve a nulla porre puntP1=NULL
![Page 21: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/21.jpg)
21
Passaggio dei puntatori ad una function.
Tenendo presente che il puntatore è una variabile che
fornisce l’indirizzo di un’altra variabile, analizziamo alcune
situazioni-tipo.
Abbiamo un programma principale contenente due
puntatori ad un intero; esso richiama due procedure: nella
prima la variabile intera è passata per valore, nella
seconda per riferimento.
Il programma principale è lo stesso, mentre faremo variare
le due procedure.
![Page 22: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/22.jpg)
22
Di seguito si mostra il codice e l’output del programma che opera chiamate dei puntatori sia per valore che per riferimento.
#include <iostream>#include <cstdlib>using namespace std;void CallVal(int*);void CallRif(int* &);int main () { int *p1, *p2; p1=new int; p2=new int; *p1=5; *p2=5;
CallVal(p1); CallRif(p2); system("pause");}
![Page 23: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/23.jpg)
23
int main () { int *p1, *p2; p1=new int; p2=new int; *p1=5; *p2=5; cout<<"indirizzo p1 pre-CalVal "<<p1<<" valore "<<*p1<<endl<<endl; CallVal(p1); cout<<"indirizzo p1 post-CalVal "<<p1<<" valore "<<*p1<<endl<<endl; cout<<"indirizzo p2 pre-CalRif "<<p2<<" valore "<<*p2<<endl<<endl; CallRif(p2); cout<<"indirizzo p2 post-CalRif "<<p2<<" valore "<<*p2<<endl<<endl;
}void CallVal(int* xp) { xp=new int; *xp=7; cout<<"indirizzo p1 in-CalVal "<<xp<<" valore "<<*xp<<endl<<endl;
}void CallRif(int* &xp) { xp=new int; *xp=7; cout<<"indirizzo p2 in-CalRif "<<xp<<" valore "<<*xp<<endl<<endl;
}
![Page 24: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/24.jpg)
24
int main () { int *p1, *p2; p1=new int; p2=new int; *p1=5; *p2=5;
CallVal(p1);
CallRif(p2);
}
Allegato: funzDinamPuntatori 3
// indirizzo p1 pre-CalVal 0x3d2490 valore 5
void CallVal(int* xp) { xp=new int; *xp=7;
}
// indirizzo p1 in CalVal 0x3d2508 valore 7
// indirizzo p1 post-CalVal 0x3d2490 valore 5
// indirizzo p2 pre-CalRif 0x3d24f8 valore 5
void CallRif(int* &xp) { xp=new int; *xp=7; }
// indirizzo p2 in CalRif 0x3d2518 valore 7
// indirizzo p2 post-CalRif 0x3d2518 valore 7
![Page 25: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/25.jpg)
25
Nell’esempio che segue il programma va in errore perché
la procedura CallRif(p2) restituisce un puntatore
p2=NULL che quindi non può essere stampato come
richiesto.
![Page 26: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/26.jpg)
26
// NON FUNZIONA
int main () { int *p1, *p2; p1=new int; p2=new int; *p1=5; *p2=5; cout<<"indirizzo p1 pre-CalVal "<<p1<<" valore "<<*p1<<endl<<endl; CallVal(p1); cout<<"indirizzo p1 post-CalVal "<<p1<<" valore "<<*p1<<endl<<endl; cout<<"indirizzo p2 pre-CalRif "<<p2<<" valore "<<*p2<<endl<<endl; CallRif(p2);// restituisce un errore perché in uscita p2 punta a NULL!! cout<<"indirizzo p2 post-CalRif "<<p2<<" valore "<<*p2<<endl<<endl; system("pause");}void CallVal(int* xp) { xp=NULL; }
void CallRif(int* &xp) { xp=NULL; }
Allegato: funzDinamPunt2
![Page 27: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/27.jpg)
struct Tpdata { int giorno; int mese; int anno; };struct Tpersona { char cognome[30]; char nome[20]; Tpdata nascita; char luogo[20]; }; typedef Tpersona* Ppersona;
//Ppersona è un nuovo tipo: puntatore a Tpersonaconst char Nomefile[]="persone.dat";
Assegnato un Array contenete dati anagrafici mostrare a video i dati ordinati per cognome, luogo di nascita e data di nascita.
// PROTOTIPI
void Stampa(Ppersona[],int); void bubble(Ppersona [] ,int,int(*)(Ppersona ,Ppersona)); int cognome(Ppersona,Ppersona); int luogo(Ppersona,Ppersona); int nascita(Ppersona ,Ppersona );
![Page 28: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/28.jpg)
main () { Tpersona persona1; Ppersona PuntaP1[101], PuntaP2[101], PuntaP3[101]; const int Lrec=sizeof(Tpersona); fstream filepers; filepers.open(Nomefile,ios::in|ios::out|ios::binary|ios::ate); int NumPers; if (!filepers) { filepers.open("persone.dat",ios::out|ios::binary|ios::trunc);
return 1;} NumPers=filepers.tellg()/Lrec; cout<<NumPers; filepers.seekg(0,ios::beg); for (int i=0; i<NumPers; i++) { //leggi I dati della persona filepers.read((char*) &persona1, Lrec); PuntaP1[i] = new Tpersona; // Inserisci i dati letti in PuntaP1[i] *PuntaP1[i] = persona1; PuntaP2[i] = PuntaP1[i]; PuntaP3[i] = PuntaP1[i]; }
![Page 29: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/29.jpg)
cout<<" STAMPA DATI "<<endl<<endl<<endl;
cout<<" INIZIALE"<<endl; Stampa(PuntaP1,NumPers);
cout<<"\n COGNOME"<<endl; bubble(PuntaP1,NumPers,cognome); Stampa(PuntaP1,NumPers);
cout<<"\n LUOGO"<<endl; bubble(PuntaP2,NumPers,luogo); Stampa(PuntaP2,NumPers);
cout<<"\n NASCITA"<<endl; bubble(PuntaP3,NumPers,nascita); Stampa(PuntaP3,NumPers);
system("pause"); return 0; }
![Page 30: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/30.jpg)
void bubble(Ppersona vet[],int N,int(*confronta)(Ppersona ,Ppersona)) { int j, k; Ppersona s; for (k=0; k<N-1; k++) { for (j=N-2; j>=k; j--) {if (confronta(vet[j], vet[j+1])>=1) { s=vet[j]; vet[j]=vet[j+1]; vet[j+1]=s; } } } }
int cognome(Ppersona Px , Ppersona Py) { return ((strcmp(Px->cognome, Py->cognome))); } int luogo(Ppersona Px , Ppersona Py){return ((strcmp(Px->luogo, Py->luogo)));} int nascita(Ppersona Px , Ppersona Py) { double data1,data2; data1=(Px->nascita.anno)*10000+(Px->nascita.mese)*100+(Px->nascita.giorno); data2=Py->nascita.anno*10000+Py->nascita.mese*100+Py->nascita.giorno; return (data1-data2);}
![Page 31: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/31.jpg)
int cognome(Ppersona Px , Ppersona Py) { return ((strcmp(Px->cognome, Py->cognome))); } int luogo(Ppersona Px , Ppersona Py){return ((strcmp(Px->luogo, Py->luogo)));} int nascita(Ppersona Px , Ppersona Py) { double data1,data2; data1=(Px->nascita.anno)*10000+(Px->nascita.mese)*100+(Px->nascita.giorno); data2=Py->nascita.anno*10000+Py->nascita.mese*100+Py->nascita.giorno; return (data1-data2);}
ArrayPuntRec3
![Page 32: 1. 2 Puntatori e function Così come il nome di un array rappresenta l’indirizzo del suo primo elemento, il nome di una function rappresenta l’indirizzo](https://reader036.vdocumenti.com/reader036/viewer/2022062512/5542eb77497959361e8e1f2c/html5/thumbnails/32.jpg)
32
ESERCIZIOSia K un intero positivo ed R una matrice mxn di interi. Si scriva una funzione ricorsiva che stabilisca se R contenga al suo interno una serie di almeno K elementi consecutivi allineati in uno qualsiasi dei tre versi orizzontale, verticale oppure diagonale. Utilizzare i puntatori.Esempio per K=3
R=
1 5 12 4 51
33 3 65 14 68
7 9 7 12 28
4 34 42 28 47
75 21 28 61 9
8 51 27 21 64