目录
传址调用和传址调用的定义
传值调用是指:调用某一个函数时参数接收的是变量的值
传址调用是指:调用某一个函数时参数接收的是变量的地址
传值调用
传值调用传进的是值,所以这种调用只能做到把变量的值传进去,比如:
int Add(int a,int b){
int c=a+b;
return c;
}
这样是可以的,但无法对函数外的变量进行修改,比如交换两个变量值的函数
#include<stdio.h>
void swap(int x,int y){
int tmp=x;
x=y;
y=tmp;
}
int main(){
int a=10;
int b=20;
swap(a,b);
printf("%d %d",a,b);
return 0;
}
这样写是不能把a和b的值交换的,因为把a、b的值传进去,x、y分别接收,函数只是把x、y的值进行了交换,它是找不到a、b的,所以最终a的值还是10,b的值还是20。
那么怎样才能在函数体内对函数外的变量直接操作呢?
这就用到了传址调用,我们都知道,每一个变量都有唯一的地址,只要拿到了地址,就可以找到那个变量,所以我们只要给函数提供变量的地址,函数就可以找到变量进行操作。
传址有两种方式,一个是指针传递,一个是引用传递,“引用”这个概念是C++中的,在C语言中是没有的,放到文章最后讲解。
传址调用
(1)指针传递
上面提到的swap函数正确写法为:
#include<stdio.h>
void swap(int* pa,int* pb){
int tmp=*pa;
*pa=*pb;
*pb=tmp;
}
int main(){
int a=10;
int b=20;
swap(&a,&b);
printf("%d %d",a,b);
return 0;
}
我们都知道,指针就是地址,那么就可以用地址传进去,用"地址变量"接收,也就是用指针变量接收。
传进去a的地址(&a),pa这个指针变量接收,因此对pa解引用(*pa)就找到了a,对 *pa的操作就是对a的操作,同理对 *pb的操作就是对b的操作,这样就做到了在swap函数内对函数外的a、b进行操作,这种地址传参方式就是指针传递。
(2)引用传递
引用这个概念是C++独有的,只能在.cpp文件中使用,在.c文件中会报错。(可以在.cpp文件中使用C库,因为C++是兼容C的)
简单介绍下引用:
引用就是一个对象的别名,地址与该对象相同。
引用的形式为:&x=a; (这里的&不是取地址的意思)
比如一个学生叫李明,在学校班主任叫他李明,在家里父母叫他小明,不管别人叫他小明还是李明,说的都是一个人,引用也与此类似,上面的形式里x就是a的别名,都占一块内存空间,地址相同,那么我们就可以得出一个结论,对 x 的操作就是对 a 的操作,利用这个结论传递参数也可以做到在函数内修改函数外的变量。
#include<stdio.h>
void swap(int &x,int &y){
int tmp=x;
x=y;
y=tmp;
}
int main(){
int a=10;
int b=20;
swap(a,b);
printf("%d %d",a,b);
return 0;
}
根据形式 &x=a ,就可以传进去变量,然后用引用接收,在函数体内对x、y的交换就是对a、b的交换,最终也能达到交换的目的。
在这个过程中,我们发现,x和a的地址相同,地址也是指针,其实对引用理解更深的话,引用的本质就是个常量指针,也就是说引用传递和指针传递的本质是一样的,只是形式不相同,这个我们以后再谈。
总结
函数的调用可以分为传值调用和传址调用,传址调用又有两种方式——指针传递和引用传递,在不同情况下根据需求选择不同的调用方式,不存在哪个调用更好。
(文章任何处如有不妥,请在评论区点醒作者,谢谢!)