Спиральное правило и "объявление следует за использованием" для синтаксического анализа объявлений C и С++
Этот вопрос следует этому другому вопросу о декларировании C. Читая ответ на этот вопрос, я прочитал о спиральном правиле, и я также понял, что означает "объявление после использования".
Хорошо. Но затем я прочитал это объявление:
char *(*(*a[N])())();
и мне было интересно, как его разобрать с помощью правила "объявление следует за использованием". Особенно для части массива.
Что я читаю:
(*(*a[N])())
является функцией ()
, возвращающей a char *
, затем разыменовывая следующую
(*a[N])() // 1
- это 'функция, возвращающая char*
', и поэтому 1 является "указателем на функцию, возвращающую char *
", то я бы сказал: "Когда вызывается (*a[N])
, это [предыдущая декларация]". На этом этапе (*a[N])
является функцией, возвращающей указатель на функцию, возвращающую char *
.
Но тогда я не знаю, как применить это правило, чтобы различать "указатель на массив" и "массив указателя".
Может ли кто-нибудь прояснить это?
Другой вопрос: каковы правила "приоритета" в таких объявлениях, между &
(в С++), *
и []
? [возможно, "приоритет" не является правильным термином]
Чтобы проверить, правильно ли я понял "правило спирали", я также разбираю это выражение ниже; скажите, пожалуйста, если я ошибаюсь.
+-----------+
| +------+ |
| | +-+ | |
| | ^ | | |
char* (*(* a[N])())();
^ ^ ^ ^ ^ ^
| | | | | |
| | +---+ | |
| +--------+ |
+--------------+
Для меня проще (цикл за циклом):
-
a
- массив из N...
- указатель на функцию возврата...
- указатель на функцию возврата...
-
char *
Но я, возможно, пропустил что-то, что в этом случае позвольте мне получить правильный ответ, но это может быть неправильно в другом более сложном случае.
Ответы
Ответ 1
Вам просто нужно создать его пошагово.
char *X(); // X =~ (*(*a[N])())
Возвращаемая функция char*
char *(*Y())(); // Y =~ (*a[N])
Функция возвращает указатель на функцию, возвращающую char*
.
В объявлении, как и в выражении (объявление следует использовать), postfix []
имеет более высокий приоритет, который унарный *
, поэтому *a[N]
эквивалентен *(a[N])
, а не (*a)[N]
.
char *(*(*Z)())(); // Z =~ a[N]
Указатель на функцию, возвращающую указатель на функцию, возвращающую char*
.
char *(*(*a[N])())();
Массив из N указателей на функции, возвращающие указатель на возвращаемую функцию char*
.