Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine porta Logan in un'avventura inedita, violenta e fortemente narrativa, costruita attorno alla sua natura di combattente e al difficile rapporto con il proprio passato. Insomniac Games punta su combattimenti spettacolari, progressione e personalizzazione, inserendo l'azione in un mondo segnato dalla persecuzione dei mutanti. Un viaggio intenso, che alterna mattanza, esplorazione e momenti sorprendentemente emotivi.
DJI Romo 2: tante novità lo rendono un robot completo
DJI Romo 2: tante novità lo rendono un robot completo
Romo 2 è la seconda generazione di robot lavapavimenti di DJI, un modello che si caratterizza per la precisione nel sistema di navigazione e per il funzionamento particolarmente silenzioso. Con le modifiche introdotte in questa seconda versione, e un posizionamento di prezzo più allineato alla concorrenza, rappresenta una valida alternativa sul mercato delle soluzioni di pulizia domestica
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Il primo Sony con retroilluminazione True RGB alla prova del banco di misura e dei contenuti: luminanza enorme, colori accurati in HDR e un antiriflesso molto efficace. I limiti sono due sole HDMI 2.1 e il blooming fuori asse
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 16-02-2015, 11:09   #1
nasio91
Senior Member
 
L'Avatar di nasio91
 
Iscritto dal: Oct 2009
Città: Lecce
Messaggi: 1356
Funzione Ricorsiva in C

Salve a tutti, mi sto affacciando alla programmazione in C da un po' di tempo, ma non riesco a capire come si faccia una funzione ricorsiva, fra gli esempi portava il calcolo del fattoriale, e lì qualcosina c'ho capito, ma del tipo calcolare la somma di un array di interi mi sembra una cosa criptica

Qualcuno di buon cuore può darmi una mano?
__________________
Oggetti attualmente in vendita:HD7950 + Phenom II 1090T /// HAF 922 ///
XFX R9 280X 230€
nasio91 è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 11:23   #2
Simonex84
Senior Member
 
L'Avatar di Simonex84
 
Iscritto dal: Jun 2003
Messaggi: 15829
Per esempio

Codice:
int somma(int A[]; int n)
{
   if (n=0) {
      return 0
   } else {
      return A[n] + somma(A, n-1)
   }
}
"A" è il vettore
"n" il numero di elementi

La logica è che la somma di un vettore è la somma del primo elemento più la somma del restante pezzo, la somma del restante peezzo, è la somma del primo elemento più la somma del restante pezzo, e così via.... finchè sei arirvato alla fine (return 0) che corrisponde al valore dell'elemento dopo la fine del vettore

Ultima modifica di Simonex84 : 16-02-2015 alle 11:35.
Simonex84 è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 11:34   #3
nasio91
Senior Member
 
L'Avatar di nasio91
 
Iscritto dal: Oct 2009
Città: Lecce
Messaggi: 1356
Quote:
Originariamente inviato da Simonex84 Guarda i messaggi
Per esempio

Codice:
int somma(int A[]; int n)
{
   if (n=0) {
      return 0
   } else {
      return A[n] + somma(A, n-1)
   }
}
"A" è il vettore
"n" il numero di elementi
scusa la domanda da tremendo ignorante, credo già di stare per sparare una stronzata, ma sbagliando si impara

return A[n]+somma(A,n-1)

vuol dire prendere l'elemento di A puntato da n e richiamare la funzione somma che andrà a prendere l'elemento n-1 di A?
__________________
Oggetti attualmente in vendita:HD7950 + Phenom II 1090T /// HAF 922 ///
XFX R9 280X 230€
nasio91 è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 11:36   #4
Simonex84
Senior Member
 
L'Avatar di Simonex84
 
Iscritto dal: Jun 2003
Messaggi: 15829
Quote:
Originariamente inviato da nasio91 Guarda i messaggi
scusa la domanda da tremendo ignorante, credo già di stare per sparare una stronzata, ma sbagliando si impara

return A[n]+somma(A,n-1)

vuol dire prendere l'elemento di A puntato da n e richiamare la funzione somma che andrà a prendere l'elemento n-1 di A?
n quando richiami la funzione indica il numero di elementi, all'interno della funziona viene usato anche come indice.

Leggi l'EDIT che ho aggiunto sopra
Simonex84 è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 13:57   #5
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 13043
Quote:
Originariamente inviato da Simonex84 Guarda i messaggi
Per esempio

