#C 语言的函数
函数是 C 语言程序的基本构建模块,即一组执行特定任务的代码集合,可以接收输入参数并返回结果。具有以下特点:
- 模块化:将程序分解为更小、更易管理的部分
- 重用性:函数可以被多次调用,避免重复编写相同代码
- 封装性:隐藏实现细节,只暴露必要接口
C 语言规定程序从 main
函数开始执行。
定义函数的基本语法:
// 定义函数
返回值类型 函数名(形式参数列表) {
函数体
}
- 返回值类型:函数通过
return
关键字返回该类型的值结果,如果一个函数只执行操作而不需要返回值,则返回值类型设为void
- 函数名:函数的名称,遵守和变量名一样的 命名规则
- 形式参数列表:形式参数就像是占位符,调用函数时被实际参数赋值
- 函数体:函数内部要执行的代码
例如:
#include <stdio.h>
/*********************************************
* @brief 返回较大值
* @param x 参与比较的值
* @param y 参与比较的值
* @return x 和 y 中较大的那个
********************************************/
int max(int x, int y)
{
if (x > y)
{
return x; // 返回 x
}
else
{
return y; // 返回 y
}
}
// 入口函数
int main(void)
{
int n = max(10, 20); // 调用 max,传参为 x=10, y=20
printf("10 与 20 相比 %d 更大\n", n);
int array[10] = {2, 7, 1, 6, 5, 9, 3, 0, 4, 8}; // 一个数组
int max_value = array[0]; // 最大值,初始化为数组的第一个值
for (int i = 1; i < 10; i += 1) // 从数组的第二个值开始循环
{
max_value = max(max_value, array[i]); // 调用 max,传参为 x=max_value, y=array[i]
}
printf("数组中的最大值是 %d\n", max_value);
return 0;
}
运行结果:
10 与 20 相比 20 更大 数组中的最大值是 9
这里定义了一个函数:
- 函数名 是
max
- 返回值类型 是
int
- 形式参数列表 包含两个参数
int
类型的x
和int
类型的y
- 函数体 中比较
x
和y
的大小,返回更大的那个值
在 max(10, 20)
调用时,形式参数 x
被实际参数 10
赋值,形式参数 y
被实际参数 20
赋值。
在 max(max_value, array[i])
调用时,形式参数 x
被实际参数 max_value
赋值,形式参数 y
被实际参数 array[i]
赋值。
#函数声明
在上例中,函数 max
的定义写在 main
函数之前。
如果 max
的定义写在 main
函数之后,或者写在另一个源文件里,则需要在调用之前进行函数声明。
函数声明的基本语法:
// 声明函数
返回值类型 函数名(形式参数列表);
上例可以改写为:
#include <stdio.h>
// 函数声明
int max(int x, int y);
// 入口函数
int main(void)
{
int n = max(10, 20); // 调用 max,传参为 x=10, y=20
printf("10 与 20 相比 %d 更大\n", n);
int array[10] = {2, 7, 1, 6, 5, 9, 3, 0, 4, 8}; // 一个数组
int max_value = array[0]; // 最大值,初始化为数组的第一个值
for (int i = 1; i < 10; i += 1) // 从数组的第二个值开始循环
{
max_value = max(max_value, array[i]); // 调用 max,传参为 x=max_value, y=array[i]
}
printf("数组中的最大值是 %d\n", max_value);
return 0;
}
/*********************************************
* @brief 返回较大值
* @param x 参与比较的值
* @param y 参与比较的值
* @return x 和 y 中较大的那个
********************************************/
int max(int x, int y)
{
if (x > y)
{
return x; // 返回 x
}
else
{
return y; // 返回 y
}
}
#返回多个值
C 语言的函数只能有一个返回值,但有些时候可能需要返回多个值。
通常有两种实现方法:
示例:
#include <stdio.h>
#include <stdbool.h>
// 结构体,除法的结果
typedef struct division_result_t
{
int quotient; // 商
int remainder; // 余数
} division_result_t;
/*********************************************
* @brief 计算除法,通过结构体返回商和余数
* @param x 被除数
* @param y 除数
* @return 商和余数构的结构体
********************************************/
division_result_t division1(int x, int y)
{
division_result_t result;
result.quotient = x / y; // 计算商
result.quotient = x % y; // 计算余数
return result; // 返回结果
}
/*********************************************
* @brief 计算除法,通过指针返回商和余数
* @param x 被除数
* @param y 除数
* @param[out] quotient_ptr 返回商
* @param[out] remainder_ptr 返回余数
* @return 是否成功
********************************************/
bool division2(int x, int y, int* quotient_ptr, int* remainder_ptr)
{
if (y == 0)
{
return false; // 返回失败
}
*quotient_ptr = x / y; // 计算商,通过指针写入外部变量
*remainder_ptr = x % y; // 计算余数,通过指针写入外部变量
return true; // 返回成功
}
int main(void)
{
// 通过结构体返回多个值
division_result_t result = division1(10, 3); // 调用 division1,传参为 x=10, y=3
printf("10 除以 3 得 %d 余 %d\n", result.quotient, result.remainder);
// 通过指针返回多个值
int quotient; // 商
int remainder; // 余数
division2(1990, 7, "ient, &remainder); // 调用 division1,传参为 x=1990, y=7, quotient_ptr="ient, remainder_ptr=&remainder
printf("1990 除以 7 得 %d 余 %d\n", quotient, remainder);
return 0;
}
运行结果:
10 除以 3 得 1 余 0 1990 除以 7 得 284 余 2
这个示例定义了两个函数:division1
和 division2
,前者通过结构体返回商和余数,后者通过指针返回商和余数。
在调用 division2(1990, 7, "ient, &remainder)
时:
- 形式参数
quotient_ptr
被实际参数"ient
赋值,即变量quotient
的地址 - 形式参数
remainder_ptr
被实际参数&remainder
赋值,即变量remainder
的地址
然后在 division2
内部:
*quotient_ptr = x / y
修改了外部变量quotient
的值*remainder_ptr = x % y
修改了外部变量remainder
的值
这样一来便实现了通过指针返回多个值。
函数本身的返回值类型可以设为 void
,即无返回值;这里返回值类型为 bool
,用来表示函数调用是否成功。