函数传参的三种方式

转自:https://blog.csdn.net/qq_39539470/article/details/79519156

感谢原创作者!

函数传参有三种传参方式:传值、传址、传引用。 

1、按值传递 
(1)形参和实参各占一个独立的存储空间。 
(2)形参的存储空间是函数被调用时才分配的,调用开始,系统为形参开辟一个临时的存储区,然后将各实参传递给形参,这是形参就得到了实参的值。
#include<stdio.h>
void swap1(int x, int y)//定义中的x,y变量是swap函数的两个形参
{
    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);//a,b变量为swap函数的实际参数
    printf("a=%d,b=%d", a, b);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

输出结果为:x=3,y=2; a=2,b=3 
代码分析:你也许会疑惑,a和b的值明明在函数swap中交换,为什么输出值却没变呢? 
那是因为你还没理解形参和实参的关系。 
为了解释这个问题,我先给出如下代码: 
int a=2; 
int x; 
x=a; 
x=x+3; 
最终的结果是不是a=2,x=5 
这段代码我们需要理解a虽然赋值给x,但是a的值并没有改变,对x的任何修改都不会改变a的值。 
而代码中值传递方式如下: 
main函数中调用了swap函数;swap中包含了以下代码

int x=a;
int y=b;/*前两行代码是函数的隐含操作不可写在代码之中,
是为了方便大家理解我自己加上的*/
int tmp;
    tmp = x;
    x = y;
    y = tmp;
    printf("x=%d,y=%d\n", x, y);
    ```

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

以上的分析中我们可以看出函数是通过赋值把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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

运行结果为*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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

输出结果:x=3,y=2; a=3,b=2; 
代码分析:我们看到该代码只与传值中swap函数定义不同,swap3中参数都加了取地址符号&,有了这个函数会将a,b分别替代了x,y,这样函数里面操作就是a,b本身了。

4、对于值传递和引用传递的比较:

在C语言中,并没有引用的概念,引用是C++的概念。 
在C++的函数参数中,有两种形式,其中 TYPE & var的形式,称为传引用方式; TYPE var的形式,称为传值。 
二者的区别为,当传引用时,实际传到函数中的形参,是实际参数的一个引用,而不是仅传递值到函数中。具体的表现有以下几条: 
1 传引用时,形参和实参是同一个变量,即使用相同的内存空间,二者有相同的地址。而传值时二者地址不同; 
2 传引用时,由于没有新建变量,所以对于类对象参数,不会产生构造和析构。而如果是传值调用,调用时会进行构造,退出函数时会进行析构; 
3 由于传引用使用的是原本实参的地址,所以对引用参数值的修改,会在退出函数后体现在主调函数中,而传值调用对参数的修改不会影响到主调函数。

猜你喜欢

转载自blog.csdn.net/song_esther/article/details/80499858