细说C语言中参数的两种传递方式 - 高小调博客

细说C语言中参数的两种传递方式

C语言中,函数的参数传递方式有两种:值传递和地址传递.

一、值传递

想要了解值传递究竟是什么,我举一个比较经典的例子.

假如我现在需要交换a和b的值,于是我写了这样的一个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
void Swap(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;
    Swap(a,b);
    printf("a=%d,b=%d\n",a,b);
    return 0;
}

最终结果我们发现:x与y的值发生了互换,但是a与b的值并没有改变!

这显然不符合我们想交换a与b的期望.

这就是一个典型值传递的例子.

那么什么是值传递?

值传递的本质是指在函数调用过程中,形参变量对实参变量进行了一份临时拷贝.

因此,形参变量与实参变量完全是两块不同的空间.

怎么来证明我说的是对的呢?我们将上面代码稍作修改,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
void Swap(int x,int y){
    int tmp = x;
    x = y;
    y = tmp;
    printf("x=%d,y=%d\n",x,y);
    printf("x的地址是%p\n",&x);
    printf("y的地址是%p\n",&y);
}
int main(){
    int a = 2;
    int b = 3;
    Swap(a,b);
    printf("a=%d,b=%d\n",a,b);
    printf("a的地址是%p\n",&a);
    printf("b的地址是%p\n",&b);
    return 0;
}

执行后的结果确实可以证明,x、y与a、b确实不在同一块内存.

x、y只是a、b的一份临时拷贝.

因此,我们可以总结如下:

1.值传递中形参变量只是实参变量的一份临时拷贝.

2.形参变量与实参变量不是同一块内存.

3.修改形参变量不会影响到实参变量.

地址传递

地址传递,顾名思义,形式参数与实际参数指向同一块内存.

实例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
void Swap(int *x,int *y){
    int tmp = *x;
    *x = *y;
    *y = tmp;
    printf("x=%d,y=%d\n",*x,*y);
    printf("x的地址是%p\n",x);
    printf("y的地址是%p\n",y);
}
int main(){
    int a = 2;
    int b = 3;
    Swap(&a,&b);
    printf("a=%d,b=%d\n",a,b);
    printf("a的地址是%p\n",&a);
    printf("b的地址是%p\n",&b);
    return 0;
}

执行后,结果我们发现,使用地址传递的方式可以在函数体内修改函数外部变量的值.

因为,使用地址传递的方式,形参与实参的始终在同一块内存上进行操作.

总结

值传递:值传递的过程中,被调用函数的形式参数被视为该函数的局部变量,即在内存的堆栈中开辟空间以存放由主调函数放进来的实参的值,从而成为了实参的一个拷贝.所以被调用函数不能修改作为实参的实际变量的值,而只能修改传递给他的那份备份.

地址传递:在地址传递过程中,被调函数的形参虽然也作为局部变量在堆栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址,被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量.正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量.

    扩展阅读
  1. printf()函数功能、原型、用法和实例
上一篇:
下一篇: