char *c = "line";
is not the same as
char c[] = "line";
it's really the same as
static const char hidden_C0[] = "line";
char *c = (char *)hidden_C0;
except that the variable hidden_C0 is not directly accessible. But you'll see it if you dump out generated assembly language (it will usually have a name that isn't a valid C identifier, like .LC0). And in your array-of-string-constants example, the same thing is going on:
char *choices[] = { "New Game", "Continue Game", "Exit" };
becomes
const char hidden_C0[] = "New Game";
const char hidden_C1[] = "Continue Game";
const char hidden_C2[] = "Exit";
char *choices[] = { (char *)hidden_C0, (char *)hidden_C1, (char *)hidden_C2 };
Now, this is a special case behavior that is available only for string constants. You cannot write
int *numbers = { 1, 2, 3 };
you must write
int numbers[] = { 1, 2, 3 };
and that's why you can't write
char **choices = { "a", "b", "c" };
either.
(Your confusion is a special case of the common misconception that arrays are "the same as" pointers in C. They are not. Arrays are arrays. Variables with array types suffer type decay to a pointer type when they are used (in almost every context), but not when they are defined.)
int (*(*)())()