Puntatori a Funzione[C]

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
antex
Prode Principiante
Messaggi: 85
Iscrizione: mercoledì 14 marzo 2012, 20:59

Re: Puntatori a Funzione[C]

Messaggio da antex »

antex ha scritto:EDIT: ho trovato un esempio più semplice, quando torno al PC lo posto...
No, niente di che.

@M_A_W, Non vorrei essere apparso impertinente nei tuoi confronti. Tu stesso hai scritto che quel codice era pessimo; ma se così è stato domando venia.
La discussione è molto interessante, che continui così. ;)
ixamit ha scritto:
antex ha scritto: Su questo sono pienamente d'accordo, in disaccordo con il citato Torvalds (se una struttura viene chiamata vps_t, non è certo facile immaginarsi che è una struttura!).
Si, quel nome dell'esempio non convince nemmeno me, ma convengo sul fatto che molte volte l'alias serva solo ad evitare di "battere"
qualche tasto in piu', indipendentemente da un eventuale utilizzo esterno della struttura dati. Ma cosa dire quando vps_t è puntatore?! Usiamo la "_p" come suffisso?!
Spero proprio di no. :) E se usiamo un puntatore a puntatore che facciamo, <x>_p_p? :o
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: Puntatori a Funzione[C]

Messaggio da gila75 »

Io inizio a non capirci più nulla :)
Credo che per i puntatori a funzione, possano essere comode le typedf, nei prossimi giorni vado avanti con lo studio.
Per le strutture, io non mi ci trovo proprio.
Che problema c'è a dire struct node *p ???
Ogni volta ti ricorda che stai trattando una struttura.
Viene anche detto nel link postato da ixamit.
Dove mi pare di aver letto che il typedf sulle strutture è deprecato (ma dovrei rivedere bene).
Mi pare anche che in una raccolta di programmi seri, linkato da M_A_W, le strutture siano dichiarate col tag e non con typedef,
ma anche qui (non sono sul mio pc) dovrei accertarmene, prima di dire sciocchezze.
Poi, penso che l'importante sia imparare a programmare, lo stile, le finezze, l'identazione, se pur importanti vengono dopo a mio avviso.
Della serie: idento perfettamente, ma non so fare un ciclo for....
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: Puntatori a Funzione[C]

Messaggio da vbextreme »

Non so a voi ma io sarei incappato molto spesso in codici simili a questo:

Codice: Seleziona tutto

int pf1( void(*print)(const char*),const char* s)
{
    print(s);
    return 1;
}

int pf2(int(*fcall)(void(*)(const char*), char*),void(*realp)(const char*),char * s)
{
    return fcall(realp,s);
}

int main(void)
{
    return pf2((int(*)(void(*)(const char*), char*))pf1,(void(*)(const char*))puts,"hello world");
}

E non pensiate che sia qualcosa di eccezzionale,anzi è una semplificazione del mondo reale,piu di una volta ho incontrato funzioni che accettano puntatori a funzione che accettano puntatori a funzione con piu parametri e giusto per star tranquilli tocca poi sempre fare il cast perchè l'altra libreria ha implementato la funzione in un'altro modo!

Codice: Seleziona tutto

typedef int(*PRINT)(const char*);
typedef int(*CALLPRINT)(PRINT,const char*);

int pf1(PRINT p ,const char* s)
{
    p(s);
    return 1;
}

int pf2(CALLPRINT fcall,PRINT realp,char *s)
{
    return fcall(realp,s);
}

int main(void)
{
    return pf2((CALLPRINT) pf1,(PRINT)puts,"hello world");
}
Semplice compatto pulito elegante.
(non ho modo di compilare il codice ma con un buon occhio di falegname dovrebbe andare bene :lol: )
E se usiamo un puntatore a puntatore che facciamo, <x>_p_p
Se ti piace....io per le matrici preferirei optare per:

Codice: Seleziona tutto

typedef int** IMATRIX;
Suona meglio non trovi? :lol:
Easy framework per il linguaggio C.
vbextreme hack your life
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: Puntatori a Funzione[C]

Messaggio da vbextreme »

scusa gila non ti avevo letto...
Per le strutture, io non mi ci trovo proprio.
Che problema c'è a dire struct node *p ???
Dipende dal contesto,in linea teorica non c'è niente di male.
Dopotutto però se sviluppi un software rubbrica, per immagazzinare nomi e numeri,diventa altamente superfluo quel struct,anzi spesso blocca la lettura del codice.

