Там это правило: http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html
Короче говоря, вы должны начать с идентификатором, то разобрать все от идентификатора вправо (это может быть ()
- функция или []
массив), а затем разобрать все от идентификатора левый. Скобки меняют этот порядок - вы должны сначала разобрать все в самых внутренних скобках и так далее, он работает как с арифметическими вычислениями.
Другими словами, существует порядок приоритета (который может быть изменен с помощью скобок), от высшего к низшему:
1) ()
- функция и []
- массива, слева направо;
2) *
- указатель, тип, модификатор типа, справа налево.
Ваш пример
int (*ptr)(char (*ch)[])
Мы начинаем с идентификатором
int (*ptr)(char (*ch)[]); // (1)ptr
|_|
1
Идентификатор ptr
в скобках, поэтому мы разбираем все в parenteses первых
(*ptr) // (1)ptr
|_|
1
Там нет ничего вправо, так что мы разбираем к левому
(*ptr) // (1)ptr is (2)a pointer
||_|
2 1
Мы закончили в скобках, теперь мы разбираем справа скобки
int (*ptr)(char (*ch)[]); // (1)ptr is (2)a pointer to (3)function
||_| |____________|
2 1 3
До сих пор мы игнорируем аргументы функции и разобрать слева от скобок
int (*ptr)(char (*ch)[]); // (1)ptr is (2)a pointer to (3)function which returns (4)int
|_| ||_| |____________|
4 2 1 3
Таким же образом разбираемого аргумент функции (я вставил некоторые пробелы для лучшего выравнивания)
char (* ch)[ ] // (1)ch is (2)a pointer to (3)array of (4)chars
|___| | |_| |_|
4 2 1 3
Наконец, мы имеем:
PTR является указателем на функцию, которая возвращает Int и принимает указатель на массив символов в качестве аргумента
Это одна область С, что дизайнеры получили очень плохо неправильно! –
Правда! Трудно оценить такие выражения. – RDX
Это синтаксическая ошибка. –