LOADING

缓存加载中...

cs106l总结

 

做完了assign,沿着这条线开始梳理。

I/O主要是围绕流(stream)进行操作:

  • 文件:ifstream输入,ofstream输出,fstream输入输出。

  • 内存:istream输入,ostream输出,iostream输入输出。

  • 字符串:stringstream输出输出。

  • 数组:spanstream输入输出。

**input >> stream << output **

  1. 状态信息:标志流状态(good()正常/eof()文件末尾/fail()非致命错误/bad()致命错误)。

  2. 控制信息:控制输入/输出序列格式化的标志以及诸如的区域设置。

流对象:stdin和stdout是行缓存;而stderr是无缓存的。cin和cout都是从缓冲区读取。

cin和cout把缓冲区的数据变成流,然后搬运到相应的目的地。cin和cout就是个搬运工,搬运的过程就是流。

操作流:std标准库函数

管道(pipeline)对比:
stream:一种数据传输方式,用于处理连续数据。
pipeline:对数据连续的作业过程。
模块化、并行、组合…

与此同时,缓冲区(buffer)

基本机制是:存储信息达到一定量后(触发IO)进行一些操作。

缓冲区满时:执行flush语句;执行endl语句;关闭文件。

  1. 全缓冲:全满后操作,刷新。

  2. 行缓冲:遇到换行符操作,刷新。

  3. 不带缓冲:直接操作。

C++通过std::streambuf类实现缓冲区管理,其核心包含

  • ​字符序列指针控制

    • 读取区(Get Area)​:通过gptr(当前读取位置)、egptr(缓冲区结束位置)指针管理输入数据

    • 写入区(Put Area)​:通过pptr(当前写入位置)、epptr(缓冲区结束位置)指针管理输出数据

    • 动态调整:当指针到达缓冲区边界时,触发缓冲区的刷新或填充。

​- 关联字符序列(Associated Sequence)​

表示与流绑定的实际数据源或目标(如文件句柄、内存块)。例如,std::cout的关联序列是标准输出设备,std::stringstream的关联序列是内存字符串

std::getline(cin(stream),name):通过gptr->egptr指针控制输入数据的位置.读取字符直到遇到指定的终止符(默认\n).
cin失败是getline失败的唯一原因。

std::getchar():用户输入字符暂存在键盘缓冲区,按回车后数据被复制到标准输入流(stdin)的缓冲区.从缓冲区逐个读取字符,返回其ASCII码值(int类型),缓冲区指针随之移动.

控制台/文件 <–读写–> 字符串/二进制表示 <–类型转换–> 程序中的对象

指针初步

定义:type * ptr

获取一个变量的地址:引用&

std::range

更加抽象的范围

  1. range之视图(views),一种范围适配器:对现有范围的变换或过滤。不拷贝数据。
    std::views::filter;//根据特定条件过滤元素
    transform;//函数应用到每个元素,生成新的元素序列
    take,drop;//提取/跳过前N个元素
  2. 基于范围的算法:sort,find,copy,for_each。
  3. 惰性求值:只在需要时才计算元素。如filter并不会立刻遍历,当实际访问元素时才过滤
  4. pipeline:串联多个范围适配器:代码文档化

lambda表达式的细节

整体上用烂了。记一下边角知识。

  1. 值捕获[=]/[x] vs 引用捕获[&]/[&x]:
    值捕获如果外部变量是引用类型,那么捕获的是引用本身,而不是引用指向的对象。
    引用捕获如果外部变量生命周期结束,使用该变量会UB。
  2. 捕获变量只能用mutable关键字标识才能改变。
  3. 自动推导返回路径–>多个返回路径且类型不一致,err.
  4. 使用std::move捕获大对象。

从运算符重载到左右值问题

  • 左值:持久性的对象/表达式,通常有明确的内存地址,可以在多条语句使用。
  • 右值:临时性的对象/表达式,没有持久性,表达式结束时就会销毁。不能取地址
  • 左值引用T&,通用引用(转发引用,根据语境判断左右值)T&&
  • 左值->右值:std::move。右值->左值:conts T&
  • 完美转发:使用std::forward保留参数左右值属性
  1. 赋值运算符=:默认按值拷贝,如果包含动态拷贝:自定义拷贝/移动语义
    优化:区分左右值:拷贝赋值/移动赋值。
  2. 算术运算符+:调用a+b会生成临时对象并拷贝。
    优化:返回值优化(RVO),直接构造result到调用者内存。强制返回右值,使用std::move
  3. 符合赋值运算+=:修改左操作数,参数左值引用。如果可能是右值,重载优化return *this
  4. 输入/输出<< / >>:参数必须是左值引用。

others:noexcept标记移动操作。

其他

概念提升,RAII,multithread。。。用到再说。