[英]How can I parse C switch-case and for Statement in AWK?
[英]How can I use ranges in a switch case statement in C?
我的邏輯是:
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':
switch(i) {
case 0 ... 9: return true;
default: return false;
}
Clang / LLVM也接受此語言擴展。 因此,如果您能夠將代碼限制在GCC和Clang編譯器中,請使用它。
另請參見本 。
我不知道為什么這個擴展沒有包含在C11標准中。
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
...
}
}
選項1:使用case 0
表示0-9
, case 1
表示11-20
,依此類推。
選項2:使用if
選項3:
另一個破舊的方法是使用這樣的情況:
#include <stdio.h>
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
C不支持除單個整數之外的大小寫值(或類似整數的東西 - 字符,枚舉值)。 所以你的選擇是:
case 1: case 2: case 3: ... case 10: do_something();
if
而不是case
。 您將無法使用switch-case
語句在標准C中執行此操作。
(正如其他答案所指出的,某些編譯器具有非標准擴展來啟用此功能)
相反,我建議制作一個數據結構,例如:
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<ARRAYSIZE(ranges); ++i)
{
if (ranges[i].start <= value && value <= ranges[i].end)
{
ranges[i].func(value);
}
}
}
在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;
}
折疊方法可能有用的地方是,當您有幾個不同的結果時,可能使用過濾器來嘗試對數據項進行分類。
#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語句不能包含動態比較。
對於這個簡單的if / else結構可以更清楚和更簡單的東西,取決於編譯器,您的case語句可能會被轉換為一系列分支比較語句。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.