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

C++---------随机库,standfor库

意外修改原始数据

  • 问题描述
    • 由于引用参数允许函数直接修改原始变量,这可能会导致意外的修改。如果函数的使用者没有意识到函数会修改传入的参数,就可能引发错误。例如,有一个函数看起来只是用于打印一个变量的值,但实际上却修改了它:
    void printAndModify(int& num) {
      std::cout << "原始值: " << num << std::endl;
      num = 100;
    }
    int main() {
      int value = 50;
      printAndModify(value);
      std::cout << "修改后的值: " << value << std::endl; 
      // 这里输出的是100,可能不符合预期
      return 0;
    }
    
  • 解决方法
    • 对于不应该修改参数的函数,应该使用const引用。const引用可以确保函数内部不会修改引用的变量。例如,将上述函数修改为:
    void printValue(const int& num) {
      std::cout << "值: " << num << std::endl;
    }
    
    这样,在函数内部尝试修改num就会导致编译错误,明确地告诉使用者这个函数不会修改传入的参数。
  1. 引用悬空(Dangling Reference)

    • 问题描述
      • 当引用所绑定的对象在引用的生命周期结束之前被销毁时,就会出现引用悬空的情况。这通常发生在函数返回局部变量的引用时。例如:
      int& danglingReference() {
        int localVariable = 10;
        return localVariable;
      }
      int main() {
        int& ref = danglingReference();
        std::cout << ref << std::endl; 
        // 这里的行为是未定义的,因为localVariable已经被销毁
        return 0;
      }
      
    • 解决方法
      • 避免返回局部变量的引用。如果需要返回一个引用,可以返回全局变量、静态局部变量或者通过动态内存分配创建的对象的引用。例如,返回一个静态局部变量的引用:
      int& validReference() {
        static int staticVariable = 20;
        return staticVariable;
      }
      
      静态局部变量在程序的整个生命周期内都存在,所以返回它的引用是安全的。
  2. 混淆引用和指针的语义

    • 问题描述
      • 引用和指针在某些方面很相似,都可以用于间接访问变量。但是它们的语义不同,引用在初始化后不能重新绑定到其他对象,而指针可以。如果在使用过程中混淆了它们的语义,可能会导致错误。例如,试图重新绑定一个引用:
      int main() {
        int num1 = 10;
        int& ref = num1;
        int num2 = 20;
        ref = num2; 
        // 这里不是重新绑定ref,而是将num2的值赋给num1
        std::cout << num1 << " " << num2 << std::endl;
        return 0;
      }
      
    • 解决方法
      • 清晰地理解引用和指针的区别。引用是一个别名,操作引用就是操作它所绑定的对象;指针是一个存储变量地址的变量,可以通过重新赋值指向不同的对象。在代码中,要根据具体的需求正确地选择使用引用还是指针。如果需要一个不可变的别名,使用引用;如果需要能够改变指向的对象,使用指针。
  3. 引用在复杂表达式中的绑定问题

    • 问题描述
      • 在复杂的表达式中,引用的绑定可能不像预期的那样清晰。例如,当引用作为函数参数并且函数调用是一个更大表达式的一部分时,可能会出现理解上的困难。考虑以下示例:
      int add(int& a, int& b) {
        return a + b;
      }
      int main() {
        int num1 = 10;
        int num2 = 20;
        int result = add(num1, num2 + 10); 
        // 这里num2 + 10会创建一个临时对象,不能绑定到非const引用
        std::cout << result << std::endl;
        return 0;
      }
      
    • 解决方法
      • 对于非const引用参数,确保传递的是左值(可以出现在赋值运算符左边的表达式,通常是变量)。如果需要传递右值(如临时对象),可以将函数参数改为const引用,或者使用右值引用(&&)来处理右值的特殊情况,右值引用主要用于移动语义和完美转发等高级特性。在上述示例中,将add函数的参数改为const引用可以解决问题:
      int add(const int& a, const int& b) {
        return a + b;
      }
      

在这里插入图片描述

