函数调用👏
参数了解完了,接下来就去学习了函数的调用。函数调用分为传值调用和传址调用,所谓传值调用,我上一篇中的Swi(c,d)就是一个典型:我把c,d的值传给谁。说到这里,还是强调一下形参修改不影响实参。传址调用,它是把函数外部创建的变量的内存地址传递给函数参数的一种调用方式;这种方式可以让函数和其外边儿的变量建立起真正的联系,也就是函数内部可以直接操作外边的变量。这就是他们的基本特点。
什么情况采用哪种调用呢?该怎么权衡呢?
传值调用👏
向函数传递参数的传值调用方法,把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。
默认情况下,C 语言使用传值调用方法来传递参数。一般来说,这意味着函数内的代码不会改变用于调用函数的实际参数。
其实上一篇我在整交换变量值时,我必须要传地址过去,c,d和a,b不属于同一空间,我单单传值是没办法的,我要在函数内部操作外部的某些变量就得传地址。假设我只是个比较大小的函数,那传值就足矣。具体情况具体分析,如下就是传值无法实现的;
定义交换函数 void Func(int x,int y) { int tem = 0; tem = a;//建立tem先接纳整型a的值 a = b;//b赋值操作给a b = tem;//将b中的值在交换给a return ; }
现在,让我们通过传递实际参数来调用函数
# define _CRT_SECURE_NO_WARNINGS # include<stdio.h> void Func(int x,int y ) { int tem = 0; tem = x; x = y; y = tem; return ; } int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); Func( a,b); printf("%d %d\n", a, b); return 0; }
当上面的代码被编译和执行时,它会产生如上的结果,上面的实例表明了虽然在函数内改变了 a 和 b 的值,但是实际上 a 和 b 的值没有发生变化。这就是我们说的传值调用。
传址调用👏
说到传址调用,就借问题说问题,我们刚刚到 Function函数之所以没有成功运行就是a,b是实参,我确实分别把a,b的值拷贝给了形参x,y,但是进入Func函数后a,b就与Func函数无关了;而x,y也确实参与了函数值得交换,但由于x,y的作用域只在Func函数内部,一出函数就立即被销毁,从而我们提出了传址调用:
# define _CRT_SECURE_NO_WARNINGS # include<stdio.h> void Func(int *x,int *y ) { int tem = 0; tem = *x; *x = *y; *y = tem; return ; } int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); Func( &a,&b); printf("%d %d\n", a, b); return 0; }
如上图,传址调用的作业就一目了然。其实道理是一样的,是将实参拷贝给形参,只是拷贝的是指针,将地址传过去进行交换,完成后就算进行销毁也不会影响实际参数的大小,因为此时已经完成了交换。
其实还有一个引用调用,但这是在咱C语言里面没有的,这是C++的语法,不做赘述。
他并没有实参到形参的拷贝,而是直接将main里面的a, b传到函数里面。