#c #pointers
#c #указатели
Вопрос:
Например, в чем разница между
(*user1).id
и
*user1.id
Было бы намного лучше иметь пример для объяснения.
Спасибо!
Ответ №1:
-
(*user1).id
разыменованияuser1
, которые должны быть указателем на структуру, содержащуюid
поле, и извлекаютid
поле из этой структуры. 100% эквивалентноuser1->id
. -
*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;
Здесь идентификатор имеет любой тип