n° 154
Settembre 2010
Settembre 03, 2010, 04:22:38 am *
Benvenuto! Accedi o registrati.
Hai dimenticato l'e-mail di attivazione?

Accesso con nome utente, password e durata della sessione
Notizia: Usi il PC già da qualche anno? partecipa alla discussione nell'area Retrocomputing
 
   Indice   Linux Windows Internet videogame hardware Aiuto Ricerca Agenda Downloads Accedi Registrati  


 SONDAGGIO
Saresti interessato a seguire online dei videocorsi?
Sì | No
Se sì, quali di questi argomenti sarebbero di tuo gradimento?

.NET Framework   PHP
ASP.NET Python
Attività SEO Ruby
C# Silverlight
C/C++ Visual Basic .NET
Java Windows Azure
Java per Android Windows Phone 7
Objective-C (iPhone / iPad) Altri

Attenzione! Per partecipare al sondaggio bisogna essere registrati al forum




* Messaggi recenti
Messaggi recenti
Pagine: [1]   Vai giù
  Stampa  
Autore Discussione: [C] Array puntatori a funzione generici  (Letto 1040 volte)
0 utenti e 1 Utente non registrato stanno visualizzando questa discussione.
VBeXtreme
Full Member
***

Karma: +12/-75
Scollegato Scollegato

Messaggi: 513



Mostra profilo
« inserita:: Dicembre 07, 2009, 11:35:55 pm »

Riesco a creare un array di puntatori a funzioni generiche grazie al casting in questo modo:

Codice:
typedef int  (*myintchartype) (char *, char *);
typedef void (*myvoidtype) (void);
typedef int  (*myintvoidtype) (void);

int func1(char *, char *);
void func2(void);

void main(void)
{
   myvoidtype ptr[1];

   ptr[0] = (myvoidtype) func1;
   ((myintchartype) ptr[0])("one", "two");
   
   ptr[1] = (myvoidtype) func2;
   ((myvoidtype) ptr[1])();
}

int func1(char *a, char *b)
{
   return printf("func1 took two parameters: %s and %s\n", a, b);
}

void func2(void)
{
   printf("func2 did not take any parameters\n");
}

ora però se so il casting da usare tutto ok ma se non lo conosco?ovvero se ho un array di puntatori a funzioni e devo eseguire una determinata funzione passando un numero?
es:
Pseudo codice:
   myvoidtype ptr[1];
   int n ={un numero casuale};
   ptr[0] = (myvoidtype) func1;   
   ptr[1] = (myvoidtype) func2;
ecco adesso se faccio ptr[n] come faccio a fare il casting?
si può mettere in un array il casting?
es:
   cast[0]=(myvoidtype);
   cast[1]=(myintvoidtype);
   ...
   ((cast[0] ptr[1])());
se si come devo dichiarare l'array?
Registrato

Ragionare non è nient’altro che calcolare
"Thomas Hobbes"
celeborn85
Global Moderator
Hero Member
*****

Karma: +42/-8
Scollegato Scollegato

Messaggi: 1752


Mostra profilo
« Risposta #1 inserita:: Dicembre 08, 2009, 03:52:03 am »

 Scioccato non so cosa tu abbia l'intenzione di fare, MA QUELLO NON E' SICURAMENTE IL MODO CORRETTO DI FARLO!!! Una funzione che si aspetta due argomenti si aspetterà sempre due argomenti anche se con un qualche trucco con i cast hai fatto pensare al tuo codice che stai lavorando con una funzione che se ne aspetta altri. I cast devono essere usati con parsimonia.

Ma non è l'unico problema del tuo codice: un array di un elemento ha, appunto, un solo elemento indicizzato con zero e quindi nel tuo esempio ptr[1] è oltre i limiti dell'array.
Registrato

I moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.
VBeXtreme
Full Member
***

Karma: +12/-75
Scollegato Scollegato

Messaggi: 513



Mostra profilo
« Risposta #2 inserita:: Dicembre 08, 2009, 10:12:55 am »

