Ну, я також повинен щось додати. Структура трохи відрізняється від масиву, оскільки масив - це вказівник, а структура - ні. Тож будьте обережні!
Скажемо, я пишу цей марний фрагмент коду:
#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-ю дереференцію вказівника і вмикати доступ до фрагменту даних, а 2-го додаєте зміщення (позначення) для вибору члена.
Перевірте це зображення, яке я зробив:

Але якби ви вклали членів, цей синтаксис став би нечитабельним і тому ->був введений. Я думаю, що читабельність є єдиною виправданою причиною його використання, оскільки це ptr->kgнабагато простіше написати, ніж (*ptr).kg.
Тепер напишемо це по-іншому, щоб ви бачили зв’язок чіткіше. (*ptr).kg⟹ (*&audi).kg⟹ audi.kg. Тут я вперше застосував той факт, що ptrце "адреса audi", тобто &audiфакт, що оператори "посилання" & та "відвантаження" * скасовують будь-яке інше.