Вас сбивает с толку разница между инициализацией и назначением ; две разные вещи.
Линия
int *jp = &j;
объявляет jp
как указатель на int
, а инициализирует его результатом выражения &j
, имеющего тип "pointer to int" (int *
).
Линия
*jp = &j;
пытается присвоить результат выражения &j
(который имеет тип int *
, запомните) результату выражения *jp
(который имеет тип int
1 ). Поскольку типов двух выражений не совпадают, вы получаете ошибку во время компиляции.
Обратите внимание, что тот факт, что jp
не был инициализирован, чтобы указывать куда-либо значимое, будет ошибкой runtime , а не ошибкой во время компиляции; Итак, если бы вы написали *jp = 5;
, программа скомпилировала бы очень хорошо (выражения *jp
и 5
имеют совместимые типы), но (скорее всего) взорвалась бы, когда вы попытался запустить его.
1 Объявления в C и C ++ основаны на типах
выражений , а не на объектах. Например, мы объявляем
jp
как указатель на
int
. Чтобы извлечь
значение целого числа, на которое мы указываем, мы
разыменовываем указатель с оператором
*
, как в операторе
x = *jp;
Тип выражения *jp
равен int
, поэтому объявление указателя равно
int *jp;