函数

什么是函数?

函数是执行特定任务的可重用代码块。它们有助于组织代码、减少重复,并使程序更加模块化和易于维护。

函数结构

return_type function_name (parameters) {
// function body
return value;
}

基本函数声明

以下是如何声明和使用基本函数:

简单函数

#include <iostream>
using namespace std;

// Function declaration (prototype)
void greet();
int add(int a, int b);
double calculateArea(double radius);

int main() {
    greet();
    
    int sum = add(5, 3);
    cout << "Sum: " << sum << endl;
    
    double area = calculateArea(2.5);
    cout << "Area: " << area << endl;
    
    return 0;
}

// Function definitions
void greet() {
    cout << "Hello, World!" << endl;
}

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

double calculateArea(double radius) {
    const double PI = 3.14159;
    return PI * radius * radius;
}

函数参数

函数可以通过不同方式接受参数:

参数传递

#include <iostream>
using namespace std;

// Pass by value
void passByValue(int x) {
    x = 100;  // Only changes local copy
    cout << "Inside function: " << x << endl;
}

// Pass by reference
void passByReference(int& x) {
    x = 100;  // Changes original variable
    cout << "Inside function: " << x << endl;
}

// Pass by pointer
void passByPointer(int* x) {
    *x = 100;  // Changes original variable
    cout << "Inside function: " << *x << endl;
}

// Const parameters
void printValue(const int& value) {
    cout << "Value: " << value << endl;
    // value = 50;  // Error: cannot modify const parameter
}

int main() {
    int num = 10;
    
    cout << "Original value: " << num << endl;
    
    passByValue(num);
    cout << "After pass by value: " << num << endl;
    
    passByReference(num);
    cout << "After pass by reference: " << num << endl;
    
    num = 20;
    passByPointer(&num);
    cout << "After pass by pointer: " << num << endl;
    
    printValue(num);
    
    return 0;
}

函数重载

C++ 允许多个同名但参数不同的函数:

函数重载示例

#include <iostream>
using namespace std;

// Overloaded functions
int multiply(int a, int b) {
    return a * b;
}

double multiply(double a, double b) {
    return a * b;
}

int multiply(int a, int b, int c) {
    return a * b * c;
}

// Display functions for different types
void display(int value) {
    cout << "Integer: " << value << endl;
}

void display(double value) {
    cout << "Double: " << value << endl;
}

void display(const string& value) {
    cout << "String: " << value << endl;
}

int main() {
    // Compiler chooses the right function based on arguments
    cout << multiply(3, 4) << endl;        // Calls int version
    cout << multiply(3.5, 2.5) << endl;    // Calls double version
    cout << multiply(2, 3, 4) << endl;     // Calls three-parameter version
    
    display(42);
    display(3.14159);
    display("Hello World");
    
    return 0;
}

默认参数

函数可以有默认参数值:

默认参数示例

#include <iostream>
using namespace std;

// Function with default parameters
void printInfo(const string& name, int age = 18, const string& city = "Unknown") {
    cout << "Name: " << name << endl;
    cout << "Age: " << age << endl;
    cout << "City: " << city << endl;
    cout << "---" << endl;
}

// Calculate power with default exponent
double power(double base, int exponent = 2) {
    double result = 1;
    for (int i = 0; i < exponent; i++) {
        result *= base;
    }
    return result;
}

int main() {
    // Different ways to call functions with default parameters
    printInfo("Alice");                    // Uses default age and city
    printInfo("Bob", 25);                  // Uses default city
    printInfo("Charlie", 30, "New York");  // No defaults used
    
    cout << "2^2 = " << power(2) << endl;      // Uses default exponent (2)
    cout << "2^3 = " << power(2, 3) << endl;   // Specifies exponent
    cout << "5^4 = " << power(5, 4) << endl;   // Specifies exponent
    
    return 0;
}

递归函数

函数可以调用自身来递归解决问题:

递归示例

#include <iostream>
using namespace std;

// Calculate factorial recursively
long long factorial(int n) {
    if (n <= 1) {
        return 1;  // Base case
    }
    return n * factorial(n - 1);  // Recursive case
}

// Calculate Fibonacci number recursively
long long fibonacci(int n) {
    if (n <= 1) {
        return n;  // Base cases: fib(0) = 0, fib(1) = 1
    }
    return fibonacci(n - 1) + fibonacci(n - 2);  // Recursive case
}

// Calculate sum of digits recursively
int sumOfDigits(int n) {
    if (n == 0) {
        return 0;  // Base case
    }
    return (n % 10) + sumOfDigits(n / 10);  // Recursive case
}

int main() {
    cout << "Factorial of 5: " << factorial(5) << endl;
    cout << "Factorial of 10: " << factorial(10) << endl;
    
    cout << "\nFibonacci sequence:" << endl;
    for (int i = 0; i < 10; i++) {
        cout << fibonacci(i) << " ";
    }
    cout << endl;
    
    cout << "\nSum of digits in 12345: " << sumOfDigits(12345) << endl;
    cout << "Sum of digits in 987: " << sumOfDigits(987) << endl;
    
    return 0;
}

Lambda 函数 (C++11)

Lambda 函数提供了一种简洁的方式来定义匿名函数:

Lambda 函数

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    // Basic lambda function
    auto greet = []() {
        cout << "Hello from lambda!" << endl;
    };
    greet();
    
    // Lambda with parameters
    auto add = [](int a, int b) {
        return a + b;
    };
    cout << "Sum: " << add(5, 3) << endl;
    
    // Lambda with capture
    int multiplier = 10;
    auto multiply = [multiplier](int x) {
        return x * multiplier;
    };
    cout << "5 * 10 = " << multiply(5) << endl;
    
    // Using lambda with STL algorithms
    vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    // Count even numbers
    int evenCount = count_if(numbers.begin(), numbers.end(), 
                            [](int n) { return n % 2 == 0; });
    cout << "Even numbers count: " << evenCount << endl;
    
    // Transform all numbers (multiply by 2)
    transform(numbers.begin(), numbers.end(), numbers.begin(),
              [](int n) { return n * 2; });
    
    cout << "Doubled numbers: ";
    for (int n : numbers) {
        cout << n << " ";
    }
    cout << endl;
    
    return 0;
}

函数最佳实践

单一职责

每个函数应该只做一件事,并且做好

有意义的命名

使用描述性名称,清楚地表明函数的功能

保持函数简短

目标是函数能在一个屏幕内显示(最多20-30行)

正确使用 const

当参数不应被修改时,将其标记为 const

避免全局变量

通过参数传递数据,而不是使用全局变量

处理边界情况

考虑并处理无效输入和边界情况