当前位置: 首页 > news >正文

【C++基础与提高】第六章:函数——代码复用的艺术

【C++基础与提高】第六章:函数——代码复用的艺术

(持续更新中,欢迎关注!)

文章目录

  • 【C++基础与提高】第六章:函数——代码复用的艺术
      • 6.1 函数基础概念——模块化编程的核心
      • 6.2 函数定义与声明——构建函数的语法结构
        • 6.2.1 函数定义语法
        • 6.2.2 函数声明与定义分离
      • 6.3 参数传递机制——数据如何进入函数
        • 6.3.1 值传递(Pass by Value)
        • 6.3.2 引用传递(Pass by Reference)
        • 6.3.3 指针传递(Pass by Pointer)
        • 6.3.4 常量引用传递(Const Reference)
      • 6.4 函数重载——同一名称的不同实现
      • 6.5 默认参数——灵活的函数调用
      • 6.6 内联函数——提高执行效率
      • 6.7 递归函数——自我调用的艺术
      • 6.8 函数指针——函数的地址操作
      • 6.9 Lambda表达式——匿名函数的魅力(C++11)
      • 6.10 函数模板——通用函数的设计
      • 6.11 现代C++函数特性——更安全更便捷
      • 6.12 函数设计最佳实践
      • 6.13 本章小结


6.1 函数基础概念——模块化编程的核心

函数是C++中执行特定任务的独立代码块,它允许我们将复杂问题分解为更小、更易管理的部分。函数就像工厂里的机器,接收原材料(参数),经过加工处理,产出成品(返回值)。

#include <iostream>
#include <cmath>// 函数声明(函数原型)
int add(int a, int b);                    // 加法函数
double circle_area(double radius);        // 计算圆面积函数
void print_greeting(const std::string& name); // 打印问候语函数int main() {// 函数调用int sum = add(10, 20);double area = circle_area(5.0);std::cout << "10 + 20 = " << sum << std::endl;std::cout << "半径为5的圆面积: " << area << std::endl;print_greeting("张三");return 0;
}// 函数定义
int add(int a, int b) {return a + b;  // 返回两数之和
}double circle_area(double radius) {const double PI = 3.14159265359;return PI * radius * radius;  // 返回圆面积
}void print_greeting(const std::string& name) {std::cout << "你好," << name << "!欢迎学习C++函数!" << std::endl;// void函数不返回值
}

6.2 函数定义与声明——构建函数的语法结构

6.2.1 函数定义语法
#include <iostream>
#include <string>// 函数定义的一般形式:
// 返回类型 函数名(参数列表) {
//     函数体
//     return 返回值;  // 如果返回类型不是void
// }// 1. 无参无返回值函数
void say_hello() {std::cout << "Hello, World!" << std::endl;
}// 2. 有参无返回值函数
void print_message(const std::string& msg) {std::cout << "消息: " << msg << std::endl;
}// 3. 无参有返回值函数
int get_default_value() {return 42;
}// 4. 有参有返回值函数
int multiply(int x, int y) {return x * y;
}int main() {// 调用各种类型的函数say_hello();print_message("C++函数很有趣!");std::cout << "默认值: " << get_default_value() << std::endl;std::cout << "5 × 8 = " << multiply(5, 8) << std::endl;return 0;
}
6.2.2 函数声明与定义分离
#include <iostream>
#include <vector>// 函数声明(通常放在头文件或文件顶部)
int factorial(int n);
bool is_prime(int num);
std::vector<int> generate_primes(int limit);// main函数可以放在声明之后、定义之前
int main() {std::cout << "5的阶乘: " << factorial(5) << std::endl;int number = 17;std::cout << number << (is_prime(number) ? " 是" : " 不是") << "质数" << std::endl;auto primes = generate_primes(20);std::cout << "20以内的质数: ";for(const auto& prime : primes) {std::cout << prime << " ";}std::cout << std::endl;return 0;
}// 函数定义(通常放在文件底部或单独的源文件中)
int factorial(int n) {if(n <= 1) return 1;return n * factorial(n - 1);  // 递归调用
}bool is_prime(int num) {if(num <= 1) return false;if(num <= 3) return true;if(num % 2 == 0 || num % 3 == 0) return false;for(int i = 5; i * i <= num; i += 6) {if(num % i == 0 || num % (i + 2) == 0) {return false;}}return true;
}std::vector<int> generate_primes(int limit) {std::vector<int> primes;for(int i = 2; i <= limit; ++i) {if(is_prime(i)) {primes.push_back(i);}}return primes;
}

