c关于收缩这个函数的想法?

c关于收缩这个函数的想法?,c,switch-statement,C,Switch Statement,我有一个巨大的switch case,里面有嵌套的switch case语句,我想知道是否有人知道如何清理 switch (datatype) { case STR: { switch(operation) { case EQUALS: { /* perform str compare */ }

我有一个巨大的switch case,里面有嵌套的switch case语句,我想知道是否有人知道如何清理

switch (datatype) {
    case STR:
    {
         switch(operation)
         {
              case EQUALS:
              {
                     /* perform str compare */
              }
              case NOTEQUALS:
              {
              }
              case LT:
              {
              }
              case GT:
              {
              }
              case GTE:
              {
              }
              case LTE:
              {
              }
              default:
                 break;
         }
         break;
    }
    case VER:
    {
         switch(operation)
         {
              case EQUALS:
              {
                     /* perform version compare */
              }
              case NOTEQUALS:
              {
              }
              case LT:
              {
              }
              case GT:
              {
              }
              case GTE:
              {
              }
              case LTE:
              {
              }
              default:
                 break;
         }
         break;
    }
    case INT:
    {
         /* same */
    }
    case FLOAT:
    {
         /* same */
    }
    /* ... more types ... */
    /* ... .......... ... */
    default:
        break;
}

如果操作的值是连续的,则可以创建函数指针表。事实上,您可以创建一个2D函数指针表,其中包含一个单独的函数来处理每个操作/类型组合。e、 g

// do some range checking on input params
// invoke the handler
handlers[datatype][operation]();

您可以尝试。

您可以使用一个大的函数指针数组,然后根据对数组中正确函数指针的索引调用相关函数。

创建一些表(数组),其中包含指向函数的指针。然后可以查找
func[STR][EQUALS]
以进行适当的调用。这个电话最后会是这样的

Func[datatype][operation]();

NOTEQUALS
案例总是可以用
EQUALS
案例来编写;同样地,
GTE
LT
方面和
LTE
GE
方面。因此,根据
操作进行外部切换
,这六种情况中只有三种需要打开
数据类型

,您是否考虑过创造性地使用一系列函数指针并将其存储在结构中

正确操作,您可以模拟对象并执行以下操作:

bool someArbitraryFunction (dataType aDatatype, operations anOperation)
{
 someUnknownStruct.datatype = aDatatype;
 someUnknownStruct.operation = anOperation;
 return someUnknownStruct->doMath(1,2);
}
然后,您可以将所有需要的数学函数、枚举和结构放在头文件的某个位置


清理代码的“肉”,并使数学可移植(只要在需要的地方导入即可)。

假设您的案例都可以返回一个简单的布尔值,那么所有六个逻辑案例都可以用LT和EQUALS重写,如下所示:

switch(operation) {
  case EQUALS:
    return isEquals();
  case NOTEQUALS:
    return !isEquals();
  case LT:
    return isLT();
  case GT:
    return !isLT() && !isEquals();
  case GTE:
    return !isLT();
  case LTE:
    reutrn isLT() || isEquals();
  default:
    break;
}
这只需要您为isLT()和isEquals()编写逻辑,这将在必要时切换数据类型。这消除了大量不必要的代码重复,但不会牺牲很多易读性


这可以与Stephen Doyle和rikh已经建议的函数指针结合使用,这将完全消除switch()语句。

您可能需要验证
数据类型
操作
是否在正确的范围内,事实上,现代编译器会自动将大型开关转换为跳转表(当然还会进行范围检查)@drhirsch:这与性能无关,而是与生成干净的代码有关。我觉得这并不干净。它将更加不透明,更难维护。我不认为长开关语句有什么内在的错误。@Kinopiko:我不同意。函数指针表是使复杂C代码更容易理解和维护的最好方法之一。如果你考虑部分排序,则不总是这样。我能问一下为什么有必要缩小这一点吗?