Pagina 7 di 8

Re: Puntatori a Funzione[C]

Inviato: mercoledì 16 aprile 2014, 20:49
da gila75
Come in un post Gila dice che la scanf che dà problemi, ma stiamo scherzando?
in tanti qui dicono che scanf è inutile e si danno interpretazioni errate, esempi banali....

ma la scanf ha anche un argomento di ritorno, che sarebbe int

infatti la definizione di scanf è

Codice: Seleziona tutto
int scanf(const char *format, ...);
Allora, sono un principiante e non mi voglio lanciare in cose che so si e no.
Intendevo dire che è un po' deprecata e non sicura.
I problemi era per il fatto che tronca l'input al primo spazio.
Trovo più versatile usare getchar() e costruirmi la stringa.

Ovvio scanf la uso, ma a volte, se unita a getchar, da problemi.
lascia perdere per ora la qsort, insisti sulle funzioni e sui puntatori, ma questo è un mio consiglio, conta niente, per carità...
Vero ,ma la qsort, da lo spunto per molte riflessioni e approfondimenti...
secondo te che errori ci sono, se ve ne sono...
io non ne ho trovati, se non che

Codice: Seleziona tutto

int perGila (char **as, size_t l)
{
  size_t ciclo = 0;

  for (ciclo = 0; ciclo < l; ciclo++)
    printf ("[%u] %s\n", ciclo, as[ciclo]);

   return (ciclo);
}
non ritorna il numeri di scambi fatti da qsort per ordinare, ma semplicemente il numero di stringhe che compone l'array.
la costante MAXSTRINGHE bisogna usarla? puoi gentilmente spiegare come
Direi che non va usata, essendo

Codice: Seleziona tutto

char *astringa[] = { "Gila", "Tex", "Alex", "Anne Marie", "Verbose", "Earth Quake" };
Un vettore a puntatori di stringhe.
Un po' come le stringhe classiche penso, se io scrivo:

Codice: Seleziona tutto

char str[]="Ciao io sono Gila";

sarà il compilatore a determinare esattamente la dimensione del vettore.
La riprova ce l'ho facendo il solito:
sizeof (str)/sizeof(char);
E coi vettori di puntatori a stringhe, penso sia uguale,
Se io scrivo char*stringa[10]
vorrebbe dire che "istanzio" dieci puntatori, ma se poi non ho dieci stringhe, a cosa puntano ? A null...dove?
Discorso diverso se avessimo usato array bidimensionali di stringhe

Codice: Seleziona tutto

char mio_array[][10]