6.3 参数传递机制——数据如何进入函数

6.3.1 值传递(Pass by Value)
#include <iostream>// 值传递:函数获得参数的副本,不影响原变量
void modify_by_value(int x) {x = 100;  // 只修改副本std::cout << "函数内x的值: " << x << std::endl;
}int main() {int original = 50;std::cout << "调用前original: " << original << std::endl;modify_by_value(original);std::cout << "调用后original: " << original << std::endl;  // 值不变return 0;
}
6.3.2 引用传递(Pass by Reference)
#include <iostream>// 引用传递:函数直接操作原变量
void modify_by_reference(int& x) {x = 100;  // 直接修改原变量std::cout << "函数内x的值: " << x << std::endl;
}int main() {int original = 50;std::cout << "调用前original: " << original << std::endl;modify_by_reference(original);std::cout << "调用后original: " << original << std::endl;  // 值已改变return 0;
}
6.3.3 指针传递(Pass by Pointer)
#include <iostream>// 指针传递:通过指针间接访问和修改原变量
void modify_by_pointer(int* x) {if(x != nullptr) {  // 安全检查*x = 100;  // 通过指针修改原变量std::cout << "函数内*x的值: " << *x << std::endl;}
}int main() {int original = 50;std::cout << "调用前original: " << original << std::endl;modify_by_pointer(&original);  // 传递地址std::cout << "调用后original: " << original << std::endl;  // 值已改变return 0;
}
6.3.4 常量引用传递(Const Reference)
#include <iostream>
#include <string>// 常量引用传递:避免复制大对象,同时防止修改
void print_string_info(const std::string& str) {std::cout << "字符串内容: " << str << std::endl;std::cout << "字符串长度: " << str.length() << std::endl;// str = "new value";  // 错误!不能修改const引用
}int main() {std::string message = "Hello, C++ Function!";print_string_info(message);  // 高效传递,无需复制return 0;
}

6.4 函数重载——同一名称的不同实现

#include <iostream>
#include <string>// 函数重载:同一函数名,不同参数列表
int add(int a, int b) {std::cout << "调用int版本的add" << std::endl;return a + b;
}double add(double a, double b) {std::cout << "调用double版本的add" << std::endl;return a + b;
}int add(int a, int b, int c) {std::cout << "调用三参数版本的add" << std::endl;return a + b + c;
}std::string add(const std::string& a, const std::string& b) {std::cout << "调用string版本的add" << std::endl;return a + b;
}int main() {std::cout << "add(3, 4) = " << add(3, 4) << std::endl;std::cout << "add(3.5, 4.2) = " << add(3.5, 4.2) << std::endl;std::cout << "add(1, 2, 3) = " << add(1, 2, 3) << std::endl;std::cout << "add(\"Hello\", \"World\") = " << add("Hello", "World") << std::endl;return 0;
}

6.5 默认参数——灵活的函数调用

#include <iostream>
#include <string>// 默认参数:为参数提供默认值
void print_info(const std::string& name, int age = 18, const std::string& city = "北京",bool is_student = true) {std::cout << "姓名: " << name << std::endl;std::cout << "年龄: " << age << std::endl;std::cout << "城市: " << city << std::endl;std::cout << "身份: " << (is_student ? "学生" : "非学生") << std::endl;std::cout << "-------------------" << std::endl;
}int calculate_power(int base, int exponent = 2) {int result = 1;for(int i = 0; i < exponent; ++i) {result *= base;}return result;
}int main() {// 使用所有默认参数print_info("张三");// 覆盖部分默认参数print_info("李四", 25);print_info("王五", 30, "上海");print_info("赵六", 22, "广州", false);// 幂运算示例std::cout << "3的平方: " << calculate_power(3) << std::endl;std::cout << "3的立方: " << calculate_power(3, 3) << std::endl;std::cout << "2的10次方: " << calculate_power(2, 10) << std::endl;return 0;
}

6.6 内联函数——提高执行效率

#include <iostream>// 内联函数:建议编译器将函数调用替换为函数体
inline int max(int a, int b) {return (a > b) ? a : b;
}inline int square(int x) {return x * x;
}// 类中的内联函数
class Calculator {
public:// 类内定义的函数自动成为内联函数int cube(int x) {return x * x * x;}// 类外定义的内联函数需要explicit inlineinline int absolute(int x);
};inline int Calculator::absolute(int x) {return (x >= 0) ? x : -x;
}int main() {int a = 10, b = 20;std::cout << "max(" << a << ", " << b << ") = " << max(a, b) << std::endl;std::cout << "square(" << a << ") = " << square(a) << std::endl;Calculator calc;std::cout << "cube(" << a << ") = " << calc.cube(a) << std::endl;std::cout << "absolute(" << -a << ") = " << calc.absolute(-a) << std::endl;return 0;
}

6.7 递归函数——自我调用的艺术

#include <iostream>// 递归计算阶乘
unsigned long long factorial(int n) {// 基础情况(递归终止条件)if(n <= 1) {return 1;}// 递归情况return n * factorial(n - 1);
}// 递归计算斐波那契数列
int fibonacci(int n) {// 基础情况if(n <= 1) {return n;}// 递归情况return fibonacci(n - 1) + fibonacci(n - 2);
}// 递归计算最大公约数(欧几里得算法)
int gcd(int a, int b) {// 基础情况if(b == 0) {return a;}// 递归情况return gcd(b, a % b);
}int main() {// 阶乘计算for(int i = 0; i <= 10; ++i) {std::cout << i << "! = " << factorial(i) << std::endl;}std::cout << "\n斐波那契数列前10项:" << std::endl;for(int i = 0; i < 10; ++i) {std::cout << "F(" << i << ") = " << fibonacci(i) << std::endl;}// 最大公约数std::cout << "\n最大公约数示例:" << std::endl;std::cout << "gcd(48, 18) = " << gcd(48, 18) << std::endl;std::cout << "gcd(56, 42) = " << gcd(56, 42) << std::endl;return 0;
}

6.8 函数指针——函数的地址操作

#include <iostream>
#include <vector>
#include <algorithm>// 示例函数
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }// 高阶函数示例
int calculate(int x, int y, int (*operation)(int, int)) {return operation(x, y);
}// 回调函数示例
void process_array(int arr[], int size, void (*callback)(int)) {for(int i = 0; i < size; ++i) {callback(arr[i]);}
}void print_square(int x) {std::cout << x << "^2 = " << (x * x) << std::endl;
}int main() {// 函数指针声明和使用int (*func_ptr)(int, int);  // 声明函数指针func_ptr = add;  // 指向add函数std::cout << "10 + 5 = " << func_ptr(10, 5) << std::endl;func_ptr = subtract;  // 指向subtract函数std::cout << "10 - 5 = " << func_ptr(10, 5) << std::endl;func_ptr = multiply;  // 指向multiply函数std::cout << "10 * 5 = " << func_ptr(10, 5) << std::endl;// 使用高阶函数std::cout << "\n使用高阶函数:" << std::endl;std::cout << "calculate(10, 5, add) = " << calculate(10, 5, add) << std::endl;std::cout << "calculate(10, 5, multiply) = " << calculate(10, 5, multiply) << std::endl;// 回调函数示例std::cout << "\n回调函数示例:" << std::endl;int numbers[] = {1, 2, 3, 4, 5};process_array(numbers, 5, print_square);return 0;
}

