即使switch语法不接受case标签的变量,是否有任何变通方法可以执行类似的操作而不是普通的if-else比较?
答案 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链更容易,如果你不这样做,我认为编写和使用复杂的宏不是一个好主意。真的需要它们。