The variable given to a switch must be an int or a defined type that resolves to an int (long int might work too, it's been awhile). The reason for this is that a switch compiles into a jump table. This is important because finding what you're looking for in a jump table would take O(1) time instead of the O(n) time (where n is the number of conditionals) it could take to check every conditional if you were to implement this as a series of if()/elseif() statements.

It's also worth pointing out that you'll probably want to put a "break;" at the end of every block of code after a condition. If you don't your code will go to the correct condition and then execute all the code after that, including code intended for other conditions. Of course this may be what you want. See Duff's Device.

Update: wharfinger has brought it to my attention that a switch doesn't always compile to a jump table. This caused me to drag out my copy of the Dragon Book. On pages 497-498 it says that if there are less than 10 values or so you can implement it as "a sequence of conditional goto's." If there are more than 10 use a hash table. However, no matter how many values you have, if they are reasonably contiguous use a jump table.

By using a switch, depending on how intelligent yoru compiler is, it may generate faster, more efficent, and more compact code.

The switch statment, as Untergeek pointed out will translate into a jump table. While the use of GOTOs and Jumps in upper level languages has been banned and alienated since as early as 1968 (Dijkstra, so says phraggle), you can use a switch statment to safely take advantage of the power that jumps give.
For conditional pattern matching where there are no recognizable patterns (and usually when there are), a jump pattern will do it in O(1), while a long string of else if()s will do it in O(n).

Probably more code than necessary, but I'm trying to prove a point. Also, above, note that in the worst case, if a were 5, and we'd have to do a default procedure, then we would have to do a comparison 5 times... if we would have 100 functions, we'd need 100 comparisons before we'd know to use the default procedure. This code has is O(n).

In C or Java, the two chunks of code would look equivalent, but (assuming you have a dumb compiler) this could turn into assembly like the following. If you don't get this at first, see me after class.

Look anything like your C-style syntax? That 'case x:' syntax in switch statements, still used in a modern language like Java came from somewhere. It wouldn't be entirely too naive to say that 'break' just jumps to the next closing bracket tied to a loop or procedure.

In our worst case above, when we had an efficiency of O(n), when looking at the assembly code generated by the switch statement, no matter what a is, we only need 4 to execute 4 opcodes before we enter into our functiona(). By definition, our code is efficient on the order O(1). So use it whenever you can.

Update: A few have msged me asking to link to Duff's Device. Crazy stuff.

Update: ariels and a couple others have pointed out that if the ranges are a lot greater, then translating into a jump table may not be feasable. YMMV.