• 十四天学会C++之第二天(函数和库)


    在这里插入图片描述

    1. 函数的定义和调用

    在C++中,函数是组织和结构化代码的关键工具之一。它们允许您将一段代码封装成一个可重复使用的模块,这有助于提高代码的可读性和维护性。

    为什么使用函数?

    函数在编程中的作用不可小觑。它们有以下几个重要用途:

    • 模块化编程: 函数允许将代码划分为小的、独立的单元,使得代码更易于理解和管理。

    • 代码重用: 一次编写,多次使用。您可以在程序的不同地方调用同一个函数,而不必重复编写相同的代码。

    • 提高可读性: 通过将代码分解为函数,您可以为每个函数取一个描述性的名字,使代码更具可读性。

    定义函数

    在C++中,函数的定义通常包括以下几个部分:

    // 函数声明(函数原型)
    返回类型 函数名(参数列表);
    
    // 函数定义
    返回类型 函数名(参数列表) {
        // 函数体
        // 执行一些操作
        return 返回值; // 如果有返回值的话
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 返回类型: 函数可以返回一个值,这个值的类型由返回类型指定。如果函数不返回任何值,可以使用 void 关键字表示。

    • 函数名: 函数的名称,是函数的标识符。

    • 参数列表: 函数可以接受零个或多个参数,这些参数在圆括号内列出,并用逗号分隔。

    • 函数体: 包含函数执行的实际代码部分。

    • 返回值: 如果函数有返回值,使用 return 语句返回该值。

    函数定义

    // 函数声明
    int add(int a, int b);
    
    // 函数定义
    int add(int a, int b) {
        int result = a + b;
        return result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    调用函数

    调用函数意味着执行函数内的代码。要调用函数,只需使用函数名和合适的参数列表。

    int main() {
        int num1 = 5;
        int num2 = 3;
        int sum = add(num1, num2); // 调用add函数
        cout << "Sum: " << sum << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    示例中,add 函数被调用来计算 num1num2 的和,并将结果存储在 sum 变量中。

    2. 参数传递

    在C++中,参数传递是函数与外部世界进行数据交换的重要方式之一。它可以通过不同的方式实现,包括按值传递和按引用传递。

    按值传递 vs. 按引用传递

    按值传递

    参数按值传递给函数时,函数会创建参数的一个副本,这意味着在函数内部对参数的更改不会影响外部的原始数据。

    void modifyValue(int x) {
        x = 10; // 在函数内部修改副本
    }
    
    int main() {
        int value = 5;
        modifyValue(value);
        cout << "Value after function call: " << value << endl; // 仍然是5
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    按引用传递

    按引用传递参数时,函数操作的是原始数据的引用,这意味着对参数的更改会影响外部的原始数据。

    void modifyValue(int &x) {
        x = 10; // 直接修改原始数据
    }
    
    int main() {
        int value = 5;
        modifyValue(value);
        cout << "Value after function call: " << value << endl; // 现在是10
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    函数参数的默认值

    函数的参数提供默认值,这意味着在调用函数时,可以省略某些参数,让编译器使用默认值。

    void printMessage(string message = "Hello, World!") {
        cout << message << endl;
    }
    
    int main() {
        printMessage(); // 使用默认消息
        printMessage("Custom message"); // 使用自定义消息
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    函数重载

    函数重载允许在同一范围内定义多个具有相同名称但不同参数列表的函数。编译器根据函数调用的参数来选择正确的函数。

    int add(int a, int b) {
        return a + b;
    }
    
    double add(double a, double b) {
        return a + b;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    示例

    参数传递的不同方式和默认值的影响:

    void modify(int x) {
        x = 10;
    }
    
    void modify(double &y) {
        y = 3.14;
    }
    
    int main() {
        int num = 5;
        double pi = 3.14159265359;
    
        modify(num); // 传值,num不变
        modify(pi);  // 传引用,pi被修改
    
        cout << "Modified num: " << num << endl;
        cout << "Modified pi: " << pi << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在示例中,modify 函数分别按值和按引用传递参数,从而导致了不同的行为。

    3. 函数的返回值

    函数的返回值是函数执行后向调用者提供的结果。在C++中,您可以指定函数的返回值类型,并使用return语句从函数中返回值。

    返回值类型

    每个C++函数都有一个返回值类型,它指定了函数返回的数据类型。返回值类型在函数声明和定义中都必须指定。

    int add(int a, int b) { // 返回值类型为int
        return a + b;
    }
    
    double divide(double x, double y) { // 返回值类型为double
        return x / y;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    返回语句

    return语句用于从函数中返回值。可以出现在函数的任何位置,但一旦执行,函数将立即终止,并将控制返回给调用者。

    int multiply(int a, int b) {
        int result = a * b;
        return result; // 返回计算结果
    }
    
    • 1
    • 2
    • 3
    • 4

    示例

    使用函数的返回值:

    int main() {
        int sum = add(5, 3); // 调用add函数并接收返回值
        double quotient = divide(10.0, 2.0); // 调用divide函数并接收返回值
    
        cout << "Sum: " << sum << endl;
        cout << "Quotient: " << quotient << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在上面的示例中,adddivide 函数返回整数和浮点数,分别被存储在 sumquotient 变量中。

    返回值在表达式中的应用

    函数的返回值可以直接用作表达式的一部分。这使得函数调用非常灵活,可以在数学表达式或其他计算中使用。

    int main() {
        int result = multiply(add(2, 3), 4); // 使用函数返回值进行嵌套调用和计算
    
        cout << "Result: " << result << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在示例中,add(2, 3) 的返回值被传递给 multiply 函数,以便进行进一步的计算。

    4. 标准C++库介绍

    C++作为一门强大的编程语言,拥有丰富的标准库,提供了许多有用的功能和数据结构。

    包含头文件

    要使用C++标准库中的功能,首先需要包含相应的头文件。头文件包含了库中的类、函数和对象的声明,它们是使用这些库的关键。

    #include   // 包含iostream头文件,用于输入输出操作
    #include     // 包含string头文件,用于字符串操作
    #include     // 包含vector头文件,用于动态数组操作
    
    • 1
    • 2
    • 3

    示例用法

    库的示例用法:

    使用iostream进行输入和输出
    #include 
    
    int main() {
        // 输出文本到控制台
        std::cout << "Hello, World!" << std::endl;
    
        // 从用户输入读取数据
        int num;
        std::cout << "Enter a number: ";
        std::cin >> num;
    
        // 输出读取到的数据
        std::cout << "You entered: " << num << std::endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    使用string进行字符串操作
    #include 
    
    int main() {
        std::string greeting = "Hello, ";
        std::string name = "John";
    
        // 字符串拼接
        std::string message = greeting + name;
    
        // 获取字符串长度
        int length = message.length();
    
        // 输出结果
        std::cout << message << " (Length: " << length << ")" << std::endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    使用vector创建动态数组
    #include 
    
    int main() {
        std::vector<int> numbers;
    
        // 向vector添加元素
        numbers.push_back(1);
        numbers.push_back(2);
        numbers.push_back(3);
    
        // 遍历并输出vector的元素
        for (int i = 0; i < numbers.size(); ++i) {
            std::cout << numbers[i] << " ";
        }
        std::cout << std::endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    5. 头文件和命名空间

    在C++编程中,头文件和命名空间是非常重要的概念。头文件用于包含声明和定义,而命名空间则用于避免命名冲突。

    头文件的作用

    头文件通常包含了函数、类和变量的声明,以及必要的函数原型和常量定义。头文件的作用是将这些声明集中在一起,以便在多个源文件中共享。这有助于模块化编程,提高了代码的可维护性。

    创建自定义头文件

    要创建自定义头文件,只需新建一个以.h.hpp为扩展名的文本文件,并在其中包含所需的声明。例如,以下是一个名为myheader.h的头文件的示例:

    #ifndef MYHEADER_H
    #define MYHEADER_H
    
    // 在这里添加声明
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    命名空间的概念

    命名空间是一种将全局作用域划分为不同部分以防止命名冲突的机制。它允许您将相关的函数、类和变量组织到一个命名空间中,以避免与其他代码的命名冲突。

    使用命名空间

    要使用命名空间,您可以使用namespace关键字定义一个命名空间,然后将相关声明放入其中。例如:

    // 定义一个名为mynamespace的命名空间
    namespace mynamespace {
        int myVariable;
        void myFunction();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    // 使用mynamespace中的变量和函数
    mynamespace::myVariable = 42;
    mynamespace::myFunction();
    
    • 1
    • 2
    • 3

    简化命名空间的使用

    为了简化命名空间的使用,可以使用using关键字来声明在命名空间中的特定成员。例如:

    // 使用mynamespace中的myVariable
    using mynamespace::myVariable;
    
    int main() {
        myVariable = 42; // 不需要指定命名空间
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    6.案例分析

    函数重载

    #include 
    
    // 函数重载:处理整数
    int add(int a, int b) {
        return a + b;
    }
    
    // 函数重载:处理双精度浮点数
    double add(double a, double b) {
        return a + b;
    }
    
    int main() {
        int intResult = add(5, 7);
        double doubleResult = add(3.5, 2.7);
    
        std::cout << "Integer Result: " << intResult << std::endl;
        std::cout << "Double Result: " << doubleResult << std::endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    运行结果:
    在这里插入图片描述

    递归函数

    #include 
    
    int fibonacci(int n) {
        if (n <= 1) {
            return n;
        }
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
    
    int main() {
        int n = 10;
        for (int i = 0; i < n; ++i) {
            std::cout << fibonacci(i) << " ";
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    运行结果:
    在这里插入图片描述

    Lambda表达式

    #include 
    #include 
    #include 
    
    int main() {
        std::vector<int> numbers = {5, 2, 8, 1, 3};
    
        // 使用Lambda表达式对向量进行排序
        std::sort(numbers.begin(), numbers.end(), [](int a, int b) {
            return a < b;
        });
    
        // 使用Lambda表达式筛选出偶数
        auto isEven = [](int x) { return x % 2 == 0; };
        std::vector<int> evenNumbers;
    
        std::copy_if(numbers.begin(), numbers.end(), std::back_inserter(evenNumbers), isEven);
    
        // 输出排序后的向量
        std::cout << "Sorted Numbers: ";
        for (int num : numbers) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    
        // 输出筛选后的偶数
        std::cout << "Even Numbers: ";
        for (int num : evenNumbers) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    运行结果:
    在这里插入图片描述

    字符串处理

    #include 
    #include 
    #include 
    
    int main() {
        std::string str = "Hello, World!";
        
        // 反转字符串
        std::reverse(str.begin(), str.end());
        std::cout << "Reversed String: " << str << std::endl;
    
        // 查找子字符串
        std::string subStr = "World";
        size_t found = str.find(subStr);
        if (found != std::string::npos) {
            std::cout << "Substring found at position: " << found << std::endl;
        } else {
            std::cout << "Substring not found." << std::endl;
        }
    
        // 将字符串拆分为单词
        std::string sentence = "This is a sample sentence";
        size_t startPos = 0;
        while (startPos < sentence.length()) {
            size_t spacePos = sentence.find(' ', startPos);
            if (spacePos == std::string::npos) {
                spacePos = sentence.length();
            }
            std::string word = sentence.substr(startPos, spacePos - startPos);
            std::cout << "Word: " << word << std::endl;
            startPos = spacePos + 1;
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    运行结果:
    在这里插入图片描述

    容器操作

    #include 
    #include 
    #include 
    #include 
    
    int main() {
        // 使用std::vector进行容器操作
        std::vector<int> numbers = {5, 2, 8, 1, 3};
    
        // 添加元素
        numbers.push_back(7);
    
        // 删除元素
        numbers.erase(std::remove(numbers.begin(), numbers.end(), 3), numbers.end());
    
        // 对容器排序
        std::sort(numbers.begin(), numbers.end());
    
        // 输出容器元素
        std::cout << "Vector Elements: ";
        for (int num : numbers) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    
        // 使用std::map进行容器操作
        std::map<std::string, int> scores;
    
        // 添加键值对
        scores["Alice"] = 95;
        scores["Bob"] = 87;
        scores["Charlie"] = 92;
    
        // 查找元素
        std::string name = "Bob";
        if (scores.find(name) != scores.end()) {
            std::cout << name << "'s Score: " << scores[name] << std::endl;
        } else {
            std::cout << "Name not found." << std::endl;
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    运行结果:
    在这里插入图片描述

    多线程和并发

    #include 
    #include 
    #include 
    
    // 用于计算部分数组总和的函数
    void partialSum(const std::vector<int>& arr, size_t start, size_t end, int& result) {
        result = 0;
        for (size_t i = start; i < end; ++i) {
            result += arr[i];
        }
    }
    
    int main() {
        const int numThreads = 4; // 使用4个线程
        const int arrSize = 1000;
        std::vector<int> numbers(arrSize, 1); // 创建一个包含1000个1的数组
    
        std::vector<std::thread> threads(numThreads);
        std::vector<int> partialResults(numThreads);
    
        // 创建并启动线程
        for (int i = 0; i < numThreads; ++i) {
            size_t start = i * (arrSize / numThreads);
            size_t end = (i == numThreads - 1) ? arrSize : (i + 1) * (arrSize / numThreads);
            threads[i] = std::thread(partialSum, std::ref(numbers), start, end, std::ref(partialResults[i]));
        }
    
        // 等待所有线程完成
        for (int i = 0; i < numThreads; ++i) {
            threads[i].join();
        }
    
        // 计算总和
        int totalSum = 0;
        for (int i = 0; i < numThreads; ++i) {
            totalSum += partialResults[i];
        }
    
        std::cout << "Total Sum: " << totalSum << std::endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    运行结果:
    在这里插入图片描述

  • 相关阅读:
    字节跳动发Seed-TTS语音合成模型,可模仿任意人的声音,效果逼真
    react native常用插件
    使用Python完成一套优美的中秋节代码
    访问者模式
    Docker安装Nacos持久化到Docker安装的Mysql
    NLP:自然语言领域NLP模型发展(ELmo→GPT/BERT→MT-DNN→XLNet→RoBERTa→ALBERT)l历程简介、重要算法介绍之详细攻略
    将Nacos注册到springboot使用以及Feign实现服务调用
    嵌入式裸机架构的探索与崩塌
    最详细Pycharm远程代码调试配置方案【针对GPU集群】
    神经网络 05(损失函数)
  • 原文地址:https://blog.csdn.net/m0_53918860/article/details/133529207