Ну, я тоже должен кое-что добавить. Структура немного отличается от массива, потому что массив является указателем, а структура - нет. Так что будьте осторожны!
Допустим, я пишу этот бесполезный кусок кода:
#include <stdio.h>
typedef struct{
int km;
int kph;
int kg;
} car;
int main(void){
car audi = {12000, 230, 760};
car *ptr = &audi;
}
Здесь указатель ptrуказывает на адрес ( ! ) Структурной переменной, audiно кроме адресной структуры также есть кусок данных ( ! )! Первый элемент блока данных имеет тот же адрес, что и сама структура, и вы можете получить его данные, только разыменовав указатель, как этот *ptr (без скобок) .
Но если вы хотите Асесс любого другого члена , чем первый, вы должны добавить условное обозначение , как .km, .kph, .kgкоторые являются не более , чем смещение к базовому адресу порции данных ...
Но из-за старшинства вы не можете написать*ptr.kg как оператор доступа .оценивается перед оператором разыменования, *и вы получите, *(ptr.kg)что невозможно, так как указатель не имеет членов! И компилятор знает это и поэтому выдаст ошибку, например:
error: ‘ptr’ is a pointer; did you mean to use ‘->’?
printf("%d\n", *ptr.km);
Вместо этого вы используете это, (*ptr).kgи вы заставляете компилятор 1-й разыменования указателя и включить Асесс в порции данных и второго добавления смещения (обозначение) , чтобы выбрать элемент.
Проверьте это изображение, которое я сделал:

Но если бы вы имели вложенные члены, этот синтаксис стал бы нечитаемым и, следовательно, -> был введен. Я думаю, что удобочитаемость является единственной оправданной причиной для его использования, поскольку это ptr->kgгораздо проще, чем писать (*ptr).kg.
Теперь давайте напишем это по-другому, чтобы вы видели связь более четко. (*ptr).kg⟹ (*&audi).kg⟹ audi.kg. Здесь я впервые использовал тот факт, что ptrэто «адрес audi», т. &audiЕ. И тот факт, что операторы «ссылка» & и «разыменование» * отменяют друг друга.