Codice: Seleziona tutto

typedef struct _PERSONA
{
    char nome[64];
    char cognome[64];
}PERSONA;

typedef struct _NUMERI
{
    char home[20];
    char cell[20];
    char fax[20];
}NUMERI;

typedef struct _RUBBRICA
{
    PERSONA p[100];
    NUMERI n[100];
    unsigned int count;
}RUBBRICA;

int main(void)
{
    RUBBRICA r;
    PERSONA p = {"vb","extreme"};
    
    rubbrica_init(&r);
    rubbrica_add(&r,&p);
    
    etc etc etc...
    
    return 0;
}

io farei cosi poi sei libero di inserirci struct.
Easy framework per il linguaggio C.
vbextreme hack your life
ixamit
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 499
Iscrizione: giovedì 14 novembre 2013, 10:16

Re: Puntatori a Funzione[C]

Messaggio da ixamit »

Questo e' l'ultimo mio messaggio in questo 3d, perche' mi sto rendendo conto che:
1) sto andando OT
2) sto confondendo gila
3) non porta a nessuna conclusione

Buon proseguimento,
~Max
Avatar utente
M_A_W_ 1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 856
Iscrizione: venerdì 15 febbraio 2013, 3:57
Desktop: KDE
Distribuzione: SuSE
Sesso: Maschile
Località: Un luogo geometrico
Contatti:

Re: Puntatori a Funzione[C]

Messaggio da M_A_W_ 1968 »

antex [url=http://forum.ubuntu-it.org/viewtopic.php?p=4554653#p4554653][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto: @M_A_W, Non vorrei essere apparso impertinente nei tuoi confronti. Tu stesso hai scritto che quel codice era pessimo; ma se così è stato domando venia.
Non ho avuto codesta impressione: il codice presentato era intenzionalmente e dichiaratamente una silloge di pessime codifiche riscontrate nel real world. D'altro canto, non ho problemi a mettermi in discussione nel confronto con programmatori di ogni esperienza e d'ogni età su questioni di engineering.
Come già richiamato, gli standard di codifica sono praticamente sempre il risultato di transazioni e accordi tra più esperti: dunque le argomentazioni, in questo campo, contano più dei singoli idiomi ed esempi isolati. Questo significa che, una volta sgombrato il campo dalle argomentazioni non valide, fallaci, e non corrette (cioé tutte quelle logicamente errate, o basate su premesse non vere) non rimane che fare appello solo a forme di razionalità meno codificate, valutando quanto le argomentazioni siano "buone" ossia psicologicamente convincenti e plausibili. Ovviamente qui nulla può essere misurato in modo attendibile e ripetibile, specialmente parlando in generale del rapporto tra uomo e codice sorgente. Possiamo solo basarci sull'esperienza: alla fine, la "bontà" di un sorgente è in qualche modo funzione della comprensibilità della sua semantica da parte di uno sviluppatore, o se vogliamo della tendenza a produrre errori disastrosi quando un programmatore X va ad eseguire su tale sorgente un refactoring o una modifica. Il che trascende la definizione di eleganza di una dimostrazione, anche se i due concetti sono in qualche misura connessi.

Riguardo a Torvalds, e rispondendo indirettamente anche a ixamit (che ha abbandonato il thread, ma sperabilmente ci legge), in realtà avevo già anticipato il tema. Mi autocito:
M_A_W_ 1968 ha scritto:In altri frangenti, come nel rilascio dei sorgenti al pubblico indistinto, fa sempre comodo adottare una delle guide di stile pubblicamente disponibili (ad esempio le guidelines GNU/Linux o BSD, o gli omologhi resi disponibili in qualche dipartimento universitario, o su qualche testo...): se non altro, il lettore del codice saprà cosa attendersi.
Tuttavia, la maggioranza delle norme di stile non concorda con i vincoli del KLCS, che è comunque riferito ad un contesto piuttosto verticale e limitato. Le convenzioni di naming usate nel real world per rendere maggiormente significative le typedef relative a puntatori e tipi definiti dall'utente sono numerose: una delle più diffuse è la (systems) hungarian notation, con la quale - piaccia o meno - presto o tardi tutti i professionisti hanno avuto a che fare, se non altro leggendo il codice di librerie e framework commerciali.

Riguardo alle typedef sui tipi di default, in stile C'99/MISRA per intenderci, credo sia davvero difficile dissentire sull'opportunità del loro uso sistematico, vista anche la spaventosa mole di codice (anche e soprattutto C'89) esistente nel mondo del cross-compiling C che adotta esplicitamente tale convenzione o un suo sottinsieme.

In chiusura, una chiosa all'ultimo intervento di ixamit. Sfortunatamente, l'unica affermazione conclusiva che si può fare in merito all'intera questione è solo un omaggio al capitano de La Palice: se la programmazione è il vostro mestiere, siate pronti anche ad adeguarvi a standard di codifica che vi appaiono arbitrari e discutibili, poiché troverete sempre qualcuno che li ha eletti a campioni di leggibilità (magari per alzata di mano: ho visto anche codesti spettacoli, in softwarehouses "moderne" e "giovani" che vantano solo sviluppatori under 30 e si etichettano con ludibrio "agile" e "lean").

Se è vero che è la dose a fare il veleno, è anche vero che nel presente caso specifico la sensibilità individuale alla densità di typedef in un progetto di media complessità varia entro ampissimi margini. Fatti salvi, ovviamente, i casi banali già elencati a sufficienza nel corso del thread, ed in una quantità esorbitante di manualistica elementare, per il resto ciascuno sviluppatore ha pieno diritto a coltivare le proprie idiosincrasie.
Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo...

"...in una società che sembra sempre più spaventata dai problemi troppo articolati e che rigetta come un corpo estraneo ogni elemento di complessità, sapremo ancora come utilizzare il parere degli esperti?"
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: Puntatori a Funzione[C]

Messaggio da gila75 »

ixamit [url=http://forum.ubuntu-it.org/viewtopic.php?p=4554691#p4554691][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Questo e' l'ultimo mio messaggio in questo 3d, perche' mi sto rendendo conto che:
1) sto andando OT
2) sto confondendo gila
3) non porta a nessuna conclusione

