Skip to content

C++ 函数

函数(Function)是设计用来执行特定任务的命名代码块。函数是 C++ 中组织代码、提高可重用性和增强模块化的基本构建块。每个 C++ 程序都必须包含一个 main 函数,它是程序的入口点。

将复杂问题分解成更小、更易于管理的函数,可以使代码更容易编写、测试、调试和维护。

函数的主要组成部分:

  • 函数声明(原型,Prototype): 告知编译器函数的名称、返回值类型及其参数的类型。允许在函数定义出现在代码之前调用该函数。
  • 函数定义(Definition): 提供函数的实际实现(代码块)。
  • 函数调用(Invocation): 执行函数定义内的代码。

C++ 标准库(Standard Library)本身提供了大量的预定义函数(例如,std::cout、std::sqrt、std::sort、std::string::length)。

函数定义的一般语法如下:

return_type function_name(parameter_list) {
// Body of the function: statements that perform the task
// 函数体:执行任务的语句
// ...
return return_value; // Optional: only if return_type is not void
// 可选:仅当返回值类型不是 void 时需要
}

各组成部分说明:

  • return_type: 函数返回给调用者的值的 数据类型。如果函数不返回任何值,使用 void。
  • function_name: 用于调用函数的 标识符(Identifier)。
  • parameter_list: 包含在括号 () 中的 参数声明列表(类型和名称),用逗号分隔。它们在函数内部充当 局部变量(Local Variables),接收来自调用者的值(实参,Arguments)。如果函数不接受参数,列表为空(())。
  • 函数体(Function Body): 包含实现函数逻辑的语句的 代码块({ ... })。
  • return 语句: 用于将值返回给调用者。return_value 的类型必须与 return_type 兼容。返回类型为 void 的函数不需要 return 语句,或者可以使用 return; 来提前退出。

下面是函数 findMax 的定义,它接受两个整数并返回较大的那个:

// Function definition for findMax
// findMax 函数定义
int findMax(int num1, int num2) { // return_type: int, name: findMax, parameters: num1, num2
// 返回值类型:int,名称:findMax,参数:num1, num2
// Function body
// 函数体
int result;
if (num1 > num2) {
result = num1;
} else {
result = num2;
}
return result; // Return the calculated maximum value
// 返回计算出的最大值
}

函数声明,或称原型(Prototype),在函数定义出现在代码 之前 向编译器介绍该函数。这允许你在文件中更早调用该函数,或从不同的文件(使用头文件,Header Files)中调用它。

语法与函数头类似,后跟一个分号:

return_type function_name(parameter_type_list);

在声明中,参数名称是可选的,但它们的类型是强制的。

// Function declaration (prototype) for findMax
// findMax 函数声明(原型)
int findMax(int num1, int num2); // Names included (optional, good for clarity)
// 包含名称(可选,但为了清晰性更好)
// Or, equivalently:
// 或者,等价地:
int findMax(int, int); // Names omitted
// 省略名称

声明通常放在头文件(.h 或 .hpp)中,以便在多个源文件中包含。

要使用函数,通过使用其名称后跟括号 () 来调用(Invoke)它,并在括号内提供所需的 实参(Arguments)。

当函数被调用时:

  • 控制权从调用代码转移到函数体。
  • 提供的实参用于初始化函数的参数。
  • 函数体中的语句被执行。
  • 如果遇到 return 语句(且函数不是 void),指定的值会返回给调用者,控制权返回到紧随函数调用之后的点。
  • 如果到达函数体末尾而未遇到 return 语句(对于非 void 函数,这通常是错误或导致未定义行为;对于 void 函数,这是正常的),控制权返回给调用者。

示例:声明、定义和调用函数