6.9 Lambda表达式——匿名函数的魅力(C++11)

#include <iostream>
#include <vector>
#include <algorithm>int main() {// 基本Lambda表达式auto add = [](int a, int b) { return a + b; };std::cout << "Lambda加法: 5 + 3 = " << add(5, 3) << std::endl;// 捕获列表示例int multiplier = 10;// [=] 按值捕获所有外部变量auto multiply_by_lambda = [=](int x) { return x * multiplier; };std::cout << "按值捕获: 5 * " << multiplier << " = " << multiply_by_lambda(5) << std::endl;// [&] 按引用捕获所有外部变量auto increment_lambda = [&]() { multiplier++; };increment_lambda();std::cout << "按引用捕获后,multiplier = " << multiplier << std::endl;// 混合捕获int offset = 5;auto complex_lambda = [=, &offset](int x) { offset++;  // 可以修改引用捕获的变量return x * multiplier + offset; };std::cout << "混合捕获结果: " << complex_lambda(3) << std::endl;std::cout << "offset现在的值: " << offset << std::endl;// STL中使用Lambda表达式std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};// 使用Lambda进行筛选std::vector<int> even_numbers;std::copy_if(numbers.begin(), numbers.end(), std::back_inserter(even_numbers),[](int n) { return n % 2 == 0; });std::cout << "\n偶数: ";for(const auto& num : even_numbers) {std::cout << num << " ";}std::cout << std::endl;// 使用Lambda进行排序std::vector<std::string> names = {"Alice", "Bob", "Charlie", "David"};std::sort(names.begin(), names.end(), [](const std::string& a, const std::string& b) {return a.length() < b.length();});std::cout << "按长度排序: ";for(const auto& name : names) {std::cout << name << " ";}std::cout << std::endl;return 0;
}

