Это потому, что a
и b
являются указателями, и вы фактически передаете адреса x
и y
в main()
в качестве аргументов функции swap()
по ссылке :
swap(&x, &y);
Если вы используете оператор &
, он получает адрес объекта.
Параметр a
назначается адресом x
и параметром b
присваивается адресом y
.
Если вы правильно разыменовываете указатели a
и b
и имеете правильный алгоритм (как в данном случае), вы меняете местами значения x
и y
внутри main()
, а не значения указателей a
и b
.
Если говорить о самом алгоритме:
int tmp = *a;
*a = *b;
*b = tmp;
int tmp = *a;
- значение x
присваивается временному объекту. Это необходимо, поскольку на следующем шаге мы меняем значение x
.
*a = *b;
- значение y
присваивается x
.
*b = tmp;
- значение, которое ранее хранилось в x
и хранилось как место между tmp
(временный объект), теперь присвоено y
.
Обратите внимание, что на всех этих шагах оператор *
не означает двойное объявление указателя. Он используется для разыменования указателя.
Для получения дополнительной информации о «разыменовании» см.:
Что означает «разыменование» указателя ?
Если значения x
и y
были переданы значением (без &
), а параметры a
и b
были только типа int
, не int *
, тогда вы измените только a
и b
внутри swap()
.
Я рекомендую вам узнать больше об указателях. Например, в бесплатной копии Modern C, сделанной членом сообщества @JensGustedt.