Спиральное правило и «объявление следует за использованием» для анализа объявлений C и C ++ - PullRequest
17 голосов
/ 14 сентября 2010

Этот вопрос следует за другим вопросом о декларациях C . Читая ответ на этот вопрос, я прочитал о спиральном правиле , и я также понял, что означает "объявление следует за использованием".

Хорошо, пока. Но тогда я читаю эту декларацию :

char *(*(*a[N])())(); 

и мне было интересно, как разобрать его с помощью «объявления после использования» «правила». Специально для части массива.

Что я читаю:

(*(*a[N])()) 

- это функция (), возвращающая char *, затем разыменовывает следующее

(*a[N])() // 1

- это «функция, возвращающая char*», и поэтому 1 - «указатель на функцию, возвращающую char *» тогда я бы сказал «когда вызывается (*a[N]), это [предыдущая декларация]». На данный момент у нас есть (*a[N]) - функция, возвращающая указатель на функцию, возвращающую char *.

Но тогда я не знаю, как применить это правило, чтобы различать «указатель на массив» и «массив указателей».

Может кто-нибудь прояснить это?

Другой вопрос: каковы правила «приоритета» в таких объявлениях между & (в C ++), * и []? [возможно, «приоритет» не является правильным термином]


Чтобы проверить, правильно ли я понял «правило спирали», я также разбираю это выражение ниже; пожалуйста, скажите мне, если я ошибаюсь.

       +-----------+
       | +------+  |
       | | +-+  |  |
       | | ^ |  |  |
char* (*(* a[N])())(); 
    ^  ^ ^   ^  ^  ^
    |  | |   |  |  |
    |  | +---+  |  |
    |  +--------+  |
    +--------------+

Для меня это проще (петля за петлей):

  • a - это массив N ...
  • указатель на функцию, возвращающую ...
  • указатель на функцию, возвращающую ...
  • char *

Но я, возможно, упускаю что-то, что в этом случае позволило мне получить правильный ответ, но это может быть неправильно в другом более сложном случае.

1 Ответ

13 голосов
/ 14 сентября 2010

Вы просто должны построить его поэтапно.

char *X();  // X =~ (*(*a[N])())

Функция возврата char*

char *(*Y())();  // Y =~ (*a[N])

Функция, возвращающая указатель на функцию, возвращающую char*.

В объявлении, как и в выражении (объявление следует за использованием), постфикс [] имеет более высокий приоритет, чем унарный *, поэтому *a[N] эквивалентно *(a[N]), а не (*a)[N].

char *(*(*Z)())();  // Z =~ a[N]

Указатель на функцию, возвращающую указатель на функцию, возвращающую char*.

char *(*(*a[N])())();

Массив из N указателей на функции, возвращающие указатель на функцию, возвращающую char*.

...