前文可知函数的调用只需要函数的参数类型、个数及返回值匹配就可以。
1.形参与实参
函数调用时,传递的参数,称为实参;函数定义时,在参数列表中声明的参数,叫做形参
。函数在调用的过程中,实参传递的过程,其实会复制一份给形参,因此,函数内部形参的值的改变,不会影响到调用方传递的实参
。
(1)函数传递的举例:
void FakeChangeValue(int x)
{
x += 5;
printf("函数内部改变数值后:%d\r\n", x);
}
void main(void)
{
int nValue = 100;
printf("nValue: %d\r\n", nValue);
FakeChangeValue(nValue);
printf("nValue: %d\r\n", nValue);
}
(2)因为是复制的作用,函数内部形参的改变不会影响到调用方传递的实参举例
:以下的函数,并没有办法交换两个变量的值
#include <stdio.h>
//函数内部形参的改变不会影响到调用方传递的实参
void FakeSwap(int x, int y)
{
int nTemp = y;
y = x;
x = nTemp;
}
int main(int argc, char* argv[])
{
int nValue1 = 10;
int nValue2 = 20;
FakeSwap(nValue1, nValue2);
printf("%d,%d\r\n", nValue1, nValue2);
return 0;
}
运行结果:
如果想要实现交换,有两种方式,一种是C中的指针,一种是C++中的引用
- 指针法
#include <stdio.h>
void FakeSwap(int* x, int* y)
{
int nTemp = *y;
*y = *x;
*x = nTemp;
}
int main(int argc, char* argv[])
{
int nValue1 = 10;
int nValue2 = 20;
FakeSwap(&nValue1, &nValue2);
printf("%d,%d\r\n", nValue1, nValue2);
return 0;
}
- 引用法
#include <stdio.h>
//函数内部形参的改变不会影响到调用方传递的实参
void FakeSwap(int& x, int& y)
{
int nTemp = y;
y = x;
x = nTemp;
}
int main(int argc, char* argv[])
{
int nValue1 = 10;
int nValue2 = 20;
FakeSwap(nValue1, nValue2);
printf("%d,%d\r\n", nValue1, nValue2);
return 0;
}
2.函数的返回值
函数使用return语句进行返回,使用return有两方面的内涵:
结束当前函数的执行,返回到上一层的调用方
将对应的返回值,带回给调用方
#include <stdio.h>
int AddTwoNumber(int x, int y)
{
printf("返回之前的语句\r\n");
return x + y;
printf("返回之后的语句\r\n");
}
void main(void)
{
int nValue = 0;
nValue = AddTwoNumber(10, 20);
printf("%d\r\n", nValue);
}
运行结果:return
结束当前函数的执行,返回到上一层的调用方;将对应的返回值,带回给调用方
return后接的返回值,应该与函数原型一致
针对void返回值类型,就需要只return不带返回值
#include <stdio.h>
void VoidFun()
{
printf("返回之前的语句\r\n");
return;
printf("返回之后的语句\r\n");
}
void main(void)
{
VoidFun();
}
运行结果:return
相当于结束当前函数的执行,返回到上一层的调用方
3.变参函数
函数的声明和实现中,参数列表中可以出现
...
来代表变参
...
它代表实参传递来的参数个数不做限制。
实际上,我们使用的printf就是这样的函数:
_CRT_STDIO_INLINE int __CRTDECL printf(
_In_z_ _Printf_format_string_ char const* const _Format,
...)
在C标准库中,提供了va_list, va_start等宏,看以下的例子,通过变参函数及相关宏,计算可变数目的参数的和:
#include <stdio.h>
#include <stdarg.h>
int Sum(int nFirst, ...)
{
int nSum = 0, i = nFirst;
va_list marker;
va_start(marker, nFirst);
while (i != -1)
{
nSum += i;
i = va_arg(marker, int);
}
va_end(marker);
return nSum;
}
void main(void)
{
//-1作为循环终止判断表达式
printf("求和: %d\n", Sum(2, 3, 4, -1));
printf("求和: %d\n", Sum(5, 7, 9, 11, -1));
printf("求和: %d\n", Sum(-1));
}
使用va_系列宏知道:
- 必须起码有一个形参
- 使用va_start和第一个形参初始化
- 使用va_arg拿下一个参数
- 使用va_end反初始化
- 调用方要么使用约定好的参数作为结束标志,要么预先传递实参个数
4. 学习视频地址:函数的参数与返回值、变参