🧠 C++ 函数教程(零基础也能看懂)

📚 从函数是什么,到怎么写函数,手把手带你入门!


🔰 一、什么是函数?

在编程中,函数(Function) 就像一个“小工厂”——你给它一些原料(输入),它按照规则加工后给你成品(输出)。

✅ 简单理解:

  • 函数 = 功能块
  • 把重复使用的代码封装起来,方便以后调用。
  • 像数学中的 f(x) = x + 1 一样,给它一个值,它返回结果。

💡 二、为什么要使用函数?

好处 解释
🔄 复用性高 写一次,可以多次调用
🧹 结构清晰 让代码更整洁,容易维护
🎯 模块化设计 把大问题拆成小问题,逐个解决

🛠️ 三、函数的定义格式(语法)

返回类型 函数名(参数列表) {
    // 函数体:你要执行的代码
    return 返回值;
}

🧾 示例:

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

🧩 四、函数的组成部分详解

1. 返回类型(Return Type)

表示这个函数会返回什么类型的数据。例如:

  • int → 整数
  • double → 浮点数
  • void → 不返回任何内容

2. 函数名(Function Name)

自定义的名字,要简短有意义,符合命名规范(如 add, printHello)。

3. 参数列表(Parameters)

括号里是传入函数的数据,可以有多个参数,也可以没有参数。

👉 参数就像原材料,供函数内部使用。

4. 函数体(Function Body)

花括号 {} 中的内容,就是函数实际要做的事情。

5. return 返回值

函数执行完后,把结果返回给调用者。


🧪 五、函数的使用步骤(完整例子)

📘 示例:计算两个数的和

#include <iostream>
using namespace std;

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

int main() {
    // 调用函数
    int result = add(3, 5);
    cout << "3 + 5 = " << result << endl;

    return 0;
}

✅ 输出结果:

3 + 5 = 8

📌 六、函数的分类(常见类型)

1. 无参数无返回值

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

2. 有参数无返回值

void printSum(int a, int b) {
    cout << "Sum is: " << a + b << endl;
}

3. 有参数有返回值

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

🧱 七、函数调用流程图解(文字版)

main函数开始
     ↓
调用add函数(传入3和5)
     ↓
add函数执行a + b
     ↓
返回8
     ↓
main函数接收并打印

🧑‍🏫 八、函数的注意事项(新手常踩坑的地方)

注意事项 说明
📝 函数必须先定义再使用 否则编译器不认识你写的函数
🧮 参数顺序不能错 传参时要和定义一致
🔄 函数不能嵌套定义 C++不允许在一个函数里定义另一个函数
📌 void 表示不返回值 如果不需要返回值,就用 void 声明

🧰 九、实战练习题(附答案)

✅ 题目1:写一个函数,判断一个数是否为偶数

bool isEven(int num) {
    return num % 2 == 0;
}

✅ 题目2:写一个函数,返回三个数中的最大值

int maxOfThree(int a, int b, int c) {
    if (a > b && a > c)
        return a;
    else if (b > c)
        return b;
    else
        return c;
}

🧠 十、总结(函数要点一览表)

项目 内容
函数作用 封装代码、提高复用性
函数组成 返回类型、函数名、参数、函数体、return
函数调用 在main函数中调用即可
注意事项 先定义、参数顺序正确、不能嵌套定义

🎯 十一、鼓励语

同学们,函数就像是我们程序的积木块,学会写函数,你就掌握了编程的核心能力之一!不要怕写错,多练多改,你一定能写出漂亮的函数!加油!💪


📘 下节课预告:数组与函数结合使用
📌 想知道怎么让函数处理一组数据吗?下一讲我们将学习如何用函数操作数组!