Buon proseguimento,
~Max
Allora ragazzi...
La discussione è vero, sta andanto un po' OT, si era partiti coi puntatoti a funzione e siamo sconfinati sul typedef.
Ma è colpa mia :)
Pregherei utenti come ixamit, di non abbandonare il 3d, ogni consiglio per me è valido e ben accetto.
E non semetterò mai di ringraziarvi.
Il fatto di confondermi ixamit, non ti preoccupare, cerco di leggere e rileggere e valutare bene ogni consiglio.
Poi ovvio, essendo voi molto più avanti di me, faccio un po' fatica. Ma senza fatica non si fa nulla nella vita.
Facciamo così: io domani o dopo provo a scrivere il codice di vbextreme senza typedef, in modo da poter
appprezzare pregi e difetti.
Poi sul typedf, al limite si può aprire una discussione a se.
Io vorrei proseguire col quick sort e dove tutti i puntatori a funzione sono richiesti.
Vi va l'idea?
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: Puntatori a Funzione[C]

Messaggio da vbextreme »

Gila un bel esercizio che ti permette di imparare molto sarebbe:
-Scrivere una funzione generica per il sorting che accetti 3 parametri.
--il primo parametro sarà il vettore stesso
--il secondo la funzione di sort voluta
--il terzo la funzione di comparazione voluta.
-La suddetta funzione oltre a riordinare il vettore dovrà calcolare il numero di confronti eseguiti per effetture tutto il riordino.

Provaci,è semplice.
Easy framework per il linguaggio C.
vbextreme hack your life
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: Puntatori a Funzione[C]

Messaggio da gila75 »

