Is it possible to get the number of cases in a switch case in C without manually adding a counter variable which is incremented in each case?
问题:
回答1:
As I commented earlier, I think you want a dispatch table rather than a switch statement. Here's a little example.
Say you got this:
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;
}
Now this ca be rewritten to this:
#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;
}
This is usually a much better way than using switch statements. Not only does it make it simpler to add more cases, but it also allows counting of cases. If you have a huge table and sparse cases you can use a hash table instead of a plain array.
EDIT: Of course there are even more advantages with the dispatch table than the switch case, as you can add and remove and change the dispatch table dynamically. That may be the greatest advantage.
回答2:
This is horrible, but if you are under gcc you can use the COUNTER macro:
#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;
}
Output:
3 cases
回答3:
(I hope you are on Linux and using a recent GCC compiler)
If you want to count the actual number of cases as seen by the compiler (think of case ranges), you need to know the compiler internal representations, and you could, if compiling with a recent GCC, customize your compiler using GCC MELT and coding our own MELT extension.
BTW, the complexity or efficiency of a switch
statement is not only (or mostly) related to the number of cases (since the distribution of cases matters a big lot). See the references here.
Perhaps you might simply use the findgimple
mode of GCC MELT to find switch
gimple statements which are wide enough.
Maybe you want computed gotos for threaded code...