13 条评论

  • @ 2025-6-15 16:30:20

    在 C、C++、Go 等常见语言里,结构体作为参数传递时,默认是“值传递”还是“引用传递”,得看语言规则和你怎么写代码,下面分语言举例说明核心逻辑:

    1. C/C++ 里的默认行为

    • 默认是“值传递”
      定义一个结构体,直接当参数传给函数时,会拷贝一份结构体的完整数据到函数里。修改函数内的结构体,不影响外面的原结构体。
      示例(C++):

      #include <iostream>
      using namespace std;
      
      struct Person {
          string name;
          int age;
      };
      
      void changePerson(Person p) {
          p.age = 100;  // 修改的是拷贝后的结构体
      }
      
      int main() {
          Person tom = {"Tom", 20};
          changePerson(tom);
          // 输出还是 20,因为传参是值拷贝
          cout << tom.age << endl;  
          return 0;
      }
      
    • 想改成“引用传递”
      得显式用指针Person* p)或引用Person& p)当参数,这样函数里操作的就是原结构体的“引用”,修改会影响外部。

    2. Go 语言里的默认行为

    • 默认也是“值传递”
      传结构体给函数时,Go 会拷贝整个结构体的值。如果结构体很大,拷贝代价高,通常会用指针(*Person)传参,变相实现“引用传递”的效果(本质还是值传递,只是拷贝的是指针地址,代价低)。
      示例:

      package main
      
      import "fmt"
      
      type Person struct {
          Name string
          Age  int
      }
      
      func changePerson(p Person) {
          p.Age = 100  // 修改的是拷贝后的结构体
      }
      
      func main() {
          tom := Person{"Tom", 20}
          changePerson(tom)
          // 输出 20,原结构体没被改
          fmt.Println(tom.Age)  
      }
      
    • 用指针实现“引用效果”
      把参数改成 func changePerson(p *Person),调用时传 &tom,函数里用 p.Age 访问、修改,就会影响外部原结构体。

    3. Python 里的特殊情况(没有“结构体”,但类/数据类类似)

    Python 里没有传统“结构体”,但用 class 定义的对象,默认传的是“引用”(更准确说叫“对象引用的传递”) 。函数里修改对象的属性,会影响外部的原对象。
    示例:

    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    def change_person(p):
        p.age = 100  # 直接修改原对象的属性
    
    tom = Person("Tom", 20)
    change_person(tom)
    # 输出 100,原对象被修改了
    print(tom.age)  
    

    (Python 里的“传参”逻辑是:传不可变对象(如 intstr )是值传递;传可变对象(如 listclass 实例 )是“引用传递”效果,但本质是共享对象引用。)

    一句话总结

    • C/C++、Go 里,结构体默认是“值传递”(拷贝数据);想改引用效果,得用指针/引用语法。
    • Python 里类似结构体的“对象”,默认传的是“引用”(操作会影响原对象),但底层逻辑和传统“引用传递”有区别(更侧重对象引用的共享 )。

    简单说:大部分语言里,结构体/对象默认传参的“值传递 vs 引用传递”,得看语言设计,写代码时要注意区分,避免逻辑错误~

    • @ 2025-6-15 16:25:07
      #include<iostream>
      using namespace std;
      void printArray(int arr[], int size) {
      //void printArray(int *arr, int size) {
      	for (int i = 0; i < size; i++) {
      		cout << arr[i] << " ";
      	}
      	cout << endl;
      }
      
      int main() {
      	int nums[] = {1, 2, 3, 4, 5};
      	printArray(nums, 5);  // 输出:1 2 3 4 5
      	
      	return 0;
      }
      
      
      
      
      
      • @ 2025-6-15 16:09:37
        #include<iostream>
        using namespace std;
        void func(int a){
        	cout<<"int"<<endl;
        }
        void func(double a){
        	cout<<"double"<<endl;
        }
        void func(char a){
        	cout<<"char"<<endl;
        }
        int main() {
        	func(4.5);
        	func(4);
        	func('a');
        	//func("str");
        	return 0;
        }
        
        
        
        
        
        • @ 2025-5-29 20:41:32
          #include <iostream>
          #include <string>
          using namespace std;
          
          template <typename T = int>
          T multiply(T a, T b) {
          	return a * b;
          }
          
          int main() {
          	int res1 = multiply(5, 3);      // T= int(默认)
          	cout<<res1<<endl;
          	double res2 = multiply(5.4, 3.7);   
          	cout<<res2<<endl;
          	double res3 = multiply<double>(2.5, 4.0); // T= double
          	cout<<res3<<endl;
          	return 0;
          }
          
          
          • @ 2025-5-29 20:33:07
            #include <iostream>
            #include <string>
            using namespace std;
            
            // 定义函数模板:求两个数的最大值
            template <typename T>
            T max1(T a, T b) {
            	return a > b ? a : b;
            }
            
            int main() {
            	// 自动类型推导调用
            	int i = max1(10, 20);           // 生成int max(int, int)
            	double d = max1(3.14, 2.71);    // 生成double max(double, double)
            	string s = max1("apple", "banana"); // 生成string max(string, string)
            	
            	cout << i << endl;   // 输出20
            	cout << d << endl;   // 输出3.14
            	cout << s << endl;   // 输出banana(按字典序比较)
            	
            	// 显式指定类型调用
            	double x = max1<double>(5, 3);  // 等价于max(5, 3)
            	cout<<sizeof(max1<double>(5, 3))<<endl;
            	return 0;
            }
            
            
            • @ 2025-5-29 20:28:13
              #include<iostream>
              using namespace std;
              // 示例:求最大值的函数模板
              template <typename T>
              T max1(T a, T b) {
              	return a > b ? a : b;
              }
              int main() {
              	cout<<max1(4,6)<<endl;
              	cout<<max1(4.5,5.6)<<endl;
              	return 0;
              }
              
              • @ 2025-5-29 20:23:17
                #include <iostream>
                using namespace std;
                // 函数1
                void func(char ch){
                	cout<<"#1"<<endl;
                }
                // 函数3
                void func(long m){
                	cout<<"#3"<<endl;
                }
                // 函数4
                void func(double f){
                	cout<<"#4"<<endl;
                }
                int main(){
                	short s = 99;
                	float f = 84.6;
                	
                	func('a'); // 精确匹配func(char),输出#1
                	func((long)s);   // 这里会出现问题,short可转换为int、long等,编译器不知道匹配哪个函数
                	func(49L);  // 同样,49是int,可转换为long等,编译器无法确定调用哪个函数
                	func(f);   // 将float转换成double,调用func(double),输出#4
                	return 0;
                }
                
                
                • @ 2025-5-29 20:16:06

                  海伦公式: 假设在平面内,有一个三角形,边长分别为a、b、c,三角形的面积S可由以下公式求得:

                  而公式里的p为半周长(周长的一半):

                  • @ 2025-5-29 20:11:39

                    一、函数重载的概念

                    在C++中,函数重载允许在同一个作用域(比如同一个类、同一个命名空间等)内定义多个同名函数,只要它们的参数列表不同即可。参数列表也叫参数签名,包括参数的类型、个数和顺序,只要其中有一个不同,就认为参数列表不同。函数的返回类型可以相同也可以不同,但仅返回类型不同不能作为函数重载的依据。

                    借助函数重载,一个函数名可以有多种用途。例如在实际开发中,可能需要交换不同类型变量的值,如intfloatchar等类型。在C语言中可能需要分别定义不同名字的函数来实现,但在C++中通过函数重载,使用同一个函数名就可以实现 。

                    二、函数重载的规则

                    1. 函数名相同:所有重载函数必须具有相同的函数名。
                    2. 参数列表不同:参数的类型、个数或顺序至少有一个方面存在差异。例如:
                    void func(int a);          // 参数为int类型
                    void func(double b);       // 参数为double类型,与上一个函数参数类型不同,构成重载
                    void func(int a, double b); // 参数个数和顺序与前面函数不同,构成重载
                    
                    1. 返回类型无关:函数的返回类型可以相同也可以不同,但仅返回类型不同不能构成函数重载。比如下面这种情况是不合法的:
                    int func(int a);
                    double func(int a); // 错误,仅返回类型不同,不构成重载
                    
                    1. 作用域相同:重载的函数必须定义在同一个作用域内,比如都在全局作用域,或者都在同一个类的内部等。

                    三、函数重载示例

                    以下是通过函数重载实现计算不同图形面积的示例:

                    #include <iostream>
                    #include <cmath>
                    using namespace std;
                    
                    // 计算圆形面积
                    double calculateArea(double radius) {
                        return 3.14159 * radius * radius;
                    }
                    
                    // 计算矩形面积
                    double calculateArea(double length, double width) {
                        return length * width;
                    }
                    
                    // 计算三角形面积(使用海伦公式)
                    double calculateArea(double base, double height, double side1, double side2) {
                        double s = (base + height + side1 + side2) / 2;
                        return sqrt(s * (s - base) * (s - height) * (s - side1) * (s - side2));
                    }
                    int main() {
                        double circleRadius = 5.0;
                        double rectangleLength = 4.0, rectangleWidth = 3.0;
                        double triangleBase = 3.0, triangleHeight = 4.0, triangleSide1 = 5.0, triangleSide2 = 6.0;
                    
                        cout << "圆形面积: " << calculateArea(circleRadius) << endl;
                        cout << "矩形面积: " << calculateArea(rectangleLength, rectangleWidth) << endl;
                        cout << "三角形面积: " << calculateArea(triangleBase, triangleHeight, triangleSide1, triangleSide2) << endl;
                    
                        return 0;
                    }
                    

                    在这个示例中,calculateArea函数被重载了三次,分别用于计算圆形、矩形和三角形的面积,编译器会根据传入参数的不同来调用相应的函数。

                    四、C++实现函数重载的原理

                    C++代码在编译时,编译器会根据参数列表对函数进行重命名。例如void Swap(int a, int b)可能会被重命名为_Swap_int_intvoid Swap(float x, float y)可能会被重命名为_Swap_float_float 。当发生函数调用时,编译器会根据传入的实参去逐个匹配这些重命名后的函数,以选择对应的函数,如果匹配失败,编译器就会报错,这个过程叫做重载决议(Overload Resolution) 。不同的编译器重命名方式可能不同。

                    五、函数重载过程中的二义性和类型转换问题

                    当实参的类型和形参的类型不一致时,编译器需要进行类型转换来匹配函数,这可能会导致一些复杂情况。例如:

                    #include <iostream>
                    using namespace std;
                    // 函数1
                    void func(char ch){
                        cout<<"#1"<<endl;
                    }
                    // 函数3
                    void func(long m){
                        cout<<"#3"<<endl;
                    }
                    // 函数4
                    void func(double f){
                        cout<<"#4"<<endl;
                    }
                    int main(){
                        short s = 99;
                        float f = 84.6;
                    
                        func('a'); // 精确匹配func(char),输出#1
                        func(s);   // 这里会出现问题,short可转换为int、long等,编译器不知道匹配哪个函数
                        func(49);  // 同样,49是int,可转换为long等,编译器无法确定调用哪个函数
                        func(f);   // 将float转换成double,调用func(double),输出#4
                        return 0;
                    }
                    

                    C++标准规定,在进行重载决议时编译器按照以下优先级顺序来处理实参的类型:

                    1. 精确匹配:不做类型转换,直接匹配。
                    2. 微不足道的转换:例如从数组名到数组指针、从函数名到指向函数的指针、从非const类型到const类型等转换 。

                    在编写重载函数时,要尽量避免出现这种让编译器难以抉择的情况,以防止出现二义性错误。

                    六、函数重载的优势与注意事项

                    • 优势
                      • 提高代码可读性:通过使用同一个函数名来处理相似功能,使代码更直观易懂。比如都用calculateArea表示计算面积相关操作,而不是定义多个不同名的面积计算函数。
                      • 增强代码复用性:减少了为相似功能编写大量不同名称函数的工作,提高了代码的复用程度。
                    • 注意事项
                      • 避免命名冲突:确保在同一作用域内,不会出现参数列表完全相同的重载函数,否则编译器会报错。
                      • 合理使用默认参数:注意默认参数与函数重载结合使用时可能产生的问题,例如可能导致调用的不确定性。
                      • 避免过度重载:过多的重载函数可能会降低代码的可读性和可维护性,也可能影响编译时间 。
                    • @ 2025-5-28 20:00:18

                      C++ 函数模板(Function Templates)完全指南

                      一、为什么需要函数模板?

                      假设我们需要实现一个求两个数最大值的函数:

                      • 对于int类型:int maxInt(int a, int b) { return a > b ? a : b; }
                      • 对于double类型:double maxDouble(double a, double b) { ... }
                      • 对于string类型:string maxString(string a, string b) { ... }

                      问题:功能相同但类型不同的函数需要重复编写,代码冗余。
                      解决方案:使用函数模板,让编译器自动生成对应类型的函数。

                      二、函数模板的基本语法

                      // 模板定义
                      template <typename 类型参数>
                      返回类型 函数名(参数列表) {
                          // 函数体(使用类型参数)
                      }
                      
                      // 示例:求最大值的函数模板
                      template <typename T>
                      T max(T a, T b) {
                          return a > b ? a : b;
                      }
                      

                      三、函数模板的使用示例

                      #include <iostream>
                      #include <string>
                      using namespace std;
                      
                      // 定义函数模板:求两个数的最大值
                      template <typename T>
                      T max(T a, T b) {
                          return a > b ? a : b;
                      }
                      
                      int main() {
                          // 自动类型推导调用
                          int i = max(10, 20);           // 生成int max(int, int)
                          double d = max(3.14, 2.71);    // 生成double max(double, double)
                          string s = max("apple", "banana"); // 生成string max(string, string)
                          
                          cout << i << endl;   // 输出20
                          cout << d << endl;   // 输出3.14
                          cout << s << endl;   // 输出banana(按字典序比较)
                          
                          // 显式指定类型调用
                          int x = max<int>(5, 3);  // 等价于max(5, 3)
                          return 0;
                      }
                      

                      四、模板参数的多种形式

                      1. 单个类型参数(如typename T
                      2. 多个类型参数
                      template <typename T, typename U>
                      T add(T a, U b) {  // 允许不同类型参数
                          return a + b;
                      }
                      
                      int main() {
                          double result = add(10, 3.5); // 生成add<int, double>(int, double)
                          cout << result << endl; // 输出13.5
                          return 0;
                      }
                      
                      1. 默认类型参数(C++11支持):
                      template <typename T = int>
                      T multiply(T a, T b) {
                          return a * b;
                      }
                      
                      int main() {
                          int res1 = multiply(5, 3);      // T= int(默认)
                          double res2 = multiply<double>(2.5, 4.0); // T= double
                          return 0;
                      }
                      

                      五、函数模板与普通函数的区别

                      特性 普通函数 函数模板
                      定义方式 直接声明类型 需要template关键字
                      类型处理 处理固定类型 类型在调用时确定
                      实例化时机 编译时直接存在 调用时生成对应类型的函数
                      代码复用 功能相同的不同类型需重复编写 一套代码处理所有类型
                      类型安全 编译时检查类型 同样具有类型检查

                      六、函数模板的实例化过程

                      1. 调用模板函数max(10, 20);
                      2. 编译器推导类型:确定Tint
                      3. 生成具体函数
                      int max(int a, int b) {
                          return a > b ? a : b;
                      }
                      
                      1. 执行函数:返回20

                      七、函数模板的限制与注意事项

                      1. 类型必须支持函数体内的操作
                      template <typename T>
                      T add(T a, T b) {
                          return a + b; // T必须支持+运算符
                      }
                      

                      错误用法:对自定义类调用add,若类未重载+运算符会编译错误。

                      1. 模板参数推导规则

                        • 优先匹配普通函数,若没有匹配才使用模板
                        • 可显式指定类型:max<double>(3.1, 2.5)
                      2. 模板不是宏

                        • 宏是简单文本替换(无类型检查)
                        • 模板是类型安全的泛型编程工具

                      八、实战案例:实现通用交换函数

                      #include <iostream>
                      using namespace std;
                      
                      // 交换函数模板
                      template <typename T>
                      void swap(T& a, T& b) {
                          T temp = a;
                          a = b;
                          b = temp;
                      }
                      
                      int main() {
                          // 交换整数
                          int x = 10, y = 20;
                          swap(x, y);
                          cout << "x=" << x << ", y=" << y << endl; // 输出x=20, y=10
                          
                          // 交换字符串
                          string s1 = "apple", s2 = "banana";
                          swap(s1, s2);
                          cout << "s1=" << s1 << ", s2=" << s2 << endl; // 输出s1=banana, s2=apple
                          
                          return 0;
                      }
                      

                      九、进阶:函数模板与函数重载

                      当模板无法处理特定类型时,可重载普通函数:

                      #include <iostream>
                      #include <cstring>
                      using namespace std;
                      
                      // 通用模板
                      template <typename T>
                      T max(T a, T b) {
                          return a > b ? a : b;
                      }
                      
                      // 重载:处理C风格字符串(char*)
                      const char* max(const char* a, const char* b) {
                          return strcmp(a, b) > 0 ? a : b;
                      }
                      
                      int main() {
                          cout << max("hello", "world") << endl; // 调用重载函数,输出world
                          cout << max<int>(5, 3) << endl;        // 调用模板函数,输出5
                          return 0;
                      }
                      

                      十、练习题

                      1. 编写模板函数min(T a, T b),返回两个数的最小值。
                      2. 实现模板函数printArray(T arr[], int n),打印数组所有元素。
                      3. 设计模板函数isEqual(T a, T b),判断两个值是否相等(需考虑==运算符支持)。

                      十一、总结

                      函数模板是C++泛型编程的基础,它允许用一套代码处理多种数据类型,避免重复编写相似功能的函数。通过template关键字和类型参数(如typename T),编译器会在调用时自动生成对应类型的函数,既保证了类型安全,又提高了代码复用性。

                      掌握函数模板后,后续可进一步学习类模板(Class Templates),实现更复杂的泛型数据结构(如vector、map等STL容器)。

                      • @ 2025-5-28 19:59:34

                        🧠 C++ 函数模板(Function Templates)

                        📚 一文看懂函数模板,零基础也能轻松掌握!


                        💡 一、什么是函数模板?

                        在C++中,函数模板就像是一个“万能公式”,可以让你写出适用于多种数据类型的通用函数,而不需要为每种类型都单独写一遍。

                        ✅ 简单理解:

                        • 函数模板 = 写一次,多种类型都能用
                        • 类似于数学中的通用公式:f(x, y) = x + y,不管x和y是整数、浮点数还是字符串,都可以使用

                        🔍 二、为什么要使用函数模板?

                        好处 说明
                        🔄 代码复用 同一个函数逻辑可以用于不同数据类型
                        🧹 减少重复代码 避免为 intdoublestring 等分别写多个函数
                        🎯 提高可维护性 修改一处,影响所有类型

                        🛠️ 三、函数模板的基本语法

                        template <typename T>
                        返回类型 函数名(T 参数1, T 参数2, ...) {
                            // 函数体
                            return 返回值;
                        }
                        
                        • template <typename T>:定义一个模板,T 是一个占位符类型
                        • 在调用时,编译器会根据传入的参数自动推导出具体类型

                        🧪 四、函数模板示例讲解

                        ✅ 示例1:实现两个值的最大值比较

                        #include <iostream>
                        using namespace std;
                        
                        // 定义模板函数
                        template <typename T>
                        T maxVal(T a, T b) {
                            return (a > b) ? a : b;
                        }
                        
                        int main() {
                            cout << "max int: " << maxVal(3, 5) << endl;        // 输出:5
                            cout << "max double: " << maxVal(3.5, 2.8) << endl; // 输出:3.5
                            cout << "max char: " << maxVal('a', 'z') << endl;   // 输出:z
                        
                            return 0;
                        }
                        

                        📌 说明

                        • 编译器会自动为 intdoublechar 分别生成对应的函数版本
                        • 不需要手动重载多个函数

                        🧩 五、函数模板的注意事项

                        注意事项 解释
                        ⚠️ 类型必须支持操作 如果你用了 > 操作符,那传入的类型必须支持这个运算
                        ⚠️ 不能自动匹配不同类型 maxVal(3, 5.6) 会报错,因为 T 要求统一类型
                        ⚠️ 命名规范建议 通常使用 T 表示类型,也可以用其他名字如 Type

                        🔄 六、函数模板与函数重载的区别

                        对比项 函数模板 函数重载
                        使用方式 自动推导类型 手动编写多个函数
                        适用范围 多个类型共享同一套逻辑 每个类型单独处理
                        可读性 更简洁 更直观但冗余
                        维护难度 易维护 修改多个函数麻烦

                        🧰 七、实战练习题(附答案)

                        ✅ 题目1:写一个模板函数,交换两个变量的值

                        template <typename T>
                        void swapValues(T &a, T &b) {
                            T temp = a;
                            a = b;
                            b = temp;
                        }
                        
                        int main() {
                            int x = 10, y = 20;
                            swapValues(x, y);
                            cout << "x = " << x << ", y = " << y << endl;  // 输出:x = 20, y = 10
                        
                            double a = 3.14, b = 2.71;
                            swapValues(a, b);
                            cout << "a = " << a << ", b = " << b << endl;  // 输出:a = 2.71, b = 3.14
                        
                            return 0;
                        }
                        

                        ✅ 题目2:写一个模板函数,打印数组内容

                        #include <iostream>
                        using namespace std;
                        
                        template <typename T>
                        void printArray(T arr[], int size) {
                            for(int i = 0; i < size; i++) {
                                cout << arr[i] << " ";
                            }
                            cout << endl;
                        }
                        
                        int main() {
                            int intArr[] = {1, 2, 3};
                            double doubleArr[] = {1.1, 2.2, 3.3};
                            char charArr[] = {'a', 'b', 'c'};
                        
                            printArray(intArr, 3);      // 输出:1 2 3
                            printArray(doubleArr, 3);   // 输出:1.1 2.2 3.3
                            printArray(charArr, 3);     // 输出:a b c
                        
                            return 0;
                        }
                        

                        🧠 八、总结(函数模板要点一览表)

                        知识点 内容
                        模板关键字 template <typename T>
                        函数模板作用 实现多类型通用逻辑
                        注意事项 类型需支持对应操作,不支持混合类型
                        优势 代码复用、结构清晰、易于维护
                        与重载区别 自动适配 vs 手动适配

                        🎯 九、鼓励语

                        同学们,函数模板就像魔法一样,让你写出“一次编写,处处可用”的强大代码!它不仅节省时间,还能提升你的编程思维。继续加油,你离高手只差几个函数模板的距离!💪


                        📘 下节课预告:类与对象入门(面向对象编程基础)
                        📌 想知道如何把现实世界的事物映射到程序中?下一讲我们将一起进入 OOP 的世界!

                        • @ 2025-5-28 19:58:57

                          🧠 C++ 函数进阶教程(零基础也能看懂)

                          📚 函数的参数传递、函数重载、函数调用详解


                          🔁 一、函数参数传递方式

                          在C++中,函数的参数可以有多种传递方式:

                          1. 值传递(Pass by Value)

                          void changeValue(int x) {
                              x = 100;
                          }
                          
                          int main() {
                              int a = 5;
                              changeValue(a);
                              cout << a;  // 输出:5
                          }
                          

                          📌 解释

                          • 值传递是把变量的值复制一份传给函数。
                          • 函数内部修改的是副本,不会影响原始变量。

                          2. 引用传递(Pass by Reference)

                          void changeValue(int &x) {
                              x = 100;
                          }
                          
                          int main() {
                              int a = 5;
                              changeValue(a);
                              cout << a;  // 输出:100
                          }
                          

                          📌 解释

                          • 引用传递是直接操作原始变量。
                          • 函数内部对参数的修改会影响原变量。

                          使用场景

                          • 想要改变实参的值时。
                          • 传递大型对象(如结构体、类)时,避免复制浪费内存。

                          3. 指针传递(Pass by Pointer)

                          void changeValue(int *x) {
                              *x = 100;
                          }
                          
                          int main() {
                              int a = 5;
                              changeValue(&a);
                              cout << a;  // 输出:100
                          }
                          

                          📌 解释

                          • 把变量的地址传入函数。
                          • 通过指针间接访问和修改变量。

                          使用场景

                          • 需要修改原始数据。
                          • 动态内存管理、数组操作等高级功能中常用。

                          🔍 二、函数重载(Function Overloading)

                          同一个函数名,根据参数类型或个数不同,执行不同的操作。

                          ✅ 示例:

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

                          🧪 使用:

                          cout << add(2, 3) << endl;       // 调用 int add(int, int)
                          cout << add(2.5, 3.1) << endl;   // 调用 double add(double, double)
                          cout << add("Hello ", "World") << endl;  // 调用 string add(string, string)
                          

                          📌 注意

                          • 不能仅靠返回值不同来重载函数。
                          • 编译器会根据传入的参数自动选择匹配的函数。

                          🔄 三、函数默认参数(Default Arguments)

                          给函数参数设置默认值,如果不传参就使用默认值。

                          ✅ 示例:

                          void greet(string name = "Guest") {
                              cout << "Hello, " << name << "!" << endl;
                          }
                          

                          🧪 使用:

                          greet();           // 输出:Hello, Guest!
                          greet("Tom");      // 输出:Hello, Tom!
                          

                          📌 注意

                          • 默认参数必须放在参数列表最后。
                          • 可以为多个参数设置默认值。

                          🎮 四、递归函数(Recursion)

                          函数自己调用自己,常用于解决分治问题(如斐波那契数列、阶乘等)。

                          ✅ 示例:计算阶乘

                          int factorial(int n) {
                              if (n == 0 || n == 1) {
                                  return 1;
                              }
                              return n * factorial(n - 1);
                          }
                          

                          🧪 使用:

                          cout << factorial(5);  // 输出:120
                          

                          📌 注意

                          • 必须有一个“终止条件”,否则会导致无限递归。
                          • 递归虽然简洁,但效率不如循环,慎用!

                          🧩 五、函数与数组结合使用

                          数组作为参数传递时,实际上是传递了数组的首地址。

                          ✅ 示例:打印数组内容

                          void printArray(int arr[], int size) {
                              for (int i = 0; i < size; i++) {
                                  cout << arr[i] << " ";
                              }
                              cout << endl;
                          }
                          

                          🧪 使用:

                          int nums[] = {1, 2, 3, 4, 5};
                          printArray(nums, 5);  // 输出:1 2 3 4 5
                          

                          📌 说明

                          • arr[] 实际上是一个指针。
                          • 在函数中无法获取数组长度,必须手动传入大小。

                          🧱 六、函数与结构体结合使用

                          结构体也可以作为函数参数传递。

                          ✅ 示例:

                          struct Student {
                              string name;
                              int age;
                          };
                          
                          void printStudent(Student s) {
                              cout << "Name: " << s.name << ", Age: " << s.age << endl;
                          }
                          

                          🧪 使用:

                          Student stu = {"Alice", 20};
                          printStudent(stu);
                          // 输出:Name: Alice, Age: 20
                          

                          📌 说明

                          • 也可以使用引用传递,提高效率:void printStudent(const Student &s)

                          🧪 七、实战练习题(附答案)

                          ✅ 题目1:写一个函数,交换两个整数的值

                          void swap(int &a, int &b) {
                              int temp = a;
                              a = b;
                              b = temp;
                          }
                          

                          ✅ 题目2:写一个函数,判断一个字符串是否为回文(正读反读一样)

                          bool isPalindrome(string str) {
                              int left = 0, right = str.length() - 1;
                              while (left < right) {
                                  if (str[left] != str[right]) return false;
                                  left++;
                                  right--;
                              }
                              return true;
                          }
                          

                          🧠 八、总结(函数进阶知识点一览表)

                          知识点 内容
                          参数传递方式 值传递、引用传递、指针传递
                          函数重载 同名函数,不同参数
                          默认参数 不传参时使用默认值
                          递归函数 自己调用自己的函数
                          函数与数组 传递数组地址
                          函数与结构体 传递结构体或结构体引用

                          🎯 九、鼓励语

                          同学们,函数是编程的灵魂之一。学会灵活使用函数,你就能写出逻辑清晰、结构优雅的程序!继续加油,未来可期!💪


                          📘 下节课预告:C++ 中的指针与数组深入解析
                          📌 想知道指针到底是什么?为什么数组和指针关系密切?下一讲我们一起来揭开它们的神秘面纱!

                          • @ 2025-5-28 19:58:25

                            一、函数的基本概念和作用

                            函数是C++中封装特定功能的代码块,类似于数学中的公式。它可以接收输入(参数),执行操作,并返回结果。例如:

                            // 计算两个数的和
                            int add(int a, int b) {
                                return a + b; // 返回a和b的和
                            }
                            

                            函数的作用

                            1. 代码复用:一个函数可以在多个地方被调用,避免重复编写代码。
                            2. 模块化:将复杂问题拆分成小功能模块,使代码更易维护。
                            3. 提高可读性:通过函数名直接反映功能,如calculateArea()一看就知道是计算面积。

                            二、函数的定义和组成部分

                            1. 函数定义的语法结构

                            返回类型 函数名(参数列表) {
                                // 函数体(执行具体操作的代码)
                                return 返回值; // 可选,用于返回结果
                            }
                            
                            • 返回类型:函数执行后返回的数据类型,如intdouble,若无返回值则用void
                            • 函数名:唯一标识符,用于调用函数。
                            • 参数列表:用逗号分隔的输入参数,如(int a, int b)
                            • 函数体:用{}包裹的代码,包含具体操作。
                            • 返回语句return语句用于结束函数并返回结果(若返回类型非void)。

                            2. 示例:计算矩形面积

                            // 函数定义
                            double calculateArea(double length, double width) {
                                double area = length * width;
                                return area; // 返回面积
                            }
                            
                            // 调用函数
                            int main() {
                                double area = calculateArea(5.0, 3.0); // 传入参数5.0和3.0
                                cout << "Area: " << area << endl; // 输出15.0
                                return 0;
                            }
                            

                            三、函数的声明和调用

                            1. 函数声明(函数原型)

                            在调用函数之前,需要先告诉编译器函数的存在,否则会报错。声明格式为:

                            返回类型 函数名(参数类型列表); // 末尾加分号,无需函数体
                            

                            示例

                            // 函数声明(在main函数前)
                            double calculateArea(double length, double width);
                            
                            int main() {
                                // 函数调用
                                double area = calculateArea(5.0, 3.0);
                                return 0;
                            }
                            
                            // 函数定义(在main函数后)
                            double calculateArea(double length, double width) {
                                return length * width;
                            }
                            

                            2. 函数调用

                            通过函数名和参数列表调用函数:

                            // 调用无参数函数
                            void printHello() {
                                cout << "Hello!" << endl;
                            }
                            
                            int main() {
                                printHello(); // 直接调用
                                return 0;
                            }
                            

                            四、参数传递方式

                            C++支持三种参数传递方式:值传递、引用传递、指针传递。

                            1. 值传递

                            • 特点:传递参数的副本,函数内部修改不影响原始变量。
                            • 示例
                            void increase(int num) {
                                num += 10; // 修改的是副本
                            }
                            
                            int main() {
                                int x = 5;
                                increase(x); // 调用后x仍为5
                                cout << x << endl; // 输出5
                                return 0;
                            }
                            

                            2. 引用传递

                            • 特点:传递参数的别名,函数内部修改会影响原始变量。
                            • 语法:在参数类型后加&
                            • 示例
                            void increase(int& num) { // 注意&符号
                                num += 10; // 修改原始变量
                            }
                            
                            int main() {
                                int x = 5;
                                increase(x); // 调用后x变为15
                                cout << x << endl; // 输出15
                                return 0;
                            }
                            

                            3. 指针传递

                            • 特点:传递参数的地址,函数内部通过解引用修改原始变量。
                            • 语法:参数类型为指针(如int*)。
                            • 示例
                            void increase(int* num) { // 接收指针
                                *num += 10; // 解引用修改原始变量
                            }
                            
                            int main() {
                                int x = 5;
                                increase(&x); // 传递x的地址
                                cout << x << endl; // 输出15
                                return 0;
                            }
                            

                            五、void函数

                            • 特点:无返回值,用于执行操作而非返回结果。
                            • 示例
                            void printMessage(string msg) {
                                cout << msg << endl;
                            }
                            
                            int main() {
                                printMessage("Hello, World!"); // 直接调用
                                return 0;
                            }
                            

                            六、函数的作用域

                            • 局部变量:在函数内部定义的变量,仅在函数内可见。
                            • 全局变量:在所有函数外部定义的变量,整个程序可见。
                            • 示例
                            int globalVar = 10; // 全局变量
                            
                            void func() {
                                int localVar = 20; // 局部变量
                                cout << globalVar << endl; // 可以访问全局变量
                                // cout << localVar << endl; // 其他函数无法访问localVar
                            }
                            

                            七、递归函数

                            递归是指函数直接或间接调用自身。必须包含终止条件,否则会导致栈溢出。

                            1. 示例:计算阶乘

                            int factorial(int n) {
                                if (n == 0) { // 终止条件
                                    return 1;
                                } else {
                                    return n * factorial(n - 1); // 递归调用
                                }
                            }
                            
                            int main() {
                                int result = factorial(5); // 计算5! = 120
                                cout << result << endl;
                                return 0;
                            }
                            

                            2. 示例:斐波那契数列

                            int fibonacci(int n) {
                                if (n <= 1) { // 终止条件
                                    return n;
                                } else {
                                    return fibonacci(n - 1) + fibonacci(n - 2);
                                }
                            }
                            

                            八、常见错误和调试技巧

                            1. 常见错误

                            • 忘记声明函数:在调用前未声明函数,会导致编译错误。
                            • 参数类型不匹配:如函数要求int参数,却传入double
                            • 返回值类型错误:函数声明为int,但未返回整数。

                            2. 调试技巧

                            • 打印中间结果:在函数中使用cout输出变量值,检查逻辑是否正确。
                            • 使用断点:在IDE中设置断点,逐行调试观察变量变化。

                            九、综合示例:统计字符串中特定字符的出现次数

                            #include <iostream>
                            #include <string>
                            using namespace std;
                            
                            // 函数声明
                            int countChar(string str, char target);
                            
                            int main() {
                                string text = "Hello, World!";
                                char target = 'l';
                                int count = countChar(text, target); // 调用函数
                                cout << "Character '" << target << "' appears " << count << " times." << endl;
                                return 0;
                            }
                            
                            // 函数定义:统计字符出现次数
                            int countChar(string str, char target) {
                                int count = 0;
                                for (char c : str) { // 遍历字符串
                                    if (c == target) {
                                        count++;
                                    }
                                }
                                return count; // 返回统计结果
                            }
                            

                            十、练习题

                            1. 编写函数max(int a, int b),返回两个整数中的较大值。
                            2. 编写函数swap(int& x, int& y),交换两个整数的值。
                            3. 编写递归函数sum(int n),计算1到n的和。

                            通过以上步骤,你可以逐步掌握C++函数的基本概念和使用方法。建议多练习,尝试将复杂问题分解为多个函数,提高代码的可读性和可维护性。

                            • 1