目录
1.实际参数(实参):
真实传给函数的参数叫实参;
说明:1. 实参可以是常量、变量、表达式、函数等;
下面用get_max()函数来举例(get_max函数的功能是:传入两个参数 返回其中较大值)
假设get_max()函数已经写好了
int main()
{
函数的实参部分是变量
int a = 10;
int b = 20;
int max = get_max(a, b);
函数的实参部分是常量
max = get_max(100, 300);
函数的实参部分是表达式
max = get_max(100*2, 300+1);
函数的实参部分是函数
max = get_max(get_max(1,5),get_max(3,7));
return 0;
}
2. 无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。(由说明1中的例子可知,实参的值都是确定的)
2.形式参数(形参):
认识形参:形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。
说明:形式参数当函数调用完成之后就自动销毁了,因此形式参数只在函数中有效。(当没有调用函数的时候,形参是不存在的,即他们没有实际的变量空间,只是一堆代码而已;当调用函数的时候,我们把实参传递给形参,这个时候才会为实参开辟一块内存)
3.形参与实参在应用中的说明(传值调用和传址调用)
首先看一个例子:
目的:写一个函数可以交换两个整型变量的内容
void Swap1(int x,int y)
{
int tmp = 0;
tmp = x;//把x备份到tmp里边去
x = y;
y = tmp;
}
int main()
{
int a = 10;
int b = 20;
//调用Swap1函数,交换两个整形变量的内容
Swap1(a, b);
printf("a = %d b = %d\n", a, b);
return 0;
}
由运行结果 可见该函数并没有成功交换a和b的值
(1)函数的传值调用:
开门见山给解释:此处是函数调用中的传值调用,x的地址和a的地址不一样,y的地址和b的地址不一样,即x、y拥有自己独立的空间,除了和实参(a、b)的值一样之外,和实参并没有直接的联系,所以我们可以简单认为:形参实例化之后其实相当于实参的一份临时拷贝。
因此不难明白,函数的形参和实参分别占有不同内存块,对形参的修改(交换x和y的值)不会影响实参(a和b的值)。
那么怎样才能 在函数内部 改变 函数外部的实参(a、b)的值 呢?
(2)函数的传址调用
传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。
修改刚才的代码:
Swap2()函数
void Swap2(int* pa,int* pb)
{
int tmp = 0;
tmp = *pa;
*pa = *pb;
*pb = tmp;
}
刚刚写的Swap1()函数
void Swap1(int x,int y)
{
int tmp = 0;
tmp = x;//把x备份到tmp里边去
x = y;
y = tmp;
}
int main()
{
int a = 10;
int b = 20;
//调用Swap1函数-传值调用
//Swap1(a, b);
//调用Swap2函数-传址调用
Swap2(&a, &b);
printf("a = %d b = %d\n", a, b);
return 0;
}
由运行结果可见 这次成功交换了a和b的值
补充分析:Swap2函数不同于Swap1的是将实参的地址传给了形参,用指针变量(int* pa和int* pb)接收,当然此时pa、pb依然有自己独立的变量空间,但是他们里面存的是a和b的地址,通过解引用操作符(*),就可以找到函数外面的变量a、b,并直接修改他们的值。
文章小结:在设计一个函数的时候,这个函数有可能要改变函数外部的某些变量的话,就要考虑传实参的地址给形参(传址调用);如果我们仅仅是想获取到函数的返回值而不需要改变外部变量的值的话,那只需要简单的将实参的值传过去就可以了(传值调用)