Citazione
  non so cosa tu abbia l'intenzione di fare

io vorrei mettere funzioni con argomenti diversi dentro un array e farli richiamare tramite un numero casuale.
Ora dato che ho funzioni con parametri diversi come posso fare?
Possa infilare in un array un tipo di cast?come?
pensavo di essermi gia spiegato nel precedente post!

Citazione
MA QUELLO NON E' SICURAMENTE IL MODO CORRETTO DI FARLO!!! Una funzione che si aspetta due argomenti si aspetterà sempre due argomenti anche se con un qualche trucco con i cast hai fatto pensare al tuo codice che stai lavorando con una funzione che se ne aspetta altri. I cast devono essere usati con parsimonia

Il metodo che ho usato non  un trucco ma un semplice convertitre dei valori.Sarebbe come fare:
int a,b;
float c;
a=1;
b=0;
c=(float)a;
b=(int)c;
a parte l'inutilità di questo codice non penso sia un uso spropositato dei cast!

tralasciamo il [1] e soffermiamoci sul problema!
Registrato

Ragionare non è nient’altro che calcolare
"Thomas Hobbes"
celeborn85
Global Moderator
Hero Member
*****

Karma: +42/-8
Scollegato Scollegato

Messaggi: 1752


Mostra profilo
« Risposta #3 inserita:: Dicembre 08, 2009, 12:58:39 pm »

Non si può creare un array di cast. Devi creare una enumerazione e poi fare dei cast in base al valore:
Codice:
switch (type[i]) {
case VOID_FUNC_INT_CHAR_CHAR:
    (*(myintchartype*)ptr[i])(c1, c2);
    break;
case VOID_FUNC_VOID:
    (*(myvoidtype*)ptr[i])();
    break;
case INT_FUNC_VOID:
    int ret = (*(myintvoidtype)ptr[i])();
    break;
default:
    /* codice di default. */
}
Registrato

I moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.
VBeXtreme
Full Member
***

Karma: +12/-75
Scollegato Scollegato

Messaggi: 513



Mostra profilo
« Risposta #4 inserita:: Dicembre 08, 2009, 10:12:43 pm »

ci avevo già pensato a quella soluzione.Solo che mi sarebbe piaciuto adottare la soluzione ad array.
Dato che devo raggruppare 50 comandi,con 3 o 4 tipi di funzioni,non so se riscrivere le funzioni in modo da creare un puntatore a funzione decente o se usare questo metodo che ho proposto,naturalmente con lo switch(come funziona adesso praticamente).

Ho provato anche con un casting di ritorno da funzione:

int_pf_int mycast_intint(void_pf_void f)
{return ((int_pf_int)f);}

