У меня есть тестовая программа, чтобы попробовать это:
int main()
{
int i = 1;
int* p, q;
p = &i;
//q = &i;//q is not pointer
int* buf[20];//type of element is int*
return 0;
}
(1) я нашел q
не указатель, так кажется int *p
звездочка является правоассоциативной.
(2) Но для int* buf[20]
, Я нашел buf
массив из 20 элементов, каждый из которых набирается int*
, Таким образом, в строке 5, кажется, звездочка левоассоциативна.
Так каково точное правило того, как *
связан с другими частями выражения, левоассоциативными или правоассоциативными, или применяется к другим правилам?
Объявление состоит из последовательности спецификаторов, за которой следует последовательность деклараторов. Каждый декларатор объявляет одно имя. Каждый спецификатор применяется к каждому декларатору независимо. Отсюда в
int* p, q;
спецификатор int
относится к обоим p
а также q
, Тем не мение, *
не является спецификатором, а является частью декларатора *p
так что это относится только к p
,
*
связывается с объектом справа, но имеет более низкий приоритет, чем []
а также ()
, Это правило приоритета такое же, как и для выражений. &
а также &&
(Только C ++) имеет тот же приоритет, что и *
, В
int* buf[20];
есть один спецификатор, int
и один декларатор, *buf[20]
и [20]
связывается более плотно, поэтому это массив указателей, а не указатель на массив, а базовый тип int
так что это массив указателей на int
,
Привязка может быть изменена в скобках:
int* buf[20]; // array of pointers
int (*buf)[20]; // pointer to array
Это работает правильно
int* p, q;
Поскольку действительно важно, что это int * p или int * p, проблема здесь в том, что q стоит после запятой, которая будет нуждаться в другом указателе *, если вы хотите, чтобы он тоже был указателем.
Эта строка:
int* buf[20];//type of element is int*
Также делает то, что должен делать, объявляет массив указателей int, который совпадает с int * buf [20]