C++ 入门完全指南(四)--函数与模块化编程

文章目录

    • [第8章 函数基础](#第8章 函数基础)
      • [8.1 为什么需要函数?](#8.1 为什么需要函数?)
      • [8.2 函数的基本语法](#8.2 函数的基本语法)
        • [8.2.1 函数的定义与调用](#8.2.1 函数的定义与调用)
        • [8.2.2 函数声明与定义分离](#8.2.2 函数声明与定义分离)
      • [8.3 函数的参数传递](#8.3 函数的参数传递)
        • [8.3.1 值传递(Pass by Value)](#8.3.1 值传递(Pass by Value))
        • [8.3.2 引用传递(Pass by Reference)](#8.3.2 引用传递(Pass by Reference))
        • [8.3.3 指针传递(Pass by Pointer)](#8.3.3 指针传递(Pass by Pointer))
        • [8.3.4 参数传递方式对比](#8.3.4 参数传递方式对比)
      • [8.4 函数的返回值](#8.4 函数的返回值)
        • [8.4.1 基本返回值](#8.4.1 基本返回值)
        • [8.4.2 返回引用与指针](#8.4.2 返回引用与指针)
        • [8.4.3 void函数与无返回值](#8.4.3 void函数与无返回值)
      • [8.5 默认参数](#8.5 默认参数)
        • [8.5.1 基本默认参数](#8.5.1 基本默认参数)
        • [8.5.2 默认参数的注意事项](#8.5.2 默认参数的注意事项)
      • [8.6 函数重载](#8.6 函数重载)
        • [8.6.1 基本函数重载](#8.6.1 基本函数重载)
        • [8.6.2 函数重载的规则与限制](#8.6.2 函数重载的规则与限制)
      • [8.7 内联函数](#8.7 内联函数)
        • [8.7.1 内联函数基础](#8.7.1 内联函数基础)
        • [8.7.2 内联与宏的对比](#8.7.2 内联与宏的对比)
      • [8.8 实践练习](#8.8 实践练习)
      • [8.9 常见错误与调试](#8.9 常见错误与调试)
        • [8.9.1 函数常见错误](#8.9.1 函数常见错误)

第8章 函数基础

8.1 为什么需要函数?

函数的必要性:

  1. 代码复用:避免重复编写相同代码
  2. 模块化:将复杂问题分解为小问题
  3. 可维护性:修改只需在一个地方进行
  4. 可读性:通过有意义的函数名提高代码可读性
  5. 团队协作:不同开发者可以并行开发不同函数

函数的核心概念:

  • 函数定义:实现函数功能的代码块
  • 函数声明(原型):告诉编译器函数的存在和接口
  • 函数调用:使用函数执行特定任务
  • 参数:传递给函数的数据
  • 返回值:函数执行后返回的结果

8.2 函数的基本语法

8.2.1 函数的定义与调用
cpp 复制代码
#include <iostream>
using namespace std;

// 函数定义
// 返回类型 函数名(参数列表) { 函数体 }
int add(int a, int b) {
    int result = a + b;
    return result;  // 返回结果
}

// 无参数、无返回值的函数
void greet() {
    cout << "Hello, welcome to C++ functions!" << endl;
}

// 多个参数的函数
double calculateAverage(double num1, double num2, double num3) {
    return (num1 + num2 + num3) / 3.0;
}

int main() {
    cout << "=== 函数的基本使用 ===" << endl;
    
    // 调用函数
    greet();  // 调用无参数函数
    
    // 调用有返回值的函数
    int sum = add(5, 3);
    cout << "5 + 3 = " << sum << endl;
    
    // 直接在表达式中使用函数调用
    cout << "10 + 20 = " << add(10, 20) << endl;
    
    // 调用多个参数的函数
    double average = calculateAverage(85.5, 90.0, 88.5);
    cout << "平均分: " << average << endl;
    
    // 嵌套函数调用
    int result = add(add(1, 2), add(3, 4));
    cout << "(1+2)+(3+4) = " << result << endl;
    
    return 0;
}
8.2.2 函数声明与定义分离
cpp 复制代码
#include <iostream>
using namespace std;

// 函数声明(原型)
// 告诉编译器函数的存在,但不提供实现
int multiply(int a, int b);
void printMessage(string message);
double getCircleArea(double radius);
int findMaximum(int arr[], int size);

int main() {
    cout << "=== 函数声明与定义分离 ===" << endl;
    
    // 函数调用 - 编译器只需要知道声明
    int product = multiply(7, 8);
    cout << "7 × 8 = " << product << endl;
    
    printMessage("Hello from function!");
    
    double radius = 5.0;
    double area = getCircleArea(radius);
    cout << "半径为 " << radius << " 的圆面积: " << area << endl;
    
    int numbers[] = {3, 7, 2, 9, 4, 1};
    int maxNum = findMaximum(numbers, 6);
    cout << "数组中的最大值: " << maxNum << endl;
    
    return 0;
}

// 函数定义(实现)
int multiply(int a, int b) {
    return a * b;
}

void printMessage(string message) {
    cout << "消息: " << message << endl;
}

double getCircleArea(double radius) {
    const double PI = 3.141592653589793;
    return PI * radius * radius;
}

int findMaximum(int arr[], int size) {
    if (size <= 0) {
        return -1;  // 错误代码
    }
    
    int max = arr[0];
    for (int i = 1; i < size; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    return max;
}

8.3 函数的参数传递

8.3.1 值传递(Pass by Value)
cpp 复制代码
#include <iostream>
using namespace std;

// 值传递:创建参数的副本,函数内修改不影响原始变量
void swapByValue(int a, int b) {
    cout << "函数内交换前: a=" << a << ", b=" << b << endl;
    int temp = a;
    a = b;
    b = temp;
    cout << "函数内交换后: a=" << a << ", b=" << b << endl;
}

// 值传递示例:修改不会影响调用者
void increment(int num) {
    num++;  // 只修改副本
    cout << "函数内: num=" << num << endl;
}

// 值传递的典型应用:计算不改变原始数据
double calculatePower(double base, int exponent) {
    double result = 1.0;
    for (int i = 0; i < exponent; i++) {
        result *= base;
    }
    return result;
}

int main() {
    cout << "=== 值传递 ===" << endl;
    
    // 示例1:尝试交换变量
    int x = 5, y = 10;
    cout << "交换前: x=" << x << ", y=" << y << endl;
    swapByValue(x, y);
    cout << "交换后: x=" << x << ", y=" << y << " (未改变)" << endl;
    
    // 示例2:修改参数
    int value = 10;
    cout << "\n调用前: value=" << value << endl;
    increment(value);
    cout << "调用后: value=" << value << " (未改变)" << endl;
    
    // 示例3:计算函数
    double base = 2.0;
    int exp = 3;
    double power = calculatePower(base, exp);
    cout << "\n" << base << " 的 " << exp << " 次方 = " << power << endl;
    
    return 0;
}
8.3.2 引用传递(Pass by Reference)
cpp 复制代码
#include <iostream>
using namespace std;

// 引用传递:使用参数的引用,函数内修改影响原始变量
void swapByReference(int &a, int &b) {
    cout << "函数内交换前: a=" << a << ", b=" << b << endl;
    int temp = a;
    a = b;
    b = temp;
    cout << "函数内交换后: a=" << a << ", b=" << b << endl;
}

// 引用传递:真正修改原始变量
void incrementByReference(int &num) {
    num++;
    cout << "函数内: num=" << num << endl;
}

// 返回多个值(通过引用参数)
void calculateMinMax(const int arr[], int size, int &min, int &max) {
    if (size <= 0) {
        min = max = -1;
        return;
    }
    
    min = max = arr[0];
    for (int i = 1; i < size; i++) {
        if (arr[i] < min) {
            min = arr[i];
        }
        if (arr[i] > max) {
            max = arr[i];
        }
    }
}

// 避免拷贝大型对象
struct LargeData {
    int data[1000];
    // ... 其他大型数据
};

void processLargeData(const LargeData &data) {
    // 使用const引用,避免拷贝,且不能修改数据
    cout << "处理大型数据,使用引用避免拷贝" << endl;
}

int main() {
    cout << "=== 引用传递 ===" << endl;
    
    // 示例1:交换变量(实际有效)
    int x = 5, y = 10;
    cout << "交换前: x=" << x << ", y=" << y << endl;
    swapByReference(x, y);
    cout << "交换后: x=" << x << ", y=" << y << " (已改变)" << endl;
    
    // 示例2:修改原始变量
    int value = 10;
    cout << "\n调用前: value=" << value << endl;
    incrementByReference(value);
    cout << "调用后: value=" << value << " (已改变)" << endl;
    
    // 示例3:返回多个值
    int numbers[] = {3, 7, 2, 9, 4, 1, 8};
    int minValue, maxValue;
    calculateMinMax(numbers, 7, minValue, maxValue);
    cout << "\n数组中的最小值: " << minValue << endl;
    cout << "数组中的最大值: " << maxValue << endl;
    
    // 示例4:避免大型对象拷贝
    LargeData bigData;
    // 初始化数据...
    processLargeData(bigData);  // 传递引用,避免拷贝
    
    return 0;
}
8.3.3 指针传递(Pass by Pointer)
cpp 复制代码
#include <iostream>
using namespace std;

// 指针传递:使用指针作为参数
void swapByPointer(int *a, int *b) {
    if (a == nullptr || b == nullptr) {
        cout << "错误:空指针!" << endl;
        return;
    }
    
    cout << "函数内交换前: *a=" << *a << ", *b=" << *b << endl;
    int temp = *a;
    *a = *b;
    *b = temp;
    cout << "函数内交换后: *a=" << *a << ", *b=" << *b << endl;
}

// 指针传递:可以修改指针指向的内容,也可以修改指针本身
void allocateArray(int **arrPtr, int size) {
    *arrPtr = new int[size];  // 分配动态数组
    for (int i = 0; i < size; i++) {
        (*arrPtr)[i] = i * 10;  // 初始化数组
    }
}

// 指针传递的典型应用:处理数组
void printArray(const int *arr, int size) {
    if (arr == nullptr) {
        cout << "空数组" << endl;
        return;
    }
    
    cout << "数组元素: ";
    for (int i = 0; i < size; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
}

// 修改指针本身
void reassignPointer(int **ptr) {
    static int newValue = 100;
    *ptr = &newValue;  // 修改指针指向的内容
}

int main() {
    cout << "=== 指针传递 ===" << endl;
    
    // 示例1:交换变量
    int x = 5, y = 10;
    cout << "交换前: x=" << x << ", y=" << y << endl;
    swapByPointer(&x, &y);  // 传递地址
    cout << "交换后: x=" << x << ", y=" << y << endl;
    
    // 示例2:动态分配数组
    int *dynamicArray = nullptr;
    int arraySize = 5;
    
    allocateArray(&dynamicArray, arraySize);
    printArray(dynamicArray, arraySize);
    
    // 清理动态内存
    delete[] dynamicArray;
    
    // 示例3:修改指针本身
    int value = 50;
    int *ptr = &value;
    
    cout << "\n修改指针前:" << endl;
    cout << "指针指向的值: " << *ptr << endl;
    cout << "指针地址: " << ptr << endl;
    
    reassignPointer(&ptr);
    
    cout << "\n修改指针后:" << endl;
    cout << "指针指向的值: " << *ptr << endl;
    cout << "指针地址: " << ptr << endl;
    
    return 0;
}
8.3.4 参数传递方式对比
cpp 复制代码
#include <iostream>
using namespace std;

// 三种参数传递方式的对比
class Data {
public:
    int value;
    
    Data(int v) : value(v) {
        cout << "构造函数调用: value=" << value << endl;
    }
    
    Data(const Data& other) : value(other.value) {
        cout << "拷贝构造函数调用: value=" << value << endl;
    }
    
    ~Data() {
        cout << "析构函数调用: value=" << value << endl;
    }
};

// 1. 值传递:调用拷贝构造函数,创建副本
void passByValue(Data data) {
    cout << "值传递函数内: data.value=" << data.value << endl;
    data.value = 999;  // 只修改副本
}

// 2. 引用传递:不调用拷贝构造函数,直接使用原始对象
void passByReference(Data &data) {
    cout << "引用传递函数内: data.value=" << data.value << endl;
    data.value = 999;  // 修改原始对象
}

// 3. 常量引用传递:不调用拷贝构造函数,不能修改对象
void passByConstReference(const Data &data) {
    cout << "常量引用传递函数内: data.value=" << data.value << endl;
    // data.value = 999;  // 错误:不能修改const引用
}

// 4. 指针传递
void passByPointer(Data *data) {
    if (data != nullptr) {
        cout << "指针传递函数内: data->value=" << data->value << endl;
        data->value = 999;  // 修改原始对象
    }
}

int main() {
    cout << "=== 参数传递方式对比 ===" << endl;
    
    cout << "\n1. 值传递演示:" << endl;
    {
        Data d1(100);
        cout << "调用前: d1.value=" << d1.value << endl;
        passByValue(d1);  // 调用拷贝构造函数
        cout << "调用后: d1.value=" << d1.value << " (未改变)" << endl;
    }
    
    cout << "\n2. 引用传递演示:" << endl;
    {
        Data d2(200);
        cout << "调用前: d2.value=" << d2.value << endl;
        passByReference(d2);  // 不调用拷贝构造函数
        cout << "调用后: d2.value=" << d2.value << " (已改变)" << endl;
    }
    
    cout << "\n3. 常量引用传递演示:" << endl;
    {
        Data d3(300);
        cout << "调用前: d3.value=" << d3.value << endl;
        passByConstReference(d3);  // 不调用拷贝构造函数
        cout << "调用后: d3.value=" << d3.value << " (未改变)" << endl;
    }
    
    cout << "\n4. 指针传递演示:" << endl;
    {
        Data d4(400);
        cout << "调用前: d4.value=" << d4.value << endl;
        passByPointer(&d4);
        cout << "调用后: d4.value=" << d4.value << " (已改变)" << endl;
    }
    
    cout << "\n=== 总结 ===" << endl;
    cout << "值传递: 安全,但可能低效(调用拷贝构造函数)" << endl;
    cout << "引用传递: 高效,可以修改原始数据" << endl;
    cout << "常量引用传递: 高效,安全(不能修改)" << endl;
    cout << "指针传递: 灵活,可以修改指针本身,需要检查nullptr" << endl;
    
    return 0;
}

8.4 函数的返回值

8.4.1 基本返回值
cpp 复制代码
#include <iostream>
#include <string>
#include <cmath>
using namespace std;

// 返回基本类型
int getSquare(int num) {
    return num * num;  // 返回int
}

// 返回浮点数
double getDistance(double x1, double y1, double x2, double y2) {
    double dx = x2 - x1;
    double dy = y2 - y1;
    return sqrt(dx * dx + dy * dy);
}

// 返回布尔值
bool isPrime(int num) {
    if (num <= 1) return false;
    if (num == 2) return true;
    if (num % 2 == 0) return false;
    
    for (int i = 3; i * i <= num; i += 2) {
        if (num % i == 0) {
            return false;
        }
    }
    return true;
}

// 返回字符
char getGrade(double score) {
    if (score >= 90) return 'A';
    else if (score >= 80) return 'B';
    else if (score >= 70) return 'C';
    else if (score >= 60) return 'D';
    else return 'F';
}

// 返回字符串
string getDayOfWeek(int day) {
    switch (day) {
        case 1: return "Monday";
        case 2: return "Tuesday";
        case 3: return "Wednesday";
        case 4: return "Thursday";
        case 5: return "Friday";
        case 6: return "Saturday";
        case 7: return "Sunday";
        default: return "Invalid day";
    }
}

// 返回数组(通过指针)
int* createSequence(int start, int end) {
    if (start > end) {
        return nullptr;
    }
    
    int size = end - start + 1;
    int* sequence = new int[size];
    
    for (int i = 0; i < size; i++) {
        sequence[i] = start + i;
    }
    
    return sequence;  // 返回动态数组指针
}

int main() {
    cout << "=== 函数的返回值 ===" << endl;
    
    // 使用不同类型的返回值
    int square = getSquare(5);
    cout << "5的平方: " << square << endl;
    
    double distance = getDistance(0, 0, 3, 4);
    cout << "点(0,0)到(3,4)的距离: " << distance << endl;
    
    int num = 17;
    cout << num << "是质数吗? " << (isPrime(num) ? "是" : "否") << endl;
    
    double score = 85.5;
    cout << "分数" << score << "的等级: " << getGrade(score) << endl;
    
    cout << "星期" << 3 << "是: " << getDayOfWeek(3) << endl;
    
    // 使用返回的动态数组
    int* sequence = createSequence(1, 10);
    if (sequence != nullptr) {
        cout << "序列: ";
        for (int i = 0; i < 10; i++) {
            cout << sequence[i] << " ";
        }
        cout << endl;
        
        // 记得释放动态内存
        delete[] sequence;
    }
    
    return 0;
}
8.4.2 返回引用与指针
cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

// 1. 返回引用(必须确保引用的对象在函数返回后仍然存在)
int& getLarger(int &a, int &b) {
    return (a > b) ? a : b;  // 返回较大值的引用
}

// 危险:返回局部变量的引用(未定义行为)
int& badFunction() {
    int localVar = 100;  // 局部变量,函数结束后被销毁
    return localVar;     // 错误:返回局部变量的引用
}

// 正确:返回静态局部变量的引用
int& getCounter() {
    static int counter = 0;  // 静态局部变量,生命周期是整个程序
    counter++;
    return counter;
}

// 2. 返回指针
int* findValue(int arr[], int size, int target) {
    for (int i = 0; i < size; i++) {
        if (arr[i] == target) {
            return &arr[i];  // 返回找到的元素的地址
        }
    }
    return nullptr;  // 未找到
}

// 返回动态分配的内存
char* duplicateString(const char* str) {
    if (str == nullptr) return nullptr;
    
    int length = 0;
    while (str[length] != '\0') {
        length++;
    }
    
    char* copy = new char[length + 1];  // +1 for null terminator
    for (int i = 0; i <= length; i++) {
        copy[i] = str[i];
    }
    
    return copy;  // 调用者负责释放内存
}

// 3. 返回常量引用(只读访问)
const string& getDefaultName() {
    static const string defaultName = "Unknown";  // 静态常量
    return defaultName;
}

int main() {
    cout << "=== 返回引用与指针 ===" << endl;
    
    // 示例1:返回引用
    int x = 5, y = 10;
    cout << "原始值: x=" << x << ", y=" << y << endl;
    
    int& larger = getLarger(x, y);
    cout << "较大的值: " << larger << endl;
    
    // 通过引用修改原始值
    larger = 100;
    cout << "修改后: x=" << x << ", y=" << y << endl;
    
    // 示例2:返回静态局部变量的引用
    cout << "\n计数器: ";
    for (int i = 0; i < 5; i++) {
        cout << getCounter() << " ";
    }
    cout << endl;
    
    // 示例3:返回指针查找元素
    int numbers[] = {10, 20, 30, 40, 50};
    int* found = findValue(numbers, 5, 30);
    
    if (found != nullptr) {
        cout << "找到值 " << *found << " 在位置 " << (found - numbers) << endl;
        *found = 99;  // 通过指针修改值
        cout << "修改后: " << numbers[2] << endl;
    }
    
    // 示例4:返回动态字符串
    const char* original = "Hello, C++!";
    char* copy = duplicateString(original);
    
    if (copy != nullptr) {
        cout << "\n原字符串: " << original << endl;
        cout << "复制字符串: " << copy << endl;
        delete[] copy;  // 释放内存
    }
    
    // 示例5:返回常量引用
    const string& name = getDefaultName();
    cout << "\n默认名称: " << name << endl;
    // name = "Changed";  // 错误:不能修改常量引用
    
    return 0;
}
8.4.3 void函数与无返回值
cpp 复制代码
#include <iostream>
#include <iomanip>
using namespace std;

// void函数:不返回任何值
void printHeader() {
    cout << "===================================" << endl;
    cout << "        学生成绩管理系统          " << endl;
    cout << "===================================" << endl;
}

// void函数带参数
void printStudentInfo(string name, int age, double score) {
    cout << fixed << setprecision(2);
    cout << "姓名: " << name << endl;
    cout << "年龄: " << age << "岁" << endl;
    cout << "成绩: " << score << "分" << endl;
    cout << "等级: " << (score >= 60 ? "及格" : "不及格") << endl;
}

// void函数可以通过引用参数"返回"值
void calculateStatistics(const double scores[], int size, 
                         double &average, double &min, double &max) {
    if (size <= 0) {
        average = min = max = 0.0;
        return;
    }
    
    double sum = 0.0;
    min = max = scores[0];
    
    for (int i = 0; i < size; i++) {
        sum += scores[i];
        if (scores[i] < min) min = scores[i];
        if (scores[i] > max) max = scores[i];
    }
    
    average = sum / size;
}

// 纯副作用函数:只产生副作用,不返回计算结果
void logMessage(const string& message, bool isError = false) {
    if (isError) {
        cerr << "[ERROR] " << message << endl;
    } else {
        cout << "[INFO] " << message << endl;
    }
}

// void函数可以提前返回
void processNumber(int num) {
    if (num < 0) {
        cout << "错误:负数无效" << endl;
        return;  // 提前返回
    }
    
    if (num == 0) {
        cout << "零没有倒数" << endl;
        return;  // 提前返回
    }
    
    cout << num << " 的倒数是: " << 1.0 / num << endl;
}

// 递归void函数
void countDown(int n) {
    if (n <= 0) {
        cout << "发射!" << endl;
        return;
    }
    
    cout << n << "..." << endl;
    countDown(n - 1);  // 递归调用
}

int main() {
    cout << "=== void函数与无返回值 ===" << endl;
    
    // 调用void函数
    printHeader();
    
    cout << endl;
    printStudentInfo("张三", 20, 85.5);
    
    cout << endl;
    printStudentInfo("李四", 19, 58.0);
    
    // 通过引用参数获取计算结果
    double testScores[] = {85.5, 92.0, 78.5, 88.0, 95.5};
    double avg, minScore, maxScore;
    
    calculateStatistics(testScores, 5, avg, minScore, maxScore);
    
    cout << fixed << setprecision(2);
    cout << "\n成绩统计:" << endl;
    cout << "平均分: " << avg << endl;
    cout << "最低分: " << minScore << endl;
    cout << "最高分: " << maxScore << endl;
    
    // 日志函数
    logMessage("程序启动成功");
    logMessage("文件读取失败", true);
    
    // 提前返回的void函数
    cout << "\n处理数字:" << endl;
    processNumber(5);
    processNumber(0);
    processNumber(-3);
    
    // 递归void函数
    cout << "\n倒计时:" << endl;
    countDown(5);
    
    return 0;
}

8.5 默认参数

8.5.1 基本默认参数
cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

// 默认参数:在函数声明中指定参数的默认值
void printMessage(string message = "Hello, World!") {
    cout << message << endl;
}

// 多个默认参数
void createWindow(string title = "Untitled", 
                  int width = 800, 
                  int height = 600,
                  bool fullscreen = false) {
    cout << "创建窗口: " << endl;
    cout << "  标题: " << title << endl;
    cout << "  宽度: " << width << endl;
    cout << "  高度: " << height << endl;
    cout << "  全屏: " << (fullscreen ? "是" : "否") << endl;
    cout << endl;
}

// 混合默认参数和非默认参数
// 注意:默认参数必须从右向左连续
double calculatePrice(double basePrice, 
                      double taxRate = 0.08,
                      double discount = 0.0) {
    double priceAfterDiscount = basePrice * (1 - discount);
    return priceAfterDiscount * (1 + taxRate);
}

// 错误示例:默认参数不在最右边
/*
void badFunction(int a = 1, int b) {  // 错误!
    // ...
}
*/

// 正确:默认参数从右向左
void goodFunction(int a, int b = 2, int c = 3) {
    cout << "a=" << a << ", b=" << b << ", c=" << c << endl;
}

int main() {
    cout << "=== 默认参数 ===" << endl;
    
    // 使用默认参数
    printMessage();           // 使用默认值
    printMessage("你好!");   // 提供自定义值
    
    // 使用多个默认参数的不同组合
    createWindow();                          // 全部使用默认值
    createWindow("我的程序");                // 只提供标题
    createWindow("游戏窗口", 1024, 768);     // 提供标题、宽度、高度
    createWindow("全屏应用", 1920, 1080, true); // 提供所有参数
    
    // 计算价格
    cout << "价格计算:" << endl;
    double basePrice = 100.0;
    
    cout << "基础价格: " << basePrice << endl;
    cout << "含税(8%): " << calculatePrice(basePrice) << endl;
    cout << "含税+9折: " << calculatePrice(basePrice, 0.08, 0.1) << endl;
    cout << "免税+8折: " << calculatePrice(basePrice, 0.0, 0.2) << endl;
    
    // 跳过中间参数(C++不支持直接跳过,需要重载函数)
    // calculatePrice(100.0, 0.1);  // 错误:不能跳过taxRate直接指定discount
    
    // 默认参数从右向左
    cout << "\n默认参数顺序:" << endl;
    goodFunction(1);        // a=1, b=2, c=3
    goodFunction(1, 4);     // a=1, b=4, c=3
    goodFunction(1, 4, 5);  // a=1, b=4, c=5
    
    return 0;
}
8.5.2 默认参数的注意事项
cpp 复制代码
#include <iostream>
using namespace std;

// 问题1:默认参数在声明中指定,定义中不要重复指定
// 函数声明(通常在头文件中)
void display(int value, bool showHex = false);

// 函数定义(在源文件中)
void display(int value, bool showHex /* = false 不要在这里写 */) {
    if (showHex) {
        cout << "十六进制: 0x" << hex << value << endl;
    } else {
        cout << "十进制: " << dec << value << endl;
    }
}

// 问题2:默认参数与函数重载的冲突
// 版本1:默认参数
void process(int a, int b = 10) {
    cout << "process(int, int): a=" << a << ", b=" << b << endl;
}

// 版本2:重载函数
void process(int a) {
    cout << "process(int): a=" << a << endl;
}

// 这会产生歧义:process(5) 调用哪个?

// 问题3:默认参数的值在调用时确定
int getDefaultValue() {
    static int counter = 0;
    return ++counter;
}

// 默认参数是表达式
void testFunction(int a = getDefaultValue()) {
    cout << "a = " << a << endl;
}

// 问题4:默认参数与指针/引用
void setupConnection(string address = "localhost",
                     int port = 8080,
                     int* status = nullptr) {
    cout << "连接到 " << address << ":" << port << endl;
    
    if (status != nullptr) {
        *status = 0;  // 成功
    }
}

// 问题5:默认参数与const
void printData(const string& data = "") {
    cout << "数据: " << data << endl;
}

int main() {
    cout << "=== 默认参数的注意事项 ===" << endl;
    
    // 示例1:声明和定义分离
    display(255);
    display(255, true);
    
    // 示例2:函数重载冲突
    process(5);     // 调用哪个?有歧义!
    process(5, 20); // 明确调用第一个版本
    
    // 示例3:默认参数表达式
    cout << "\n默认参数表达式:" << endl;
    testFunction();     // a = 1
    testFunction();     // a = 2(每次调用表达式都会重新求值)
    testFunction(100);  // a = 100(使用提供的值)
    
    // 示例4:指针默认参数
    cout << "\n指针默认参数:" << endl;
    int statusCode;
    
    setupConnection();  // 使用所有默认值
    setupConnection("example.com", 443, &statusCode);
    cout << "状态码: " << statusCode << endl;
    
    // 示例5:const引用默认参数
    printData();
    printData("Hello");
    
    // 最佳实践建议:
    cout << "\n=== 最佳实践 ===" << endl;
    cout << "1. 在函数声明中指定默认参数,不要在定义中重复" << endl;
    cout << "2. 避免默认参数导致函数重载歧义" << endl;
    cout << "3. 默认参数可以是常量、全局变量或静态变量的表达式" << endl;
    cout << "4. 对于复杂默认值,考虑使用函数重载代替" << endl;
    cout << "5. 指针默认参数通常使用nullptr" << endl;
    
    return 0;
}

8.6 函数重载

8.6.1 基本函数重载
cpp 复制代码
#include <iostream>
#include <string>
#include <cmath>
using namespace std;

// 函数重载:同名函数,不同参数列表

// 版本1:两个整数相加
int add(int a, int b) {
    cout << "调用 int add(int, int)" << endl;
    return a + b;
}

// 版本2:两个浮点数相加
double add(double a, double b) {
    cout << "调用 double add(double, double)" << endl;
    return a + b;
}

// 版本3:三个整数相加
int add(int a, int b, int c) {
    cout << "调用 int add(int, int, int)" << endl;
    return a + b + c;
}

// 版本4:两个字符串相加(连接)
string add(const string& a, const string& b) {
    cout << "调用 string add(const string&, const string&)" << endl;
    return a + b;
}

// 版本5:整数数组求和
int add(const int arr[], int size) {
    cout << "调用 int add(const int[], int)" << endl;
    int sum = 0;
    for (int i = 0; i < size; i++) {
        sum += arr[i];
    }
    return sum;
}

// 计算面积的不同重载
double area(double radius) {  // 圆面积
    return 3.14159 * radius * radius;
}

double area(double length, double width) {  // 矩形面积
    return length * width;
}

double area(double base, double height, bool isTriangle) {  // 三角形面积
    if (isTriangle) {
        return 0.5 * base * height;
    }
    return base * height;  // 实际上是平行四边形
}

// 显示不同类型的值
void display(int value) {
    cout << "整数: " << value << endl;
}

void display(double value) {
    cout << "浮点数: " << value << endl;
}

void display(const char* value) {
    cout << "字符串: " << value << endl;
}

void display(bool value) {
    cout << "布尔值: " << (value ? "true" : "false") << endl;
}

int main() {
    cout << "=== 函数重载 ===" << endl;
    
    // 自动选择正确的重载版本
    cout << "\n1. 加法函数重载:" << endl;
    cout << "整数相加: " << add(5, 3) << endl;
    cout << "浮点数相加: " << add(5.5, 3.3) << endl;
    cout << "三个整数相加: " << add(1, 2, 3) << endl;
    cout << "字符串连接: " << add("Hello, ", "World!") << endl;
    
    int numbers[] = {1, 2, 3, 4, 5};
    cout << "数组求和: " << add(numbers, 5) << endl;
    
    // 类型转换和重载解析
    cout << "\n2. 类型转换示例:" << endl;
    cout << "add(5, 3.14) = " << add(5, 3.14) << endl;  // 调用double版本
    // 发生隐式类型转换:int转换为double
    
    // 面积计算重载
    cout << "\n3. 面积计算重载:" << endl;
    cout << "圆面积 (半径=5): " << area(5.0) << endl;
    cout << "矩形面积 (长=4, 宽=6): " << area(4.0, 6.0) << endl;
    cout << "三角形面积 (底=3, 高=4): " << area(3.0, 4.0, true) << endl;
    
    // 显示函数重载
    cout << "\n4. 显示不同类型:" << endl;
    display(42);
    display(3.14159);
    display("C++ Programming");
    display(true);
    
    return 0;
}
8.6.2 函数重载的规则与限制
cpp 复制代码
#include <iostream>
using namespace std;

// 规则1:重载基于参数列表(类型、个数、顺序),而不是返回类型
int process(int a) {
    cout << "process(int)" << endl;
    return a * 2;
}

// 错误:仅返回类型不同不能重载
/*
double process(int a) {  // 编译错误
    return a * 2.0;
}
*/

// 正确:参数类型不同可以重载
double process(double a) {
    cout << "process(double)" << endl;
    return a * 2.0;
}

// 正确:参数个数不同可以重载
int process(int a, int b) {
    cout << "process(int, int)" << endl;
    return a + b;
}

// 正确:参数顺序不同可以重载
void configure(int width, double ratio) {
    cout << "configure(int, double)" << endl;
}

void configure(double ratio, int width) {
    cout << "configure(double, int)" << endl;
}

// 规则2:const可以作为重载依据
class Data {
public:
    void print() {
        cout << "非const版本" << endl;
    }
    
    void print() const {  // const成员函数
        cout << "const版本" << endl;
    }
};

// 规则3:引用和const引用可以作为重载依据
void handleValue(int& x) {
    cout << "可修改引用版本" << endl;
    x++;
}

void handleValue(const int& x) {
    cout << "只读引用版本,值=" << x << endl;
}

// 规则4:指针类型也可以重载
void analyze(int* ptr) {
    cout << "整数指针版本" << endl;
}

void analyze(double* ptr) {
    cout << "浮点数指针版本" << endl;
}

// 规则5:默认参数可能引起重载歧义
void compute(int a, int b = 0) {
    cout << "compute(int, int) with default" << endl;
}

// 这个重载会导致歧义:compute(5) 调用哪个?
void compute(int a) {
    cout << "compute(int)" << endl;
}

// 测试重载解析
void test(int a) {
    cout << "test(int)" << endl;
}

void test(double a) {
    cout << "test(double)" << endl;
}

void test(int a, int b) {
    cout << "test(int, int)" << endl;
}

int main() {
    cout << "=== 函数重载的规则与限制 ===" << endl;
    
    // 测试不同参数类型
    cout << "\n1. 不同参数类型:" << endl;
    process(10);      // 调用int版本
    process(10.0);    // 调用double版本
    process(10, 20);  // 调用两个int版本
    
    // 测试参数顺序
    cout << "\n2. 不同参数顺序:" << endl;
    configure(100, 1.5);   // int, double
    configure(1.5, 100);   // double, int
    
    // 测试const重载
    cout << "\n3. const重载:" << endl;
    Data d1;
    const Data d2;
    
    d1.print();  // 调用非const版本
    d2.print();  // 调用const版本
    
    // 测试引用重载
    cout << "\n4. 引用重载:" << endl;
    int value = 10;
    handleValue(value);       // 调用可修改版本
    handleValue(20);          // 调用只读版本(字面量)
    handleValue(value);       // 仍然调用可修改版本
    
    // 测试指针重载
    cout << "\n5. 指针重载:" << endl;
    int intValue = 5;
    double doubleValue = 3.14;
    
    analyze(&intValue);      // 整数指针版本
    analyze(&doubleValue);   // 浮点数指针版本
    
    // 测试重载解析
    cout << "\n6. 重载解析:" << endl;
    test(5);          // 精确匹配:test(int)
    test(5.0);        // 精确匹配:test(double)
    test(5.0f);       // 提升为double:test(double)
    test('A');        // 提升为int:test(int)
    
    // 测试歧义情况
    cout << "\n7. 歧义测试:" << endl;
    // compute(5);     // 错误:歧义调用
    
    // 通过强制类型转换解决歧义
    compute(static_cast<double>(5));  // 明确调用某个版本
    
    // 重载解析顺序:
    cout << "\n=== 重载解析顺序 ===" << endl;
    cout << "1. 精确匹配" << endl;
    cout << "2. 提升转换(char→int, float→double)" << endl;
    cout << "3. 标准转换(int→double, double→int)" << endl;
    cout << "4. 用户定义转换" << endl;
    cout << "5. 可变参数匹配" << endl;
    
    return 0;
}

8.7 内联函数

8.7.1 内联函数基础
cpp 复制代码
#include <iostream>
#include <chrono>
using namespace std;
using namespace std::chrono;

// 常规函数
int square(int x) {
    return x * x;
}

// 内联函数
inline int cube(int x) {
    return x * x * x;
}

// 内联函数可以定义在头文件中
inline int max(int a, int b) {
    return (a > b) ? a : b;
}

inline double max(double a, double b) {
    return (a > b) ? a : b;
}

// 内联函数也可以有多个语句
inline void swapValues(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

// 内联递归函数(编译器可能不内联)
inline int factorial(int n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}

// 测试性能的函数
void testPerformance() {
    const int ITERATIONS = 100000000;
    
    // 测试常规函数
    auto start = high_resolution_clock::now();
    int sum1 = 0;
    for (int i = 0; i < ITERATIONS; i++) {
        sum1 += square(i % 100);  // 函数调用
    }
    auto end = high_resolution_clock::now();
    auto duration1 = duration_cast<milliseconds>(end - start);
    
    // 测试内联函数
    start = high_resolution_clock::now();
    int sum2 = 0;
    for (int i = 0; i < ITERATIONS; i++) {
        sum2 += cube(i % 100);  // 可能被内联
    }
    end = high_resolution_clock::now();
    auto duration2 = duration_cast<milliseconds>(end - start);
    
    // 测试直接计算(比较基准)
    start = high_resolution_clock::now();
    int sum3 = 0;
    for (int i = 0; i < ITERATIONS; i++) {
        int x = i % 100;
        sum3 += x * x * x;  // 直接计算
    }
    end = high_resolution_clock::now();
    auto duration3 = duration_cast<milliseconds>(end - start);
    
    cout << "性能测试结果 (迭代 " << ITERATIONS << " 次):" << endl;
    cout << "常规函数: " << duration1.count() << " 毫秒" << endl;
    cout << "内联函数: " << duration2.count() << " 毫秒" << endl;
    cout << "直接计算: " << duration3.count() << " 毫秒" << endl;
}

int main() {
    cout << "=== 内联函数 ===" << endl;
    
    // 使用内联函数
    cout << "5的立方: " << cube(5) << endl;
    cout << "最大值(10, 20): " << max(10, 20) << endl;
    cout << "最大值(3.14, 2.71): " << max(3.14, 2.71) << endl;
    
    // 交换值
    int a = 5, b = 10;
    cout << "\n交换前: a=" << a << ", b=" << b << endl;
    swapValues(a, b);
    cout << "交换后: a=" << a << ", b=" << b << endl;
    
    // 递归内联函数
    cout << "\n5的阶乘: " << factorial(5) << endl;
    
    // 性能测试
    cout << "\n=== 性能测试 ===" << endl;
    testPerformance();
    
    // 内联函数的优缺点
    cout << "\n=== 内联函数的优缺点 ===" << endl;
    cout << "优点:" << endl;
    cout << "1. 消除函数调用开销" << endl;
    cout << "2. 编译器可以进行更好的优化" << endl;
    cout << "3. 避免函数调用的参数压栈/出栈" << endl;
    
    cout << "\n缺点:" << endl;
    cout << "1. 代码膨胀(每个调用点都复制代码)" << endl;
    cout << "2. 可能增加编译时间" << endl;
    cout << "3. 调试困难(没有明显的函数调用)" << endl;
    cout << "4. 复杂的函数不适合内联" << endl;
    
    cout << "\n=== 使用建议 ===" << endl;
    cout << "适合内联的函数:" << endl;
    cout << "1. 非常小的函数(1-5行)" << endl;
    cout << "2. 频繁调用的函数" << endl;
    cout << "3. 简单的访问器和修改器" << endl;
    
    cout << "\n不适合内联的函数:" << endl;
    cout << "1. 递归函数" << endl;
    cout << "2. 包含循环的函数" << endl;
    cout << "3. 包含复杂逻辑的函数" << endl;
    cout << "4. 虚函数(运行时多态)" << endl;
    
    return 0;
}
8.7.2 内联与宏的对比
cpp 复制代码
#include <iostream>
#include <cmath>
using namespace std;

// C风格宏(预处理阶段替换)
#define SQUARE_MACRO(x) ((x) * (x))
#define MAX_MACRO(a, b) ((a) > (b) ? (a) : (b))
#define SWAP_MACRO(type, a, b) { type temp = a; a = b; b = temp; }

// C++内联函数
inline int square_inline(int x) {
    return x * x;
}

inline int max_inline(int a, int b) {
    return (a > b) ? a : b;
}

template<typename T>
inline void swap_inline(T& a, T& b) {
    T temp = a;
    a = b;
    b = temp;
}

// 测试宏的问题
void testMacroProblems() {
    cout << "=== 宏的问题 ===" << endl;
    
    // 问题1:参数多次求值
    int counter = 0;
    int result1 = SQUARE_MACRO(++counter);
    cout << "SQUARE_MACRO(++counter): " << result1 << endl;
    cout << "counter 现在的值: " << counter << " (应该是1,但实际是2)" << endl;
    
    // 使用内联函数
    counter = 0;
    int result2 = square_inline(++counter);
    cout << "\nsquare_inline(++counter): " << result2 << endl;
    cout << "counter 现在的值: " << counter << " (正确:1)" << endl;
    
    // 问题2:运算符优先级问题
    int x = 2, y = 3;
    int result3 = SQUARE_MACRO(x + y);
    cout << "\nSQUARE_MACRO(x + y): " << result3 << endl;
    cout << "预期: (2+3)*(2+3) = 25" << endl;
    cout << "实际: " << result3 << " (正确,因为宏加了括号)" << endl;
    
    // 如果没有括号会怎样?
    #define SQUARE_BAD(x) x * x  // 缺少括号
    int result4 = SQUARE_BAD(x + y);
    cout << "\nSQUARE_BAD(x + y): " << result4 << endl;
    cout << "展开: " << x + y << " * " << x + y << " = " << result4 << endl;
    cout << "错误!应该是 2+3*2+3 = 11" << endl;
    
    // 问题3:类型不安全
    double d1 = 2.5, d2 = 3.5;
    double result5 = MAX_MACRO(d1, d2);  // 可以工作
    cout << "\nMAX_MACRO(2.5, 3.5): " << result5 << endl;
    
    // 但可能有问题
    int a = 5;
    double b = 5.1;
    double result6 = MAX_MACRO(a, b);  // 混合类型
    cout << "MAX_MACRO(5, 5.1): " << result6 << endl;
    
    // 使用模板内联函数
    cout << "\n使用模板内联函数: " << max_inline(a, static_cast<int>(b)) << endl;
    
    // 问题4:调试困难
    cout << "\n调试问题:" << endl;
    int val1 = 10, val2 = 20;
    cout << "交换前: val1=" << val1 << ", val2=" << val2 << endl;
    
    // 使用宏交换
    SWAP_MACRO(int, val1, val2);
    cout << "交换后: val1=" << val1 << ", val2=" << val2 << endl;
    
    // 调试时看不到SWAP_MACRO的实现
    // 而内联函数可以在调试器中跟踪
    
    // 使用内联函数交换
    swap_inline(val1, val2);
    cout << "再次交换: val1=" << val1 << ", val2=" << val2 << endl;
}

// 宏的独特用途(内联函数无法替代)
void testMacroAdvantages() {
    cout << "\n=== 宏的独特优势 ===" << endl;
    
    // 1. 字符串化
    #define STRINGIFY(x) #x
    cout << "字符串化宏: " << STRINGIFY(Hello World) << endl;
    
    // 2. 连接
    #define CONCAT(a, b) a##b
    int xy = 100;
    cout << "连接宏: CONCAT(x, y) = " << xy << endl;
    
    // 3. 条件编译
    #define DEBUG_MODE 1
    #if DEBUG_MODE
        cout << "调试模式启用" << endl;
    #endif
    
    // 4. 文件、行号信息(用于调试)
    #define LOG(msg) cout << __FILE__ << ":" << __LINE__ << " " << msg << endl
    LOG("这是一条日志消息");
    
    // 5. 变参宏
    #define PRINT_ARGS(...) cout << __VA_ARGS__ << endl
    PRINT_ARGS("多个参数:", 1, 2, 3, "结束");
}

int main() {
    cout << "=== 内联函数与宏的对比 ===" << endl;
    
    testMacroProblems();
    testMacroAdvantages();
    
    cout << "\n=== 总结 ===" << endl;
    cout << "宏的优点:" << endl;
    cout << "1. 文本替换,非常灵活" << endl;
    cout << "2. 支持字符串化、连接等高级功能" << endl;
    cout << "3. 与预处理器的其他功能集成" << endl;
    
    cout << "\n宏的缺点:" << endl;
    cout << "1. 容易出错(运算符优先级、多次求值)" << endl;
    cout << "2. 没有类型检查" << endl;
    cout << "3. 调试困难" << endl;
    cout << "4. 没有作用域" << endl;
    
    cout << "\n内联函数的优点:" << endl;
    cout << "1. 类型安全" << endl;
    cout << "2. 调试方便" << endl;
    cout << "3. 有作用域" << endl;
    cout << "4. 编译器可以更好地优化" << endl;
    
    cout << "\n内联函数的缺点:" << endl;
    cout << "1. 不能做字符串化、连接等操作" << endl;
    cout << "2. 不如宏灵活" << endl;
    
    cout << "\n=== 现代C++建议 ===" << endl;
    cout << "1. 优先使用内联函数代替宏进行计算" << endl;
    cout << "2. 使用constexpr代替编译时常量宏" << endl;
    cout << "3. 使用模板代替类型相关的宏" << endl;
    cout << "4. 宏仅用于条件编译、日志等特殊用途" << endl;
    
    return 0;
}

8.8 实践练习

练习1:数学函数库

cpp 复制代码
/*
 * 作业:创建数学函数库
 * 功能:
 * 1. 基本运算函数(加、减、乘、除、取模)
 * 2. 数学函数(幂、平方根、绝对值、四舍五入)
 * 3. 几何计算(圆面积、矩形面积、三角形面积)
 * 4. 统计函数(平均值、方差、标准差)
 * 5. 三角函数(sin, cos, tan,使用C++标准库)
 * 
 * 要求:
 * - 使用函数重载支持不同类型
 * - 使用默认参数
 * - 合理使用引用和值传递
 * - 提供错误处理(如除零错误)
 */

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

int main() {
    // 在这里编写你的代码
    
    return 0;
}

练习2:学生成绩管理系统(函数版)

cpp 复制代码
/*
 * 作业:学生成绩管理系统(使用函数重构)
 * 功能:
 * 1. 添加学生信息(姓名、学号、成绩)
 * 2. 显示所有学生信息
 * 3. 查找学生(按姓名或学号)
 * 4. 统计功能(平均分、最高分、最低分)
 * 5. 排序功能(按成绩或姓名排序)
 * 6. 保存/加载数据到文件
 * 
 * 要求:
 * - 每个功能实现为独立的函数
 * - 使用结构体表示学生信息
 * - 使用数组或vector存储多个学生
 * - 实现清晰的操作菜单
 * - 处理各种边界情况和错误输入
 */

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iomanip>
using namespace std;

int main() {
    // 在这里编写你的代码
    
    return 0;
}

练习3:日期时间工具函数

cpp 复制代码
/*
 * 作业:日期时间工具函数库
 * 功能:
 * 1. 验证日期合法性(考虑闰年)
 * 2. 计算两个日期之间的天数差
 * 3. 计算某日期是星期几
 * 4. 日期加减运算(加N天、加N月、加N年)
 * 5. 时间转换(24小时制↔12小时制)
 * 6. 计算时间差
 * 7. 显示当前日期时间
 * 
 * 要求:
 * - 使用结构体表示日期和时间
 * - 实现完整的错误检查
 * - 提供丰富的函数重载
 * - 使用合理的默认参数
 */

#include <iostream>
#include <ctime>
#include <string>
using namespace std;

int main() {
    // 在这里编写你的代码
    
    return 0;
}

8.9 常见错误与调试

8.9.1 函数常见错误
cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

// 错误1:忘记返回语句
int add(int a, int b) {
    int result = a + b;
    // 忘记 return result;
    // 编译器可能不会报错,但返回的值是未定义的
}

// 错误2:返回局部变量的引用/指针
int& badReturnReference() {
    int local = 100;
    return local;  // 错误:返回局部变量的引用
}

int* badReturnPointer() {
    int local = 100;
    return &local;  // 错误:返回局部变量的地址
}

// 错误3:函数声明与定义不匹配
// 声明
double calculate(int a, double b);

// 定义(参数类型不匹配)
double calculate(double a, int b) {  // 错误!
    return a + b;
}

// 错误4:递归函数没有终止条件
void infiniteRecursion(int n) {
    cout << n << " ";
    infiniteRecursion(n + 1);  // 没有终止条件!
    // 最终会导致栈溢出
}

// 错误5:默认参数位置错误
void wrongDefault(int a = 1, int b) {  // 错误:默认参数必须在最后
    cout << a << ", " << b << endl;
}

// 错误6:函数重载歧义
void ambiguous(int a) {
    cout << "版本1" << endl;
}

void ambiguous(double a) {
    cout << "版本2" << endl;
}

// 调用 ambiguous(5) 是合法的,但 ambiguous(5.0f) 可能产生歧义

// 错误7:未使用的参数(可能导致警告)
void process(int data) {
    // 没有使用data参数
    cout << "处理中..." << endl;
}

// 正确做法:明确标记未使用参数
void process2(int /*data*/) {  // 注释掉参数名
    cout << "处理中..." << endl;
}

void process3(int data) {
    (void)data;  // 显式忽略参数
    cout << "处理中..." << endl;
}

// 错误8:数组作为参数时忘记传递大小
void printArray(int arr[]) {  // 错误:不知道数组大小
    // 无法安全地遍历数组
    for (int i = 0; i < 10; i++) {  // 假设大小是10
        cout << arr[i] << " ";
    }
}

// 正确做法
void printArrayCorrect(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        cout << arr[i] << " ";
    }
}

int main() {
    cout << "=== 函数常见错误 ===" << endl;
    
    // 演示错误1
    cout << "\n错误1演示:" << endl;
    int sum = add(5, 3);
    cout << "add(5, 3) = " << sum << " (可能是垃圾值)" << endl;
    
    // 演示错误2(危险!)
    cout << "\n错误2演示(未定义行为):" << endl;
    /*
    int& ref = badReturnReference();
    cout << "返回的引用值: " << ref << endl;  // 未定义行为
    
    int* ptr = badReturnPointer();
    cout << "返回的指针值: " << *ptr << endl;  // 未定义行为
    */
    
    // 演示错误4:栈溢出
    /*
    cout << "\n错误4演示(栈溢出):" << endl;
    infiniteRecursion(1);  // 最终会崩溃
    */
    
    // 演示错误6:重载歧义
    cout << "\n错误6演示(重载歧义):" << endl;
    ambiguous(5);     // 明确调用int版本
    ambiguous(5.0);   // 明确调用double版本
    // ambiguous(5.0f);  // 可能产生歧义:float可以转int或double
    
    // 演示错误8
    cout << "\n错误8演示(数组大小问题):" << endl;
    int smallArray[3] = {1, 2, 3};
    // printArray(smallArray);  // 错误:可能越界访问
    
    printArrayCorrect(smallArray, 3);  // 正确做法
    
    cout << "\n=== 调试技巧 ===" << endl;
    
    // 调试技巧1:添加日志输出
    auto debugAdd = [](int a, int b) -> int {
        cout << "[DEBUG] 调用add: a=" << a << ", b=" << b << endl;
        int result = a + b;
        cout << "[DEBUG] 返回结果: " << result << endl;
        return result;
    };
    
    debugAdd(5, 3);
    
    // 调试技巧2:使用断言
    #include <cassert>
    
    auto safeDivide = [](int a, int b) -> double {
        assert(b != 0);  // 调试时检查除数不为0
        return static_cast<double>(a) / b;
    };
    
    cout << "\n10 / 2 = " << safeDivide(10, 2) << endl;
    // cout << "10 / 0 = " << safeDivide(10, 0) << endl;  // 断言失败
    
    // 调试技巧3:分步执行
    auto complexCalculation = [](int x) -> int {
        // 分步计算,方便调试
        int step1 = x * x;
        cout << "步骤1: x² = " << step1 << endl;
        
        int step2 = step1 + 5;
        cout << "步骤2: x² + 5 = " << step2 << endl;
        
        int step3 = step2 * 2;
        cout << "步骤3: (x² + 5) × 2 = " << step3 << endl;
        
        return step3;
    };
    
    cout << "\n分步调试演示:" << endl;
    complexCalculation(3);
    
    return 0;
}

恭喜! 你已经完成了第四部分的学习。在这一部分中,你掌握了:

  1. 函数基础:定义、声明、调用
  2. 参数传递:值传递、引用传递、指针传递
  3. 返回值:各种返回类型,返回引用/指针的注意事项
  4. 默认参数:使用方法与注意事项
  5. 函数重载:实现多态接口
  6. 内联函数:提高性能的优化技术
  7. 实践与调试:常见错误与解决方案

现在你已经能够编写模块化、可复用的代码了。在接下来的第五部分中,我们将学习复合数据类型,包括数组、字符串和结构体,这是构建复杂数据结构的基础。

相关推荐
汉克老师14 小时前
GESP2025年12月认证C++八级真题与解析(判断题8-10)
c++·快速排序··lcs·gesp八级·gesp8级
listhi52014 小时前
对LeNet-5的matlab实现,识别MINST手写数字集
开发语言·matlab
qq_4335545414 小时前
C++ manacher(求解回文串问题)
开发语言·c++·算法
csbysj202015 小时前
Chart.js 饼图:全面解析与实例教程
开发语言
浩瀚地学15 小时前
【Java】常用API(二)
java·开发语言·经验分享·笔记·学习
程序员小寒15 小时前
从一道前端面试题,谈 JS 对象存储特点和运算符执行顺序
开发语言·前端·javascript·面试
七夜zippoe15 小时前
事件驱动架构:构建高并发松耦合系统的Python实战
开发语言·python·架构·eda·事件驱动
古城小栈15 小时前
Rust Trait 敲黑板
开发语言·rust
HL_风神16 小时前
设计原则之迪米特
c++·学习·设计模式