Если вы хотите изменить исходные объекты функции, вы должны передать их функции по ссылке.
В C передача объектов по ссылке означает косвенную передачу их через указатели, указывающие на исходный объект. .
В противном случае, если вы передадите сами исходные объекты в функцию, функция будет иметь дело с копиями объектов. Очевидно, что изменение копий не влияет на исходные объекты.
Это именно то, что происходит в этой функции
void swap(int *a,int *b){
int *p=b;
b=a;
a=p;
}
Функция имеет дело с копиями указателей, переданных функции в качестве аргумента в этом вызове
swap(&a,&b);
То есть функция действительно поменяла местами значения двух указателей, которые объявлены как ее параметры. Но они не являются оригинальными указателями, переданными функции. Они являются копиями указателей. Значения исходных указателей не изменились
Функция подкачки в общем случае может выглядеть следующим образом
void swap( T *a, T *b )
{
T tmp = *a;
*a = *b;
*b = tmp;
}
, где T
- это тот же спецификатор типа.
Так что если вы хотите поменять местами объекты типа int
, то в приведенной выше функции T
будет int
и функция будет выглядеть как
void swap( int *a, int *b )
{
int tmp = *a;
*a = *b;
*b = tmp;
}
Если вы хотите поменять местами значения указателей введите int *
, тогда T
будет int *
, а функция будет выглядеть так:
void swap( int **a, int **b )
{
int *tmp = *a;
*a = *b;
*b = tmp;
}
Вот демонстрационная программа.
#include <stdio.h>
void swap1( int *pa, int *pb )
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void swap2( int **ppa, int **ppb )
{
int *tmp = *ppa;
*ppa = *ppb;
*ppb = tmp;
}
int main(void)
{
int a = 3, b = 5;
swap1( &a, &b );
printf( "a = %d b = %d\n", a, b );
// reset again the values of the variables
a = 3; b = 5;
int *pa = &a, *pb = &b;
swap2( &pa, &pb );
printf( "*pa = %d *pb = %d\n", *pa, *pb );
return 0;
}
Ее вывод
a = 5 b = 3
*pa = 5 *pb = 3
То есть сначала в программе меняются два объекта типа int
, поэтому воображаемый спецификатор типа T
равен int
.
Затем два указателя, которые указывают на объекты a
и b
меняются местами. Таким образом, воображаемый спецификатор типа T
int *
.
После смены указателей указатель pa
теперь указывает на объект b
, а указатель pb
теперь указывает на объект a
.