[杂学笔记]STL容器的迭代器、CMake与Makefile、完美转发、NULL与nullptr的区别 、GDB调式命令、平衡树与红黑树

目录

1.STL容器的迭代器

2.CMake与Makefile

3.完美转发

4.NULL与nullptr的区别

5.GDB调式命令

6.平衡树与红黑树


1.STL容器的迭代器

  • InputIterator输入迭代器、OutputIterator输出迭代器与ForwardIterator前向迭代器:只支持向前迭代的操作(++)
  • BidirectionalIterator双向迭代器:支持++与--的操作
  • RandomIterator随机迭代器:支持++、--、+、-的操作,类似于下标随机访问

        构造函数:STL容器基本上都是可以使用迭代器进行相互构造的,除非是类型不兼容,int类型的数组非要拷贝到string数组中,那么是不可以的。又或者说是某些容器的特性决定了他们不能直接使用其他容器进行构造,例如stack、queue以及priority_queue是容器适配器,他们没有直接的迭代器,所以不能使用其他容器的迭代器进行构造,但可以直接指定类型进行初始化。

        对于vector是随机迭代器,为什么可以构造set类型的对象呢?在STL中迭代器分为上述的五种类型,高级的迭代器包含了低级迭代器的所有功能,所以高级迭代器可以当低级迭代器使用,所以可以构造set。

2.CMake与Makefile

        Makefile是一个文本文件,他可以在里面定义源代码如何编译、连接以及最终生成可执行文件或库文件等规则。make工具会读取并执行makefile中的内容。

        Cmake是一个跨平台的元构建工具,他本身并不参与编译项目,而是根据项目的源文件以及配置信息生成不同平台下的构建文件,例如makefile、vistual studio项目文件等。生成makefile之后,在使用make工具进行执行即可。

        Makefile的语法相对来说复杂一些,尤其是大型的项目来说,编写和维护Makefile可能会变得非常困难,需要开发者熟悉各种编译命令和规则,以及处理各种文件依赖关系等。而CMake的语法简单,开发者只需要关注项目的结构和依赖关系即可,不需要关系具体平台下的编译命令。

        可以理解为使用CMake可以更简单的编写项目的构建文件,同时CMake会根据不同平台的编译命令,自动帮我们生成不同平台下可以运行的Makefile文件。当然也不一定是形成Makefile文件,对于vs2022下,就会自动生成vs的项目文件,运行该文件就可以形成vs下的程序了。

3.完美转发

        完美转发是 C++ 中的一个重要特性,主要用于在模板函数中准确地将参数以原始的值类别(左值或右值)传递给其他函数,避免不必要的拷贝或移动操作,保持参数的原始属性。

        在模板函数中的T&&参数类型属于通用类型引用,也叫转发引用,他是一直特殊的右值引用。如果传递的参数是左值类型,那么他就是推导为左值引用类型,就会变成类似于int& &&类型的参数,根据引用折叠规则,就会变为int&,所以该参数最终就会是左值引用。

        如果传递的是右值,就会推到为普通类型的传参,那么就会变成 int&&的参数了。

#include 
#include 

// 处理左值的函数
void process(int& value) { std::cout << "处理左值: " << value << std::endl; }

// 处理右值的函数
void process(int&& value) { std::cout << "处理右值: " << value << std::endl; }

// 使用完美转发的转发函数模板
template
void forwarder(T&& arg) {
    process(std::forward(arg));
}

int main() {
    int x = 42;
    // 传递左值
    forwarder(x);

    // 传递右值
    forwarder(123);

    return 0;
}

        例如上述代码,如果不使用完美转发的话,传递左值还是右值都是会调用左值版本的函数,因为在传参的过程中,会发生一次拷贝,拷贝的对象在赋值给参数,拷贝的数据他是左值,所以就只会调用左值版本的函数了。也无法使用std::move去改变,因为这个拷贝是自动的,我们无法去获取到该临时数据。

4.NULL与nullptr的区别

         NULL是C语言的宏定义,而nullptr是C++的关键字。他们都代表的是空指针的意思,但是为什么C++还需要单独弄一个呢?因为C语言中的NULL代表两个含义,一个是0,一个是(void*)0。如果说有一个函数重载了两个版本,一个是版本参数是int类型,另一个传递的是void*类型,那么如果传递的是NULL的话,就会发生函数调用的二义性。所以C++单独引入了一个nullptr来代表空指针,也就是(void*)0。

5.GDB调式命令

命令

功能

break 行号 设置断点
break 函数名 设置函数入口的断点
break 文件名:行号 设置指定文件的断点
info b 查看断点信息
delete 断点编号 删除断点
run/r 运行程序,遇到断点则停下
n 单步执行,不会进入函数调用
s 单步执行,会进入函数调用
finish 跳出函数
print 变量名 打印变量值
set variable 变量名=新值 改变变量值
bt

查看调用堆栈

l 查看该位置附近的代码

6.平衡树与红黑树

        平衡树是AVL树(平衡二叉搜索树),他需要保证严格的平衡,任意节点的左右子树的高度差不能超过1,这种严格的控制使得树的高度始终保持在了logn的高度,使得插入、删除以及搜索的查找时间大幅降低。但是为了严格的平衡就需要频繁的去旋转调整树的结构了,所有会带来额外的开销。适用于查找密集型的场景。

        红黑树是一个近似平衡的二叉树,他对于高度没有那么严格的要求,对于最长的分支不大于最短分支的2倍即可,那么插入和删除也就不需要频繁的去旋转了,那么插入和删除的效率也就会大大的提高,搜索效率相当于AVL树来说,就没有那么高了。适用于频繁的插入和删除的场景,以及堆性能要求较高的场景。

你可能感兴趣的:(笔记,c++,开发语言)