函数传参
一、形参与实参
形参即形式上的参数,对实参的一种抽象类型描述只是声明一个函数能够接受什么类型的实参,而不确定接受的实参的具体内容是什么。
实参即传递给函数对应形参的具体内容。
即函数实参是函数定义的地方的参数,形参是函数引用的时候的参数。
二、参数传递两种方式
1、传值(就是理解为一次用品不对实参有影响)
将实参的值拷贝给函数或方法,在函数内对形参进行操作,操作的对象是实参的拷贝,对实参本身没有影响,在函数结束返回后,形参被丢弃释放,实参的内容不会被改变
2、传址(在此时就是理解成为对实参有影响,在调用的时候如果变化,定义的里面也会发生变化)
三、函数传参有三种传参方式:传值、传址、传引用。
1、按值传递
一、形参和实参各占一个独立的存储空间。
二、形参的存储空间是函数被调用时才分配的,调用开始,系统为形参开辟一个临时的存储区,然后将各实参传递给形参,这是形参就得到了实参的值。
#include<stdio.h>
void swap1(int x, int y)//此时是实参
{
//int x=a;int y=b;(此时就是将a,b赋值给x,y不参与其中的变换)
int tmp;
tmp = x;
x = y;
y = tmp;
printf("x=%d,y=%d\n", x, y);
}
int main()
{
int a = 2;
int b = 3;
swap1(a, b);//此时是形参
printf("a=%d,b=%d", a, b);
return 0;
}
输出结果为:x=3,y=2; a=2,b=3
a和b的值明明在函数swap中交换,为什么输出值却没变。我们可以看出函数是通过赋值把a,b赋给x,y,这是一个隐含操作,我们不能把它显式的写出来,进行函数中变量的值进行交换时只是形参x,y的交换,并没有对实参进行真正交换,所以a,b值不变。
2、地址传递
地址传递与值传递的不同在于,它把实参的存储地址传送给形参,使得形参指针和实参指针指向同一块地址。因此,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。
void swap2(int *px, int *py)
{
int tmp;
tmp = *px;
*px = *py;
*py = tmp;
printf("px=%d,py=%d\n", *px, *py);
}
int main()
{
int a = 2;
int b = 3;
swap2(&a, &b);/*调用了swap函数,同样也有隐含动作px=&a;py=&b;*/
printf("a=%d,b=%d", a, b);
return 0;
}
运行结果为*px=3,py=2 a=3,b=2;
代码分析:有了两行隐含赋值操作,我们可以清晰的看出指针px,*py是对变量a,b的值操作。函数里面对a和b的值进行了交换。这就是传址。
在里面需要注意的是传址和加 *进行相应的运算从而得到结果。
3、引用传递
引用传递是以引用为参数,则既可以使得对形参的任何操作都能改变相应数据,又使函数调用方便。引用传递是在形参调用前加入引用运算符“&”。引用为实参的别名,和实参是同一个变量,则他们的值也相同,该引用改变则它的实参也改变。
#include<stdio.h>
void swap3(int &x,int &y)
{
int tmp = x;
x = y;
y = tmp;
printf("x=%d,y=%d\n", x, y);
}
int main()
{
int a = 2;
int b = 3;
swap3(a, b);//调用方式与传值一样
printf("a=%d,b=%d", a, b);
system("pause");
return 0;
}
输出结果:x=3,y=2; a=3,b=2;
代码分析:因为在x,y 前有一个取地址符号&,在调用exchang3(a,b)时会用替换x,y,称xy引用了变量ab,在函数内部便是对实参ab进行操作了,函数 内部可以直接修改a,b的值。