Указатель - это, в основном, адрес. Думайте о указателе как о метке адреса, а о качестве как о реальном доме. Вы можете использовать ярлык для поиска дома, но ярлык не дома.
int *ptr; // declares a pointer to an int
Таким образом, ptr - это адрес памяти. (Возможно, спецификация C на самом деле не указывает, что это адрес, но потерпите меня).
int i = 5; // create a local int.
Объявляет целое число в стеке и устанавливает его значение 5. Адрес i находится где-то в пространстве стека.
Давайте посмотрим на один промежуточный шаг, прежде чем мы продолжим. Это, вероятно, не скомпилируется, и если бы это было так, на самом деле ничего не сделал бы .
&i;
То, что делает это выражение, возвращает адрес переменной i. Это местоположение i в памяти - адрес целого числа.
И последний ...
*ptr;
Опять же, это, вероятно, на самом деле ничего не сделает, это просто выражение. Но он разыменовывает указатель - он ссылается на фактический int, расположенный по адресу, указанному в ptr.
Хорошо, давайте посмотрим на несколько вещей, которые мы можем сделать.
ptr = i;
Это ничего не делает, по крайней мере, то, что мы хотим сделать. Вероятно, не скомпилируется, но я не проверил это. Он ничего не делает, потому что назначает целое число на адрес целого числа. Это похоже на отправку ящика через почтовое отделение на адресную этикетку - вы на самом деле хотите, чтобы он пошел домой!
i = ptr;
Хорошо, это то же самое, что и последний, но наоборот. Следуя нашей аналогии, мы пытаемся превратить дом в этикетку!
*ptr = i;
Здесь мы разыменовали указатель и присвоили ему значение i. Разыменование указателя по существу похоже на использование метки для проезда к дому. Как только мы окажемся там, мы сможем что-то сделать с настоящим домом. Это работает, потому что разыменованный указатель на int является int, а int также является int.
ptr = &i;
Это тоже работает. И я в основном делаю новый ярлык для дома «я». Поскольку у нас есть указатель с обеих сторон, мы можем назначить один другому. Это в основном копирование метки адреса для i в метку адреса с именем ptr.
*ptr = &i;
Это не имеет смысла. Мы начали с двух разных вещей и превратили друг в друга! Сейчас мы пытаемся присвоить метку дому, тогда как раньше мы присваивали дом метке адреса.