C++随机数库(<random>)的设计

  • 引擎(Engines)
    • 基本概念:随机数引擎是生成随机数序列的核心组件。它维护着一个内部状态,并根据这个状态生成随机数。不同的引擎有不同的算法来更新状态和生成数字。例如,linear_congruential_engine是一种线性同余引擎,它使用线性同余算法来生成随机数。
    • 使用示例
    #include <iostream>
    #include <random>
    int main() {
      std::linear_congruential_engine<unsigned int, 16807, 0, 2147483647> lce;
      // 生成一个随机数
      unsigned int random_num = lce();
      std::cout << "随机数: " << random_num << std::endl;
      return 0;
    }
    
  • 分布(Distributions)
    • 基本概念:分布用于将引擎生成的原始随机数映射到特定的范围或遵循特定的概率分布。例如,uniform_int_distribution用于生成均匀分布的整数,normal_distribution用于生成正态分布的数字。
    • 使用示例(均匀分布)
    #include <iostream>
    #include <random>
    int main() {
      std::random_device rd;
      std::mt19937 eng(rd());
      std::uniform_int_distribution<int> distr(1, 10);
      int random_num_in_range = distr(eng);
      std::cout << "1到10之间的随机数: " << random_num_in_range << std::endl;
      return 0;
    }
    
  • 种子(Seeding)
    • 基本概念:种子是用于初始化随机数引擎的初始值。相同的种子会导致引擎生成相同的随机数序列。为了获得真正的随机序列,通常使用random_device来获取一个非确定性的种子,或者使用系统时间等动态因素作为种子。
    • 示例(使用random_device作为种子)
    #include <iostream>
    #include <random>
    int main() {
      std::random_device rd;
      std::mt19937 eng(rd());
      std::uniform_int_distribution<int> distr(1, 100);
      for (int i = 0; i < 5; ++i) {
        int random_num = distr(eng);
        std::cout << random_num << " ";
      }
      std::cout << std::endl;
      return 0;
    }
    
  1. <iostream>标准库介绍(你可能想说<iostream>,因为没有standfor库)

    • 基本输入输出流(I/O Streams)
      • std::cout(标准输出):用于将数据输出到控制台。它是ostream类的一个对象,支持多种数据类型的输出,如整数、浮点数、字符串等。例如:
      #include <iostream>
      int main() {
        int num = 10;
        std::cout << "数字: " << num << std::endl;
        return 0;
      }
      
      • std::cin(标准输入):用于从控制台读取数据。它是istream类的一个对象。例如,读取一个整数:
      #include <iostream>
      int main() {
        int num;
        std::cin >> num;
        std::cout << "你输入的数字是: " << num << std::endl;
        return 0;
      }
      
    • 文件输入输出流(fstream
      • 基本概念fstream库提供了用于文件操作的输入输出流。std::ofstream用于写入文件,std::ifstream用于读取文件,std::fstream可以用于读写文件。
      • 写入文件示例(ofstream
      #include <iostream>
      #include <fstream>
      int main() {
        std::ofstream out_file("test.txt");
        if (out_file) {
          out_file << "这是写入文件的内容" << std::endl;
          out_file.close();
        } else {
          std::cerr << "无法打开文件进行写入" << std::endl;
        }
        return 0;
      }
      
      • 读取文件示例(ifstream
      #include <iostream>
      #include <ifstream>
      int main() {
        std::ifstream in_file("test.txt");
        if (in_file) {
          std::string line;
          while (std::getline(in_file, line)) {
            std::cout << line << std::endl;
          }
          in_file.close();
        } else {
          std::cerr << "无法打开文件进行读取" << std::endl;
        }
        return 0;
      }
      

在这里插入图片描述


http://www.kler.cn/a/449868.html

相关文章:

  • 【蓝桥杯——物联网设计与开发】基础模块8 - RTC
  • GIS 文件格式 及 常规应用总结
  • MySQL 8.0:explain analyze 分析 SQL 执行过程
  • 【杂谈】-为什么Python是AI的首选语言
  • 记录一个SVR学习
  • 大数据操作实验一
  • 16×16LED点阵字符滚动显示-基于译码器与移位寄存器(设计报告+仿真+单片机源程序)
  • IMX6ULL开发板如何关掉自带的QT的GUI界面和poky的界面的方法
  • [spring]处理器
  • SpringCloudGateway+Nacos注册与转发Netty+WebSocket
  • 02-8.python入门基础一函数的高级使用
  • 一次性部署:使用Docker部署PHP应用
  • 源码分析之Openlayers中ZoomSlider滑块缩放控件
  • 【C语言】深入探讨 C 语言 `int` 类型大小及其跨平台影响
  • 【机器人】ATM 用于策略学习的任意点轨迹建模 RSS 2024 | 论文精读
  • 音视频入门基础:MPEG2-TS专题(20)——ES流简介
  • 取多个集合的交集
  • Spring Boot @Conditional注解
  • 设计模式--工厂方法模式【创建型模式】
  • [vLLM vs TensorRT-LLM] :系统调度schedule比较
  • 浅谈算法交易
  • MySQL表名传参SP
  • Linux文件目录 --- 复制命令CP、递归复制目录、软连接、硬链接
  • Windows开启IIS后依然出现http error 503.the service is unavailable
  • 使用 ffmpeg 拼接合并视频文件
  • 代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和