Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Deep Tech Revolution: così Area Science Park apre i laboratori alle startup
Deep Tech Revolution: così Area Science Park apre i laboratori alle startup
Siamo tornati nel parco tecnologico di Trieste per il kick-off del programma che mette a disposizione di cinque startup le infrastrutture di ricerca, dal sincrotrone Elettra ai laboratori di genomica e HPC. Roberto Pillon racconta il modello e la visione
HP OMEN MAX 16 con RTX 5080: potenza da desktop replacement a prezzo competitivo
HP OMEN MAX 16 con RTX 5080: potenza da desktop replacement a prezzo competitivo
HP OMEN MAX 16-ak0001nl combina RTX 5080 Laptop e Ryzen AI 9 HX 375 in un desktop replacement potente e ben raffreddato, con display 240 Hz e dotazione completa. Autonomia limitata e calibrazione non perfetta frenano l'entusiasmo, ma a 2.609 euro è tra le proposte più interessanti della categoria.
Recensione Google Pixel 10a, si migliora poco ma è sempre un'ottima scelta
Recensione Google Pixel 10a, si migliora poco ma è sempre un'ottima scelta
Google ha appena rinnovato la sua celebre serie A con il Pixel 10a, lo smartphone della serie più conveniente se consideriamo il rapporto tra costo e prestazioni. Con il chip Tensor G4, un design raffinato soprattutto sul retro e l'integrazione profonda di Gemini, il colosso di Mountain View promette un'esperienza premium a un prezzo accessibile. E il retro non ha nessuno scalino
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 16-02-2015, 12: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, 12: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 12:35.
Simonex84 è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 12: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, 12: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, 14:57   #5
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12960
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, 15: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, 15:07   #7
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12960
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 15:10.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 16: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 16:43.
M@Rk0 è offline   Rispondi citando il messaggio o parte di esso
Old 16-02-2015, 18:55   #9
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2788
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, 18: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, 20:21   #11
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12960
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, 20: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, 15: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, 21: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, 08: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, 04: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, 10: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, 10: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


Deep Tech Revolution: così Area Science Park apre i laboratori alle startup Deep Tech Revolution: così Area Science P...
HP OMEN MAX 16 con RTX 5080: potenza da desktop replacement a prezzo competitivo HP OMEN MAX 16 con RTX 5080: potenza da desktop ...
Recensione Google Pixel 10a, si migliora poco ma è sempre un'ottima scelta Recensione Google Pixel 10a, si migliora poco ma...
6G, da rete che trasporta dati a rete intelligente: Qualcomm accelera al MWC 2026 6G, da rete che trasporta dati a rete intelligen...
CHUWI CoreBook Air alla prova: design premium, buona autonomia e qualche compromesso CHUWI CoreBook Air alla prova: design premium, b...
Il nuovo MacBook Neo ha una memoria SSD ...
Xbox Project Helix, le prime specifiche ...
Annunci pubblicitari sulla TV quando cam...
Prezzi aumentati del 50% durante la nott...
Sconti studiati per singolo utente: Sony...
Addio alla Kia Niro EV, il crossover sar...
Apple crede nel suo iPhone Fold: la prod...
Fortnite, un nuovo listino per i pacchet...
Ecco i nuovi Sonos Play ed Era 100 SL: d...
Razer svela il futuro del gaming potenzi...
Tre robot Narwal in offerta: pulizia aut...
Gracenote denuncia OpenAI: ChatGPT addes...
Microsoft AI Tour Milano: dall'efficienz...
Asus ExpertBook Ultra: Intel Core Ultra ...
Intel presenta i processori desktop Core...
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: 22:58.


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