【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值。

        当我们创建了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两个变量,此时再打印他们的值,就会依然是其原本的值。

       

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

三、传址调用

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

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

      代码如下:

 

总结

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

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

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

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

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

  • 44
    点赞
  • 87
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
在C语言中,可以通过函数指针来调用函数。首先,需要定义一个函数指针,表示指向函数的指针。函数指针的定义方法是将函数名修改为指针名,并用括号括起来,例如`void (*p)();`。然后,将函数指针指向要调用的函数,可以通过将函数名赋给函数指针来实现。最后,通过函数指针的调用运算符`()`来调用函数。例如,如果函数指针`p`指向一个无返回、无参数的函数`hello()`,可以通过`p()`来调用该函数。\[1\] 另外,在C语言中还可以使用指针数组来存储多个指针变量。指针数组是一个数组,其中的每一项都是一个指针变量。可以通过将变量的地给指针数组的元素来实现。例如,可以定义一个指针数组`int *parray\[3\];`,并将变量`a`、`b`、`c`的地分别赋给`parray\[0\]`、`parray\[1\]`、`parray\[2\]`,然后通过循环遍历指针数组来访问指针所指向的变量。\[2\] 此外,如果要在函数中使用结构体指针,需要使用箭头运算符`->`来访问结构体中的变量。通过结构体指针可以动态分配内存,并使用`malloc()`函数来分配内存空间。需要注意的是,使用结构体指针之前要确保指针不是野指针或者NULL。可以使用`malloc()`函数来为结构体指针分配内存空间,并使用`->`来访问结构体指针所指向的结构体中的变量。\[3\] #### 引用[.reference_title] - *1* *2* *3* [C语言的指针各种用法](https://blog.csdn.net/weixin_48856218/article/details/119850150)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值