Function pointer to different functions with different arguments in C

前端 未结 6 1059
独厮守ぢ
独厮守ぢ 2020-12-31 08:48

I have two functions with variable number and types of arguments

double my_func_one(double x, double a, double b, double c) { return x + a + b + c }
double my         


        
6条回答
  •  天涯浪人
    2020-12-31 08:58

    An old topic but I am facing same issue and finally came with this idea.

    If you want the same prototype for each functions you can wrap the parameters in structure like this :

     typedef struct {
         double a,
                b,
                c; 
     }chunk1_t;
    
      typedef struct {
         double p[];
         double c; 
     }chunk2_t;
    

    Then your function pointer becomes:

     double (*pfunc) (double x, void *args);
    

    which leads to something like this :

     pfunc cb;
    
     double swap_function(double x, pfunc cb, void *args);
    
     double my_func_one(double x, void *args) { 
       chunk1_t *chunk = (chunk1_t*) args;
       return x + chunk->a + chunk->b + chunk->c; 
     }
    
     double my_func_two(double x, void *args) {
       chunk2_t *chunk = (chunk2_t*) args;
       return x + chunk->p[0] + chunk->p[1] + chunk->c ;
     }
    
     int main(){
       // declare a, b,...
       double a = 1.0f;
       //...
       // cast for safety
       chunk1_t myChunk1 = {(double)a, (double)b, (double)c};
       // don't if you like risk
       chunk2_t myChunk2 = {p, c};
    
       swap_function(x, cb, &myChunk1); 
       swap_function(x, cb, &myChunk2);
     }
    

    Using function pointer stored in structure:

     #define FUNC_ONE_METHOD 1
     #define FUNC_TWO_METHOD 2
    
     typedef struct chunk{
         double a, b, c;
         double p[];
         int method;
         double (*pfunc) (double x, struct chunk *self);
     }chunk_t;
    
     double swap_function(double x, chunk_t *ch){
        switch (ch->method)
        {
            case FUNC_TWO_METHOD:
                ch->pfunc = my_func_two;
                break;
            case FUNC_ONE_METHOD:
                ch->pfunc = my_func_one;
                break;
            default:
                return -1; // or throw error
        return ch->pfunc(x, ch);
     }
    
    
     chunk c = {.a= 1, .b=3, .c=1, .method=1};
     swap_function(x, &c);
    

提交回复
热议问题