void_pf_void cast[2];
cast[0]=mycast_intint;
...
r=((cast[0](ptr[0]))(1);

(spero di non avere scritto male)
Anche in questo caso naturalmente non funziona ma stavolta la causa è il cast sempre per lo stesso motivo,infatti la funzione di mycast ritorna tipi differenti per ogni cast e quindi non possono essere raggruppati in un array.
Registrato

Ragionare non è nient’altro che calcolare
"Thomas Hobbes"
M.A.W. 1968
** LEGGETE IL REGOLAMENTO ! **
Global Moderator
Hero Member
*****

Karma: +126/-3
Scollegato Scollegato

Messaggi: 2115


Discrete And Combinatorial Mathematics


Mostra profilo WWW
« Risposta #5 inserita:: Dicembre 08, 2009, 11:16:15 pm »

I cast in C vengono definiti unicamente a compile time, sono statici e assolutamente non manipolabili a runtime.
Per ovviare a questa limitazione C++ ha introdotto i new cast e RTTI, una delle features maggiormente deprecate dal punto di vista prestazionale ed escluse senza mezzi termini da suo cuggino ad alte prestazioni Embedded C++.

Questo implica che la domanda non ammette risposta entro le caratteristiche standard del linguaggio C.

D'altro canto, nessun programmatore C penserebbe jamais di utilizzare l'approccio ventilato in questo thread.

La soluzione standard per un dispatcher prevede l'uso di funzioni void e il passaggio dei necessari parametri tramite uno o più dei seguenti metodi:

- Variabili static a livello di modulo o eseguibile, deprecata ma efficientissima;

- Passaggio di un numero costante di puntatori, anche void (al limite, uno). Nulla vieta di passare una serie di NULL per i parametri non utilizzati, e di includere un puntatore al valore di ritorno richiesto: mediamente efficiente;

- Uso dell'apposita sintassi per un numero di argomenti variabile con conseguente utilizzo di va_start(), va_arg(), va_end()... scarsamente efficiente ma adeguatamente generico;

- Emulazione high-level di un parameter stack tramite heap o simili: minima efficienza, massima portabilità.

Esistono inoltre librerie e/o preprocessori per la programmazione generica (vulgo: template) e il cast automatico in puro C, nessuno dei quali sembra però funzionare decentemente.
Registrato

I Moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.

Un blog? Io?
VBeXtreme
Full Member
***

Karma: +12/-75
Scollegato Scollegato

Messaggi: 513



Mostra profilo
« Risposta #6 inserita:: Dicembre 09, 2009, 11:42:36 am »

grazie maw era proprio quello che pensavo,riscrivo le funzioni e la prossima volta so come comportarmi!
Passaggio di valori con null quando non servono,il metodo dei ... Non fa al caso mio,diventerebbe tutto troppo generico, in fondo se raggruppo le variabili usate devo passare 5 o 6 parametri.grazie
Registrato

Ragionare non è nient’altro che calcolare
"Thomas Hobbes"
M.A.W. 1968
** LEGGETE IL REGOLAMENTO ! **
Global Moderator
Hero Member
*****

Karma: +126/-3
Scollegato Scollegato

Messaggi: 2115


Discrete And Combinatorial Mathematics


Mostra profilo WWW
« Risposta #7 inserita:: Dicembre 09, 2009, 02:12:14 pm »

In alternativa, rimanendo alle opzioni "semplici" e come caso particolare della strategia "Passaggio di un numero costante di puntatori", è possibile passare un singolo puntatore ad una struttura composita che contiene tutti i possibili parametri (anche con eventuale uso di union) e valori di ritorno.

Ciò però rende in genere più pesante e farraginosa la notazione, è oggettivamente meno leggibile ed è concettualmente più vicino all'uso di static che al passaggio di parametri vero e proprio. Per questo si tende a non consigliare una simile soluzione, che pure taluni sviluppatori amano molto.
In realtà occorre una valutazione complessiva: per un cross compiler nel quale è vitale limitare il numero di parametri, la massima efficienza è comunque raggiunta con le variabili condivise a livello di modulo, e così via.
Registrato

I Moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.

Un blog? Io?
VBeXtreme
Full Member
***

Karma: +12/-75
Scollegato Scollegato

Messaggi: 513



Mostra profilo
« Risposta #8 inserita:: Dicembre 09, 2009, 02:40:09 pm »

non avevo pensato alle union,sicuramente si complica molto il progetto,ma ci provo lo stesso.anche perché modificare tutte quelle funzioni potrebbe farmi dare di matto.
diciamo che ho solo 3 variabili static che servono per la parte grafica, il resto( due struct e 4 var) sono dichiarate all'inizio del main e un ciclo fa eseguire le operazioni su queste variabili in base ai comandi dell'utente.
il raggruppare tutti i comandi in un array mi eviterebbe l'uso di un lunghissimo blocco switch.
grazie ancora
Registrato

Ragionare non è nient’altro che calcolare
"Thomas Hobbes"
Pagine: [1]   Vai su
  Stampa  
 
Vai a:  

Copyright © 2009 Edizioni Master SpA. p.iva : 02105820787

Tutti i diritti di proprietà letteraria e artistica riservati. - Privacy



Links to Page