在C语言中调用函数交换两个数的数值是一个经典的问题。
#include
void swap(int x,int y);
void main()
{
int a=3,b=4;
swap(a,b);
printf("a=%d,b=%d\n",a,b);
}
void swap(int x,int y)
{
int t;
t=x;x=y;y=t;
}
执行的结果,发现值是没有交换的。在这种情况下传给形参的是变量的值。传递是单向的,即如果在执行函数期间形参的值发生变化,并不传回给实参,这就是值传递方式。因为在调用函数期间,形参和实参不是同一个存储单元。在主函数中a ,b 对应的存储单元的值并没有发生什么变化。
但是如果改用指针,这个问题就可以解决。
#include
void swap(int *x,int *y);
void main()
{
int a=3,b=4;
swap(&a,&b);
printf("a=%d,b=%d\n",a,b);
}
void swap(int *x,int *y)
{
int t;
t=*x;*x=*y;*y=t;
}
这是因为,使用指针,传递的是a ,b的地址,调用函数,从而改变了地址a,b中的数值。
如果想要改变指针值,传递指针参数,这样也是出现问题,如下面的例子:
#include
void fun(int *ptr)
{
int i;
int a[10];
for(i=0;i<10;i++)
{
a[i]=i;
}
ptr=a;
}
int main()
{
int *b=NULL;
fun(b);
printf("%d\n",b[4]);
}
例子中传递的是指针b,在函数fun()中,将数组a的地址赋给b,在返回后同样没有改变指针b的值(b中存储的是地址,是一个指针)。在这种情况下,如果采用二重指针,就能够改变指针b的内容,是b指向数组a的起始地址。修改后的程序如下:
#include
void fun(int **ptr)
{
int i;
int a[10];
for(i=0;i<10;i++)
{
a[i]=i;
}
*ptr=a;
}
int main()
{
int *b=NULL;
fun(&b);
printf("%d\n",b[4]);
}
这是因为,函数中传递的是指针b的地址,通过*ptr将b中的内容赋值为数组a的地址,从而实现目标。
可以总结为一句话,在函数参数传递中,如果要改变实参的值,就必须传递实参的地址。比如,实参是一个数值,就要传递数值的地址,被调用函数中的形参就是一维指针;如果实参是一维指针,被调用函数中的形参就需要是二重指针。牢记,调用函数期间,形参和实参不是同一个存储单元。