Ну, я тоже должен кое-что добавить. Структура немного отличается от массива, потому что массив является указателем, а структура - нет. Так что будьте осторожны!
Допустим, я пишу этот бесполезный кусок кода:
#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
Е. И тот факт, что операторы «ссылка» &
и «разыменование» *
отменяют друг друга.