#include <iostream>
// 1. Function Declaration (Prototype)
// 1. 函数声明(原型)
int findMax(int num1, int num2);
int main() {
// Local variables in main
// main 函数中的局部变量
int value1 = 100;
int value2 = 200;
int maximumValue;
// 3. Calling the function
// 3. 调用函数
// Arguments 'value1' and 'value2' are passed
// 实参 'value1' 和 'value2' 被传递
maximumValue = findMax(value1, value2);
std::cout << "Max value is: " << maximumValue << std::endl;
// Call again with different arguments
// 再次调用,使用不同的实参
std::cout << "Max of -5 and 10 is: " << findMax(-5, 10) << std::endl;
return 0;
}
// 2. Function Definition
// 2. 函数定义
int findMax(int num1, int num2) {
// Parameters 'num1' and 'num2' receive the argument values
// 参数 'num1' 和 'num2' 接收实参值
int result;
if (num1 > num2) {
result = num1;
} else {
result = num2;
}
return result;
}

程序输出:

Max value is: 200
Max of -5 and 10 is: 10

参数(Parameters): 列在函数定义括号中的变量(例如,findMax 中的 num1、num2)。它们在函数内部作为局部变量。

实参(Arguments): 调用函数时传递给函数的实际值或表达式(例如,调用 findMax 时传递的 value1、value2、-5、10)。

C++ 支持不同的参数传递方式:

传递方法描述概念示例
值传递(Pass by Value)参数接收的是 实参值的 副本。函数内部对参数所做的更改 不会 影响函数外部的原始实参。对于基本类型和对象(除非另有指定),这是默认方式。void func(int x) { x = 10; } int main() { int y = 5; func(y); // y 仍然是 5 }
指针传递(Pass by Pointer)传递的是 实参的 内存地址(作为指针)。函数可以使用该指针访问并 修改 原始实参的值。需要小心处理以避免空指针问题。void func(int* p) { *p = 10; } int main() { int y = 5; func(&y); // y 变为 10 }
引用传递(Pass by Reference)传递的是原始实参的 别名(引用)。参数成为原始实参的另一个名称。对参数所做的更改 会 影响原始实参。由于语法更简洁且引用必须被初始化(不可能为空),通常比指针更适合用于修改实参。void func(int& r) { r = 10; } int main() { int y = 5; func(y); // y 变为 10 }
常量引用传递(Pass by Constant Reference)传递的是原始实参的别名(引用),但函数被 禁止 通过该引用进行修改(使用 const 关键字)。当函数只需要读取大型对象时,这是 高效 传递大型对象(避免复制)的首选方式。void func(const std::string& s) { std::cout << s; /* s = "No!"; // Error! */ }

根据是否需要修改原始实参以及复制的开销(大型对象通过引用或常量引用传递),选择合适的传递方法。

可以在函数声明(或定义,如果声明和定义分开则不能在两者中都指定)中为参数提供 默认值(Default Values)。默认值必须为末尾参数(位于参数列表末尾的参数)指定。

如果调用者省略了带有默认值的参数的实参,编译器会使用默认值。如果调用者提供了实参,提供的值将覆盖默认值。

#include <iostream>
// Function declaration with default value for 'b'
// 函数声明,为 'b' 提供默认值
int sum(int a, int b = 20);
int main() {
int x = 100;
int y = 200;
int total;
// Calling with both arguments: default for 'b' is ignored
// 使用两个实参调用:'b' 的默认值被忽略
total = sum(x, y); // a=100, b=200
std::cout << "Total value (sum(100, 200)): " << total << std::endl;
// Calling with only one argument: default value for 'b' is used
// 只使用一个实参调用:使用 'b' 的默认值
total = sum(x); // a=100, b=20 (default)
std::cout << "Total value (sum(100)): " << total << std::endl;
return 0;
}
// Function definition
// 函数定义
// (Default value should NOT be repeated here if declared in prototype)
// (如果在原型中已声明,此处不应重复默认值)
int sum(int a, int b /* = 20 */) {
return a + b;
}

输出:

Total value (sum(100, 200)): 300
Total value (sum(100)): 120