Как сказал Джошуа, при анализе объявлений на Си лучше начинать изнутри.
void (^(^myblockptr)(void (^)()))();
Поскольку myblockptr
- переменная, давайте разделим объявление на две части слевапеременной и справа от переменной:
void (^(^myblockptr) (void (^)()))();
Мы знаем, что (^myblockptr)
является блоком из-за ^
, поэтому слева от него мы должны найти его тип возврата, а справамы должны найти типы его параметров.
Давайте проанализируем параметры, которые принимает myblockptr
, двигаясь вправо.Они должны быть сгруппированы по скобкам сразу после (^myblockptr)
:
void (^(^myblockptr) (void (^)()) )();
Это один параметр, который является блоком из-за ^
:
void (^)()
и теперь это легкочтобы увидеть, что параметр является блоком, который возвращает void
и не принимает параметров.
При перемещении вправо справа есть закрывающая скобка, поэтому нам нужно проанализировать крайнюю левую часть:
void (^ (^myblockptr)…
, где мы видим, что myblockptr
возвращает блок, который возвращает void
.Поскольку он возвращает блок, мы должны найти типы параметров, принятые возвращаемым блоком после закрывающей скобки, которая соответствует крайнему левому открытому парантезу:
void (^ (^myblockptr)(void (^)()) )();
, так как это ()
, мы видим, что возвращенный блок нене имеет никаких параметров.
http://f.cl.ly/items/0N3l000g0X2f1O0F2B0n/blocks.png
В итоге: myblockptr
- это блок, который (справа) принимает параметр, который является блоком, который не принимает параметрови возвращает void
и (слева) возвращает блок , который не принимает параметров и возвращает void
.Поскольку тип возвращаемого значения myblockptr
и (одиночный) тип параметра одинаковы:
typedef void (^Block)();
, что приводит к:
Block (^myblockptr)(Block);
Возможно, вы захотите прочитать Стив РидингОбъявления типа C и, как упомянул Джереми, Fish's cdecl.org .