Pagina 3 di 4
Re: [C] help ricorsione
Inviato: sabato 29 giugno 2013, 16:48
da gila75
Non è mai troppo presto per il debugger! Da noi in università spiegano prima come si usa un debugger, poi come si scrive hello world in C!

Comunque un debugger dovresti già averlo: gdb

Provalo, è veramente una manna dal cielo! Poi magari ci sarà tempo per utilizzare un IDE sofisticato con un sacco di funzionalità in più rispetto all'accoppiata gedit+gdb, ma se sei all'inizio il debugger non può che aiutarti a capire come avviene il flusso d'esecuzione del tuo codice

Non sapevo questa cosa, che ci fosse in ubuntu un debugger (gdb). Appena torno a casa lo provo. Se ho probelemi mi date una mano?
Grazie Tux
Re: [C] help ricorsione
Inviato: sabato 29 giugno 2013, 18:13
da faveroandrea
Ciao Gila, se vuoi imparare bene ad usare gdb ti rimando al sito del libro C Corso completo di programmazione, considerato uno dei migliori per imparare il C.
In Italia è pubblicato da apogeo (ed adesso nell' ultima edizione anche dalla Pearson).
L' apogeo online pubblica le appendici scaricabili gratuitamente, oltre al codice di tutti gli esercizi.
L' appendice G GNU parla proprio del gdb, e visto che spiega abbastanza bene ti consiglio di scaricarla (tanto è gratuita).
sito libro:http:
http://www.apogeonline.com/libri/9788850329540/scheda
appendice G:
http://www.apogeonline.com/2010/libri/9788850329540/ebook/pdf/2954_appendiceGGnu.pdf.
P.S. Spero che pubblicare i link sia valido. Se non è consentito vi prego di dirmelo, provvederò immediatamente a rimuoverli.
Re: [C] help ricorsione
Inviato: sabato 29 giugno 2013, 19:28
da gila75
Grazie Andrea! io sto studiando passo per passo da il libro di N. King (se non ricordo male il nome), e sono arrivato proprio ora alle funzioni ricorsive.
Ho trovato in rete la sequenza di fibonacci iterativa contro quella ricorsiva...pazzesco: quella ricorsiva impiega più di 20 secondi con input a n 40.
Quella iterativa..un nonnulla!!!
Per il debug, appena arrivo a casa (ora sto scrivendo non dal mio pc, e non è installato Ubuntu), provo a vedere come fare.
Venendo dalla programmazione a livello hobbistico dei pic, so per esperienza che senza il debug, in certi casi se in emme!!!
Una volta ho passato giorni solo per capire che l'impazzimento del programma era dato dal mancato azzeramento di un registro.
Quindi so che il debug prima o poi sarà da imparare, senza sarebbe come dire...ok..provo, vado a caso.
Il mio "sogno" sarebbe quello di capire l'assembly, che ti da piena padronanza della macchina, anche se è impensabile fare tutto con quello.
Non so fare calcoli in virgola mobile in assembly...aiuto!!
Anche questo l'ho appurato con mano dai microcontrollori che programmavo in assembler...ma penso che sia solo l'uno per mille
della complessità assembly di un processore da pc.
Comunque, davvero grazie a tutti. Siete davvero gentili, considernado (da quanto vedo), che siete tutti ad un livello molto alto rispetto a me, e ascoltare i dielmmi del principiante, non tutti ne hanno voglia e tempo!!
Re: [C] help ricorsione
Inviato: domenica 30 giugno 2013, 14:07
da Vincenzo1968
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
uint64_t FibonacciIterative(uint8_t n)
{
uint8_t i;
uint64_t F2 = 0, F1 = 1, res;
if ( n < 2 )
res = n;
else
for ( i = 2 ; i <= n; i++ )
{
res = F1 + F2;
F2 = F1;
F1 = res;
}
return res;
}
uint64_t FibonacciRecursive(uint8_t n)
{
if ( n < 2 )
return n;
else
return FibonacciRecursive(n - 1) + FibonacciRecursive(n - 2);
}
uint64_t FibonacciRecursiveFast(uint64_t prev, uint64_t curr, uint8_t n)
{
if( n == 0 )
return prev;
if( n == 1 )
return curr;
return FibonacciRecursiveFast(curr, curr + prev, n - 1);
}
int main ()
{
clock_t c_start, c_end;
double TempoImpiegato;
uint8_t num = 50;
c_start = clock();
printf("Fibonacci Iterative(%d) = %llu\n", num, (unsigned long long)FibonacciIterative(num));
c_end = clock();
TempoImpiegato = (double)(c_end - c_start) / CLOCKS_PER_SEC;
printf("Tempo impiegato -> %5.5f secondi\n\n", TempoImpiegato);
c_start = clock();
printf("Fibonacci Recursive Fast(%d) = %llu\n", num, (unsigned long long)FibonacciRecursiveFast(0, 1, num));
c_end = clock();
TempoImpiegato = (double)(c_end - c_start) / CLOCKS_PER_SEC;
printf("Tempo impiegato -> %5.5f secondi\n\n", TempoImpiegato);
c_start = clock();
printf("Fibonacci Recursive(%d) = %llu\n", num, (unsigned long long)FibonacciRecursive(num));
c_end = clock();
TempoImpiegato = (double)(c_end - c_start) / CLOCKS_PER_SEC;
printf("Tempo impiegato -> %5.5f secondi\n\n", TempoImpiegato);
return 0;
}

Re: [C] help ricorsione
Inviato: domenica 30 giugno 2013, 14:49
da gila75
Vincenzo, mi stai dicendo che ci può essere anche una ricorsione veloce?
Non posso provare i listati purtroppo, non ho installato nulla su questo pc.
Ma ci studio sopra a casa, nel frattempo vedo che le 2 funzioni sono diverse, quindi presumo proprio di si

Re: [C] help ricorsione
Inviato: domenica 30 giugno 2013, 15:16
da Vincenzo1968
Si Gila,
la funzione
FibonacciRecursive è più elegante e compatta ma, purtroppo, ha complessità esponenziale.
La funzione
FibonacciRecursiveFast è meno elegante ma ha complessità lineare(come la versione iterativa).
Altro esempio in cui la versione iterativa è equivalente, in efficienza(velocità di esecuzione), alla versione iterativa: calcolo del fattoriale:
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
uint64_t FactorialIterative(uint8_t n)
{
uint64_t product;
uint8_t i;
product = 1;
for (i = 2; i <= n; i++)
product *= i;
return product;
}
uint64_t FactorialRecursive(uint8_t n)
{
if (n == 0)
return 1;
return n * FactorialRecursive(n - 1);
}
int main ()
{
clock_t c_start, c_end;
double TempoImpiegato;
uint8_t num = 50;
c_start = clock();
printf("Factorial Iterative(%d) = %llu\n", num, (unsigned long long)FactorialIterative(num));
c_end = clock();
TempoImpiegato = (double)(c_end - c_start) / CLOCKS_PER_SEC;
printf("Tempo impiegato -> %5.15f secondi\n\n", TempoImpiegato);
c_start = clock();
printf("Factorial Recursive(%d) = %llu\n", num, (unsigned long long)FactorialRecursive(num));
c_end = clock();
TempoImpiegato = (double)(c_end - c_start) / CLOCKS_PER_SEC;
printf("Tempo impiegato -> %5.15f secondi\n\n", TempoImpiegato);
return 0;
}
Quindi: in generale le versioni iterative risultano più efficienti rispetto alle versioni ricorsive ma non sempre come abbiamo visto negli esempi.
Il vero motivo per cui si potrebbe preferire una soluzione iterativa anziché una ricorsiva, sta dunque, imho, nell'utilizzo delle risorse(stack) che, come hai potuto verificare, nelle versioni ricorsive potrebbe dare problemi(stack esaurito -> crash).
Re: [C] help ricorsione
Inviato: domenica 30 giugno 2013, 19:06
da Vincenzo1968
Re: [C] help ricorsione
Inviato: martedì 2 luglio 2013, 15:53
da Vincenzo1968
Eventualmente, per la generazione delle combinazioni, si può ottenere la versione iterativa seguendo questa guida:
https://secweb.cs.odu.edu/~zeil/cs361/w ... rsion.html
Partiamo dalla versione ricorsiva:
Codice: Seleziona tutto
void combinations(int v[], int start, int n, int k, int maxk)
{
int i;
if (k > maxk)
{
for (i = 1; i <= maxk; i++)
printf ("%i ", v[i]);
printf ("\n");
return;
}
for (i = start; i <= n; i++)
{
v[k] = i;
combinations (v, i+1, n, k+1, maxk);
}
}
Qui abbiamo una piccola difficoltà: la chiamata ricorsiva è all'interno di un ciclo for. La guida non spiega come intervenire in questi casi.
Noi possiamo adottare il seguente stratagemma: cambiamo il ciclo for simulando il compilatore: utilizziamo i salti(il famigerato
goto):
Codice: Seleziona tutto
void combinations(int v[], int start, int n, int k, int maxk)
{
int i;
if (k > maxk)
{
for (i = 1; i <= maxk; i++)
printf ("%i ", v[i]);
printf ("\n");
return;
}
i = start;
startFor:
if ( i > n )
goto endFor;
v[k] = i;
combinations(v, i+1, n, k+1, maxk);
i++;
goto startFor;
endFor:
;
}
A questo punto possiamo seguire la guida; utilizziamo uno stack esplicito.
Nello stack inseriamo soltanto i parametri
start e
k.
Non abbiamo la necessità di inserire gli altri parametri,
v,
n e
maxk, in quanto il loro valore non cambia tra una chiamata e l'altra.
Abbiamo, invece, la necessità di inserire, nello stack, la variabile locale
i.
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct tagParams
{
int start;
int k;
int i;
int ra;
} Params;
void combinations(int v[], int start, int n, int k, int maxk)
{
Params g_stack[1024];
Params currentParams;
Params newParams;
int top = -1;
int i;
currentParams.start = start;
currentParams.k = k;
currentParams.i = start;
currentParams.ra = 0;
g_stack[++top] = currentParams;
while ( top >= 0 )
{
currentParams = g_stack[top];
top--;
switch ( currentParams.ra )
{
case 0:
if (currentParams.k > maxk)
{
for (i = 1; i <= maxk; i++)
printf ("%i ", v[i]);
printf ("\n");
continue;
}
startFor:
if ( currentParams.i > n )
goto endFor;
v[currentParams.k] = currentParams.i;
currentParams.ra = 1;
g_stack[++top] = currentParams;
newParams.start = currentParams.i + 1;
newParams.k = currentParams.k + 1;
newParams.i = currentParams.i + 1;
newParams.ra = 0;
g_stack[++top] = newParams;
break;
case 1:
currentParams.i++;
goto startFor;
endFor:
;
break;
}
}
}
int main(int argc, char *argv[])
{
int n, k;
int *v;
clock_t c_start, c_end;
double TempoImpiegato;
if (argc != 3)
{
printf ("Uso: %s n k\n", argv[0]);
exit (1);
}
n = atoi (argv[1]);
k = atoi (argv[2]);
v = (int*)calloc(n + 1, sizeof(int));
if ( !v )
{
printf("Errore: memoria insufficiente.\n");
return -1;
}
c_start = clock();
combinations(v, 1, n, 1, k);
c_end = clock();
TempoImpiegato = (double)(c_end - c_start) / CLOCKS_PER_SEC;
printf("Tempo impiegato -> %5.5f secondi\n\n", TempoImpiegato);
free(v);
return 0;
}
Non otteniamo nessun vantaggio in termini di velocità di esecuzione.
In compenso, il nostro codice è, adesso, più complicato e di difficile lettura.

Re: [C] help ricorsione
Inviato: martedì 2 luglio 2013, 20:56
da gila75
Grazie Vincenzo, sto leggendo tutto con cura, anche se la cosa si sta facendo un po' tosta

Re: [C] help ricorsione
Inviato: mercoledì 17 luglio 2013, 20:57
da gila75
Stavo ancora guardando la ricorsione, mentre procedo col manuale, e facendo girare il programma di elevamento a potenza, mi sono chiesto se si poteva migliorare e come.
Stavo notando che per esempio 2^18=262144 , ma è vero anche che 4^9=262144.
Ora, visto che la ricorsione è pesante in termini di prestazione, non sarebbe meglio ottimizzare?
2^24, lo stack dovrebbe accumulare 24 chiamate, e poi successivamente "srotolarle", peggiorando le prestazioni, mentre invece si potrebbe fare : 256^3.
Io ho scritto un programma, che analizza l'esponente e lo riduce finchè non è dispari, e contemporaneamente, eleva la base al quadrato.
La mia domanda è se quelle righe di codice in più, hanno senso. Detto in breve, se il gioco vale la candela.
Col la ricorsione, io ritengo di si, mentre se fosse stato iterativo, direi proprio di no. Ma qui mi rimando a voi.
Il congelamento nello stack, penso sia abbastanza oneroso, e tra l'altro non illimitato.
Nei microcontrollori (famiglia pic) per esempio i salti tipo call, richiedono 2 cicli di clock, anzichè 1 come altre istruzioni...quindi.
Comunque il programma fa questo:
* analizza e divide l'esponente finchè non diventa dispari
* se è dispari, non fa nulla
insomma provate a dare un occhiata, e magari ho fatto tutto per nulla, ma se non altro rimane una "palestra" di programmazione...
Codice: Seleziona tutto
/*******************************************************************
* Programma ricorsivo elevamento a potenza
* modifiche:
* se abbiamo p.e. 2^12=4096
* si può benissimo fare 16^3=4096
* risparmiando cicli e "pile" nello stack (nel caso di ricorsione
* il programma valuta l'esponende e vede se è divisibile per 2
* se lo è, contemporaneamente la base diventa base^2
******************************************************************/
#include <stdio.h>
#include <stdlib.h>
/*********************************************************
* Funzione ricorsiva
*********************************************************/
unsigned long long int power (unsigned long long int x, int n) {
if (n==0)
return 1;
else
return x*power(x,n-1);
}
/*********************************************************/
int main(void) {
unsigned long long int base;
int exp;
int new_exp;
printf ("base ");
scanf("%llu",&base);
printf ("esponente ");
scanf("%d",&exp);
if (exp%2==0) {
while (1) {
if (exp%2==0) {
new_exp=exp/2;
exp=new_exp;
base=base*base; }
else {
printf ("nuovo esponente %d\n",new_exp);
break;}
}
}
else {
printf ("esponente dispari, non posso ottimizzare nulla, ris= %llu\n",power(base,exp));
return 0;}
printf ("nuovi valori (base,esponente) %llu %d\n", base, new_exp);
printf ("risultato= %llu\n", power(base,new_exp));
return 0;
}
Re: [C] help ricorsione
Inviato: mercoledì 17 luglio 2013, 21:32
da crap0101
mi sembra una buona idea, oltre al problema del limite di chiamate, facendo qualche prova al volo sembra velocizzarsi anche parecchio.
Re: [C] help ricorsione
Inviato: mercoledì 17 luglio 2013, 21:41
da gila75
Bene! hai provato il listato?
Ovviamente (non l'ho detto prima) in alcuni casi, il risultato viene fatto in maniera sia iterativa che ricorsiva (e qui ci sarebbe da fare una correzione al programma)
es 2^32..
4^16----->16^8----->256^4----->65536^2------>4294967296^1 (risultato)
In questo caso, non bisognerebbe passare nulla alla funzione ricorsiva in quanto si è potuto arrivare direttamente al risultato.
Invece il mio programma passa il risultato e l'esponente 1... che è inutile.
Al limite, si potrebbe risolvere con una condizione:
se new_exp=1 stampa risultato ed esci.
Ecco, ho corretto:
Codice: Seleziona tutto
/*******************************************************************
* Programma ricorsivo elevamento a potenza
* modifiche:
* se abbiamo p.e. 2^12=4096
* si può benissimo fare 16^3=4096
* risparmiando cicli e "pile" nello stack (nel caso di ricorsione
* il programma valuta l'esponende e vede se è divisibile per 2
* se lo è, contemporaneamente la base diventa base^2
******************************************************************/
#include <stdio.h>
#include <stdlib.h>
/*********************************************************
* Funzione ricorsiva
*********************************************************/
unsigned long long int power (unsigned long long int x, int n) {
if (n==0)
return 1;
else
return x*power(x,n-1);
}
/*********************************************************/
int main(void) {
unsigned long long int base;
int exp;
int new_exp;
printf ("base ");
scanf("%llu",&base);
printf ("esponente ");
scanf("%d",&exp);
if (exp%2==0) {
while (1) {
if (exp%2==0) {
new_exp=exp/2;
exp=new_exp;
base=base*base;
if (new_exp==1) { // se exp=1, salta ricorsione
printf ("risultato (salto ricorsione) %llu\n",base);
exit(0);
}
}
else {
printf ("nuovo esponente %d\n",new_exp);
break;}
}
}
else {
printf ("esponente dispari, non posso ottimizzare nulla, ris= %llu\n",power(base,exp));
return 0;}
printf ("nuovi valori (base,esponente) %llu %d\n", base, new_exp);
printf ("risultato= %llu\n", power(base,new_exp));
return 0;
}
Re: [C] help ricorsione
Inviato: giovedì 18 luglio 2013, 2:00
da crap0101
mah, quella mi sembra l'ultima cosa di cui preoccuparsi, è vero che fai una chiamata che può essee evitata, ma non è che ti risparmi chissà cosa. Piuttosto, potresti fare la stessa "semplificazione" (che, btw, invece che "sparsa" lì nel main ci starebbe bene dentro a una funzione) anche quando l'esponente è dispari e != 1, cioè diminuendo di un'unità l'esponente, facendo i calcoli come nel caso di esponente pari e alla fine moltiplicando la nuova base per la base originaria.
Re: [C] help ricorsione
Inviato: giovedì 18 luglio 2013, 8:38
da gila75
Si, potrei fare come dici tu, magari a tempo perso, faccio prove. Ma non vorrei sacrificare troppo lo "studio" sul manuale che ho preso. Ora devo iniziare i puntatori, croce e delizia del C

Ma ultima domanda crap0101: usare funzioni, non è anche quello un po' pesante per il calcolatore, se se ne può fare a meno?
Comunque quando io scrivo una funzione e da li deve fare il salto es:
printf ("%d risultato", mia_funzione (x,y));
Il programma deve "congelare" il tutto (presumo valori dei bit dei vari registri), tener traccia della posizione, fare la funzione, poi tornare, ripristinare i valori ecc...
Direi che è gravoso in termini di tempo/prestazioni.
Poi logico, se si va a vedere la potenza di calcolo di un processore moderno, è come dire non metto un peso di un kg su una macchina da 400 cavalli, perchè se pur poco rallenta, no?
Ma il concetto rimane quello.
Dalla mia poca esperienza che ho ancora col C, vedo che si fa molto uso delle funzioni, ma a volte potrebbero essere evitate.
Ma con le funzioni, è tutto più elegante vero.
Non lo so, forse perchè vengo da un passato hobbista coi pic, dove avevi 8 bit, un micro che girava con un quarzo da 8 Mhz, max 20 Mhz, uno stack profondo appena 8 livelli ecc...
e quindi l'ottimizzazione diventa un po' più una priorità.
Tutt'altra storia coi processori da pc, ma la "taccagneria" sulle risorse mi è un po' rimasta

Re: [C] help ricorsione
Inviato: giovedì 18 luglio 2013, 21:31
da crap0101
ti immagini scrivere qualcosa di un pelino complesso *senza* usare funzioni? O in qualunque modo si chiamino nel linguaggio che stai utilizzando? Niente riuso del codice, correggere eventuali errori diventa un incubo e un' enorme perdita di tempo, illegibilità del codice, etc. ...... .
Re: [C] help ricorsione
Inviato: giovedì 18 luglio 2013, 22:06
da Claudio_F
gila75 ha scritto:
Il programma deve "congelare" il tutto (presumo valori dei bit dei vari registri), tener traccia della posizione, fare la funzione, poi tornare, ripristinare i valori ecc...
Deve salvare sullo stack l'indirizzo di ritorno e gli argomenti (dati) su cui la funzione (ricevendoli come parametri) lavorerà. Lo stack di una CPU è molto più flessibile dello stack di un PIC che è dedicato esclusivamente agli indirizzi di ritorno.
Direi che è gravoso in termini di tempo/prestazioni.
Dipende, se, devi realizzare una temporizzazione precisa al nanosecondo anche una chiamata ha il suo peso, ma su un PC con un sistema operativo e altri programmi che girano in parallelo, non ha neppure senso pensare di fare una cosa del genere. I vantaggi superano grandemente gli svantaggi (e comunque in C l'ottimizzazione è molto elevata).
Usare le funzioni non è solo questione di eleganza, ma di scrivere codice modulare, testabile, comprensibile, riutilizzabile, oltre che di poter decomporre un compito complesso in parti più elementari. Le macchine di adesso non hanno più problemi di velocità come ai tempi delle CPU a 4MHz (e le funzioni si usavano lo stesso), mentre per l'essere umano rimane importante potersi concentrare su porzioni di codice/logica piccole e comprensibili.
la "taccagneria" sulle risorse mi è un po' rimasta
Buona cosa, ma teniamola per i sistemi embedded, sui PC adesso si può (finalmente) lavorare ad altissimo livello senza preoccuparsi troppo della macchina, o addirittura senza occuparsene proprio perché (come nel caso di Python e Java) gira tutto su macchina virtuale più velocemente di come una volta girava un compilato puro.
Re: [C] help ricorsione
Inviato: venerdì 19 luglio 2013, 16:40
da gila75
No, certo, ma intendevo dire che ho visto usare funzioni, quando invece poteva stare tutto nel main....ma ripeto, sono ancora un novello in C, e quindi molte cose le capirò poi
Grazie anche a te Claudio...sai, mi sono trovato parecchio spiazzato a passare dalla programmazione asm dei pic, alla programmazione C...non pensavo ci fossero così tante differenze!!!
Re: [C] help ricorsione
Inviato: venerdì 19 luglio 2013, 22:23
da Claudio_F
gila75 ha scritto:mi sono trovato parecchio spiazzato a passare dalla programmazione asm dei pic, alla programmazione C...non pensavo ci fossero così tante differenze!!!
L'ASM dei PIC è quanto di più involuto abbia mai visto, già quello di una CPU "vera" è tutto un altro mondo.
Con il C (e gli altri linguaggi ad alto livello) sei ad un livello superiore ai registri e alle operazioni binarie con 8 bit: chiami funzioni invece di subroutines, puoi usare variabili, numeri float, strutture dati come gli array, disponi di strutture di controllo flusso come if e for. Con i puntatori e l'allocazione dinamica della memoria puoi "espandere" i tuoi dati fino ad occupare tutta la memoria ma senza doverti occupare direttamente di indirizzi e pagine (come quell'incubo di PCLATH) ecc.
Poi ci sono i linguaggi ad altissimo livello con cui non ti occupi più nemmeno di puntatori, allocazioni di memoria, dichiarazioni dei tipi di dati, ma solo di "oggetti" con attributi e comportamenti individuali, giusto per fare un esempio in Python un oggetto numero intero ha dimensioni automatiche limitate solo dalla memoria disponibile, è normale scrivere due elevato alla 50mila senza doversi occupare di nient'altro, nè dichiarazioni di tipi, nè allocazioni di memoria, niente di niente:
a = 2**50000 (questa comodità e "potenza" ovviamente si paga con una minore velocità)
Re: [C] help ricorsione
Inviato: sabato 20 luglio 2013, 0:29
da gila75
Codice: Seleziona tutto
L'ASM dei PIC è quanto di più involuto abbia mai visto, già quello di una CPU "vera" è tutto un altro mondo.
E io che ci ho speso un bel po' di tempo per imparare e credevo di aver fatto anche cose carine per essere partito da zero....mi accoltelli così

Dai, tornado seri, certo ci credo che sia un paragone improprio tra un microcontrollore e un processore da pc.
Sarebbe come dire un petardo e una bomba, no?
Per quanto riguarda i linguaggi ad altissimo livello, non mi sono mai andati molto a genio.
Ok, due righe e fai molte cose...studi di meno e hai successi subito, ma cosa fa l'utente davvero di mano sua, quanto capisci?
Io ho optato per il C, perchè anche se oramai esistono altri linguaggi (java, c++,perl, python), rimane comunque un caposaldo della programmazione.
Trovare tutto pronto, non mi piace...
per tornare ai pic di prima, è come scrivere in C un codice o in asm, se hai delle rogne col c, non sai dove mettere mano, visto che una routine (che so per un lcd) la trovi già
confezionata, magari va a 4 linee, e se io la volessi a 8?
Certo col C tutto era più facile, ma come dici tu le comodità si pagano.
E qui uguale, il python da quello che capisco è veramente ad altissimo livello, non so quanto s'impara (se si parte da li intendo)
Re: [C] help ricorsione
Inviato: sabato 20 luglio 2013, 10:05
da Claudio_F
L'assembly dei PIC è stato ridotto all'osso per permettere istruzioni lunghe una parola eseguite nel minor tempo possibile, questo impone però dei limiti (hardware e software) che obbligano il programmatore a farsi carico di una grande quantità di piccoli dettagli che una CPU più evoluta (come è già uno Z80 del 1976 per esempio) non richiede.
In sostanza una vera CPU è studiata per facilitare la vita al programmatore con un ricco set di istruzioni, registri a 16/32 bit, salti condizionati, confronti su numeri con segno, moltiplicazioni e divisioni in hardware, ricerca in blocchi di dati ecc, mentre i PIC sono pensati solo per essere più economici possibili (il che ha portato a scelte che dal punto di vista del programmatore sono a dir poco sadiche).
Sono d'accordo su tutti i punti, diciamo che sono ambiti applicativi diversi. Ci sono cose per cui l'assembly è insostituibile, ma in genere non sono le stesse cose di cui ci si occupa con un linguaggio ad alto livello. In C si possono fare con molta semplicità calcoli con i logaritmi che in ASM sarebbe un suicidio... non che sia impossibile, visto che il C è realizzato con subroutines assembly, ma in un complesso programma matematico l'eccessiva "semplicità" dell' ASM è di ostacolo, serve lavorare ad un livello di astrazione maggiore.
Allo stesso modo ci sono ambiti applicativi in cui l'eccessiva "semplicità" del C è di ostacolo perché di nuovo bisognerebbe occuparsi di eccessivi dettagli non pertinenti alla logica su cui si lavora, anche in questo caso non che sia impossibile, visto che praticamente tutti i linguaggi di livello più alto sono a loro volta realizzati con funzioni C, ma se devo occuparmi di spostare dati avanti e indietro tra gli elementi di una lista vorrei principalmente "usarla", e non dover perdere tempo a scrivere anche il funzionamento a basso livello della lista, aggiornare i puntatori ai nodi, allocare/deallocare la memoria, debuggare la lista stessa (attività principale del pascaliano

) ecc.
Sono d'accordo anche sul fatto che per chi inizia l'eccessiva astrazione sia un ostacolo a capire "cosa succede sotto"... personalmente farei partire tutti dalla lettura dei datasheet + saldatura degli integrati + programmazione "a mano"
