Typedefs для wusses. Вот простой механический метод определения волосатых объявлений:
a -- a
a[N] -- is an N-element array
*a[N] -- of pointers
(*a[N])() -- to functions
*(*a[N])() -- returning pointers
(*(*a[N])())() -- to functions
*(*(*a[N])())() -- returning pointers
char *(*(*a[N])())() -- to char.
Итак, ответ находится в окрестности char *(*(*a[N])())();
. Я говорю «по соседству», так как никогда не указывается, какие аргументы принимают функции.
Это неприятный вопрос для собеседования (такие уродливые, это действительно редкий IME), но он дает интервьюеру представление о том, насколько хорошо вы понимаете деклараторов. Либо так, либо им было скучно, и они просто хотели посмотреть, могут ли они заставить мозг болеть.
EDIT
Большинство других рекомендует использовать typedefs. Единственный раз, когда я рекомендую использовать typedef, это если тип должен быть действительно непрозрачным (т.е. не манипулироваться непосредственно программистом, а передаваться в API, вроде как тип FILE). В противном случае, если программист предназначен для непосредственного манипулирования объектами этого типа, то в IME лучше иметь всю эту информацию доступной в объявлении, какой бы ужасной она ни была. Например, что-то вроде
NameFuncPickerPointer a[N];
не дает мне никакой информации о том, как на самом деле использовать a[i]
. Я не знаю, что a[i]
может быть вызвано, или что он возвращает, или какие аргументы он должен принять (если есть), или многое другое. Мне нужно искать typedef
typedef char *NameFunc();
typedef NameFunc *NameFuncPicker();
typedef NameFuncPicker *NameFuncPickerPointer;
и из этой головоломки выясните, как написать выражение, которое фактически вызывает одну из функций. Принимая во внимание, что используя «голое» объявление, не являющееся typedef'd, я сразу же знаю, что структура вызова
char *theName = (*(*a[i])())();