在C语言中,我们肯定听说过值传递的参数传递方式,但有时候可能会忘记其中的原理,下面将用图片以及代码解释值传递。
我们知道在定义函数的时候所用到的参数称为形式参数,这些参数其实是不存在的,系统不会为他分配空间,所以在调用这个函数的时候会经历两个步骤,首先根据形式参数所定义的数据类型分配空间,然后才是将实际参数传递给形式参数进行函数操作。因此将实际参数传递给形式参数的过程其实就是一个赋值的过程。这种值传递有两个特点(1)单向性,即从实际参数传递给形式参数(2)参数传递结束后实际参数与形式参数没有任何关系,二者的改变互不影响。正是由于这种机制会导致一些误解,看如下代码:
//用swap函数实现将两个数值交换
#include<stdio.h>
void swap(int x,int y);
int main(){
int a = 1;
int b = 2;
printf("\n交换前 a:%d,b:%d",a,b);
swap(a,b);
printf("\n交换后 a:%d,b:%d",a,b);
return 0;
}
void swap(int x,int y){
int temp;
temp = x;
x = y;
y = temp;
printf("\n函数中 x:%d,y:%d",x,y);
}
本来应该是将两者进行交换,看着挺好但是运行之后奇怪的现象发生了:
为什么交换后a还是a,b还是b,但在函数中x,y却换了呢?这就是值传递可能引起的错误,看下面这张图:
如图所示,由于值传递的原因,形式参数与实际参数互不影响,所以形式参数进行交换,实际参数不受影响。那么应该如何使用函数来完成这种类似更改某存储地址中元素数值的操作呢,使用指针!
说白了,指针类型其实就是存储元素对应的地址,比如 int * a,这句话的含义就是a是一个执行int类型的指针变量,如果在进行上述改变某存储地址中元素数值的操作时直接用地址进行操作,那么问题是不是就解决了呢?
//用swap函数实现将两个数值交换
#include<stdio.h>
void swap(int *x,int *y);
int main(){
int a = 1;
int b = 2;
printf("\n交换前 a:%d,b:%d",a,b);
swap(&a,&b); //传入a,b的存储地址
printf("\n交换后 a:%d,b:%d",a,b);
return 0;
}
void swap(int *x,int *y){
int temp;
temp = *x;
*x = *y;
*y = temp;
printf("\n函数中 x:%d,y:%d",*x,*y);
}
在上述代码中我们实际交换的x,y的地址,因此可以实现我们想要的结果,原理如下:
其中*x,*y代表的意思是取地址为x,y的元素值,这里根据地址进行交换就可以将实际参数的值一起改变。