Getting the number of cases in a switch-case in C

天大地大妈咪最大 提交于 2019-12-06 12:13:26

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.

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
Basile Starynkevitch

(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...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!