2016-11-18 2 views
0

Я знаю, что если у меня есть указатель на языке программирования C, и я должен указать на структуру, я:Почему * ptr.member ошибочен и (* ptr).

struct mystruct S; 
struct mystruct *ptr; 
ptr=&S; 
ptr->member=5; 

Я понял это, но я не понимаю, почему, если я делаю :

ptr=&S; 
(*ptr).member=5; 

*ptr должен указывать на первый адрес структуры, но почему это не работает, если я делаю это:

*ptr.member=5; 
+6

Из-за [Приоритет Оператора] (http://en.cppreference.com/w/c/language/operator_precedence) –

ответ

0

У вас есть структура и указатель на структуры:

struct mystruct S; 
    struct mystruct *ptr; 

Теперь хранятся в PTR в адрес этой структуры

ptr = &S; 

Если вам необходимо получить доступ к одному члену этой структуры через указатель, у вас есть ДВА альтернативных синтаксисов

(*ptr).member = 5; 

и

ptr->member = 5; 

Эти два синтаксисами эквивалентны и сделать точно такое же действие.

Это только вопрос личного вкуса.

В вашем вопросе у вас есть ошибка, потому что Вы писали:

(*p).member = 5; 

Вместо

(*ptr).member = 5; 

Следовательно, ошибка

последний совет:

(*ptr).member = 5; 

и

*ptr.member = 5; 

разные вещи

(* PTR) .member = 5; означает, что вы получите адрес, на который указывает PTR, а затем хранить 5 в поле имени член

* ptr.member = 5; означает, что вы получите адрес, указанный ptr.member, а затем сохраните 5 в памяти, указанной этим адресом.

1

Если у вас есть ул ucture

struct A 
{ 
    int x; 
}; 

и объекта типа структуры

A a; 

затем получить доступ к его члену данных x вы должны написать

a.x = 5; 

Или вы можете написать

(&a)->x = 5; 

Теперь, если у вас есть указатель типа struct A *, который инициализируется адресом объекта a

struct A *pa = &a; 

то выражение *pa дает объект a сам. Поэтому вы можете написать

(*pa).x = 5; 

Так что теперь сравните. С одной стороны

a.x = 5;  and  (*pa).x = 5; 

, а с другой стороны

(&a)->x = 5; and  pa->x = 5; 
1

Поскольку доступ к оператору члена (точка) имеет приоритет над dereferenciation (*).

Итак, ваше выражение эквивалентно:

*(p.member) = 5 

И p.member не является указателем.

2

Операторы имеют precedence: оператор доступа к члену . имеет наивысший приоритет, в то время как разыменование * имеет следующий высокий приоритет. Итак, *p.member пытается найти участника member указателя на mystruct, а затем разыменовать его. Поскольку *mystruct не имеет члена с именем member, это ошибка.

1

Унарное * имеет более низкий приоритет, чем операторы выбора члена . и ->, поэтому *p.member обрабатывается как *(p.member); другими словами, вы пытаетесь разыменовать результат p.member. Это две проблемы:

  • p является тип указателя, так что компилятор будет жаловаться, что вы пытаетесь использовать оператор . на то, что не является структура или объединение типа;

  • memberне тип указателя, так что вы не можете применить унарную * к нему.

(*p).member эквивалентно p->member; оба разыменования p перед доступом к member.