Skip to content

C 函数

函数是执行特定任务的独立代码块。函数对于构建程序结构、促进代码重用以及提高可读性和可维护性至关重要。每个 C 程序都必须至少有一个函数:main(),它是程序执行的入口点。

将复杂问题分解为更小、更易于管理的任务,每个任务由一个函数处理,这是过程式编程的基本原则。

  • 函数定义: 提供函数的实际实现(代码)。
  • 函数声明(原型): 告诉编译器函数的名称、返回类型及其参数的类型。这使得编译器即使在遇到函数定义之前也能检查对函数的调用。
  • 函数调用: 执行函数定义内的代码。

C 标准库提供了一套丰富的预定义函数(如 printf()、scanf()、strcpy()、malloc() 等),您可以在包含适当的头文件后在程序中调用它们。

在 C 语言中定义函数的一般语法是:

return_type function_name(parameter_type1 parameter_name1, parameter_type2 parameter_name2, ...) {
// Function body: declarations and statements
// 函数体:声明和语句
// ... code to perform the task ...
// ... 执行任务的代码 ...
return value; // Optional: only if return_type is not void
// 可选:仅当 return_type 不是 void 时需要
}

函数定义的组成部分:

  • 返回类型: 函数返回给调用者的值的 数据类型。如果函数不返回值,请使用关键字 void。
  • 函数名称: 函数的唯一标识符。遵循标准的 C 命名约定(例如,字母、数字、下划线;不能以数字开头)。
  • 参数(Arguments): 括号内列出的变量,用于在调用函数时接收值(实际参数)。它们在函数内部充当局部变量。如果函数没有参数,请使用 (void):return_type function_name(void) { ... }。
  • 函数体: 包含在花括号 {} 中的代码块,包含函数执行的指令。

示例:一个寻找两个整数中最大值的函数

Section titled “示例:一个寻找两个整数中最大值的函数”
/*
* Function definition for max
* max 函数定义
* Takes two integers as input
* 接受两个整数作为输入
* Returns the larger of the two integers
* 返回两个整数中较大的一个
*/
int max(int num1, int num2) { // Function header
// 函数头
// Function body starts here
// 函数体从这里开始
int result; // Local variable declaration
// 局部变量声明
if (num1 > num2) {
result = num1;
} else {
result = num2;
}
return result; // Return the calculated maximum value
// 返回计算出的最大值
}

函数声明,也称为原型,在函数被调用或定义之前通知编译器该函数的签名。如果在函数的定义出现在源代码中之前调用了该函数,或者函数定义在不同的源文件中,这一点至关重要。

语法类似于函数头,但以分号结束,并且参数名称是可选的(尽管为了清晰起见,通常会包含):

return_type function_name(parameter_type1, parameter_type2, ...);

对于上面定义的 max 函数,其原型将是:

int max(int num1, int num2); // Prototype with parameter names
// 带参数名称的原型
// or equivalently:
// 或者等效地:
int max(int, int); // Prototype without parameter names
// 不带参数名称的原型

原型通常放在源文件的顶部或头文件(.h)中,然后通过 #include 包含。

要使用函数,您需要通过其名称后跟包含参数(传递给函数参数的实际值或变量)的括号来调用它。

  1. 控制从调用点转移到函数体的第一条语句。
  2. 实际参数的值被复制到相应的函数参数中。
  3. 函数体执行。
  4. 如果遇到带有值的 return 语句,该值将返回给调用者,控制权返回到函数调用点紧随其后的位置。
  5. 如果函数返回类型是 void 或者到达函数体结束(})但没有 return 语句,控制权简单地返回给调用者。
#include <stdio.h>
#include <stdlib.h> // For EXIT_SUCCESS
// 用于 EXIT_SUCCESS
// Function prototype (declaration) - Essential here because max is defined after main
// 函数原型(声明)- 这里很重要,因为 max 定义在 main 之后
int max(int num1, int num2);
int main(void) { // Standard main signature
// 标准的 main 函数签名
int a = 100;
int b = 200;
int ret;
// Calling the function and storing the returned value
// 调用函数并存储返回的值
ret = max(a, b);
printf("Max value is: %d\n", ret);
// 最大值是:%d
return EXIT_SUCCESS;
}
// Function definition
// 函数定义
int max(int num1, int num2) {
int result;
if (num1 > num2) {
result = num1;
} else {
result = num2;
}
return result;
}

编译并运行此代码将产生以下输出:

Max value is: 200

函数定义中声明的参数称为形式参数(formal parameters)。函数调用期间传递的值称为实际参数(actual arguments)。

C 语言默认对函数参数使用传值(pass by value)。这意味着:

  • 传值调用(Call by Value): 实际参数值的副本被创建并传递给形式参数。在函数内部对参数所做的更改不会影响调用者中的原始参数。
  • 模拟传引用调用(传指针): 为了允许函数修改调用者中的原始变量,您必须将变量的地址(使用 & 运算符)作为参数传递。相应的形式参数必须声明为指针(例如 int *ptr)。在函数内部,您可以使用解引用运算符(*)来访问或修改该地址处的值。这模拟了传引用调用。

max 函数示例使用了传值调用。a 和 b 的值被复制到 num1 和 num2 中。如果 max 尝试修改 num1 或 num2,它不会改变 main 中的 a 或 b。

传指针示例(模拟传引用调用):

#include <stdio.h>
#include <stdlib.h>
// Function prototype: takes a pointer to an integer
// 函数原型:接受一个指向整数的指针
void increment(int *value_ptr);
int main(void) {
int counter = 10;
printf("Before increment: %d\n", counter);
// 递增前:%d
// Pass the address of 'counter' to the function
// 将 'counter' 的地址传递给函数
increment(&counter);
printf("After increment: %d\n", counter); // Original 'counter' is modified
// 递增后:%d (原始的 'counter' 被修改了)
return EXIT_SUCCESS;
}
// Function definition: parameter is a pointer
// 函数定义:参数是一个指针
void increment(int *value_ptr) {
// Dereference the pointer to access and modify the original value
// 解引用指针来访问和修改原始值
(*value_ptr)++;
// Parentheses are important due to operator precedence
// 由于运算符优先级,括号很重要
// Alternatively: *value_ptr = *value_ptr + 1;
// 或者:*value_ptr = *value_ptr + 1;
}

输出:

Before increment: 10
After increment: 11