Codice:
int somma(int A[]; int n)
{
   if (n=0) {
      return 0
   } else {
      return A[n] + somma(A, n-1)
   }
}
"A" è il vettore
"n" il numero di elementi

La logica è che la somma di un vettore è la somma del primo elemento più la somma del restante pezzo, la somma del restante peezzo, è la somma del primo elemento più la somma del restante pezzo, e così via.... finchè sei arirvato alla fine (return 0) che corrisponde al valore dell'elemento dopo la fine del vettore
Tre appunti:

1) Non controlli se l'indice è negativo (conviene passare un unsigned)
2) A[n] provoca un buffer overflow, in C gli indici degli array vanno da 0 a N-1.
3) Per le variabili è meglio usare nomi con lettere minuscole

Codice:
int somma(int a[], size_t n)
{
   if (n == 0) return 0;

   return a[n-1] + somma(a, n-1);
}
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 14:03   #6
Simonex84
Senior Member
 
L'Avatar di Simonex84
 
Iscritto dal: Jun 2003
Messaggi: 15829
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
Tre appunti:

1) Non controlli se l'indice è negativo (conviene passare un unsigned)
2) A[n] provoca un buffer overflow, in C gli indici degli array vanno da 0 a N-1.
3) Per le variabili è meglio usare nomi con lettere minuscole

Codice:
int somma(int a[], size_t n)
{
   if (n == 0) return 0;

   return a[n-1] + somma(a, n-1);
}
ma se do a nasio91 una soluzione perfetta poi lui non deve più fare nulla

a parte gli scherzi l'ho buttato giù al volo prima di andare a pranzo, comunque anche la tua non va bene perchè così non sommi l'elemento in prima posizione a(0)

così invece dovremmo esserci

Codice:
int somma(int a[], int n)
{
   if (n < 0) return 0;

   return a[n-1] + somma(a, n-1);
}
Simonex84 è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 14:07   #7
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 13043
Quote:
Originariamente inviato da Simonex84 Guarda i messaggi
ma se do a nasio91 una soluzione perfetta poi lui non deve più fare nulla

a parte gli scherzi l'ho buttato giù al volo prima di andare a pranzo, comunque anche la tua non va bene perchè così non sommi l'elemento in prima posizione a(0)
...
Aspetta eh... fammici pensare .

Quando n = 1 prendo a[0], quindi in teoria dovrebbe funzionare.

La cosa più semplice per capirlo è considerare che n indica il numero di elementi da sommare.

Quindi mi sa che la mia è ancora valida .

Cmq spero che i nostri ragionamenti aiutino nasio a capire.

Ultima modifica di WarDuck : 16-02-2015 alle 14:10.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 15:37   #8
M@Rk0
Senior Member
 
L'Avatar di M@Rk0
 
Iscritto dal: May 2008
Città: Torino - Valenza (AL)
Messaggi: 1221
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
Aspetta eh... fammici pensare .

Quando n = 1 prendo a[0], quindi in teoria dovrebbe funzionare.

La cosa più semplice per capirlo è considerare che n indica il numero di elementi da sommare.

Quindi mi sa che la mia è ancora valida .

Cmq spero che i nostri ragionamenti aiutino nasio a capire.
quando n==1 chiami somma(a,0)
ma in quest'ultima chiamata fai il check if n==0 e restituisci subito 0, non il contenuto di a[0]
quindi correggendo (io non lo scriverei mai così) sarebbe:
Codice:
int somma(int a[], size_t n)
{
   if (n == 0) return a[n];

   return a[n-1] + somma(a, n-1);
}

resta il fatto che la somma degli elementi di un array si potrebbe senza problemi calcolare iterativamente, aggirando a monte il problema

Ultima modifica di M@Rk0 : 16-02-2015 alle 15:43.
M@Rk0 è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 17:55   #9
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2794
Quando n=1 return a[n-1] + somma(a, n-1) cioè a[0] + somma(a, 0) cioè a[0] + 0 quindi è corretto
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 17:59   #10
Simonex84
Senior Member
 
L'Avatar di Simonex84
 
Iscritto dal: Jun 2003
Messaggi: 15829
Quote:
Originariamente inviato da M@Rk0 Guarda i messaggi

resta il fatto che la somma degli elementi di un array si potrebbe senza problemi calcolare iterativamente, aggirando a monte il problema
in questo esempio usare la ritorsione è una forzatura a scopo didattico (userei anche io un ciclo), però è bene prenderci la mano perché una tecnica di programmazione molto utile
Simonex84 è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 19:21   #11
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 13043
Quote:
Originariamente inviato da M@Rk0 Guarda i messaggi
quando n==1 chiami somma(a,0)
ma in quest'ultima chiamata fai il check if n==0 e restituisci subito 0, non il contenuto di a[0]
...
E dev'essere così.

