I'm reading over a solution to a problem in K&R's chapter 7 posted here. Basically, the program will convert the standard input into lowercase or uppercase depending on the name of the program ("upper" or "lower"). It seems to store the names of the conversion functions in some kind of dictionary, like so:
int (*convcase[2])(int) = {toupper, tolower};
and later access these functions depending on whether the name of the program started with a u or an l:
if(argc > 0)
{
if(toupper((unsigned char)argv[0][0]) == 'U')
{
func = 0;
}
else
{
func = 1;
}
while((ch = getchar()) != EOF)
{
ch = (*convcase[func])((unsigned char)ch);
putchar(ch);
}
}
I understand what that code block is doing, but I've never seen anything like the initial declaration of convcase. It seems like some kind of weird combination of a macro, an enum, and an array. Could anyone explain (1) why convcase is a pointer; (2) what's with the (int) cast after its name; (3) what exactly toupper and tolower are within that declaration, because they're not char *s; and (4) when/why to use this kind of setup. Is it just a quick macro-like tool to save some space when you have multiple possible function calls?