【C语言】传值调用和传址调用


前言

          当我们C语言学到函数时,相信大家都会动手用一个函数来实现一个简单的功能,比如交换a,b两个数的值,但当我们写出来这个函数时,却会发现a,b两个数的值并没有交换,这是为什么呢?其实很简单,原因就在于我们在实现交换函数时有可能只是将a,b两个数只进行了传值调用而不是传址调用


一、形式参数和实际参数

          那么什么是传值调用,什么是传址调用呢?不急,首先,我们先来了解一下形式参数和实际参数。

实际参数:真实传给函数的参数,也叫实参。实参可以是:常量,变量,表达式,函数等。而无论实参是什么类型,在进行函数调用时,它都必须有一个确定的值,以便把这些值传给形参

形式参数:形式参数就是函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后自动销毁,因此形式参数只在函数中有效。

          通过上面对实参和形参的描述,仔细思考一下,我们就会产生一些疑问,既然形参只在函数中有效,函数调用完成之后自动销毁,那么我们之前传递给交换函数的a,b两个值在函数完成调换之后是不是就被销毁了?如果是的话,那么我们没有完成交换也就说得通了。

二、传值调用

          传值调用:调用时系统先计算实参表达式的值,再将实参按位置赋给形参,也就是对形参的初始化。

         我先写出一个简单的交换a,b两个值的swap函数,这也可能是大部分初学者会写出的代码,而这个函数就是典型的传值调用。

void swap(int x, int y)//实现交换a,b两个值的函数,x接收a,y接收b
{
	int tem = x;//临时变量存放x的值
	x = y;//将y的值赋给x
	y = tem;//将临时变量存放的x的值赋给y

}
int main()
{
	int a = 1;
	int b = 2;
	swap(a, b);
    printf("%d %d", a, b);

	return 0;
}

         我们可以来看一下最终打印的结果,结果并不是我们所想的a=2,b=1,仍然是没有交换之前的a,b值。

【C语言】传值调用和传址调用_第1张图片

        当我们创建了a,b两个变量时,我们是在内存中开辟了一块空间来存放a,b,而当我们将实际参数a,b传入swap函数时,形式参数x,y会拷贝a,b的值,另外开辟一块空间存放x,y,其实此时我们是一共创建了四个变量a,b和x,y,而x和y代替了a,b在swap函数中进行交换,最终x和y交换成功之后,出了swap函数,x和y被销毁,对应的内存空间也被释放,即此时只存在没有进行任何操作的a和b两个变量,此时再打印他们的值,就会依然是其原本的值。

       【C语言】传值调用和传址调用_第2张图片

          上图就是整个函数进行时,a,b和x,y变量的变化情况,有助于我们更好理解传值调用。

三、传址调用

            传址调用:传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式

       我们可以将变量a,b的地址传给swap函数,那么x,y复制了a,b的地址并储存起来之后,我们再通过解引用操作访问到a,b,对a,b进行交换的操作,那么即使x和y会被销毁,但我们已经达到了交换a和b的值的目的。

      代码如下:【C语言】传值调用和传址调用_第3张图片

 【C语言】传值调用和传址调用_第4张图片

总结

         对于传值调用和传址调用,都有各自不同的特性,可以根据具体需要选择不同的函数调用。

        1.传值调用:当实参传给形参的时候,形参其实是实参的一份临时拷贝,形参和实参分别占有不同的内存块,对形参的修改是不会改变实参的。

        2.传址调用:可以让函数和函数外面的变量建立起联系,也就是函数的内部可以直接操作函数外部的变量。

        3.应用场景:当你想要对传递进函数的实参经过函数内的操作发生改变,那么就用传址调用。

如果不对实参作出任何改变,那么就用传值调用。

你可能感兴趣的:(开发语言,c语言)