As Tyr42 has so astutely observed, I have meant that pattern matches in function declarations, let-bindings and list comprehensions are desugared into the case expression. Also, it would be kind of pointless to compare C switch and Haskell case. Especially, in your example Haskell, probably, 'wins' because primarilt because a more powerful type system and algebraic data-types (and absence of pointers, hehe). That said, it's not like you can't emulate the pattern matching (with placing nested values/subtrees in scope): https://gist.github.com/2832755 (it's in JavaScript, because I felt like it -- but I'm pretty sure you can devise something similar in C). Of course, it's plain ugly and doesn't carry any nice static guarantees that the Haskell type-system will give you (like warning about incomplete patterns)... but, hey, it works.
Anyway, the point of my comment was that pattern-matching is hardly a feature characterizing and exclusive to Haskell (ML/OCaml/F#, Coq, Scheme have it, probably other functional languages too). Although, it's still the one I enjoy every day :)