获取 C 中 switch-case 中的案例数
Getting the number of cases in a switch-case in C
是否可以在 C 中获取 switch case 中的 case 数量,而无需手动添加在每个 case 中递增的计数器变量?
这太可怕了,但是如果你在 gcc 下,你可以使用 COUNTER 宏:
#include <stdio.h>
#define ncase (void)__COUNTER__; case
int main(void)
{
int n = __COUNTER__ + 1;
switch (1 + 1) {
ncase 0: break;
ncase 1: break;
ncase 2: break;
}
n = __COUNTER__ - n;
printf("%d cases\n", n);
return 0;
}
输出:
3 cases
正如我之前评论的那样,我认为您需要一个 dispatch table 而不是 switch 语句。这是一个小例子。
假设你得到了这个:
int find_the_case();
void do_something();
void do_something_different();
void do_something_completly_different();
void do_default();
int main(int argc, char *argv[])
{
int c = find_the_case();
switch(c){
case 0:
do_something();
break;
case 1:
do_something_different();
break;
case 5:
do_something_completly_different();
break;
default:
do_default();
break;
}
return 0;
}
现在可以改写为:
#define MAX_NUMBER_OF_CASES 6
int main_dispatchtable()
{
void (*table[MAX_NUMBER_OF_CASES])(void) = {
[0] = do_something,
[1] = do_something_different,
[5] = do_something_completly_different
};
int c = find_the_case();
if( table[c] )
table[c]();
else
do_default();
/* for the counting */
int count = 0;
for (int i = 0; i < MAX_NUMBER_OF_CASES; i++ )
if( table[i] ) count++;
return 0;
}
这通常比使用 switch 语句好得多。它不仅使添加更多案例变得更简单,而且还允许对案例进行计数。如果你有一个巨大的 table 和稀疏的情况,你可以使用散列 table 而不是普通数组。
编辑:
当然,dispatch table 比 switch case 有更多优势,因为您可以动态地添加、删除和更改 dispatch table。这可能是最大的优势。
(希望您在 Linux 上并使用 最近的 GCC 编译器)
如果你想计算编译器看到的实际个案例数(想想案例范围),你需要了解编译器的内部表示,如果使用最近的 GCC 进行编译,您可以使用 GCC MELT 自定义编译器并编写我们自己的 MELT 扩展。
顺便说一句,switch
语句的复杂性或效率不仅(或大部分)与案例数量有关(因为案例的 分布 很重要很多)。请参阅参考文献 .
也许您可以简单地使用 findgimple
mode of GCC MELT 来找到 switch
足够宽的 gimple 语句。
也许你想要computed gotos for threaded code...
是否可以在 C 中获取 switch case 中的 case 数量,而无需手动添加在每个 case 中递增的计数器变量?
这太可怕了,但是如果你在 gcc 下,你可以使用 COUNTER 宏:
#include <stdio.h>
#define ncase (void)__COUNTER__; case
int main(void)
{
int n = __COUNTER__ + 1;
switch (1 + 1) {
ncase 0: break;
ncase 1: break;
ncase 2: break;
}
n = __COUNTER__ - n;
printf("%d cases\n", n);
return 0;
}
输出:
3 cases
正如我之前评论的那样,我认为您需要一个 dispatch table 而不是 switch 语句。这是一个小例子。
假设你得到了这个:
int find_the_case();
void do_something();
void do_something_different();
void do_something_completly_different();
void do_default();
int main(int argc, char *argv[])
{
int c = find_the_case();
switch(c){
case 0:
do_something();
break;
case 1:
do_something_different();
break;
case 5:
do_something_completly_different();
break;
default:
do_default();
break;
}
return 0;
}
现在可以改写为:
#define MAX_NUMBER_OF_CASES 6
int main_dispatchtable()
{
void (*table[MAX_NUMBER_OF_CASES])(void) = {
[0] = do_something,
[1] = do_something_different,
[5] = do_something_completly_different
};
int c = find_the_case();
if( table[c] )
table[c]();
else
do_default();
/* for the counting */
int count = 0;
for (int i = 0; i < MAX_NUMBER_OF_CASES; i++ )
if( table[i] ) count++;
return 0;
}
这通常比使用 switch 语句好得多。它不仅使添加更多案例变得更简单,而且还允许对案例进行计数。如果你有一个巨大的 table 和稀疏的情况,你可以使用散列 table 而不是普通数组。
编辑: 当然,dispatch table 比 switch case 有更多优势,因为您可以动态地添加、删除和更改 dispatch table。这可能是最大的优势。
(希望您在 Linux 上并使用 最近的 GCC 编译器)
如果你想计算编译器看到的实际个案例数(想想案例范围),你需要了解编译器的内部表示,如果使用最近的 GCC 进行编译,您可以使用 GCC MELT 自定义编译器并编写我们自己的 MELT 扩展。
顺便说一句,switch
语句的复杂性或效率不仅(或大部分)与案例数量有关(因为案例的 分布 很重要很多)。请参阅参考文献
也许您可以简单地使用 findgimple
mode of GCC MELT 来找到 switch
足够宽的 gimple 语句。
也许你想要computed gotos for threaded code...