6.10 函数模板——通用函数的设计

#include <iostream>
#include <string>// 函数模板:创建适用于多种类型的通用函数
template<typename T>
T max_value(T a, T b) {return (a > b) ? a : b;
}// 多参数类型模板
template<typename T, typename U>
auto multiply_and_add(T x, U y, U z) -> decltype(x * y + z) {return x * y + z;
}// 特化模板
template<>
const char* max_value<const char*>(const char* a, const char* b) {return (strcmp(a, b) > 0) ? a : b;
}// 可变参数模板(C++11)
template<typename T>
T sum(T value) {return value;
}template<typename T, typename... Args>
T sum(T first, Args... args) {return first + sum(args...);
}int main() {// 使用函数模板std::cout << "max_value(3, 5): " << max_value(3, 5) << std::endl;std::cout << "max_value(3.14, 2.71): " << max_value(3.14, 2.71) << std::endl;std::cout << "max_value('apple', 'banana'): " << max_value("apple", "banana") << std::endl;// 多参数类型模板std::cout << "multiply_and_add(3, 4.5, 2): " << multiply_and_add(3, 4.5, 2) << std::endl;// 可变参数模板std::cout << "sum(1, 2, 3, 4, 5): " << sum(1, 2, 3, 4, 5) << std::endl;std::cout << "sum(1.1, 2.2, 3.3): " << sum(1.1, 2.2, 3.3) << std::endl;return 0;
}

6.11 现代C++函数特性——更安全更便捷

#include <iostream>
#include <memory>// 使用auto作为返回类型(C++14)
auto calculate_area(double radius) {return 3.14159 * radius * radius;
}// constexpr函数(编译时计算)
constexpr int factorial_constexpr(int n) {return (n <= 1) ? 1 : n * factorial_constexpr(n - 1);
}// noexcept说明符
int safe_divide(int a, int b) noexcept {return (b != 0) ? a / b : 0;
}// 函数参数包展开
template<typename... Args>
void print_all(Args... args) {((std::cout << args << " "), ...);  // C++17折叠表达式std::cout << std::endl;
}int main() {// auto返回类型auto circle_area = calculate_area(5.0);std::cout << "半径为5的圆面积: " << circle_area << std::endl;// constexpr函数在编译时计算constexpr int fact5 = factorial_constexpr(5);std::cout << "5的阶乘(编译时计算): " << fact5 << std::endl;// noexcept函数std::cout << "safe_divide(10, 2): " << safe_divide(10, 2) << std::endl;std::cout << "safe_divide(10, 0): " << safe_divide(10, 0) << std::endl;// 参数包展开std::cout << "打印所有参数: ";print_all(1, 3.14, "Hello", 'A');return 0;
}

6.12 函数设计最佳实践

