Вы путаетесь между двумя использованиями амперсанда (&). В одном случае это оператор, а в другом - часть типа объявления.
int x = 5;
int* y = &x; // (1) Here it's an operator
int& z = x; // (2) Here it's part of the type of y
В строке (1) выше мы объявляем и определяем переменную с именем y
типа pointer to int
. Это означает, что переменная y
должна содержать адрес переменной типа int
. Чтобы получить адрес переменной, вы используете &
в качестве оператора. Таким образом, &x
является адресом x
, и мы храним его в указателе. y
теперь указатель на x
.
В строке (2) мы определяем переменную с именем z
, которая имеет тип reference to int
. Поскольку мы привязываем x к этой ссылке, это означает, что мы можем использовать z
в качестве другого имени для x
. Изменение z
изменит x
(а также значение, на которое указывает y
!).
Поэтому, когда у вас есть функция, которая принимает указатель, например, void func(int* p)
, вам нужно передать ей адрес типа int. Для этого вам нужно либо передать указатель напрямую, либо взять адрес int
:
int x = 5;
func(&x);
Если у вас есть функция, которая принимает ссылку, например, void func(int& r)
, вам нужно только передать ей int
. Ссылка будет относиться к тому же int
.
int x = 5;
func(x);
Их можно использовать аналогичным образом: передать аргумент функции, чтобы она могла изменить его, или избежать копирования. Тем не менее, аргумент указателя также позволяет передавать нулевой указатель в функцию. Это не работает со ссылкой, потому что ссылка всегда должна быть привязана к чему-либо. Кроме того, после привязки ссылка не может быть восстановлена на другой объект.
Ссылки, как правило, гораздо удобнее и не полагаются на манипуляции с указателями в стиле C. В C ++ вы обычно хотите использовать ссылку, когда можете, и указатель, если необходимо. Подробнее см. FAQ по C ++ .