Приоритет оператора в определениях C - PullRequest
4 голосов
/ 22 января 2011

Википедия утверждает, что оператор [] предшествует оператору * в оценке.

Тогда почему следующее утверждение:

char *a[3];

объявлять массив из 3 символьных указателей, а не указатель на массив из 3 символов в соответствии с приоритетом оператора?

Ответы [ 3 ]

7 голосов
/ 22 января 2011

Поскольку, как говорит Википедия, [] имеет более высокий приоритет, чем *?

Обрабатывая объявление, a[3] обрабатывается как «массив из 3» перед обработкой *.

Чтобы объявить указатель на массив из трех символов, вы должны использовать скобки, чтобы переопределить приоритет по умолчанию:

char (*a)[3];

Теперь скобки имеют приоритет над массивом.

2 голосов
/ 23 января 2011

Вот грамматика для объявления, взятая из стандарта (& sect; 6.7.5):

<i>declarator</i>:
    <i>pointer<sub>opt</sub> direct-declarator</i>

<i>direct-declarator</i>:
    <i>identifier</i>
    <code>(</code> <i>declarator</i> <code>)</code>
    <i>direct-declarator</i> <code>[</code> <i>type-qualifier-list<sub>opt</sub> assignment-expression<sub>opt</sub></i> <code>]</code>
    <i>direct-declarator</i> <code>[ static</code> <i>type-qualifier-list<sub>opt</sub> assignment-expression</i> <code>]</code>
    <i>direct-declarator</i> <code>[</code> <i>type-qualifier-list</i> <code>static</code> <i>assignment-expression</i> <code>]</code>
    <i>direct-declarator</i> <code>[</code> <i>type-qualifier-list<sub>opt</sub></i> <code>* ]</code>
    <i>direct-declarator</i> <code>(</code> <i>parameter-type-list</i> <code>)</code>
    <i>direct-declarator</i> <code>(</code> <i>identifier-list<sub>opt</sub></i> <code>)</code>

<i>pointer</i>:
    <code>*</code> <i>type-qualifier-list<sub>opt</sub></i>
    <code>*</code> <i>type-qualifier-list<sub>opt</sub> pointer</i>

<i>type-qualifier-list</i>:
    <i>type-qualifier</i>
    <i>type-qualifier-list type-qualifier</i>

<i>parameter-type-list</i>:
    <i>parameter-list</i>
    <i>parameter-list</i> <code>, ...</code>

<i>parameter-list</i>:
    <i>parameter-declaration</i>
    <i>parameter-list</i> <code>,</code> <i>parameter-declaration</i>

<i>parameter-declaration</i>:
    <i>declaration-specifiers declarator</i>
    <i>declaration-specifiers abstract-declarator<sub>opt</sub></i>

<i>identifier-list</i>:
    <i>identifier</i>
    <i>identifier-list</i> <code>,</code> <i>identifier</i>

Как видите, и [], и () связываются с декларатором до *. Возьми декларацию

int *a[N];

Декларатор - *a[N], который соответствует указателю opt , прямой декларатор , указанному выше, и поэтому анализируется как *(a[N]), поэтому a является N массив элементов указателя.

Подводя итог:

T *a[N]      -- declares an N-element array of pointer to T
T (*a)[N]    -- declares a pointer to an N-element array of T
T *f()       -- declares a function returning pointer to T
T (*f)()     -- declares a pointer to a function returning T  
0 голосов
/ 22 января 2011

Я запутался в вопросе - интерпретация объявления соответствует приоритету оператора. Если вам нужен указатель на массив, вы должны использовать парены, чтобы «связать * с идентификатором» перед привязкой [].

char (*a)[3];
...