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.

Slides:



Advertisements
Presentazioni simili
Puntatori Linguaggio C.
Advertisements

INFORMATICA Algoritmi fondamentali
Puntatori in C e C++.
Procedure e funzioni A. Ferrari.
Procedure e funzioni In linguaggio C.
MATLAB.
MATLAB. Scopo della lezione Programmare in Matlab Funzioni Cicli Operatori relazionali Esercizi vari.
1 Informatica Generale Susanna Pelagatti Ricevimento: Mercoledì ore presso Dipartimento di Informatica, Via Buonarroti,
Fondamenti di Informatica I CDL in Ingegneria Elettronica - A.A CDL in Ingegneria Elettronica - A.A Strutture dati dinamiche.
Fondamenti di Informatica I CDL in Ingegneria Elettronica - A.A CDL in Ingegneria Elettronica - A.A Strutture dati dinamiche.
Introduzione al linguaggio C Dr. Francesco Fabozzi Corso di Informatica.
Indirizzi delle variabili A ogni variabile sono associati tre concetti fondamentali: il valore memorizzato; il tipo dati di appartenenza; lindirizzo. Il.
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Argomenti dalla linea dei comandi Gli argomenti possono essere passati a qualsiasi funzione di un programma, compresa la main(), direttamente dalla linea.
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Funzioni definite dall’utente
Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a – 3° ciclo.
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di programmazione a.a. 2009/2010 Prof.ssa Chiara Petrioli.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 21 Marzo 2013.
Allocazione dinamica della memoria
Laboratorio di Linguaggi lezione VI: puntatori 2/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.
Laboratorio di Linguaggi lezione V Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in.
Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.
CORSO DI PROGRAMMAZIONE II
CORSO DI PROGRAMMAZIONE II Introduzione alla ricorsione
CORSO DI PROGRAMMAZIONE II
1. 2 ALCUNE INFORMAZIONI PRELIMINARI Docente: E. Burattini Libri di testo: Deitel H.M., Deitel P.J. – C++ Fondamenti di programmazione,
e array a più dimensioni
memoria gestita staticamente:
1 Strutture Dinamiche Corso di Informatica A Vito Perrone.
Esercizi FUNZIONI Passaggio di parametri per valore, variabili e tipi locali e globali, prototipo.
Esercizi Puntatori, struct con campi puntatore, puntatori a struct, rapporto tra array e puntatori. FUNZIONI Passaggio di parametri per indirizzo, passaggio.
Le funzioni.
1 ListaDiElem Cancella( ListaDiElem lista, TipoElemento elem ) { ListaDiElem puntTemp; if( ! ListaVuota(lista) ) if( lista–>info == elem ) { puntTemp =
1. 2 Struct Al fine di illustrare luso del tipo struct, utilizzando le struct descritte nella lezione precedente, mostriamo come si scrive un programma.
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di programmazione a.a. 2009/2010 Prof.ssa Chiara Petrioli.
Unità Didattica 3 Linguaggio C
Passaggio di parametri per indirizzo
Esercizi Liste.
Corso JAVA Lezione n° 11 Istituto Statale di Istruzione Superiore “F. Enriques”
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 5 Le strutture informative Corso di Informatica 2 a.a. 2003/04 Lezione 5.
1 Fabio Scotti ( ) Laboratorio di programmazione per la sicurezza Valentina Ciriani ( ) Laboratorio di programmazione Lezione 11 e 12 -
CORSO DI PROGRAMMAZIONE II Lezione 22
Struttura di una lista legata Una lista legata è una variabile strutturata in cui ogni elemento mantiene l’indirizzo (mediante un puntatore) dell’elemento.
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Corso di Programmazione 1 a.a.2006/2007 Prof.ssa Chiara Petrioli Corso di Laurea.
1. 2 Variabili statiche e dinamiche Un programma è un processo in esecuzione a cui il sistema operativo assegna una certa zona di memoria. Tale zona può.
Vettori, indirizzi e puntatori Finora abbiamo usato gli indirizzi nel chiamare  la funzione scanf()  le altre funzioni per riferimento Tuttavia la vera.
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 11 Ottobre 2014.
Università di Torino – Facoltà di Scienze MFN Corso di Studi in Informatica Programmazione I - corso B a.a prof. Viviana Bono Blocco 7 – Array.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a – 3° ciclo.
Informatica 4 Funzioni. FUNZIONE: definizione MATEMATICA Relazione (o applicazione) binaria tra due insiemi A e B che associa a ogni elemento di A un.
Allievi Elettrici - AA Le funzioni ricorsive in C
CORSO DI PROGRAMMAZIONE II
Procedure e funzioni In linguaggio C.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 11 Marzo 2014.
1. 2 Esempi d’uso di file binari. Scriviamo un semplice programma che calcola la lunghezza di un file di qualsiasi natura. I commenti all’interno del.
Relazione sulle strutture dati Svolta da: Buccella Simone Strutture di dati Aree di memoria Puntatore numericibooleani alfabetici Statici dinamici Puntatori.
1 Il linguaggio C Precisazioni sull’esperienza in laboratorio.
ALLOCAZIONE STATICA: LIMITI Per quanto sappiamo finora, in C le variabili sono sempre dichiarate staticamente –la loro esistenza deve essere prevista e.
Il linguaggio C Puntatori e dintorni.
Fondamenti di Informatica
Sommario Oggetti immutabili e non Tipi Primitivi: String, Arrays.
Copyright © Istituto Italiano Edizioni Atlas
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 8 Aprile 2015.
30/10/01Array 1  Un array e’ una struttura dati che contiene piu’ valori del medesimo tipo.  La lunghezza di un array e’ stabilita quando l’array viene.
13. Strutture dati dinamiche Ing. Simona Colucci Informatica - CDL in Ingegneria Industriale- A.A
Linguaggio C: Funzioni e Puntatori Laboratorio di Programmazione Gruppo 1.
1 MODULO STRUTTURE DATI FONDAMENTALI: Strutture dinamiche classe 4° INDUSTRIALE INFORMATICA Focus on.
Transcript della presentazione:

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 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

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 tipo int funz1(char) e int funz2(char) ed un’altra function funz void 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?

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)

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.

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)

7 #include #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; }

8 // implementazione delle procedure e function void 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

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

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.

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).

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’array P2=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.

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

14 #include #include "InsertArraypunt.h" using namespace std; // PROTOTIPI void 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

15 // DEFINIZIONI void 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.

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

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 #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 >*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; }

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

19 Per memorizzare il contenuto cui punta puntP dobbiamo: Usare new per allocare lo spazio nello Heap puntP=new Tpersona Inserire i dati cout<<“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 “.”

20 Abate Luca Napoli Zurlo Aldo Milano puntP puntP1 Supponiamo siano assegnate due variabili Se poniamo puntP1=puntP si avrà Abate Luca Napoli puntP puntP1 La zona di memoria a cui puntava puntP1 resta occupata ma irraggiungibile in quanto ne abbiamo perso l’indirizzo. Si crea così garbage o spazzatura e non serve a nulla porre puntP1=NULL

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.

22 Di seguito si mostra il codice e l’output del programma che opera chiamate dei puntatori sia per valore che per riferimento. #include 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"); }

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; }

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

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.

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

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 Tpersona const 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 );

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]; }

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; }

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);}

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

32 ESERCIZIO Sia 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=