模拟器/生成的开关语句范围,单位为c

时间:2011-01-13 13:21:59

标签: objective-c c macros switch-statement c99

在c(99?)或目标C switch语句中是否存在支持范围情况的hack? 我知道不支持写这样的东西:

switch(x)
   case 1:
   case 2..10:
   case 11:

但我认为应该有一种使用#define宏生成代码的方法。当然 我可以用案例列表定义一个宏,但我希望有一个更优雅的方式 CASERANGE(x,x + 10)将生成:

case x
case x+1
case x+2

甚至可能吗?

3 个答案:

答案 0 :(得分:3)

GCC有一个extension to the C language允许类似于你的第一个例子,但除此之外,如果有一个便携式/ ANSI方式,它现在就已经完成了。我不相信有一个。

答案 1 :(得分:2)

使用宏执行此操作几乎或不可能。存在编译器扩展,但它们是特定于编译器的,而不是跨平台/标准的。没有标准的方法可以做到这一点,而是使用if / else链。

答案 2 :(得分:2)

在现代C(C99,可变长度宏)中,可以使用宏来执行此操作。但你可能不想自己完全编码。 P99为此提供了一个工具箱。特别是有一个元宏P99_FOR,它允许你展开有限长度的参数列表。

#define P00_CASE_FL(NAME, X, I) case I: NAME(X); break
#define CASES_FL(NAME, ...) P99_FOR(NAME, P99_NARG(__VA_ARGS__), P00_SEQ, P00_CASE_FL, __VA_ARGS__)

会将CASES_FL(myFunc, oi, ui, ei)扩展为类似

的内容
case 0: myFunc(oi); break; case 1: myFunc(ui); break; case 2: myFunc(ei); break

修改以回复具体问题

#define P00_CASESEP(NAME, I, X, Y) X:; Y
#define P00_CASERANGE(NAME, X, I) case ((NAME)+I)
#define P99_CASERANGE(START, LEN) P99_FOR(START, LEN, P00_CASESEP, P00_CASERANGE, P99_REP(LEN,))

其中P00_CASESEP只确保案例之间存在:;P99_REP生成一个包含LEN空参数的列表。

你可以用它作为

switch(i) {
P99_CASERANGE('0',10): return i;
}

观察宏之后的:以使其尽可能接近通常的case语法,并且LEN参数必须扩展为纯十进制数,而不是表达式等等