Another fun use is in the GNU regular expression library. I'm sure there are others in there, but this is one that sticks out through the interface:

When you search a string for a regular expression, you can pass in a pointer to a "translation table", which is an array of 256 characters. If you do that, then for each character the library deals with, it'll pull the corresponding character out of the translation table and use that instead. This is nifty; it's obvious enough to do a case-blind or diacritical-blind translation table, but there are other, weirder applications. It probably takes up a bit more space than the machine code to do the same job with an algorithm, but as whizkid observes, if you'd written a function your best hope would be that the optimizer would turn it into a look-up table anyway. So you'd just be back where you started. Space for speed is a fair trade; optimizers do it all the time. That's what caching is all about, too. If you're working with embedded systems, that's a different matter of course.

Obviously, a lot of the fun and space-efficiency of this is lost with a 16-bit character set like Unicode. The table would have to be 65k instead of 1/4k.

The GNU regex library is tons of fun in any case. It's like getting a holodeck for your birthday, when all you were expecting was a giant panda and a bottle of cheap liquor.