I PUNTATORI Allocazione Statica Dato un blocco ogni variabile è allocata in memoria quando inizia l’elaborazione del blocco e deallocata quando l’elaborazione.

Slides:



Advertisements
Presentazioni simili
Esercizio Usate il ciclo repeat until (controllo post condizionale) per simulare il prodotto N x M con M somme di N. Esempio: 5 x 3 equivale a fare 5 +5.
Advertisements

Informatica 22/03/2012.
Puntatori in C e C++.
LS Tron Classe 4TC – as 2006/07 LORGANIZZAZIONE DEI PROGRAMMI UD. 8 p. 282.
PROGRAMMARE IN PASCAL (le basi)
Le funzioni UD. 8 – Lorganizzazione dei programmi p. 309 LS Tron 4TC 06/07.
Algoritmi e Programmazione
1 Strutture dati nel supporto a run time. 2 Entità presenti quando un programma va in esecuzione §programmi dutente (compilati) §routines del supporto.
Introduzione al linguaggio C
Argomenti dalla linea dei comandi Gli argomenti possono essere passati a qualsiasi funzione di un programma, compresa la main(), direttamente dalla linea.
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.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Stringhe e Puntatori Marco D. Santambrogio – Ver. aggiornata al 18 Marzo 2013.
File.
Allocazione dinamica della memoria
Laboratorio di Linguaggi lezione VIII Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea.
MATLAB. …oggi… Programmare in Matlab Programmare in Matlab m-file m-file script script Funzioni Funzioni Cicli Cicli Operatori relazionali Operatori relazionali.
Ricorsione e Debug.
Eliana minicozzi linguaggi L1 Lezione3.
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,
Programmazione Mod. B - Alberi - prof. E. Burattini
Il linguaggio Fortran 90: 4. Array: Vettori e Matrici
Introduzione alla programmazione lll
Procedure e funzioni nei linguaggi di alto livello Lab Programmazione - turno /2006.
nome: sequenza di caratteri usata per denotare un oggetto
Algoritmi su Tipi Semplici
Istruzioni Decisionali
Puntatori - Cenni Nicola Fanizzi Corso di Programmazione C.d.L. in Informatica DIB - Università degli Studi di Bari.
memoria gestita staticamente:
Esercizi Puntatori, struct con campi puntatore, puntatori a struct, rapporto tra array e puntatori. FUNZIONI Passaggio di parametri per indirizzo, passaggio.
Problema Ci sono 5 signore nel parco. Ognuna di loro ha 1 figlio. Ogni bambino ha 10 figurine di calciatori, per un totale quindi di 50 figurine. Questi.
OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.
CAPITOLO 7.
FILE TESTO OUTPUT INPUT + DATI PROGRAMMA OUTPUT INPUT PROGRAMMA CARICAMENTO DATI FILE DATI.
RICORDARSI DI PRENOTARE GLI SCRITTI NOTE SUL PROGETTO LA FRASE CHIAVE DEVE POTER CONTENERE SIA SPAZI CHE LETTERE MAIUSCOLE. QUANDO SI MOSTRA IL CONTENUTO.
In Pascal è possibile avere oltre ai file testo, cioè file di char, anche file di interi, stringhe, records. Unica condizione è quella che se un file.
CAPITOLO 6.
Le funzioni.
FUNZIONI... Una funzione permette di dare un nome a una espressione rendendola parametrica float f(){ return * sin(0.75); } float f1(int x) { return.
Programmazione Mod. B - prof. Burattini - Cap 17 1.
TURBOPASCAL …. ripassiamo - prof. V. Riboldi -.
Cicli in Fortran I cicli consentono di eseguire una sequenza di istruzioni più di una volta due tipi: Cicli iterativi Cicli while.
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
Problema: come dividere due numeri
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
CORSO DI PROGRAMMAZIONE II Lezione 22
- prof. V. Riboldi - SOTTOPROGRAMMI IN TPASCAL METODO TOP DOWN.
Il linguaggio Fortran 90: 3. Procedure e Funzioni
ESERCIZIO Assegnata una lista L di caratteri ed un carattere k, scrivere una procedura che cancelli tutte le occorrenze di k in L. PROGRAM Liste(output,input);
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.
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.
Allievi Elettrici - AA Le funzioni ricorsive in C
PROVA INTERCORSO MOD.B a.a RICORSIONE ESERCIZI A1.1-A1.6.
In Pascal è possibile avere oltre ai file testo, cioè file di char, anche file di interi, stringhe, records. Unica condizione è quella che se un file.
RossiUgo /8796 BianchiCarlo /8746 II I Sia dato un file di testo riguardante un insieme di studenti di cui è.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 11 Marzo 2014.
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.
Linguaggio C: Le basi Stefano Cagnoni e Monica Mordonini
Procedure - Funzioni. Procedure e funzioni Parti di programma a cui è associato un nome e che può essere attivata mediante una chiamata. Le funzioni a.
13. Strutture dati dinamiche Ing. Simona Colucci Informatica - CDL in Ingegneria Industriale- A.A
Transcript della presentazione:

I PUNTATORI Allocazione Statica Dato un blocco ogni variabile è allocata in memoria quando inizia l’elaborazione del blocco e deallocata quando l’elaborazione di tutto il blocco termina. Allocazione Dinamica Quando ogni variabile è allocata o deallocata in memoria durante l’elaborazione del blocco. Il puntatore Un puntatore è una variabile il cui valore rappresenta un indirizzo di memoria. Esso serve per creare o eliminare una variabile dinamica. Variabile dinamica E’ una variabile alla quale si assegna spazio in memoria durante l’elaborazione di un blocco.

identificatoretype =^ ESEMPIO TYPE DataType = RECORD Giorno:1..31; Mese:1..12; Anno:integer END; DataPunt=^DateType; IntPunt=^integer; VAR Oggi:DataPunt; A,B:IntPunt; Domani:DataType; Si noti che la variabile Oggi, così come la variabile IntPunt, non assume i tre valori del record, o il valore di intero, a cui fa riferimento ma solo quello dell’indirizzo di memoria a partire dal quale vi sono eventualmente i valori Variabile Anonima: una variabile alla quale si accede solo tramite un puntatore Variabile Nominata: una variabile alla quale si accede tramite un nome

Puntatori Nome Type DataPunt=^ Record IntPunt=^ Integer ……………... Run-Time Heap Oggi A B C ……………... Nome Variabile Oggi^ A^ B^ C^ ……………... Memoria ……………... Indirizzi di memoria ………… TYPE DataType = RECORD Giorno:1..31; Mese:1..12; Anno:integer END; DataPunt=^DateType; IntPunt=^integer; VAR Oggi:DataPunt; A,B:IntPunt; Domani:DataType;

Per assegnare un indirizzo a una variabile puntatore si usa la procedura new: es. new(Oggi) TYPE DataType = RECORD Giorno:1..31; Mese:1..12; Anno:integer END; DataPunt=^DateType; IntPunt=^integer; VAR Oggi:DataPunt; A,B:IntPunt; Spazio di memoria assegnato Prima di fare la chiamata new(Oggi) Oggi^  ? Dopo la chiamata new(Oggi) Oggi^  ??? Per assegnare dei valori alla variabile dinamica Oggi new(Oggi) Oggi^  ??? read(Oggi^.Giorno, Oggi^.Mese, Oggi^.Anno) Enter Oggi^ .Giorno.Mese.Anno

TYPE DateType = RECORD Giorno:1..31; Mese:1..12; Anno:integer END; DataPunt=^DateType; IntPunt=^integer; VAR Oggi:DataPunt; A,B:IntPunt; new(A); new(B); new(Oggi); A^:=5; B^:=7; write(‘Dammi la data (giorno mese anno): ‘); WITH Oggi^ DO readln(Giorno, Mese, Anno) Dammi la data (giorno mese anno) : Oggi^  5 A^  7 B^ 

Gli unici operatori che si applicano alle variabili puntatori sono: operatore di assegnazione:= operatori booleani=<> TYPE DataType = RECORD Giorno:1..31; Mese:1..12; Anno:integer END; DataPunt=^DateType; IntPunt=^integer; VAR Oggi:DataPunt; A,B,C:IntPunt; Domani:DataType; L’operazione C :=B 12 C^ 7 B^ X garbage 7 L’operazione A^ :=B^ 5 A^  7 B^  12 C^ 

TYPE IntPunt=^integer; VAR A,B,C:IntPunt; 7 A^  7 B^  A^ : =5 B^ := 7 A^ :=B^ IF (A^ = B^) AND (A <> B) THEN writeln(‘ I puntatori sono diversi ma i valori delle variabili puntate sono eguali’) 5 A^  7 B^ A^ : =5 B^ := 7 A :=B IF (A^ = B^) AND (A <> B) THEN writeln(‘ I puntatori sono eguali e anche i valori delle variabili puntate sono eguali’)

TYPE IntPunt=^integer; VAR A,B,C:IntPunt; C :=B IF (C = B) THEN writeln(‘ I puntatori puntano alla stessa variabile’) 12 C^ 7 B^ X garbage dispose(C) C :=B IF (C = B) THEN writeln(‘ I puntatori puntano alla stessa variabile’) 7 B^ C^ ? 7 B^ C^ Come eliminare la spazzatura

In memoria esiste una speciale area detta run-time-heap dove sono allocate le variabili puntatore. Nello heap ci sono le variabili puntatori create da new ad es.A B C D

Vi è un solo valore che una variabile puntatore può assumere e che non punta a nulla: NIL. Es: D:= NIL; Questa assegnazione serve per informare che per ora la variabile puntatore non è stata ancora associata a una variabile dinamica. Si possono fare test per vedere se il puntatore è libero di essere associato ad una variabile dinamica. Attenzione NIL non è assegnato per default. L’istruzione C:=B mostra che possiamo assegnare memoria ad un puntatore senza fare uso di new questo ci permette di avere due puntatori che puntano alla stessa variabile dinamica, riducendo così lo spazio di memoria usato. Possiamo quindi scrivere new(B); B^:=18; C:=B Questa istruzione è valida solo se il puntatore C esiste. Attenzione se a un puntatore è assegnato NIL, es. D:= NIL, non è possibile fare dispose(D).

Se abbiamo allocato memoria es. new(D); D^:=5; D:= NIL resta spazzatura bisogna invece fare come di seguito new(D); D^:=5; dispose(D); D:= NIL; NIL non elimina la spazzatura

PROGRAM ArrayPuntatori(input, output, Semester); CONST MaxStu=100; TotaleProve=100; TYPE Stringa4 = STRING[4]; Stringa10 = STRING[10]; Stringa25 = STRING[25]; RisultatiArray=ARRAY[1..TotaleProve] OF integer; StuRec = RECORD Cognome, Nome : Stringa25; Nascita:Stringa10; Matricola:Stringa10; AnnoCorso:Stringa4; Risultati:RisultatiArray; Media:real; END; StuFile=FILE OF StuRec; StuPointer=^StuRec; PointArr=ARRAY[0.. MaxStu] OF StuPointer; VAR Semester: StuFile; ByName, ByMat: PointArr; TotalStu:integer; Matr:Stringa10; StuRec NomeNascitaMatricolaAnnoCorsoRisultatiMedia

PROBLEMA Leggere il file Semester e realizzare due array di puntatori uno ordinato per nome (ByName) ed uno per matricola (ByMat). L’array ByName contiene i puntatori agli studenti ordinati per nome. Vogliamo scrivere una funzione che faccia una ricerca di uno studente per numero di matricola sull’array ByMat. 1 mid TotalStu 1 mid TotalStu ByName ByMat 050/ AbateCarlo 30/11/ / CarliniAnna 30/11/ / ZucchiUgo 03/01/

PROGRAM ArrayPuntatori(input, output, Semester); CONST MaxStu=100; TotaleProve=100; TYPE Stringa4 = STRING[4]; Stringa10 = STRING[10]; Stringa25 = STRING[25]; RisultatiArray=ARRAY[1..TotaleProve] OF integer; StuRec = RECORD Cognome, Nome : Stringa25; Nascita:Stringa10; Matricola:Stringa10; AnnoCorso:Stringa4; Risultati:RisultatiArray; Media:real; END; Puntatori Nome Type StuPointer=^ StuRec PointArr=^ Array OF Run-Time Heap By Name ByMat Nome Variabile By Name ^ ByMat ^ ……………... Memoria ……………... Indirizzi di memoria …………. StuFile=FILE OF StuRec; StuPointer=^StuRec; PointArr=ARRAY[0.. MaxStu] OF StuPointer; VAR Semester: StuFile; ByName, ByMat: PointArr; TotalStu:integer; Matr:Stringa10;

PROCEDURE OrganizzaDati(VAR ByName,ByMat:PointerArray;VAR TotalStu:integer; VAR StuOnFile:StuFile); VAR AStu:StuPointer; BEGIN reset(StuOnFile); TotalStu := 0; new(ByMat[0]); ByMat[0]^.Matricola:='00000'; WHILE NOT eof(StuOnFile) DO BEGIN new(AStu); read(StuOnFile, AStu^); TotalStu := TotalStu + 1; ByName[TotalStu] := AStu; Insert(AStu, TotalStu, ByMat) END; close(StuOnFile) END; PROCEDURE Insert(NewElement:StuPointer; Candidate: integer; VAR ByMatP:PointerArray); BEGIN WHILE (ByMatP[Candidate-1]^.Matricola > NewElement^.Matricola ) DO BEGIN ByMatP[Candidate]:= ByMatP[Candidate-1]; Candidate:=Candidate-1 END; ByMatP[Candidate]:=NewElement END;

FUNCTION CercaStudente(VAR ByMatP: PointerArray; Numero:Stringa10; Lo,Hi:integer): StuPointer; VAR J:integer; BEGIN IF Lo > Hi THEN CercaStudente :=NIL ELSE BEGIN J:=(Lo+Hi) DIV 2; IF ByMatP[J]^.Matricola = Numero THEN CercaStudente:= ByMatP[J]; ELSE IF ByMatP[J]^.Matricola < Numero THEN CercaStudente:= CercaStudente(ByMat, Numero, J+1,Hi) ELSE CercaStudente:= CercaStudente(ByMat, Numero, Lo,J-1) END END; PROCEDURE Risultati(MatrCand:Stupointer); BEGIN writeln(Matrcand^.Cognome,' ', MatrCand^.Nome,' ', MatrCand^.Matricola); END;

{******************** MAIN ******************} BEGIN assign(semester,'a:\probe.dat'); OrganizzaDati(ByName,ByMat, TotalStu, Semester); readln; write('Dammi la matricola cercata: '); readln(Matr); Risultati(CercaStudente(ByMat,Matr,1,TotalStu)); readln END.

Esercizio Scrivere il programma completo per la gestione dei records attraverso array di puntatori ordinati per Nome, Matricola, Data di Nascita, Media.

Alcuni suggerimenti sui puntatori Per il passaggio di parametri relativi ai puntatori valgono le stesse regole che si applicano per gli altri tipi di variabili. Quando un puntatore è chiamato per valore viene fatta una copia locale del suo valore, cioè dell’indirizzo. Quando un puntatore è chiamato per variabile viene prodotto un alias locale per il suo valore attuale, ricordando sempre che si tratta di indirizzi.

PROGRAM TestChiamatePuntatori; TYPE IntP=^integer; VAR AnIntP:IntP; PROCEDURE ValCall(XP:IntP); BEGIN XP^:=7; END; PROCEDURE VarCall(VAR XP:IntP); BEGIN XP^:=7; END; BEGIN new(AnIntP); AnIntP^:=5; ValCall(AnIntP); writeln(‘Output= ‘,AnIntp^:1); END. Output= 7 Questo accade perché l’indirizzo passato dalla chiamata rimane lo stesso mentre il valore della variabile dinamica è cambiato. Questa chiamata equivale ad una chiamata per VAR su XP^. BEGIN new(AnIntP); AnIntP^:=5; ValCallVar(AnIntP); writeln(‘Output= ‘,AnIntp^:1); END. Output= 7 Il valore resta lo stesso essendo la chiamata precedente equivalente ad una chiamata per VAR su XP^.

PROGRAM TestChiamatePuntatori; TYPE IntP=^integer; VAR AnIntP:IntP; PROCEDURE ValCall(XP:IntP); BEGIN dispose(XP); END; PROCEDURE VarCall (VAR XP:IntP); BEGIN dispose(XP); END; BEGIN new(AnIntP); AnIntP^:=5; ValCall(AnIntP); writeln(‘Output= ‘,AnIntp^:1); END. Output= non predicibile Questo accade perché l’indirizzo passato dalla chiamata viene deallocato. Poiché questo indirizzo nel main corrisponde anche a quello di AnInt^ il valore di AnInt^ ora non è più predicibile. BEGIN new(AnIntP); AnIntP^:=5; VarCall (AnIntP); writeln(‘Output= ‘,AnIntp^:1); END. Output= non predicibile Come prima.

PROGRAM TestChiamatePuntatori; TYPE IntP=^integer; VAR AnIntP:IntP; PROCEDURE ValCall(XP:IntP); BEGIN dispose(XP); new(XP); END; PROCEDURE VarCall (VAR XP:IntP); BEGIN dispose(XP); new(XP); END; BEGIN new(AnIntP); AnIntP^:=5; ValCall(AnIntP); writeln(‘Output= ‘,AnIntp^:1); END. Output= non predicibile Questo accade perché l’indirizzo passato dalla chiamata viene deallocato. Poiché questo indirizzo nel main corrisponde anche a quello di AnInt^ il valore di AnInt^ ora non è più predicibile. Inoltre la memoria allocata da new diventa spazzatura non appena si esce dal blocco. BEGIN new(AnIntP); AnIntP^:=5; VarCall (AnIntP); writeln(‘Output= ‘,AnIntp^:1); END. Output= non predicibile Come prima. Solo che ora non si crea spazzatura.

PROGRAM TestChiamatePuntatori; TYPE IntP=^integer; VAR AnIntP:IntP; PROCEDURE ValCall(XP:IntP); BEGIN XP:=NIL; END; PROCEDURE VarCall (VAR XP:IntP); BEGIN XP:=NIL; END; BEGIN new(AnIntP); AnIntP^:=5; ValCall(AnIntP); writeln(‘Output= ‘,AnIntp^:1); END. Output= 5 Questa istruzione riassegna un valore a XP. Ora XP e AnInt hanno valori differenti. Quando si esce da ValCall XP è perso e quindi AnInt resta =5. Non c’è spazzatura perché abbiamo usato il NIL. BEGIN new(AnIntP); AnIntP^:=5; VarCall (AnIntP); writeln(‘Output= ‘,AnIntp^:1); END. Output= non predicibile Questa istruzione riassegna a AnIntP il valore NIL. Quindi quando si esce da VarCall AnIntP^ non è predicibile inoltre a AnIntP è stato assegnato un nuovo valore per cui il precedente contenente 5 è diventato spazzatura.

PROGRAM TestChiamatePuntatori; TYPE IntP=^integer; VAR AnIntP:IntP; PROCEDURE ValCall(XP:IntP); BEGIN new(XP); XP^:=7 writeln(‘OutputCall ‘,XP^:1) END; PROCEDURE VarCall (VAR XP:IntP); BEGIN new(XP); XP^:=7 writeln (‘OutputCall ‘, XP^:1) END; BEGIN new(AnIntP); AnIntP^:=5; ValCall(AnIntP); writeln(‘Output= ‘,AnIntp^:1); END. OutputCall=7 Output= 5 Qui si alloca un nuovo indirizzo per la variabile che prima aveva indirizzo AnInt. L’effetto della assegnazione XP:=7 è ristretto solo agli scopi della procedura ValCall. Ora XP e AnIntP rappresentano due diverse variabili puntatore, quando usciamo dalla procedura AnIntP^ vale sempre 5, mentre il valore di XP^ è perduto come spazzatura. BEGIN new(AnIntP); AnIntP^:=5; VarCall (AnIntP); writeln(‘Output= ‘,AnIntp^:1); END. OutputCall=7 Output= 7 L’istruzione new(XP) fa sì che AnIntP diventa spazzatura. Quindi il valore 7 è mostrato due volte poiché tramite la Call VAR restituisce detto valore a AnIntp^.

ESERCIZI SULLA RICORSIONE

Sia data una stringa di lunghezza N e una sottostringa di lunghezza K con K sottomultiplo di N. Scrivere una funzione ricorsiva che conti tutte le sottostringhe di N che non sono uguali a K. PROGRAM ESERCIZIO3 (input, output); TYPE String30=STRING[30]; VAR Carat:char; S1: String30; S2: String30; M1,M2,Numstr,C:integer; {*********** MAIN *********} BEGIN S1:='ababababa'; S2:='aba'; M1:=length(S1); M2:=length(S2); writeln('Prima stringa ',S1); writeln('Seconda stringa ',S2); NumStr:=Cerca(S1,S2,M1,M1,M2,C); Writeln(' Diverse ',Numstr,' Uguali ',C:5); FUNCTION Cerca(VAR S1,S2:String30;i,L1,L2:integer):integer; BEGIN IF (i=length(S2)-1) THEN Cerca:=0 ELSE IF (L2=0) THEN BEGIN Cerca:=Cerca(S1,S2,i-1,i-1,length(S2)); END ELSE IF S1[L1]=S2[L2] THEN Cerca:=Cerca(S1,S2,i,L1-1,L2-1) ELSE Cerca:=Cerca(S1,S2,i-1,i-1,length(S2))+1 END;

PROGRAM Esercizio4(output); CONST MaxSucc=50; TYPE SuccNoArr=ARRAY[0..MaxSucc] OF real; VAR SuccNos:SuccNoArr; VAR No,I:integer; K:real; PROCEDURE SetSuccNo(N:integer; VAR SuccNos:SuccNoArr); {ritorna l'N-esimo valore della successione} BEGIN IF N=3 THEN BEGIN SuccNos[3]:=2; SuccNos[2]:=1; SuccNos[1]:=1; SuccNos[0]:=0; END ELSE BEGIN SetSuccNo(N-1,SuccNos); SuccNos[N]:=SuccNos[N-1]+SuccNos[N-2]*SuccNos[N-3]-SuccNos[N-4]; END END; {MAIN} BEGIN write(' Dammi N ');readln(No); SetSuccNo(No+1,SuccNos); K:=SuccNos[No+1]*SuccNos[No-1] -2*SuccNos[No]* SuccNos[No]; writeln; writeln('K= ',K:20:0); readln END. Sia data la successione: a 0 =0 a 1 =1 a 2 =1 a 3 =2 a n = a n-1 + a n-2 * a n-3 - a n-4 Scrivere una PROCEDURA ricorsiva che, assegnato un N, calcoli il numero K dato da: K=a n+1 *a n-1 - 2*a 2 n