如何在C中的switch case语句中使用范围?

我的逻辑是:

if number is between 1 to 10, execute first case statement if number is from 20 to 30, execute second case statement 

有没有下面的解决方案?

 case '1' ... '10': case '20' ... '30': 

作为语言扩展 , GCC编译器支持以下情况范围 :

  switch(i) { case 0 ... 9: return true; default: return false; } 

Clang / LLVM也接受此语言扩展。 因此,如果您能够将代码限制为GCC和Clang编译器,请使用它。

另见这个 。

我不知道为什么这个扩展不包含在C11标准中。

选项1:用case 0表示0-9 case 1表示11-20 ,依此类推。

选项2:使用if

选项3:

另一个破旧的方法是使用这样的情况:

 #include  int main(void) { int i=1; for(i=1;i<=25;i++) { switch(i) { case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: printf("%d is in between 1-10\n", i); break; case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: printf("%d is in between 11-20\n", i); break; default: printf("%d is above 20\n", i); } } return 0; } 

输出:

 1 is in between 1-10 2 is in between 1-10 3 is in between 1-10 4 is in between 1-10 5 is in between 1-10 6 is in between 1-10 7 is in between 1-10 8 is in between 1-10 9 is in between 1-10 10 is in between 1-10 11 is in between 11-20 12 is in between 11-20 13 is in between 11-20 14 is in between 11-20 15 is in between 11-20 16 is in between 11-20 17 is in between 11-20 18 is in between 11-20 19 is in between 11-20 20 is in between 11-20 21 is above 20 22 is above 20 23 is above 20 24 is above 20 25 is above 20 

https://ideone.com/Cw6HDO

 void SwitchDemo(int value) { switch(value / 10) { case 0: ...; break; // 0 - 9 case 1: ...; break; // 10 - 19 ... } } 

或者,具体到问题范围:

 void SwitchDemo(int value) { switch((value-1) / 10) { case 0: ...; break; // 1 - 10 case 1: ...; break; // 11 - 20 ... } } 

C不支持除单个整数之外的大小写值(或类似整数的东西 – 字符,枚举值)。 所以你的选择是:

  • 正如pzaenger在现在删除的评论中所建议的那样:将您正在使用的数字转换为可以打开的数字(在这种情况下,除以10)。
  • 多个案例陈述(利用漏洞): case 1: case 2: case 3: ... case 10: do_something();
  • 使用if而不是case

您将无法使用switch-case语句在标准C中执行此操作。
(正如其他答案所指出的,某些编译器具有非标准扩展来启用此function)

相反,我建议制作一个数据结构,例如:

 struct RangeData { int start; int end; void (*func)(int); }; RangeData ranges[] = { { 1, 10, Handle10s }, { 20, 30, Handle20s }, {5000, 10000, HandleBigNumbers} }; 

然后,应该很容易做出一个循环的微小循环,找到合适的范围,并调用正确的函数。

 void DoNumber(int value) { for(int i=0; i 

在C编程语言中, switch()语句中使用的case语句必须指定编译器可以某种方式转换为常量的值。 case语句中使用的每个值在switch()的范围内必须是唯一的。 如果case语句都不匹配switch()语句中的表达式,则default关键字指示缺省值。

另外,请查看Duff的设备,以显示switch()case的有趣用法。 看看Duff的设备是如何工作的?

因此,下面显示了switch()中正确case语句的几个示例:

 #define XXVAL 2 #define CASETEST(x) (x + 5) int iValue; // set the value of the variable iValue at some point switch (iValue) { case 0: // do the case if iValue == 0 break; case XXVAL: // do the case if iValue == XXVAL break; case CASETEST(3): // do the case if iValue == CASETEST(3) // works because preprocessor generates the source text which is // then compiled and the expression can be resolved to a constant break; case CASETEST(5) * 2: // do the case if iValue == CASETEST(5) * 2 // works because preprocessor generates the source text which is // then compiled and the expression can be resolved to a constant break; default: break; } 

如果您仍想使用带有远程case语句的switch() ,则可以执行的操作是提供一些将表达式折叠为一个或多个特定常量值的机制。

因此,在一个简单,琐碎的例子中,您可以执行以下操作。 这是一个简单的案例来展示最终使简单if语句的逻辑变得不透明的技术。 这种技术可用于复杂的决策和分类,可以折叠成一组简单的常量。

 int foldit (int iValue) { if (iValue < 5000) return 0; else if (iValue < 10000) return 1; else if (ivalue < 20000) return 2; else return 9999; // triggers the default part of the switch } switch (foldit(iValue)) { case 0: // do what is needed for up to but not including 5000 break; case 1: // do what is needed for 5000 up to but not including 10000 break; case 2: // do what is needed for 10000 up to but not including 20000 break; default: // handle anything else break; } 

折叠方法可能有用的地方是,当您有多个不同的结果时,可能使用filter来尝试对数据项进行分类。

 #define type1 0x00001 #define type2 0x00002 #define type3 0x00004 #define type4 0x00008 struct datatype { int iVal; int jVal; }; unsigned long is_a_type1(struct datatype * thing) { unsigned long retVal = 0; // initialize to not a type1, set to type1 if turns out to be // do checks for the type and if so set retVal to type1 if it matches return retVal; } unsigned long is_a_type2(struct datatype * thing) { unsigned long retVal = 0; // initialize to not a type2, set to type2 if turns out to be // do checks for the type and if so set retVal to type2 if it matches return retVal; } unsigned long is_a_type3(struct datatype * thing) { unsigned long retVal = 0; // initialize to not a type3, set to type3 if turns out to be // do checks for the type and if so set retVal to type3 if it matches return retVal; } unsigned long is_a_type4(struct datatype * thing) { unsigned long retVal = 0; // initialize to not a type4, set to type4 if turns out to be // do checks for the type and if so set retVal to type4 if it matches return retVal; } unsigned long classify (struct datatype *thing) { unsigned long ulTestResult = 0; // test to see if this is a type1 thing ulTestResult |= is_a_type1(thing); // test to see if this is a type2 thing ulTestResult |= is_a_type2(thing); // test to see if this is a type3 thing ulTestResult |= is_a_type3(thing); // test to see if this is a type4 thing ulTestResult |= is_a_type4(thing); return ulTestResult; } int main () { struct datatype myThing; // other source code then switch (classify(&myThing)) { case type1 | type2 | type3: // do stuff if this is a type1, type2, and type3 but not type4 // that is classify() determined that myThing matched all three types. break; case type1: // do stuff if type1 which includes stuff you do for type2 as well under // special values of myThing. if (myThing.iVal < 50) { case type2: // at this point we have type2 case stuff that we do. Code above is skipped // and the switch () will jump straight to here if classify() is type2. // // Also stuff we do if type1 and myThing.iVal < 50 // in other words this code is execute if classify(&myThing) is type2 or // if classify(&myThink) is type1 and there is a special processing for myThing.iVal < 50 break; // if classify() type2 or if classify() type1 and myThing.ival < 50 } // do stuff if only type1 and myThing.iVal >= 50 break; case type2 | type3: // do stuff if type2 and type3 matched but none of the others. break; default: // any other case break; } return 0; } 

c中的switch语句只能对常量表达式进行操作,case语句不能包含动态比较。

C中的“常量表达式”是什么,而不是什么?

对于这个简单的if / else结构可以更清晰和简单,取决于编译器,您的case语句可能会被转换为一系列分支比较语句。