c - 泛化函数指针

标签 c pointers function-pointers

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

 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;

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

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

atm 的基本值仅包含整数、 float 和 bool 值。

但我想知道是否可以使其更加紧凑和高效。 例如,我声明了两个函数指针,但我只使用其中之一。有没有办法概括函数指针?

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

任何建设性的建议都会被接受:)

最佳答案

在您的示例中,我没有看到使用 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);
    }

这正是不能使用单个函数指针的原因:浮点( double )和整数参数传递给函数以及返回结果的方式存在巨大差异。当然,您可以进行大量转换,只是为了保存函数指针,但这会混淆代码,所以我建议不要这样做。

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

相关文章:

c - 内联汇编: Passing pointers to a function and using it in that function in assembly

matlab - 使用 MATLAB 从另一个应用程序中的控件获取文本

C - 随机数生成器的问题

c++ - 使用 C++ 模板的数据映射器设计模式

c++ - 为什么 std::function 不是有效的模板参数,而函数指针是?

C - 内存分配问题 - 需要解释

c - 在c中打印char数组的元素

c - 函数返回指向 C 中数组类型的指针

c++ - 静态对象上的 shared_ptr 好吗?

c - 函数指针和调用约定