#include <iostream>
#include <vector>
#include <stdexcept>// 1. 函数应该单一职责
// 好的设计:每个函数只做一件事
int find_max(const std::vector<int>& numbers) {if(numbers.empty()) {throw std::invalid_argument("Vector is empty");}int max_val = numbers[0];for(size_t i = 1; i < numbers.size(); ++i) {if(numbers[i] > max_val) {max_val = numbers[i];}}return max_val;
}// 2. 合理使用const
void print_vector(const std::vector<int>& vec) {for(const auto& element : vec) {std::cout << element << " ";}std::cout << std::endl;
}// 3. 提供有意义的函数名
bool is_even(int number) {return number % 2 == 0;
}bool is_positive(int number) {return number > 0;
}// 4. 合理处理错误情况
enum class ResultCode {SUCCESS,INVALID_INPUT,OUT_OF_RANGE
};ResultCode validate_age(int age) {if(age < 0) {return ResultCode::INVALID_INPUT;}if(age > 150) {return ResultCode::OUT_OF_RANGE;}return ResultCode::SUCCESS;
}int main() {try {std::vector<int> numbers = {3, 7, 2, 9, 1, 8};std::cout << "数组内容: ";print_vector(numbers);std::cout << "最大值: " << find_max(numbers) << std::endl;int test_number = 42;std::cout << test_number << (is_even(test_number) ? " 是" : " 不是") << "偶数" << std::endl;std::cout << test_number << (is_positive(test_number) ? " 是" : " 不是") << "正数" << std::endl;// 错误处理示例int ages[] = {-5, 25, 200};for(int age : ages) {auto result = validate_age(age);switch(result) {case ResultCode::SUCCESS:std::cout << "年龄 " << age << " 有效" << std::endl;break;case ResultCode::INVALID_INPUT:std::cout << "年龄 " << age << " 无效(负数)" << std::endl;break;case ResultCode::OUT_OF_RANGE:std::cout << "年龄 " << age << " 超出范围" << std::endl;break;}}} catch(const std::exception& e) {std::cerr << "错误: " << e.what() << std::endl;}return 0;
}

6.13 本章小结

本章深入探讨了C++函数的各种特性和使用方法:

  1. 函数基础:定义、声明、调用的基本语法
  2. 参数传递:值传递、引用传递、指针传递的区别
  3. 函数重载:同一函数名的多种实现
  4. 默认参数:提供灵活的函数接口
  5. 内联函数:优化函数调用性能
  6. 递归函数:自我调用解决问题的方法
  7. 函数指针:函数作为一等公民的体现
  8. Lambda表达式:现代C++的匿名函数特性
  9. 函数模板:创建通用函数的技术
  10. 现代特性:auto返回类型、constexpr函数等

函数是C++程序的基本构建块,掌握函数的各种特性对于编写高质量、可维护的代码至关重要。合理的函数设计不仅能提高代码复用性,还能增强程序的可读性和可维护性。


专栏预告:第七章将介绍作用域和存储类,深入探讨变量的生命周期、链接性和存储持续时间等重要概念,帮助读者更好地理解C++的内存模型。

http://www.dtcms.com/a/597539.html

相关文章:

  • 【学习记录】ros2中处理livox_ros_driver1格式的msg
  • 仙游县住房和城乡建设局网站wordpress编辑角色无法上传图片
  • 邮箱类网站模板智联招聘官方网
  • 台湾旺久PL27A1芯片参数|USB3.0对拷线方案芯片|PL27A1对拷线芯片规格书
  • 开源企业建站系统哪个好广州网站建设q479185700棒
  • 网站开发制作流程中国招商网
  • 复杂网络入门到精通5:网络动力学
  • 【论文阅读】PhotoBot: Reference-Guided Interactive Photography via Natural Language
  • Alpha稳定分布概率密度函数的MATLAB实现
  • 国内做网站好的公司淄博做网站小程序的公司
  • Python处理 “列表套字典” 结构JSON数据的三种方式对比
  • 广州市官网网站建设公司详情页模板尺寸
  • 深度学习_神经网络_损失函数基础
  • Centos7.9创建新用户,授权远程登录,禁用root远程登录
  • 柔性软风管-连续测量十分便利
  • 手机网站优化排名首页浏阳seo
  • 辽宁住房与城乡建设厅网站网站单子
  • python类的内置函数
  • chrome的Network上经常看不到网络请求,解决方案
  • 复现------
  • 专业网站建设制作多少钱江门网站建设技术托管
  • 基于MATLAB的POD-DMD联合分析实现方案
  • saas 平台架构做网站简述建设一个网站的具体步骤6
  • 均安公司网站建设wordpress tag做专题
  • 邯郸手机网站开发价格怎样找做淘宝客的网站
  • Linux系统编程——进程通信之无名管道
  • 基于springboot高校办公室行政事务管理系统【带源码和文档】
  • Amplitude使用记录
  • 云南建网站需要多少钱莱芜雪野湖别墅
  • 慢查询日志在性能优化中的价值