il codice che hai scritto, ho lasciato più o meno uguale, tranne che ho aggiunto un variabile globale per contare i cicli.
Ho cambiato anche il casting (solo perchè è una forma che conosco un po' meglio)

Codice: Seleziona tutto

int ast_confronto (const void *a, const void *b)
{
    const char **ia = (const char **)a;
    const char **ib = (const char **)b;
    return strcmp(*ia, *ib);
}
in

Codice: Seleziona tutto

return strcmp( *( char ** ) a, *( char ** ) b ) ;  
    
Credo siano inutili ia e ib, non so se era un trabocchetto :)
Come discusso altrove, non credo che la variabile globale sia una grossa ineleganza (se si può dire... :D ), ma sarebbe bello riuscire a passarla dalla funzione che compara, ma per ora non mi riesce :(
Ecco il codice:

Codice: Seleziona tutto

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

void perGila (char **, size_t l);
int ast_confronto (const void *, const void *);

int scambi=0;
int main (void)
{
    char *astringa[] = { "Gila", "Tex", "Alex", "Anne Marie", "Verbose", "Earth Quake","Jhonny" };
    size_t stringa_lun = sizeof(astringa) / sizeof(char *);
    
    
    printf ("indici componenti astringa %d\n", stringa_lun);
    perGila (astringa, stringa_lun);

    qsort(astringa, stringa_lun, sizeof(char *), ast_confronto);
    perGila (astringa, stringa_lun);
   return (0);
}

void perGila (char **as, size_t l)
{
    size_t ciclo = 0;
    for (ciclo = 0; ciclo < l; ciclo++)
    {
        printf ("[%u] %s\n", ciclo, as[ciclo]);
    }
    printf ("cicli ritornati dalla funzione perGila (char **, size_t): %u\n", scambi);
    return ;
}

int ast_confronto (const void *a, const void *b)
{
    ++scambi;
    return strcmp( *( char ** ) a, *( char ** ) b ) ;  
    
}
EDIT:
Mi sa che mi sono sbagliato su:
la costante MAXSTRINGHE bisogna usarla? puoi gentilmente spiegare come
Direi che non va usata, essendo
è possibile farlo, ma devo rivedere bene l'esempio.
A prima vista, funziona tutto bene solo se le stringhe sono in numero uguali alla definizione
# define N_STRINGHE 5
ma ci rifletto bene con calma

Re: Puntatori a Funzione[C]

Inviato: mercoledì 16 aprile 2014, 21:54
da M_A_W_ 1968
gila75 [url=http://forum.ubuntu-it.org/viewtopic.php?p=4564321#p4564321][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto: Allora, sono un principiante e non mi voglio lanciare in cose che so si e no.
Intendevo dire che è un po' deprecata e non sicura.
La funzione scanf() è ampiamente deprecata per quasi ogni tipo di utilizzo corrente (inclusa una miriade di esempi sbagliati nella manualistica di minore qualità e, peggio-mi-sento, sul web). Sono tollerati, e solo in ambito didattico, alcuni limitati campi di applicazione, come l'input su piccoli interi e poco altro. I motivi principali alla base di tali indicazioni, esposti in numerosi manuali di provata serietà, sono brevemente riassunti ad esempio in questa serie di post.

Re: Puntatori a Funzione[C]

Inviato: giovedì 17 aprile 2014, 7:05
da gila75
Grazie M_A_W.
Ho fatto 2 prove e ho letto il manuale, anche se sul mio non vi è nulla a riguardo, ma viene dichiarato così un array di puntatori:

char *str[]={"ciao","casa"};

Ho scritto due righe, e ho notato che se dichiaro il numero max di puntatori, ma non li sfrutto tutti il programma va in crash.

Codice: Seleziona tutto

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

int main(void)
{
    char *prova[3]={"cane","ciao"};
    printf ("%s\n",prova[0]);
    printf ("%s\n",prova[1]);
    if (prova[2]!=NULL)
        printf ("%s\n",prova[2]);
    
    return 0;
}
Se io tolgo il controllo if, il puntatore, non viene utilizzato e in fase di stampa, tento di stampare un valore fasullo.
Se il ragionamento è corretto, allora basterebbe mettere un controllo if, una cosa del genere:

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 80

int main(void)
{
    char *prova[MAX]={"cane","ciao","casa","gila","Ubuntu","Italia","1975"};
    int i;
    for (i=0; i<MAX; i++)
    {
        if (prova[i]!=NULL)
            {
                printf("%s\n",prova[i]);
            }
    }
    
    return 0;
}

Re: Puntatori a Funzione[C]

Inviato: giovedì 17 aprile 2014, 7:30
da vbextreme
Il codice che hai postato va in crash perchè presupponi che i puntatori siano automaticamente settati a NULL. Devi ricordare che il c non nasconde praticamente nulla ed è un c agnolino perfetto, fa solo quello che tu gli dici.
Avendo creato un vettore di puntatori, se non li setti tutti, sicuramente uno punterà ad un'area della memoria non valida, causando naturalmente un errore.

Riguarda alla scanf,io ad esempio l'ho capito da solo che è meglio non utilizzarla. Se ogni volta che uno scrive un programma con la scanf ha dei problemi allora è meglio usare un'altra funzione! Se aggiungiamo le ottime spiegazioni di MAW allora si può metterla definitivamente nel cestino.

Re: Puntatori a Funzione[C]

Inviato: giovedì 17 aprile 2014, 19:56
da gila75
Avendo creato un vettore di puntatori, se non li setti tutti, sicuramente uno punterà ad un'area della memoria non valida, causando naturalmente un errore.
Infatti se io definisco :

Codice: Seleziona tutto

char *str[3]={"marco", "gino"};
un puntatore è "vacante", e in fase di stama ho il crash.
Viceversa:

Codice: Seleziona tutto

char *str[3]={"marco", "gino","franco"}
Sarebbe corretto, giusto?
A sto punto, più comodo fare :

Codice: Seleziona tutto

char *str[]={"farnco","pippo"ecc...};
Il compilatore se ne occuperà per i fatti suoi.
Riguarda alla scanf,io ad esempio l'ho capito da solo che è meglio non utilizzarla. Se ogni volta che uno scrive un programma con la scanf ha dei problemi allora è meglio usare un'altra funzione! Se aggiungiamo le ottime spiegazioni di MAW allora si può metterla definitivamente nel cestino.
Io la uso per le prove didattiche, veloce e spiccia, molto di più che getchar(); , ma so bene che è meglio non usarla, o perlomeno con cautela e accortezza.
Peccato che sui manuali la propongano così spesso.

Re: Puntatori a Funzione[C]

Inviato: venerdì 18 aprile 2014, 19:41
da vbextreme
Io la uso per le prove didattiche, veloce e spiccia, molto di più che getchar(); , ma so bene che è meglio non usarla, o perlomeno con cautela e accortezza.
Peccato che sui manuali la propongano così spesso.
Il primo esercizio utilisso che userai per tutta la vita è il creare la funzione gets con parametro un puntatore a char e la sua dimensione massima. Ovvero fgets ma senza lo '\n' incorporato.
Se hai il k&r c'è un pezzo di codice bellissimo da dove partire.
Dovrai quindi prendere carattere per carattere e contare quanti te ne mancano.

Del resto la scanf rimane una funzione bella per quanto superflua date le funzioni contenute in "string.h"
Dopotutto l'input diventa tale dopo l'enter per cui my_gets con annesso minimicro parser elementare rimane la soluzione piu veloce,performante,sicura ed efficace.Se aggiungiamo che è semplice ricreare tutto anche per un neofita,diventa oltre che un buon esercizio un bel punto per iniziare a gongolarsi delle proprie capacità "programmative"

Re: Puntatori a Funzione[C]

Inviato: venerdì 18 aprile 2014, 20:23
da gila75
Io per il momento, quando devo fare le cose per bene (se per bene sono fatte...), uso getchar, memorizzando in un vettore e piazzando alla fine il carattere terminatore "\0",
Facendo diventare il vettore una stringa. Sempre che ne abbia bisogno: il carattere '\0' non è sempre necessario.
Logico se lavoriamo con stringhe e funzioni annesse (srtstr, strcat ecc...) allora li si, serve.
Il k&r ce l'ho e più avanti proverò a guardare. Ora voglio concludere questo capitolo...e mi mancano i vettori di puntatori a funzione.
Al solito il mio manuale liquida un po' l'argomento (ormai crederete che è una scusa :D ), ma non lo è.
Ho fatto un programmino di vettori di strutture, poi uso la qsort per ordinare sia in base ai numeri immessi, o, a scelta le stringhe sempre della struttura.
Sarebbe stato bello, integrare un vettore di puntatori a funzione, e in base alla scelta, richiamare il puntatore dall'array.
Sto cercando di capire come funzionano tali vettori...magari...chi avesse tempo e voglia, un piccolo esempio, sarebbe assai gradito ;)
Terrò a mente comunque Vbextreme di spulciare nel K&R, grazie.

Re: Puntatori a Funzione[C]

Inviato: venerdì 18 aprile 2014, 21:22
da gila75
Per ora, da prove sommarie, sono riuscito a fare questo piccolo esempio.
Credo che la logica sia così, anche se l'esempio è semplice e scarno:

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void f1 ();
void f2 ();

void f1 ()
{
    printf ("sono la funzione void f1\n");
    return;
}

void f2 ()
{
    printf ("sono la funzione void f2\n");
    return;
}

int main(void)
{
    
    void (*ptr_f1)(void)=f1;/* definisco puntatore a funzione di f1*/
    void (*ptr_f2)(void)=f2;/* definisco puntatore a funzione di f2*/

    /*************************************************
    * creo un vettore di puntatori a funzioni        *             
    * di tipo void e che come argomento hanno        *             
    * void                                           *
    **************************************************/

    void (*array_cmd[])(void)={ptr_f1,ptr_f2}; 
  
    array_cmd[0](); /* chaimo indice array 0=puntatore ptr_f1 (f1)*/
 
    
    return 0;
 }
         
tutto ok, con la compilazione normale (-Wall attivato)
ma se compilo con -pedantic, ottengo 2 warning:

Codice: Seleziona tutto

gila@ubuntu:~/Scrivania$ gcc -W -pedantic -Wall -g -o xx 3d.c
3d.c: In function ‘main’:
3d.c:28:5: warning: initializer element is not computable at load time [enabled by default]
3d.c:28:5: warning: initializer element is not computable at load time [enabled by default]
gila@ubuntu:~/Scrivania$ 

Ma su questo posso per il momento chiudere un occhio.
Al di la che l'esempio è veramente ridicolo e devo impegnarmi a fare qualcosa di più corposo, ho un altro dubbio:

Codice: Seleziona tutto

void (*array_cmd[])(void)={ptr_f1,ptr_f2}; 
inizializzo un array di puntatori a funzioni di tipo void e che non abbiano argomenti, quindi ancora void.
ma questo cosa significa?
Non posso fare un array di puntatori a funzioni diverse mi sembra di capire.
Non posso inserire un puntatore ad una funzione di tipo void, ma con argomento int, o che so io, tipo float, argomento float.
Riflettendo però, non posso nemmeno creare array misti. O lo faccio di tipo int, o float, o double, ma misti no.
O meglio lo posso fare ma con trucchetti e l'aiuto delle unioni.
Penso che il fatto di non poter fare array di puntatori a funzioni di tipi diversi, sia come detto sopra per gli array normali, e il C
mantiene anche qui la sua "filosofia".
Mi sa che il dubbio che ho suscitato, è lo stesso che si poneva vbextreme nel link messo da M_A_W.
Comunque, sono cose già più in la del mio bagaglio.
Mi confermate se ho detto giusto?

Re: Puntatori a Funzione[C]

Inviato: domenica 20 aprile 2014, 11:51
da matteovid
vedo che tutti quelli che hanno risposto alla mia affermazione della scanf, si sono subito affrettati a specificare che è deprecata... ok era una provocazione, ma anche una attenta esplorazione su quanti poi hanno veramente programmato.... su sistemi vari e con varie tipologie... e vari compilatori, sia posix che VMS che socket vari...

Ok ne prendo atto....

ma nessuno ha detto il perchè di questo
il codice che hai scritto, ho lasciato più o meno uguale, tranne che ho aggiunto un variabile globale per contare i cicli.
Ho cambiato anche il casting (solo perchè è una forma che conosco un po' meglio)

Codice: Seleziona tutto

 int ast_confronto (const void *a, const void *b)
    {
        const char **ia = (const char **)a;
        const char **ib = (const char **)b;
        return strcmp(*ia, *ib);
    }
in

Codice: Seleziona tutto

 return strcmp( *( char ** ) a, *( char ** ) b ) ; 

Credo siano inutili ia e ib, non so se era un trabocchetto :)
perchè sono inutili? Intendo ib e ia... nessun trabocchetto...

Lasciando stare all'aggiunta della costante per contare i cicli, che seppure sia importantissima e serve,
certamente Gila al tuo attuale livello dovresti sapere come implementare meglio ed senza uasare costanti... quella variabile conta cicli....

Invece nell'esempio che ti ho postato, vi è un leggerissimo errore, madornale e di difficile individuazione se applichi tale esempio in più file e con tantissime funzioni e altro... e non è nella funzione di confronto....

Apprezzo che hai implementato la funzione pointer sul confronto, come mi aspettavo

Matteo

Re: Puntatori a Funzione[C]

Inviato: domenica 20 aprile 2014, 18:35
da gila75
Riguardo alla scanf, non metto becco, ne parlerete tra di voi, so che è deprecata, ma ripeto, non dico nulla.
perchè sono inutili? Intendo ib e ia... nessun trabocchetto...
Intendevo dire che si può fare comodamente così:

Codice: Seleziona tutto

return strcmp( *( char ** ) a, *( char ** ) b ) ; 
Lasciando stare all'aggiunta della costante per contare i cicli, che seppure sia importantissima e serve,
certamente Gila al tuo attuale livello dovresti sapere come implementare meglio ed senza uasare costanti... quella variabile conta cicli...
Infatti nemmeno a me piace.
L'idea iniziale, era di passare un parametro alla funzione "compara", ma non so se aggiungendo quseto parametro, si vada in conflitto con la
funzione qsort.
Non so se mi spiego, ma per esempio se io faccio un puntatore a funzione (esempio sin), devo fare il puntatore come il prototipo della funzione:

Codice: Seleziona tutto

double (*punt_sin)(double)=sin;
Sono restato fedele al prototipo della funzione sin. Se io scrivo :

Codice: Seleziona tutto

double (*punt_sin)(double,double)=sin;
vado contro il prototipo di sin, e quindi ho un errore.
Non vorrei che la stessa cosa succedesse con qsort, aggiungendo un parametro in più alla funzione compare, che si aspetta solo due
const void *
Invece nell'esempio che ti ho postato, vi è un leggerissimo errore, madornale e di difficile individuazione se applichi tale esempio in più file e con tantissime funzioni e altro... e non è nella funzione di confronto....
qui sarà davvero dura che riesca a capire. Ho studiato come "frammentare" un programma con più files, ma ho solo studiato le basi.
Per esempio il makefile e rebuilding, non li so fare.
Ho ritenuto (forse erroneamente) che sia un argomento d'approfondire più in la. Magari sbaglio.
Grazie Matteo.
Intanto provo a vedere se trovo il modo di contare gli scambi senza la variabile globale.

Re: Puntatori a Funzione[C]

Inviato: lunedì 21 aprile 2014, 13:40
da Actarus5
il codice che hai scritto, ho lasciato più o meno uguale, tranne che ho aggiunto un variabile globale per contare i cicli.
Ho cambiato anche il casting (solo perchè è una forma che conosco un po' meglio)

Codice: Seleziona tutto

 int ast_confronto (const void *a, const void *b)
    {
        const char **ia = (const char **)a;
        const char **ib = (const char **)b;
        return strcmp(*ia, *ib);
    }
in

Codice: Seleziona tutto

 return strcmp( *( char ** ) a, *( char ** ) b ) ; 

Credo siano inutili ia e ib, non so se era un trabocchetto :)
Beh Gila, converrai che utilizzando ia ed ib risulti più leggibile no? :D
Però, come sempre ti ricordo che potresti fare tutto in modo più semplice utilizzando typedef... Eviti del tutto quei cast che potrebbero creare problemi se la base dati che utilizzi fosse più complessa, oltre a guadagnarci in leggibilità visto che alla funzione mycmp passi direttamente come parametri ciò che intendi ordinare.

Codice: Seleziona tutto

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

int mycmp ( char **a, char **b )
{
    return strcmp( * a, *b ) ;
}
/*...*/
qsort(base,num,size,(ptr)mycmp);

Re: Puntatori a Funzione[C]

Inviato: lunedì 21 aprile 2014, 17:00
da gila75
Il discorso typedef, è una "bestia grama" per me, faccio fatica ad utilizzarlo.
Io adotto (non so se è lo stesso il #define)
Esempio:

Codice: Seleziona tutto

 #include <math.h>
    #include <stdio.h>
    #define SIN double (*f)(double)

    double seno (SIN, double x);

    double seno (SIN, double x)
    {
        return (*f)(x);
       
    }

    int main (void)
    {
        double y=45;
        double res; 
        double (*ptr_sin)(double)=sin;
        res=seno (ptr_sin,y);
        printf ("risultato di sin %3.0f = %f\n",y,res);
        return 0;

Re: Puntatori a Funzione[C]

Inviato: lunedì 21 aprile 2014, 21:09
da vbextreme
se la define potesse equiparare il potenziale della typedef non sarebbe mai stata creata.
Impara a creare i tuoi tipi.

Re: Puntatori a Funzione[C]

Inviato: lunedì 21 aprile 2014, 21:56
da matteovid
non ho capito che vuoi fare con la sin

se hai errori, devi usare un #undef sin, e a volte non basta, ma ripeto non so a quale scopo devi fare uso della sin della libreria per poi scriverla a modo tuo, certamente avrai una buona ragione... è come se vuoi scrivere una tua funzione strcpy chiamandola con strcpy, senza la #undef e poi altro farai solo errori, se ti ostini a chiamare funzioni con il nome di quelle già dichiarate nelle librerie....

niente in confronto alla compare che serve alla qsort che in pratica la devi scrivere come meglio ti serve la compare, (per tipi string, int, array di string, struct e i suoi membri), quindi perchè dici che servono due parametri? Ok che la compare serve con due parametri, ma se vuoi puoi passargli altri parametri, limportante che la compare restituisca quello che chiede la qsort... poi che restituisca a te anche altro, importa a te...

poi non capisco la tua perplessità sulla typedef, vuoi usare la #define a tutti i costi, posso capire che vuoi capire la #define, ma cerca anche di capire perchè hanno implementato la typedef

come vorrei darti un compilatore della Texas che non ha nemmeno la printf e le #define e neppure la typedef... però sfrutti le cpu 64 bit in modo meraviglioso....
oppure un compilatore della HP su processore 32 bit.... purtroppo non posso darteli, costano tanto e hanno il numero di serie....

per quanto riguarda scanf, senza polemiche per nessuno....

Codice: Seleziona tutto

To use the dynamic allocation conversion specifier, specify m as a
 length modifier (thus %ms or %m[range]).  The caller must free(3) the
 returned string, as in the following example:

           char *p;
           int n;

           errno = 0;
           n = scanf("%m[a-z]", &p);
           if (n == 1) {
               printf("read: %s\n", p);
               free(p);
           } else if (errno != 0) {
               perror("scanf");
           } else {
               fprintf(stderr, "No matching characters\n");
           }

As shown in the above example, it is necessary to call free(3) only
if the scanf() call successfully read a string.
è preso dal man scanf di GNU/Linux... quindi prendi questo come informazione da tralasciare....
come compilatore usare uno compatibile C99... quello della IBM va benissimo, Link compiler IBM, anche il gcc va benino ma devi dare parametri di ottimizazione... e poi hai problemi lo stesso...

Matteo

Re: Puntatori a Funzione[C]

Inviato: lunedì 21 aprile 2014, 22:19
da matteovid
vbextreme [url=http://forum.ubuntu-it.org/viewtopic.php?p=4567796#p4567796][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:se la define potesse equiparare il potenziale della typedef non sarebbe mai stata creata.
Impara a creare i tuoi tipi.
Ciao

mi sembra che nelle prime versioni del C K & R la typedef non era implementata, poi verso il 1975 ma posso non ricordarmi bene, vedendo che con la #define avevano problemi hanno implementato la typedef come standard

Matteo

Re: Puntatori a Funzione[C]

Inviato: martedì 22 aprile 2014, 9:29
da gila75
se la define potesse equiparare il potenziale della typedef non sarebbe mai stata creata.
Impara a creare i tuoi tipi.
Certo, non è la stessa cosa, ho detto solo che faccio fatica ad apprezzare la comodità, un mio limite, che prima o poi devo affrontare.
Sono tante le cose da capire, non è propriamente un giochetto capire tutto :)
ma ripeto non so a quale scopo devi fare uso della sin della libreria per poi scriverla a modo tuo
Era solo un esempio, tratto (a grandi linee dal mio manuale).
Certo, non ha molto senso, ma è per capire come fare.
Avendo una funzione di libreriria, puoi andare a ritroso e capire come costruire i puntatori a funzione.
Che tipo ritorna sin? Cosa accetta e cosa le passo a sin?
Studiando il prototipo della funzione, secondo me,puoi capire meglio come scrivere il puntatore a funzione.
niente in confronto alla compare che serve alla qsort che in pratica la devi scrivere come meglio ti serve la compare, (per tipi string, int, array di string, struct e i suoi membri), quindi perchè dici che servono due parametri? Ok che la compare serve con due parametri, ma se vuoi puoi passargli altri parametri, limportante che la compare restituisca quello che chiede la qsort... poi che restituisca a te anche altro, importa a te...
Perchè avevo il dubbio, che aumentando i parametri della funzione compare, si andasse contro il prototipo della qsort, non so se mi spiego.
Se hai visto l'esempio sopra della sin:

Codice: Seleziona tutto

double (*punt_sin)(double,double)=sin;
Ho aggiunto un parametro in più rispetto al prototipo della funzione sin, e infatti nella compilazione ottengo un warning.
Il mio dubbio era appunto quello. Qsort, nel prototipo ha il puntatore a funzione di cmp, e credevo potesse rognare un parametro in piu.
L'idea, era quella di passare una variabile a cmp (chiamata prima da qsort).
Una volta dentro a cmp, passo tale variabile ad una funzione void che l'aumenta.
Non posso fare il return da cmp perchè il "ritorno" è gia occupato, e serve a qsort.
Ma con la funzione void, se passo la variabile come puntatore, me la ritrovo modificata anche nel main, e non ho una variabile globale.
Molto probabilmente, come diceva Vbextreme, mi sto incasinando la vita per nulla.
In fondo le variabili globali non sono vietate, e mi sa che sto facendo una cosa un po' complessa per me, a scapito delle cose basilari.
Comunque l'idea era quella.

Re: Puntatori a Funzione[C]

Inviato: venerdì 25 aprile 2014, 3:43
da matteovid
Ciao Gila

penso di aver sopravalutato la questione della compare, ricordavo che passavo altri parametri negli esempi che il prof. dava, purtroppo non trovo più gli esempi, almeno ricordavo di averli anche stampati, ma nulla per ora...
ho solo trovato cose che purtroppo anche se te lo posto non ti servano attualmente, tutte in assembler...
mi sto scrivendo un esempio, appena pronto lo posto ... è che manca il tempo come sempre dal resto...

tra progetti di elettronica e studio attualmente mi passano le giornate come fulmini... poi metti che a giorni arriva anche l'erede, che qui in famiglia è tutto una caotica attesa, tra i miei e i suoi, miii che stress, ma penso a lei che euforicamente è corraggiosa, io sarei già defunto...

bhè dai ti posto un esempietto carino, almeno per me... niente a che fare con la compare, ma bhè guarda...

Codice: Seleziona tutto

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

void bin_to_char (char c, char *pu_str)
{
  int m, n = 0;

  for (m = 128; m != 0; m >>= 1)
  {
    if (n == 0)
    {
      strcpy (pu_str, (c & m ? "1" : "0"));
      n++;
    }
    else
      strcat (pu_str, (c & m ? "1" : "0"));
  }
}

int binstr_to_char (char *str, char *pstr_ret)
{
  char c, pstr_comodo = 0;

  while ((c = *str++) != '\0')
  {
    if (c != '0' && c != '1')
      return -1;  /* Errore, carattere non valido */

    if (pstr_comodo & 128)
      return 1;  /* Errore, overflow */

  pstr_comodo = pstr_comodo << 1 | (c == '1');
  }

  *pstr_ret = pstr_comodo;

  return 0;  /* ok */
}

int main (void)
{
  char c = 'r';
  char st[] = "Prova StringA";
  char e[] = "01000111";
  char f[64], g[10];
  int r = 0;
  size_t lu = strlen (st), sc = 0;

  printf ("> [ASCII] \'%c\'\n", c);    /* ASCII */
  printf ("> [dec] %dd\n", c & 0xff);  /* decimale */
  printf ("> [hex] %xh\n", c & 0xff);  /* esadecimale */
  printf ("> [Oct] %oo\n", c & 0xff);  /* ottale */

  r = binstr_to_char (e, f);
  if (r == 0)
    printf ("> [bin] %sb to [ASCII] %s\n>\n", e, f);
  if (r > 0)
    printf ("> errore ... overflow\n>\n");
  if (r < 0)
    printf ("> errore ... carattere non valido\n>\n");

/* scandisce una stringa st, e per ogni carattere stampa
 * chr bin hex dec oct
*/
  for (sc = 0; sc < lu; sc++)
  {
    bin_to_char (st[sc], g);
    printf ("> \'%c\' --> %sb --> ", st[sc], g);
    printf ("%xh --> %s%dd --> %s%oo\n", st[sc] & 0xff,
                                    (((st[sc] & 0xff) < 100) ? " " : ""),
                                    st[sc] & 0xff,
                                    (((st[sc] & 0xff) < 64) ? " " : ""),
                                    st[sc] & 0xff);
  }

  printf (">\n");

/* tabella chr bin hex dec oct ... da 32 a 126 dec*/
  for (r = 32; r < 127; r++)
  {
    bin_to_char ((char)r, g);
    printf ("> \'%c\' --> %sb --> ", (char)r, g);
    printf ("%xh --> %s%dd --> %s%oo\n", (char)r & 0xff,
                                    ((((char)r & 0xff) < 100) ? " " : ""),
                                    (char)r & 0xff,
                                    ((((char)r & 0xff) < 64) ? " " : ""),
                                    (char)r & 0xff);
  }

  printf (">\n> done...\n>\n");

  return (0);
}
scusa se è indentato male, ma sto scrivendo con un PC che va a tratti.... non sarebbe un problema se non per il fatto che mi hanno involato il portatile, rubato, e sono tre per ora, mii che periodo... felice e stressante.

Matteo

Re: Puntatori a Funzione[C]

Inviato: venerdì 25 aprile 2014, 6:55
da gila75
penso di aver sopravalutato la questione della compare,
Ciao Matteo, forse intendi sottovalutato :)
Nel senso che è un po' difficile, ci ho provato in più modi, ma da problemi.
Ripeto, credo che ci siano difficoltà sollevata dal prototipo di qsort, che "vede" che c'è un parametro in più nella funzione cmp, o qualcosa del genere.
Comunque, è meglio se non m'intestardisco e proseguo, col tempo ci tornerò.
Ho studiato, modificato, capito vari tuoi programmi che hai postato, faccio ancora un po' fatica a capire la potenzialità dei puntatori a funzione rispetto alle funzioni classiche,
ma so già (per esperienza passata), che più fai prove ed esempi e più la matassa pian piano si srotola.
Più che altro mi premeva sapere se il discorso degli array a puntatore che ho fatto qualche post fa è corretto.
Adesso vedo il tuo codice.
P.S.: (OT): visto che sei elettronico, avrei da farti qualche domanda, su un progetto mio vecchio (un Theremin), dove mi manca l'antenna volume, volevo consigli su un VCA.
Dimmi tu se e dove possiamo parlare.
Ciao e grazie

Re: Puntatori a Funzione[C]

Inviato: venerdì 25 aprile 2014, 12:06
da ixamit
[OT]
@Matteo

Codice: Seleziona tutto

void bin_to_char (char c, char *pu_str)
{
  int m, n = 0;

  for (m = 128; m != 0; m >>= 1)
  {
    if (n == 0)
    {
      strcpy (pu_str, (c & m ? "1" : "0"));
      n++;
    }
    else
      strcat (pu_str, (c & m ? "1" : "0"));
  }
}
Questo pezzo non mi piace perchè rindondante e "scomoda" due funzioni inutili allo scopo.
Ovviamente esistono diversi modi per ottenere lo stesso risultato piu' o meno leggibile

Codice: Seleziona tutto

void bin_to_char (char c, char *pu_str)
{
    int lb=sizeof(char)*8;

    for (pu_str[lb]=0;lb;c>>=1)
        pu_str[--lb]=(c&1)?'1':'0';
}
AUGURI per il nascituro

[/OT]

Re: Puntatori a Funzione[C]

Inviato: venerdì 25 aprile 2014, 16:41
da gila75
Non avevo afferrato al momento Matteo che diventi papà....auguri!!!! Papà ultragiovane...bene ;)