如何在switch语句的case字段中使用变量?

时间:2012-11-05 12:46:12

标签: c switch-statement

即使switch语法不接受case标签的变量,是否有任何变通方法可以执行类似的操作而不是普通的if-else比较?

4 个答案:

答案 0 :(得分:2)

通常为了解决这个问题,我使用了一个struct和function指针,只有一个if。

未经测试的例子,只是想知道我在说什么:

#include "cases_functions.h"

typedef struct s_switch
{
  char* value;
  void (*do)(void);
} t_switch;

t_switch cases[] =
{
  {"add", add},
  {"sub", sub},
  {"divide", div},
  {0, 0}
};

void personal_switch(char *what)
{
  int i = 0;

  while (cases[i].value)
  {
    if (strcmp(cases[i].value, what) == 0)
      cases[i].do();
    i++;
  }
}

有了这个,您可以在运行时更改不同的情况,添加新的情况等等...... 当然,选择方法是免费的,例如,您可以只使用int并使用==进行测试,或者更复杂的事情。

答案 1 :(得分:1)

您可以使用枚举。

enum my_enum {
    element1,
    element2
};

my_enum var;
switch(var)
{
    case element1:
    case element2:
}

例如

,它可以用于星期几

答案 2 :(得分:1)

根据我的经验,最好的方法是使用查找表。

你可以简单,这将是一个索引查找表。这只适用于整数,而且只有相邻的整数0 - > Ñ

或者你可以使它成为通用的,这是一个复杂的实现,但是你可以使用任何形式的“case”:它们不必是相邻的整数,它们甚至不必是整数根本(可能是花车,弦乐,等等)。

我将举例说明通用版本(未经测试)。此示例使用二进制搜索,因此访问时间将是确定性的,并且如果案例数量很多则是最佳的。

// declare a custom search key for the foo object, could be any type
typedef int foo_key_t; 

// declare the actual data object:
typedef void(*foo_func_t)(void);
typedef enum
{
  const foo_key_t   key;
  foo_func_t        foo_func; // things to do when this "case" is found
} foo_t;


// a comparison function for objects of type foo_t
int foo_comp (const void* obj1, const void* obj2)
{
  const foo_t* f1 = obj1;
  const foo_t* f2 = obj2;

  return f1->key - f2->key;
}

---

// declare a "good to have" enum with a list of indices 
// indices are guaranteed to be adjacent numbers 0 -> n
typedef enum  
{
  FOO_FOO,
  FOO_BAR
  FOO_N // number of items in this enum
} foo_index_t;

// define a list of variables corresponding to the above enum
const foo_t foo [FOO_N] =  // a list sorted in adjacent search key order:
{
  { 123, &foo_func },
  { 456, &bar_func }
};

---

const foo_t* result;

result = bsearch(456,           // search for this "case"
                 foo,           // in the table foo
                 FOO_N,         // with this many objects
                 sizeof(foo_t), // with this object size
                 foo_comp);     // use this comparison function

if(result != NULL)
{
  result.foo_func();
}
else
{
  // this equals "default" in a switch-case.
}

答案 3 :(得分:0)

如果你的“标签”是常量,你可以定义宏......

#define FOO 1
#define BAR(x) (2*x)

switch (var)
{
    case FOO:    // foo
    case BAR(3): // bar
}

也许你可以定义一些奇怪的宏来获得你想要的东西,但是编写一个简单的if-else-if链更容易,如果你不这样做,我认为编写和使用复杂的宏不是一个好主意。真的需要它们。