使用C中的宏处理双变量switch语句

jimkokko5

比方说,我有两个指针,两个结构ab这两个结构均包含一个枚举,我们将其称为x给定所有可能的ab,我想根据其x枚举的值调用特定的函数在我的案例中,有趣的是我要调用的函数如下所示:

X0_to_X1();
X0_to_X2();
...
X1_to_X0();
...
etc

其中X0X1等是枚举的可能值x,这意味着有X_to_Y对于每个功能和的值的每个组合x的枚举。

一个明显的“天真”解决方案将是一个switch语句,该语句会很大(考虑到x有很多可能的值):

switch (a->x) {
    case X0:
        switch (b->x) {
            case X1:
                X0_to_X1();
                break;

// ... and so on and so forth for every possible pair!

为了更好地解决这个问题,我的第一个尝试是实现一个宏,该宏在给定两个值的情况下x可以形成函数调用:

#define CALL_FUNCTION(x1, x2) x1 ## _to_ ## x2 ()

但是,这是行不通的,因为在我的代码中,我永远无法知道运行时之前实际x,因此最终看起来像:

CALL_FUNCTION(a->x, b->x);

当然可以转换为:

a->x_to_b->x();

这绝对没有道理。

有没有一种方法可以更优雅地解决此问题,或者我应该只是硬着头皮,而是执行大量的switch语句?

约翰·波德

查找表会激怒这个问题,在该表中您存储了指向各种函数的指针,并且这些指针由枚举值进行键控。

如果您的enum值是顺序的(并且没有两个枚举常量共享相同的值),则可以将查找表构建为简单的2D数组:

enum x_t { X0, X1, X2, ..., NUM_X }; 
void (*lookup[NUM_X][NUM_X])(void) = {
  { NULL, X0_to_X1, X0_to_X2, X0_to_X3, ... },
  { X1_to_X0, NULL, X1_to_X2, X1_to_X3, ... },
  { X2_to_X0, X2_to_X1, NULL, X2_to_X3, ... },
  ...
};

假定您xy相同时没有“身份”功能

然后,通过索引到表中来调用所需的函数,如下所示:

if ( x != y )
  lookup[x][y]();

不,它不是很漂亮,但是它击败了嵌套switch语句。您可以根据需要将其隐藏在宏或其他函数调用之后。

如果枚举值不是连续的,则此特定实现将无法正常工作-您必须使用列表或稀疏矩阵以其他方式构建查找表。但是,尽管设置代码可能很乏味,但它将大大简化调用方的逻辑。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章