CPP笔记

使用 cpp 语言的相关笔记

lambda函数

auto toNumber = [&](string const& s) -> unsigned {
...
}
形式 解释
[] 定义匿名函数
[&] 以引用形式捕获所有外部变量,也就是外部变量均可用
(string const &s) 匿名函数的参数
-> 定义匿名函数
unsigned 函数返回值类型
{...} 函数实现体

uint32_t, size_t,int

size_t:适用于移植,表示对应平台的无符号整型

uint32_t:则显示地考虑到是否会溢出

string

string 没有replace

string → int : atoi

max_elementarr+first,arr+last//返回数组最大值的位置

*max_elementarr+first,arr+last//返回数组最大值

lower_bound 与 upper_bound

用法:

数组必须有序,当有多个相同时,lower就是第一个大于等于n的,upper就是第一个大于n的

https://codeforces.com/blog/entry/107962 的C题

找bound的序号:减去开始的迭代器

若找不到,则返回end迭代器。

next_permutation

产生全排列

next_permutation(nums.begin(), nums.end());

tuple

get<0>(tuple) 获取tuple的第0个数据

mt19937(C++11)

属于库 <random>

初始随机化引擎:mt19937 gen{random_device{}()}; //高效的随机化,范围大,周期长

随机数分布类:uniform_real_distribution<double> dis; //根据种子生成特定范围的随机数,均匀分布,输入必须是随机化引擎。


uniform_int_distribution<int> //均匀分布(整形)
normal_distribution<> dis(a,b)//正态分布

获取随机数:dis(gen)

#include <random>

mt19937 gen{random_device{}()};
uniform_int_distribution<int> dis(1,5); //整型分布,两边取闭区间
cout << dis(gen) << endl;

optional(C++17)

表示暂时没有

std::optional<T>类型的变量要么是一个T类型的变量,要么是一个表示“什么都没有”的状态

比如一个string,我是不能给它NULL,所以无法给它一个暂未赋值的状态,这里空字符串也是一个赋值状态。

而又了optional,我们可以用 has_value() 去查询。用 value() 来获取值。

参考:

https://zhuanlan.zhihu.com/p/251306766?utm_source=wechat_session

move

以非常简单的方式将左值引用转换为右值引用

move操作实际上是系统将这一块地址属于哪一个地址的登记改一下,实际上这一块内存根本没有发生任何变化

用法:比如一个vector赋值给另外一个vector:v2=move(v1);

左值:指表达式结束后依然存在的持久对象,可以取址,

右值:指表达式结束后不再存在的临时对象,不可以取址,

Semaphore 信号量

sem_t :变量

sem_init :初始化

sem_wait : P操作,减1

sem_post : V操作,加1

Fence 内存屏障

现代编译器的代码优化和编译器指令重排可能会影响到代码的执行顺序,两行逻辑无关的代码可能会重排,但这会导致一些糟糕的后果。

使用内存屏障,就是我们使用具有同步语义的指令来标记真正需要同步的变量和操作,告诉CPU和编译器不要对这些标记好的同步操作和变量做违反顺序一致性的优化,而其它未被标记的地方可以做原有的优化,这样就可以解决指令重排导致的问题。

主要有:

  1. 编译器在生成指令时做了重排
  2. CPU在执行时做了指令重排

参考: https://blog.csdn.net/zhuhongshu/article/details/111327141

alignas对齐

参考: C++11新增关键字: alignas

内建函数

__builtin_popcount

用于计算一个 32 位无符号整数有多少个位为1

结构体

五种结构体声明并定义的方式

# 声明方式一
# 不推荐。
struct Mystruct{}; //声明

struct Mystruct ms;  //C写法的定义
Mystruct ms;  //C++写法的定义

# 声明方式二
# 相当于定义了一个Mystruct,同时定义了一个指针变量。不推荐这样用
struct Mystruct{} * mst; //声明

# 声明方式三
# 只是定义了一个mystruct变量,一次性使用的。不推荐这样写
struct {} mystruct; //声明

# 声明方式四,推荐使用
typedef struct {} Mystruct; //声明
Mystruct ms;  //C, C++均可

# 声明方式五,推荐使用
# 定义方式:如果使用C,则可以使用Mst;如果使用C++,则可以使用Mystruct 或Mst
typedef struct Mystruct {} Mst; //声明

结构体的使用问题

  1. 在vector,map里面怎么用? 推荐使用上面第4个。
  2. 是否要new? 指针要new,非指针不用new。(new使用堆空间,否则使用栈空间)