函数形参中有两种传值方式,直接传值与间接的地址传值。下面说说这两种方式的差别:
值传递
形参中值传递,并不会改变原值的数据。因为原址只是拷贝一份数据传进去,修改的值是拷贝的数据。
void swap(int a,int b)
{
int c = a;
a = b;
b = c;
printf("func: a = %d, b = %d\n",a,b);
}
int main()
{
int a = 10;
int b = 20;
swap(a,b);
printf("a = %d, b = %d\n",a,b);
}
结果
func: a = 20, b = 10
a = 10, b = 20
值传递
可以看到原先的a,b值并没有改变,因为传进函数的是原值的拷贝,函数一运行结束,这些拷贝的变量就会被系统回收,函数内部的数据处理与函数外部的原值一点联系也没有。值传递没法改变原值的数据。
地址传递
使用地址传递,可以在函数内部通过*间接操作来改变函数外部的原值。
void swap(int *a,int *b)
{
int c = *a;
*a = *b;
*b = c;
printf("func: a = %d, b = %d\n",*a,*b);
}
int main()
{
int a = 10;
int b = 20;
swap(&a,&b);
printf("a = %d, b = %d\n",a,b);
}
结果
func: a = 20, b = 10
a = 20, b = 10
地址传递
使用地址传递,函数内部的拷贝变量与函数外部的变量有关联,拷贝变量指向原值得地址,这样可以通过*间接操作修改原值。
使用值传递的场景
如果并不需要改变原值,只是通过原来原值来得到一些数据。比如求和,遍历数组等等这些函数,可以使用值传递当作形参,然后返回需要的数据。例如:
int add(int a,int b)
{
return a+b;
}
int main()
{
int a = 10;
int b = 20;
int sum = add(a,b);
printf("sum = %d\n",sum);
}
结果
sum = 30
使用地址传递的场景
如果需要某个函数体来改变函数外部的值,且开辟在栈的内存中,就只能使用地址传递来实现。
//求绝对值
void myabs(int *a)
{
if(*a < 0) *a = -(*a);
}
int main()
{
int a = -10;
myabs(&a);
printf("b = %d\n",a);
}
地址传值的形式
我们如果想要传进去的值改变函数外部的值,就使用地址传递,但是有时形参的数据类型不清楚,下面说一种方法,就是形参总是比原值的数据类型多一个。这很好理解,想一下获得某个int类型的变量地址,就要定义int指针类型,如果是获得int类型的地址,就定义int*类型的变量接收。
int a;
//形参
int * b;
int *a;
//形参
int **b;
总之就是形参的数据类型总是比原值的数据类型多一个*,使用时传值记得使用&,不然报错。
微信号
网友评论