vbextreme [url=http://forum.ubuntu-it.org/viewtopic.php?p=4554880#p4554880][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Gila un bel esercizio che ti permette di imparare molto sarebbe:
-Scrivere una funzione generica per il sorting che accetti 3 parametri.
--il primo parametro sarà il vettore stesso
--il secondo la funzione di sort voluta
--il terzo la funzione di comparazione voluta.
-La suddetta funzione oltre a riordinare il vettore dovrà calcolare il numero di confronti eseguiti per effetture tutto il riordino.

Provaci,è semplice.
Ci proverò...
Ma intendi usando il quick sort?
Provaci,è semplice.
Certo.... :o
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: Puntatori a Funzione[C]

Messaggio da vbextreme »

la funzione puo accettare qualsiasi algoritmo di sorting quindi ovviamente anche la qsort.(per adesso basta anche solo che accetti lei)
É semplice nel senso che é basato praticamente solo sul corretto uso dei puntatori a funzione,se riesci puoi passare al capitolo sucessivo ad occhi chiusi.
Se incontri difficolta e ti trovi in panico,prova ad aiutarti con le typedef.
Easy framework per il linguaggio C.
vbextreme hack your life
antex
Prode Principiante
Messaggi: 85
Iscrizione: mercoledì 14 marzo 2012, 20:59

Re: Puntatori a Funzione[C]

Messaggio da antex »

M_A_W_ 1968 [url=http://forum.ubuntu-it.org/viewtopic.php?p=4554705#p4554705][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Ovviamente qui nulla può essere misurato in modo attendibile e ripetibile, specialmente parlando in generale del rapporto tra uomo e codice sorgente. Possiamo solo basarci sull'esperienza: alla fine, la "bontà" di un sorgente è in qualche modo funzione della comprensibilità della sua semantica da parte di uno sviluppatore, o se vogliamo della tendenza a produrre errori disastrosi quando un programmatore X va ad eseguire su tale sorgente un refactoring o una modifica. Il che trascende la definizione di eleganza di una dimostrazione, anche se i due concetti sono in qualche misura connessi.
È un piacere leggerti. :birra:
Fatti salvi, ovviamente, i casi banali già elencati a sufficienza nel corso del thread, ed in una quantità esorbitante di manualistica elementare, per il resto ciascuno sviluppatore ha pieno diritto a coltivare le proprie idiosincrasie.
Ahah! :D Mi fai morire!
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: Puntatori a Funzione[C]

Messaggio da gila75 »

Ho provato a fare l'esempio proposto da vbextreme:
Non ho ancora implementato il conteggio di quante volte deve eseguire le comparazioni per riordinare il vettore...devo ragionare un po'.
Comunque, ecco cosa è saltato fuori:
Versione typedef:

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>
#define N 5

typedef int (*ptr)(const void*,const void*);

int compara (const void * a, const void * b); //prototipo funzione

int compara (const void * a, const void * b)
	{
		return ( *(int*)a - *(int*)b );
	}



int  main()
{
    int i;
    int array[N]={5,4,3,2,1};
    qsort(array, N, sizeof(int),(ptr) compara);
    for (i=0; i<N; i++)
    {
        printf ("%d\n", array[i]);
	}
    return 0;
}
Versione normale:

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>
#define N 5

int compara (const void * a, const void * b)
	{
		return ( *(int*)a - *(int*)b );
	}

 

int  main()
{
    int i;  
    int array[N]={33,55,18,87,0};
    int(*ptr)(const void*, const void*)=compara;
    qsort(array, N, sizeof(int),(*ptr));
    for (i=0; i<N; i++)
    { 
    printf ("%d\n", array[i]);
	}
    return 0;
}


e versione che richiama semplicemente una funzione (senza puntatore a funzione) :

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>
#define N 5

int compara (const void * a, const void * b)
	{
		return ( *(int*)a - *(int*)b );
	}

 

int  main()
{
    int i;  
    int array[N]={33,55,18,87,0};
     
    qsort(array, N, sizeof(int),compara);
    for (i=0; i<N; i++)
    { 
    printf ("%d\n", array[i]);
	}
    return 0;
}


e a tal proposito chiedo: perchè usare un puntatore a funzione se posso usare direttamente una funzione?

Codice: Seleziona tutto

 qsort(array, 5, sizeof(int),compara);
Spero siano corretti i codici, anche se sono cose elementari :shy:
Più avanti cerco di fare l'ordinamento con le stringhe.
Avatar utente
Actarus5
Prode Principiante
Messaggi: 220
Iscrizione: mercoledì 3 luglio 2013, 17:15
Desktop: Mate
Distribuzione: Fedora
Località: Abutalabashuneba

Re: Puntatori a Funzione[C]

Messaggio da Actarus5 »

Gila un'osservazione veloce sul primo codice:
gila75 ha scritto:

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>
#define N 5

typedef int (*ptr)(const void*,const void*);

int compara (const void * a, const void * b); //prototipo funzione

int compara (const void * a, const void * b)
	{
		return ( *(int*)a - *(int*)b );
	}



int  main()
{
    int i;
    int array[N]={5,4,3,2,1};
    qsort(array, N, sizeof(int),(ptr) compara);
    for (i=0; i<N; i++)
    {
        printf ("%d\n", array[i]);
	}
    return 0;
}
A che ti serve quel typedef se poi alla funzione compara passi comunque i 2 parametri come const void?
Cambiala così, in questo modo non devi deferenziare i puntatori e ci guadagni in leggibilità visto che passi direttamente i parametri che ti servono, oltre a ridurre la possibilità di errore con i vari cast:

Codice: Seleziona tutto

int compara (int * a, int * b)
{
return (*a-*b );
}
"An extremely helpful console message: “SPANK! SPANK! SPANK! Naughty programmer!”. Really, I’m not joking about that one."
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: Puntatori a Funzione[C]

Messaggio da gila75 »

Giusto, grazie Actarus...ma col typedef, se hai letto tutto il 3d, non ho molta dimestichezza
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: Puntatori a Funzione[C]

Messaggio da vbextreme »

Gila non hai svolto correttamente l'esercizio.
Ho scritto che devi creare una funzione che accetti 3 parametri,il primo un vettore,il secondo una funzione di sort ed il terzo una funzione di comparazione.
Poi richiamerai la suddetta funzione dal main di un programma,tu invece non hai fatto altro che usare la qsort.
Il protototipo sarà una fattispece di:

Codice: Seleziona tutto

int vsort( void* v, CALLSORT fncsort, CALLCMP cmp);
Ho usato apposta degli pseudo typedef per non risolverti l'esercizio.
e nel main la userai cosi:

Codice: Seleziona tutto

...
ret = vsort(vettore, qsort, compara);
...
Buon lavoro.
Easy framework per il linguaggio C.
vbextreme hack your life
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: Puntatori a Funzione[C]

Messaggio da gila75 »

Non ti seguo :(
è vero che ho fa fatto un semplice quick sort ora che me le fai notare.
Ma non ho capito bene cosa intendi:
CALLSORT sarebbe il nome del puntatore che punta a quick sort e
CALLCMP quello che punta alla comparazione?
Scusami vbextreme, ma a quest'ora sono anche un po' stanco e divento più zuccone del solito :)
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: Puntatori a Funzione[C]

Messaggio da vbextreme »

si esatto gila non ho scritto nella forma estesa perchè altrimenti ti avrei tolto tutto il divertimento.CALLCMP sarà quindi uguale alla tua typedef ptr.
Ora riposa poi finisci l'esercizio.Non sei obbligato ad usare le typedef.
Easy framework per il linguaggio C.
vbextreme hack your life
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: Puntatori a Funzione[C]

Messaggio da gila75 »

Purtroppo, svolgendo l'esercizio proposto da vbextreme, mi accorgo di non aver ancora padronanza sui puntatori a funzione.
Ok, l'esempio didattico, l'ho capito:

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
void prova(int x)
{
    x=x+100;
    printf ("ciao mondo %d\n",x);     
}

int main(void)
{
    int a=19;
    void (*ptr)(int)=prova;
    (*ptr)(a);     
    return 0;
}
Fin qui, nessun problema. Ma già mi sorge un dubbio:

Codice: Seleziona tutto

void (*ptr)(int)=prova;
e perchè non

Codice: Seleziona tutto

void (*ptr)(int)=&prova;
stiamo creando un puntatore che deve essere indirizzato alla funzione prova, quindi perchè l'operatore & non ci va?
Forse è come negli array e stringhe, che è scontato che puntino all'inizio, al primo elemento?
Qui è implicito che si punta "all'inizio" della funzione?
Detto questo, i problemi sono insorti nel passare ad una funzione un puntatore a funzione.
Io ho provato questo codice, scritto da me, ma non funziona e da un sacco di warning e errori:

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>
void prova_stampa ();
int foo(int a,int b,void **ptr_stampa);


void prova_stampa ()
{
    printf ("ciao\n");
    return ;
}

int foo(int a,int b,void **ptr)
{
    *(ptr);
    return a+b;
}

int  main()
{
   
    int ris;
    int a=10;
    int b=15;
    void   (*ptr_stampa)(void)=prova_stampa;
    
    ris=foo (a,b,&ptr_stampa );
    printf ("%d\n", ris);
    return 0;
}


Qui, pensavo di passare il puntatore stampa, tramite & già citato prima:

Codice: Seleziona tutto

void   (*ptr_stampa)(void)=prova_stampa;
    
    ris=foo (a,b,&ptr_stampa );

e qui

Codice: Seleziona tutto

int foo(int a,int b,void **ptr)
{
    *(ptr);
    return a+b;
}
ho messo il doppio ** perchè dal main ho passato un puntatore, quindi nella funzione foo, vado a lavorare con puntatore a puntatore.

Codice: Seleziona tutto

*(ptr);
Qui col puntatore, pensavo di puntare alla funzione che stampa, ma evidentemente il discorso è sballato...perchè?
Passare puntatori a funzione, lo so fare, l'ho fatto con le liste, ma qui, dov'è la differenza?
Non capisco.
Guardando poi su un'altro manuale ho trovato questo modo:

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>
void print () 
{
    printf ("ciao\n");
    return;
}

int foo (int a,int b,void (*f)(void))
{
    f();
    return a+b;
}

int  main()
{
    int a=10;
    int b=10;
    int res;
    res=foo (a,b,print);
    printf ("%d\n",res);

    return 0;
}

Che funziona.
La cosa triste, è che come ho pensato io, non va bene per nulla, e mi fa pensare che del c...non ho capito un c :D
Cosa sbaglio nel mio ragionamento?
In fondo passo un puntatore a funzione, come dicevo prima..ma non va!!
Avrò detto un sacco di sciocchezze, lo so, ma se qualcuno mi facesse chiarezza...maledetti manuali che si fermano all'esempio didattico!!! :devilmad:
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: Puntatori a Funzione[C]

Messaggio da vbextreme »

ho poco tempo ma il void* é un puntatore generico mentre a te serve un puntatore a funzione che sono due cose opposte,uno accede ad un'area di memoria,l'altro salta in un'area della memoria.Ho semplificato moolto.
Quindi il primo parametro che punta ad un vettore di tipo indefinito sarà void*,poi avrai due puntatori a funzione e per di piu uno l'hai già scritto pochi messaggi sopra.
Io ti consiglio vivamente di provarci con le typedef.
Easy framework per il linguaggio C.
vbextreme hack your life
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: Puntatori a Funzione[C]

Messaggio da gila75 »

L'errore grosso che ho commesso è:

Codice: Seleziona tutto

 void   (*ptr_stampa)(void)=prova_stampa;
    
    ris=foo (a,b,&ptr_stampa );
Cioè pensare di passare il puntatore che punta a prova stampa.
Quando invece dovevo fare:

Codice: Seleziona tutto

 ris=foo (a,b,prova_stampa );
e poi nella funzione foo specificare i parametri accettati da prova stampa:

Codice: Seleziona tutto

ris=foo (a,b,prova_stampa );
.....
int foo(int a,int b,void (*f)(void))
{
    (*f)();
    return a+b;
}

però ugualmente non capisco perchè non posso passare il puntatore a funzione come si fa nelle liste e poi usare il doppio **...

Questo è un esempio didattico

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>

void prova_stampa_1 ();
void prova_stampa_2 ();
int foo(int a,int b,void (*f_2)(void), void (*f_1)(void) );


void prova_stampa_1 ()
{
    printf ("word\n");
    return ;
}

void prova_stampa_2 ()
{
    printf ("hello ");
    return ;
}


int foo(int a,int b,void (*f_2)(void), void (*f_1)(void))
{
    (*f_2)();
    (*f_1)();
    return a+b;
}

int  main()
{
   
    int ris;
    int a=10;
    int b=15;
    ris=foo (a,b,prova_stampa_2,prova_stampa_1 );
    printf ("%d\n", ris);
    return 0;
}

e in effetti qui si nota la carenza della typedf:

Codice: Seleziona tutto

int foo(int a,int b,void (*f_2)(void), void (*f_1)(void))
se le specifiche dei parametri sono molti, si finisce per non capire nulla, giusto?
Ma quello che mi preme più di tutto (senza pressarvi ) è:
però ugualmente non capisco perchè non posso passare il puntatore a funzione come si fa nelle liste e poi usare il doppio **...
Mi autocito :D sto impazzendo!!! :sisi:
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 2 ospiti