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