0

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

4

4 回答 4

2

通常为了解决这个问题,我使用结构和函数指针,只有一个 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++;
  }
}

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

于 2012-11-05T13:12:19.030 回答
1

您可以使用枚举。

enum my_enum {
    element1,
    element2
};

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

例如,它可以用于一周中的每一天

于 2012-11-05T13:11:09.630 回答
1

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

你可以让它变得简单,这将是一个索引查找表。这仅适用于整数,并且仅适用于相邻的整数 0 -> n。

或者你可以让它通用,这是一个复杂的实现,但让你能够使用任何形式的“案例”:它们不必是相邻的整数,甚至根本不必是整数(可以是浮点数、字符串等)。

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

// 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.
}
于 2012-11-05T14:38:56.627 回答
0

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

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

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

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

于 2012-11-05T13:06:01.003 回答