昨天晚上,我编写了以下代码来执行一些算术运算(加法,乘法,减法,除法)。

 data operation(int oper, data e1, data e2){
   data res;
   basic b;
   //pointer to a funcion that takes two int input and return an int
   int (*funIntPtr)(int,int);
   float (*funFloatPtr)(float,float);

   funIntPtr = NULL;
   funFloatPtr= NULL;
   //I look for the function to be called
     switch (oper) {
       case MINUS:
         //*functionPtr = &subInt;
         switch (e1.b.type) {
           case basic_int_value:funIntPtr = subInt;break;
           case basic_float_value:funFloatPtr = subFloat;break;
           case basic_boolean_value:
             yyerror("boolean arithmetic operation are NOT_ALLOWED");
             exit(NOT_ALLOWED);
             break;
         }
         break;
       case PLUS :
         switch (e1.b.type) {
           case basic_int_value:funIntPtr = addInt;break;
           case basic_float_value:funFloatPtr = addFloat;break;
           case basic_boolean_value:
             yyerror("boolean arithmetic operation are NOT_ALLOWED");
             exit(NOT_ALLOWED);
             break;
         }
         break;
       case MULTIPLY:
         switch (e1.b.type) {
           case basic_int_value:funIntPtr = mulInt;break;
           case basic_float_value:funFloatPtr = mulFloat;break;
           case basic_boolean_value:
             yyerror("boolean arithmetic operation are NOT_ALLOWED");
             exit(NOT_ALLOWED);
             break;
         }
         break;
       case DIVIDE :
         switch (e1.b.type) {
           case basic_int_value:funIntPtr = divInt;break;
           case basic_float_value:funFloatPtr = divFloat;break;
           case basic_boolean_value:
             yyerror("boolean arithmetic operation are NOT_ALLOWED");
             exit(NOT_ALLOWED);
             break;
         }
         break;
       default:
         yyerror("what now?");
         exit(BUGGY_THE_CLOWN);
         break;
      }
    //look for values to be used
    if( funIntPtr == NULL && funFloatPtr == NULL){
      yyerror("no function found for the specified operation..");
      exit(BUGGY_THE_CLOWN);
    }
    res.type = basic_dataType;
    res.b.type = e1.b.type;//inherithed
    switch (e1.b.type) {
      case basic_int_value:
        {
          res.b.i = funIntPtr(e1.b.i, e2.b.i);
        }
        break;
      case basic_float_value:
        {
          res.b.f = funFloatPtr(e1.b.f, e2.b.f);
        }
        break;
      case basic_boolean_value:
      default:
        yyerror("no data found for the specified operation..");
        exit(BUGGY_THE_CLOWN);
    }
   return res;
 }


在第一部分中,我找到了要使用的功能,在第二部分中,我收集了要使用的输入数据。它工作正常,可以达到目的。

typedef struct data{
    dataType type;
    union{
      complex c;
      basic b;
    };
}data;


数据是包含基本类型值或复杂值的结构。复数值是数组类型和结构。目前,我不在乎。

typedef struct basic{
  basicType type;
  union{
     int i;
     float f;
     bool b;
  };
}basic;


基本值atm仅包含整数,浮点数和布尔值。

但是我想知道是否可以使其更紧凑,更高效。
例如,我声明了两个函数指针,但仅使用其中之一。有什么方法可以泛化函数指针吗?

我知道我必须声明输入类型和返回类型,但是在这种情况下,最好推迟这样的函数专门化以便只具有一个指针。
有可能还是应该改变解决问题的方式?

任何建设性的建议都是可以接受的:)

最佳答案

在您的示例中,我看不到使用float函数:

  case basic_float_value:
    {
      res.b.i = funIntPtr(e1.b.i, e2.b.i);
    }


我希望这样的事情:

  case basic_float_value:
    {
      res.b.f = funFloatPtr(e1.b.f, e2.b.f);
    }


这就是为什么您不能使用单个函数指针的原因:在将float(双精度)和整数参数传递给函数以及如何返回结果方面存在巨大差异。当然,您可以进行繁重的转换,只是保存一个函数指针,但这会使代码模糊不清,因此我建议不要这样做。

关于c - 泛化函数指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33787703/

10-08 22:03
查看更多