L'ultimo passo rimane: a[0] + 0, che quindi è corretto .

Quote:
Originariamente inviato da M@Rk0 Guarda i messaggi
resta il fatto che la somma degli elementi di un array si potrebbe senza problemi calcolare iterativamente, aggirando a monte il problema
Chiaro, ma l'autore del thread voleva delucidazioni sulla versione ricorsiva.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 19:37   #12
oNaSsIs
Member
 
L'Avatar di oNaSsIs
 
Iscritto dal: Apr 2007
Messaggi: 182
Al di là della questione sugli indici del vettore restituito, il problema credo sia un altro, ovvero che ti concentri troppo sull'aspetto implementativo e poco sull'aspetto matematico. Devi provare a scrivere la funzione ricorsiva prima in termini matematici e poi vedrai che tradurla in qualsiasi linguaggio di programmazione diventa un problema banale.

Il fattoriale, che già ti è chiaro può essere definito come
Codice:
factorial 0 = 1
factorial n = n * factorial (n - 1)
Quello che ho scritto è codice Haskell, ma ho fatto questa scelta semplicemente perché è un linguaggio molto ad alto livello con una notazione vicinissima a quella matematica.
Il codice significa la seguente cosa. Il fattoriale di 0 è uguale 1, mentre il fattoriale di un generico numero n è uguale a n moltiplicato il fattoriale di n-1. Mi sembra piuttosto semplice da interpretare.
Personalmente sono abituato a scrivere prima il caso generale (la seconda riga dell'esempio) e poi il caso base (la prima riga). Questo perché in pratica il caso base serve come condizione di arresto della ricorsione. Ripeto, è solo un consiglio e non una regola.

Il tuo problema di calcolare la somma di un vettore può quindi essere risolto come:
Codice:
sum []     = 0
sum (head:tail) = head + sum tail
Considerando che (head:tail) scompone il vettore affinché head contenga la testa del vettore, ovvero il primo elemento, e tail la sua coda, ovvero tutti i restanti elementi, nel seguente esempio abbiamo:
Codice:
vettore = [3,5,6,7,8,2]
quindi
head = 3
tail = [5,6,7,8,2]
La funzione ricorsiva della sommatoria di un vettore, può quindi essere pensata nel caso generale come la somma del primo elemento più la sommatoria della parte restante del vettore. Il caso base ovviamente è quello della lista vuota la cui somma assumiamo sia 0.
Questo è quello che dovrebbe essere il tuo modo di pensare, ad alto livello aiutandoti con una notazione vicina a quella matematica.

Ora purtroppo per te implementare questa funzione ricorsiva in C non può essere fatto in maniera diretta usando i vettori, quindi quello che si fa è usare un contatore che scorre il vettore durante la ricorsione.
Usando uno pseudo-codice simile a quello usato finora, ma più vicino al C:
Codice:
sum vect index = 
    if index < 0
        return 0
    else
        return vect[index] + sum vect (index-1)
Ho fatto questo giro lunghissimo e forse un po' complicato per mostrarti quello che dovrebbe essere il tuo modo di ragionare.
Per questo problema, come sottolineato anche da altri utenti, la ricorsione è un po' una forzatura, soprattutto perché l'implementazione in C con vettori forza l'uso di un contatore.
Al contrario, usando un altro linguaggio che supporta nativamente le liste il codice sarebbe risultato pressoché identico a quello che ho scritto prima in Haskell.
Ad esempio in Python:
Codice:
def sumList(list):
    if len(list)==0:
            return 0
    else:
            return list[0] + sumList(list[1:])
Come vedi, se trascuri la sintassi, la logica è esattamente la stessa. Nota che list[1:] è l'equivalente del tail definito in precedenza.
oNaSsIs è offline   Rispondi citando il messaggio o parte di esso
Old 18-02-2015, 14:15   #13
M@Rk0
Senior Member
 
L'Avatar di M@Rk0
 
Iscritto dal: May 2008
Città: Torino - Valenza (AL)
Messaggi: 1221
Quote:
Originariamente inviato da wingman87 Guarda i messaggi
Quando n=1 return a[n-1] + somma(a, n-1) cioè a[0] + somma(a, 0) cioè a[0] + 0 quindi è corretto
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
E dev'essere così.
L'ultimo passo rimane: a[0] + 0, che quindi è corretto .
si è vero, avevo letto male

Quote:
Originariamente inviato da Simonex84 Guarda i messaggi
in questo esempio usare la ritorsione è una forzatura a scopo didattico (userei anche io un ciclo), però è bene prenderci la mano perché una tecnica di programmazione molto utile
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
Chiaro, ma l'autore del thread voleva delucidazioni sulla versione ricorsiva.
altrettanto chiaro che fosse una battuta, o quando leggete non parsificate le emoticon? [segue faccina "asd"]
M@Rk0 è offline   Rispondi citando il messaggio o parte di esso
Old 19-02-2015, 20:32   #14
vbextreme
Member
 
L'Avatar di vbextreme
 
Iscritto dal: Dec 2013
Messaggi: 90
Codice:
int somma(int v[], int n)
{
    return ( --n ) ? v[n] + somma(v,n) :  v[n];
}
__________________
Easy framework per il linguaggio C.
vbextreme hack your life
vbextreme è offline   Rispondi citando il messaggio o parte di esso
Old 20-02-2015, 07:11   #15
Simonex84
Senior Member
 
L'Avatar di Simonex84
 
Iscritto dal: Jun 2003
Messaggi: 15829
Quote:
Originariamente inviato da vbextreme Guarda i messaggi
Codice:
int somma(int v[], int n)
{
    return ( --n ) ? v[n] + somma(v,n) :  v[n];
}
per utente alle prime armi io userei un codice più "semplice" e meno sintetico
Simonex84 è offline   Rispondi citando il messaggio o parte di esso
Old 03-03-2015, 03:41   #16
nasio91
Senior Member
 
L'Avatar di nasio91
 
Iscritto dal: Oct 2009
Città: Lecce
Messaggi: 1356
Quote:
Originariamente inviato da Simonex84 Guarda i messaggi
per utente alle prime armi io userei un codice più "semplice" e meno sintetico
Yep è un po criptica come codice... Grazie comunque a tutti ragazzi! Chiarissimi e disponibili
__________________
Oggetti attualmente in vendita:HD7950 + Phenom II 1090T /// HAF 922 ///
XFX R9 280X 230€
nasio91 è offline   Rispondi citando il messaggio o parte di esso
Old 03-03-2015, 09:31   #17
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Quote:
Originariamente inviato da vbextreme Guarda i messaggi
Codice:
int somma(int v[], int n)
{
    return ( --n ) ? v[n] + somma(v,n) :  v[n];
}
Ovviamente assumendo che n > 0. Per n == 0 va in crash.
__________________
In God we trust; all others bring data
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 03-03-2015, 09:35   #18
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Quote:
Originariamente inviato da Simonex84 Guarda i messaggi
così invece dovremmo esserci

Codice:
int somma(int a[], int n)
{
   if (n < 0) return 0;

   return a[n-1] + somma(a, n-1);
}
Andrai in crash per n == 0. Quella che aveva scritto warduck era invece corretta:

Codice:
int somma(int a[], size_t n)
{
   if (n == 0) return 0;

   return a[n-1] + somma(a, n-1);
}
__________________
In God we trust; all others bring data
sottovento è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED Sony Bravia 9 II: il True RGB alla prova, dove l...
Geely EX5, un mese al volante: il SUV elettrico cinese che ci ha sorpreso (quasi) senza riserve Geely EX5, un mese al volante: il SUV elettrico ...
Mova Z70 Ultra Roller Complete: motore potente, rullo di lavaggio e l'IA a guidare Mova Z70 Ultra Roller Complete: motore potente, ...
Dopo 23 anni di silenzio, Warcraft 3 spi...
Roblox sfida l'ecosistema gaming: app st...
OpenAI accusata di plagio dai migliori m...
Altro attacco hacker dell'IA: gli agenti...
Stiamo davvero perdendo il controllo del...
Microsoft perde un pilastro: Frank Shaw ...
Diablo V annunciato a sorpresa: il colpo...
Meno di 5 euro per il 5G: l'offerta Kena...
World of Warcraft: Forever è il Classic+...
La Serie A con DAZN e Amazon Prime con l...
Giochi Ubisoft su Steam senza Ubisoft Co...
Miami Beach ha autorizzato la maxi opera...
Apple regala un altro anno di funzioni s...
Alla fine è successo davvero: Vol...
Il meglio di Amazon del weekend in uno s...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 00:24.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v