C++函数基础 #

一、函数概述 #

函数是完成特定任务的独立代码块,可以提高代码的复用性和可读性。

1.1 函数的优点 #

  • 代码复用
  • 模块化设计
  • 易于维护
  • 便于测试

1.2 函数的基本结构 #

cpp
returnType functionName(parameterList) {
    // 函数体
    return value;  // 如果返回类型不是void
}

二、函数定义 #

2.1 基本语法 #

cpp
// 无参无返回值
void sayHello() {
    std::cout << "Hello, World!" << std::endl;
}

// 有参有返回值
int add(int a, int b) {
    return a + b;
}

// 有参无返回值
void printSum(int a, int b) {
    std::cout << a + b << std::endl;
}

// 无参有返回值
int getInput() {
    int x;
    std::cin >> x;
    return x;
}

2.2 返回类型 #

cpp
// 返回基本类型
int getInt() { return 10; }
double getDouble() { return 3.14; }
bool isTrue() { return true; }
char getChar() { return 'A'; }

// 返回指针
int* getPointer() {
    static int x = 10;
    return &x;
}

// 返回引用
int& getReference() {
    static int x = 10;
    return x;
}

// 无返回值
void doSomething() {
    // 不需要return语句
}

2.3 返回类型推导(C++14) #

cpp
// 自动推导返回类型
auto add(int a, int b) {
    return a + b;  // 返回int
}

auto getPI() {
    return 3.14;  // 返回double
}

// 尾置返回类型(C++11)
auto divide(double a, double b) -> double {
    return a / b;
}

三、函数声明 #

3.1 函数原型 #

cpp
// 函数声明(原型)
int add(int a, int b);
void printHello();

// 主函数
int main() {
    printHello();
    int result = add(3, 5);
    return 0;
}

// 函数定义
int add(int a, int b) {
    return a + b;
}

void printHello() {
    std::cout << "Hello!" << std::endl;
}

3.2 声明与定义分离 #

cpp
// math.h
#ifndef MATH_H
#define MATH_H

int add(int a, int b);
int subtract(int a, int b);

#endif

// math.cpp
#include "math.h"

int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

// main.cpp
#include "math.h"

int main() {
    int result = add(3, 5);
    return 0;
}

3.3 参数名可省略 #

cpp
// 声明时参数名可以省略
int add(int, int);

// 定义时必须有参数名
int add(int a, int b) {
    return a + b;
}

四、函数调用 #

4.1 基本调用 #

cpp
int add(int a, int b) {
    return a + b;
}

int main() {
    // 直接调用
    int result = add(3, 5);
    
    // 嵌套调用
    int result2 = add(add(1, 2), add(3, 4));
    
    // 表达式中调用
    int result3 = add(1, 2) * 2;
    
    return 0;
}

4.2 无返回值函数调用 #

cpp
void printLine() {
    std::cout << "----------" << std::endl;
}

int main() {
    printLine();  // 作为独立语句
    return 0;
}

4.3 忽略返回值 #

cpp
int getValue() {
    return 10;
}

int main() {
    getValue();  // 忽略返回值
    int x = getValue();  // 使用返回值
    return 0;
}

五、main函数 #

5.1 main函数形式 #

cpp
// 最简单形式
int main() {
    return 0;
}

// 带命令行参数
int main(int argc, char* argv[]) {
    return 0;
}

// 或使用const
int main(int argc, const char* argv[]) {
    return 0;
}

5.2 返回值 #

cpp
int main() {
    // 返回0表示成功
    // 返回非0表示失败
    
    if (success) {
        return 0;  // EXIT_SUCCESS
    } else {
        return 1;  // EXIT_FAILURE
    }
}

// 使用标准宏
#include <cstdlib>

int main() {
    return EXIT_SUCCESS;
    // 或
    return EXIT_FAILURE;
}

5.3 命令行参数 #

cpp
int main(int argc, char* argv[]) {
    std::cout << "程序名: " << argv[0] << std::endl;
    
    for (int i = 1; i < argc; i++) {
        std::cout << "参数" << i << ": " << argv[i] << std::endl;
    }
    
    return 0;
}

六、函数重载 #

6.1 基本概念 #

函数重载允许同名函数有不同的参数列表。

cpp
// 重载函数
int add(int a, int b) {
    return a + b;
}

double add(double a, double b) {
    return a + b;
}

int add(int a, int b, int c) {
    return a + b + c;
}

// 调用
int main() {
    std::cout << add(1, 2) << std::endl;        // 调用第一个
    std::cout << add(1.5, 2.5) << std::endl;    // 调用第二个
    std::cout << add(1, 2, 3) << std::endl;     // 调用第三个
    return 0;
}

6.2 重载规则 #

cpp
// 参数数量不同
void func(int a);
void func(int a, int b);

// 参数类型不同
void func(int a);
void func(double a);

// 参数顺序不同
void func(int a, double b);
void func(double a, int b);

// 不能仅通过返回值区分
// int func();  // 错误
// double func();  // 错误

6.3 重载解析 #

cpp
void print(int x) {
    std::cout << "int: " << x << std::endl;
}

void print(double x) {
    std::cout << "double: " << x << std::endl;
}

int main() {
    print(10);      // 调用print(int)
    print(3.14);    // 调用print(double)
    print('A');     // 'A'是char,转换为int,调用print(int)
    return 0;
}

七、内联函数 #

7.1 inline关键字 #

cpp
inline int square(int x) {
    return x * x;
}

int main() {
    int result = square(5);  // 编译器可能内联展开
    return 0;
}

7.2 内联的优点 #

  • 减少函数调用开销
  • 适合小型、频繁调用的函数

7.3 注意事项 #

cpp
// 内联函数应该定义在头文件中
// inline只是建议,编译器可能忽略

// 复杂函数不适合内联
inline void complexFunction() {
    // 大量代码...
    // 编译器可能不会内联
}

八、constexpr函数 #

8.1 编译期计算 #

cpp
constexpr int square(int x) {
    return x * x;
}

int main() {
    constexpr int val = square(5);  // 编译期计算
    int arr[square(3)];  // 数组大小:9
    
    int x = 5;
    int y = square(x);  // 运行时计算
    
    return 0;
}

8.2 constexpr规则 #

cpp
// constexpr函数必须只有一条return语句(C++11)
constexpr int add(int a, int b) {
    return a + b;
}

// C++14允许更复杂的函数体
constexpr int factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

九、最佳实践 #

9.1 函数命名 #

cpp
// 使用动词开头
void printReport();
int calculateSum();
bool isValid();

// 使用驼峰或下划线
void processData();
void process_data();

9.2 单一职责 #

cpp
// 不推荐:一个函数做太多事
void processUser() {
    // 验证用户
    // 保存用户
    // 发送邮件
}

// 推荐:每个函数只做一件事
bool validateUser(const User& user);
void saveUser(const User& user);
void sendEmail(const User& user);

9.3 函数长度 #

cpp
// 函数不宜过长,建议不超过50行
// 如果过长,考虑拆分

void processData() {
    loadData();
    validateData();
    transformData();
    saveData();
}

十、总结 #

函数要点 #

概念 说明
定义 函数的具体实现
声明 函数的原型
调用 使用函数
重载 同名不同参数
内联 减少调用开销

最佳实践 #

  1. 函数名要有意义
  2. 保持单一职责
  3. 函数不宜过长
  4. 合理使用重载
  5. 小函数考虑内联

下一步,让我们学习函数参数!

最后更新:2026-03-26