一、首先需要引入函数中的实际参数与形式参数
实际参数(实参)是指真实传给函数的参数。实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。
形式参数(形参)是指函数名后括号中的变量。因为形式参数只有在函数被调用的过程中才会分配内存单元,调用结束后,立刻释放内存(形参只在函数中有效),所以叫形式参数。
通过一个例子来加深理解:
如以下加法程序中,ADD()函数中的参数x、y为形参,在main函数中传给ADD函数的a、b为实参。
#include <stdio.h>
int ADD(int x, int y)
{
int z = x + y;
return z;
}
int main()
{
int a = 1;
int b = 2;
int sum = ADD(a, b);
printf("%d", sum);
return 0;
}
1、 在main函数中ADD()函数调用前,已经定义了参数a、b的确定值,即系统给参数a、b分配了内存单元;而此时由于函数未被调用,系统并不会给x、y分配内存。通过在编译器中监视这四个参数以及这四个参数的地址可以非常直观地看出。
2、当ADD()函数被调用时,系统会给参数x、y分配内存单元,并将a、b的值传给x、y。
可以简单得认为:形参是函数调用后,对实参内容的一个临时拷贝。
二、函数中的传值调用与传址调用
那么函数内改变x、y的值是否会改变main函数中a、b的值呢?
请看下面这个程序并给出a、b的值
#include <stdio.h>
void Swap1(int x, int y)
{
int tmp = 0;
tmp = x;
x = y;
y = tmp;
}
int main()
{
int a = 1;
int b = 2;
Swap1(a, b);
printf("a = %d b = %d\n", a, b);
return 0;
}
.....
.....
.....
答案是a=1 b=2
这是因为函数的形参和实参分别占有不同内存块,即它们的地址不同,对形参的修改不会影响实参。这是函数传值调用的特点。
传值调用便是如上述两个程序所示,是指直接将实参的值传给形参。
那么要如何更改程序,才能使函数具有交换a、b的值的功能呢?
在函数中,除了直接将实参的值传给形参,还可以通过实参的地址获得实参的值。
可以把实参的内存地址传递给形参,在函数内部通过解引用操作符(*)改变内存地址所存储的值,这便是传址调用
#include <stdio.h>
void Swap2(int *px, int *py)
{
int tmp = 0;
tmp = *px;
*px = *py;
*py = tmp;
}
int main()
{
int a = 1;
int b = 2;
Swap2(&a, &b);
printf("a = %d b = %d\n", a, b);
return 0;
}
总结:
1.传值调用是指直接将实参的值传给形参。而形参和实参分别占有不同内存块,对形参的修改不会影响实参。
2.传址调用是把实参的内存地址传递给形参的一种调用函数的方式。这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接改变实参的值。