2014-09-09 3 views
2

Я читал, что если у нас есть указатель на объект типа struct, мы не можем получить доступ к полю объекта, используя звездочку (*), но нам нужно использовать это -> (как стрелка знак).C struct pointer accessing fields

Теперь, хотя я читал об этом, я не понимал, почему мы не можем использовать звездочку, я попытаюсь представить пример кода и изображение того, как я визуализирую структуру в памяти, чтобы помочь вам понять, что такое не позволяя мне понять эту тему.

Итак, вот наш код:

#include <stdio.h> 

typedef struct MyStruct 
{ 
    char c1; 
    char c2; 
} MyStruct; 

int main() 
{ 
    MyStruct s1; // Let's assume s1's address is 0x34A 
    s1.c1 = 'A'; 
    s1.c2 = 'B'; 
    printf("s1 c1 is %c and c2 is %c.\n", s1.c1, s1.c2); 

    MyStruct *p = &s1; // Declaring our pointer to point to s1 address, so p points to 0x34A 
    printf("s1 c1 is %c and c2 is %c.\n", p->c1, p->c2); // I know this is the valid way 
    printf("s1 c1 is %c.\n", *p.c1); // I don't understand why this would be invalid 
    return 0; 
} 

Теперь позвольте мне попытаться объяснить, почему я не понимаю, почему этот синтаксис является недопустимым. Так р указывает на адрес s1, который 0x34A и как я вижу это, как я вижу, s1 в памяти:

enter image description here

Так что я представляю его как в памяти, что s1 имеет собственный адрес, который в нашем примере равен 0x34A, и указывает на адрес c1 в памяти, за которым следует адрес c2. Так что, когда я делаю это:

printf("s1 c1 is %c.\n", (*p.c1)++, *p.c2); 

Я думаю о нем, как я возвращающее значении, которое внутри адрес указателя на нашем указателе, поэтому мы доступ к значению, которое c1.

Но, поскольку я сказал, что это недействительно, и я просто ломаю голову, пытаясь понять, почему, я попытался прочитать об этом, но не мог поместить пальцем на ответ, который удовлетворит меня тем, почему на самом деле, поэтому я Я привел пример кода и картинку, чтобы вы могли войти в мою голову, и попытаться понять, почему я здесь ошибаюсь.

+1

Потому что '* p.c1' означает, что вы хотите разыменовать' c1' (который не является указателем). '(* p) .c1' будет работать, с другой стороны, но вы можете увидеть, как это изгиб пальца, чтобы вытащить это (по сравнению с просто' p-> c1'). – Groo

+0

@Groo так в основном (* p) .c1 эквивалентен p-> c1, а просто другому синтаксису? нет других различий? например, когда u может делать в указателе на массив, например, * (p + i) и p [i], поэтому просто другой синтаксис? – Akes55

+0

Да, эти выражения эквивалентны. – Groo

ответ

4

*p.c1 разобран как *(p.c1) не (*p).c1.

Итак, когда вы делаете *(p.c1), вы пытаетесь использовать оператор-указатель на указателе, который терпит неудачу.

+0

так (* p) .c1 эквивалентно p-> c1? – Akes55

+1

@ Akes55: Это правильно. –

+1

Чтобы добавить некоторый фон, почему: «.» - оператор имеет более высокий приоритет в C, чем «*» - оператор. cf: http://en.cppreference.com/w/c/language/operator_precedence – midor

0

Здесь есть проблема с приоритетом. Если вы хотите получить доступ к этому, то перейдите к (* p) .c1. Теперь, выполнив (* p), вы дойдете до своей структуры, а затем после участников.