参参数:形参和实参
-------------------------------
形参实现一种数据传入的接口 ,由实参 拷贝 给 形参
拷贝!!!!!!!!!!!
拷贝1:
void func(int tmp){ //我们的意图是实现传进来的参数 +1
tmp++;
}
int mian(){
int a = 10;
func(a);
printf("%d\n",a); //输出结果还是 10, 并没有实现我们需要的功能
}
解析:参数传递是拷贝的概念.由于函数设计的时候,形参是 int tmp, 执行的动作是将 a 的值 拷贝成 tmp 所以 ,传递后 tmp = 10, tmp++; tmp = 11
因为tmp 是由a 拷贝出来的,是副本的存在,改动副本并不会影响 a 数据本身,所以 a 的值并不会发生改变.
需求:我们确确实实想通过参数传递,来改变实参的内容.
拷贝2:
void func2(int *tmp){
(*tmp)++;
}
int main(){
a = 10;
func2(&a);
printf("%d\n",a); //a = 11;
}
解析:同样是拷贝,为什么func2 的实际让实参发生了改变? 因为 func2 拷贝的是 a 的地址, 把a的拷贝给tmp,这时候 *tmp 指向的也是 int a这个空间 在操作*tmp的时候,就是直接对这个空间内的数据进行改变,所以让a 的值发生了改变
func1 是 值传递
func2 是 地址传递
值传递 和 地址传递 本身不具备 某种特定的标签 在参数传递的过程 只有拷贝两个字 .
而拷贝什么东西 ,其实是由我们人为设计的.
拷贝的是空间本身 ,就是创建空间副本,不会影响到原始空间,称作 值传递
拷贝的是空间的地址, 就是将 指针A 拷贝成 指针B, 指针B指向的空间是和指针A指向的空间是一样的,因为指针B是指针A的副本, 既然指针B能够操作这个空间,那自然能够改变这个空间里面的内容.
总结:
值传递: int func1(int tmp){} 在保护原始数据的时候用值传递 缺点:拷贝空间本身,而非地址,创建副本耗费资源,不灵活
地址传递: int func2(int *tmp){} 好处:传递参数灵活, 拷贝的是指针,拷贝内容少,指针只有 int大小 .
地址传递的 形参和实参汇总:
数据: 实参: 形参:
普通数据类型的 char/int/float/... a; func(&a); func( char/int/float/... *tmp )
一维数组 char a[10]; func(a); func( char *tmp)
二维数组 char a[2][3] func(a); func( char (*tmp)[3] )
指针数组 char *a[10] func(a); func( char **tmp )