tags:

views:

227

answers:

5

what is the alternate way of doing function of switch-case (and if-else) in c?

+1  A: 

Function pointers and a semi implementation of the strategy pattern :)

.. though youll need some logic to determine which function to call

cwap
"semi implementation"? How would this differ from a "full implementation"?
Noldorin
I'd say that a full implementation would require interfaces instead of raw functions, but the point still stands..
cwap
+2  A: 

You could always use gotos... :-p

Vicky
A: 

Just use a switch case?

Matt Grande
+3  A: 

Function pointers are one alternative. Consider the following snippet that calls a function through a function pointer array:

#include <stdio.h>

void fn0(int n) { printf ("fn0, n = %d\n",n); }
void fn1(int n) { printf ("fn1, n = %d\n",n); }
void fn2(int n) { printf ("fn2, n = %d\n",n); }
void fn3(int n) { printf ("fn3, n = %d\n",n); }

static void (*fn[])(int) = {fn0, fn1, fn2, fn3};

int main(void) {
    int i;
    for (i = 0; i < 4; i++)
        fn[i](10-i);
    return 0;
}

This generates:

fn0, n = 10
fn1, n = 9
fn2, n = 8
fn3, n = 7

This sort of construct makes it very easy to implement things such as finite state machines where, instead of a massive switch statement or near-unmanageable nested if's, you can just use an integer state variable to index into an array of function pointers.

paxdiablo
+1  A: 

There are several different ways to handle conditional branch-and-switch scenarios in C.

The typical patterns, which you yourself mention, are switch( ) statements and if/else if/else groups. However, sometimes these flow control constructs are not the best choice for certain problems. Specifically cases such as:

  • High performance branching over a large domain
  • Branching on value domains only known at runtime
  • Changing the branch paths at runtime based on other conditions

In these cases, there are two patterns that I find helpful:

  1. The Strategy pattern with a direct dispatch
  2. The Strategy pattern with a chained dispatch

In the first approach, you map each value from your domain to a collection of function pointers. Each function handles a particular case (value) from your domain. This allows you to "jump" directly to the right handler for a particular case. This pattern works well when each case is separated from all the others and there is little or no overlapping logic.

In the second approach, you chain all of the dispatch methods together - and call each of them for all cases. Each dispatched method decides if it handles the case or not, and either returns immediately or performs some processing. This pattern is useful when there is overlap between the responsibilities of some of the handlers. It is somewhat less performant, since multiple handlers are invoked, and each decides whether it needs to perform its processing. However, this is one of the easier ways to deal with overlapping logic - the kind you could normally handle in a switch() statement with fall through (or jump) conditions.

You should only use one of these techniques if the problem really requires it, since they are less obvious to future developers and can introduce unnecessary complexity and maintenance problems if implemented poorly. It also makes your code more difficult to understand, over more common constructs like switch or if/else.

LBushkin
Large switch statements are actually optimized into binary trees by modern compilers so performance should not be an issue.
Peter Olsson