函数
C 语言中的函数等价于 Fortran 语言中的子程序或函数,也等价于 Pascal 语言中的过程或函数。
- 函数可以返回基本类型、结构、联合或指针类型的值
- 任何函数都可以递归调用
- 局部变量通常是 “自动的”,即在每次函数调用时重新创建
- 函数定义可以不是嵌套的,但可以用块结构的方式声明变量
- 一个 C 语言程序的不同函数可以出现在多个单独编译的不同源文件中
- 变量可以只在函数内部有效,也可以在函数外部但仅在一个源文件中有效,还可以在整个程序中都有效
一个 C 语言程序,无论其大小如何,都是有
函数
和变量
组成函数(function)也可以叫做方法(method)、子例程(sub-routine)或过程(procudure)。
参数
如果函数使用了参数,它必须声明接受参数值的变量。这些变量叫做函数的形式参数(formal parameters)或形参。
形式参数的行为与函数内部其他局部变量相似:在进入函数时创建,在退出时销毁。
在调用函数时,有两种方式将参数传递给函数:
引用调用(Call by reference)
该方法复制参数的地址到形式参数(formal parameter)。在函数内部,该地址用于访问调用中使用的实际参数(actual argument)。这意味着对形式参数所做的修改将影响实际参数。
被调用的函数必须访问原始参数,而不是访问参数的本地副本。
传值调用(Call by value)
该方法将实际参数(actual arguments)的值复制到函数的形式参数(formal parameters)。这种情况下,在函数内部对形式参数进行修改不会对实际参数产生影响。
默认情况下,C 语言的所有函数参数都是 通过值传递(call by value) 的,意味着函数内的代码不能改变实际参数。也就是说,传递给被调用函数的参数值存放在临时变量中(即拷贝一份副本),而不是存放在原来的变量中。
C 语言中,被调用函数不能直接修改主调函数中变量的值,而只是修改其私有的临时副本的值。
#include <stdio.h>
int g;
void increase(int x, int increment)
{
x = x + increment;
}
// 所有函数都是 call by value
int main()
{
printf("g: %d\n", g); // g: 0
increase(g, 10);
printf("g: %d\n", g); // g: 0
return 0;
}
可变参数
type fname(int x,...)
数组参数
当数组名作为实参传递给函数时,传递的是数组第一个元素的地址,而非赋值数组元素本身。在被调用函数中,可以通过数组下标访问或修改数组元素的值。
所以,在定义形参时,采用指针即可。
void max(int *arr) {}
返回值
int main()
的返回值可以省略,其他函数的返回值也可省略。
值传递、指针传递、引用传递
传递方式 | 函数定义 | 函数调用 | 函数副作用 |
---|---|---|---|
值传递 | func(int x) | func(a) | 无(将 a 复制一份给 x) |
指针传递 | func(int* x) | func(&a) | 有(将 a 的内存地址给 x) |
引用传递 | func(int &x) | func(a) | 有(x 取 a 的地址) |