Каково влияние круглых скобок на указатели в C

#c #pointers

#c #указатели

Вопрос:

Например, в чем разница между

 (*user1).id
  

и

 *user1.id
  

Было бы намного лучше иметь пример для объяснения.
Спасибо!

Ответ №1:

  1. (*user1).id разыменования user1 , которые должны быть указателем на структуру, содержащую id поле, и извлекают id поле из этой структуры. 100% эквивалентно user1->id .

  2. *user1.id возвращает поле id , из user1 которого должна быть структура (не указатель на структуру) id , содержащая поле. Затем он разыменовывает это значение, что означает id , что поле должно иметь тип указателя.

Все это простой приоритет оператора C. Оператор . (выбор элемента по ссылке) имеет более высокий приоритет, чем оператор * (косвенного / разыменования).

Ответ №2:

Без круглых скобок . оператор (точка) имеет приоритет над (т.е.. привязывается ближе, чем) оператор *. http://en.cppreference.com/w/cpp/language/operator_precedence

Круглые скобки в этом примере сначала связывают оператор с более низким приоритетом.

 *user1.id
  

эквивалентно:

 *(user1.id)   The * operator dereferences .id, which if .id is not a pointer, is illegal syntax
  

Отличается от

 (*user1).id   The * operator dereferences user1, which must be a pointer, to get the id member
  

Сокращения дерева синтаксического анализа выглядят примерно так:

     (*user1).id
    member_expression
    ( struct_expression )              DOT member
    ( pointer_expression )             DOT member
    ( DEREFERENCE_OP IDENTIFIER )      DOT member )
    ( DEREFERENCE_OP IDENTIFIER )      DOT IDENTIFIER )
  

против.

     *user1.id 
    DEREFERENCE_OP user1.id
    DEREFERENCE_OP ( member_expression )
    DEREFERENCE_OP ( struct_expression DOT member )
    DEREFERENCE_OP ( IDENTIFIER        DOT member )
    DEREFERENCE_OP ( IDENTIFIER        DOT IDENTIFIER ) 
  

Ответ №3:

Вот как вы могли видеть — как это выглядит, в первом (на изображении ниже) вам нужно, чтобы пользователь был объявлен как:

     user user1;
  

и убедитесь, что идентификатор поля является указателем, потому что это то, что вы разыменовываете!

Во втором вы, должно быть, объявили, что:

     user* user1;
  

Здесь идентификатор имеет любой тип

введите описание изображения здесь