刷题笔记01

发布于 / 笔记 / 0 条评论

最近一直在勤奋的刷题,在洛谷的试炼场一步一步地往下走着。今天回头看了看,发现这几天遇到了,也用到了很多有用的小知识点。这些东西大概都充不满一篇博客的篇幅,但是这些零零总总的却都有点重要性。所以开了个坑,把这些零散的小知识点整理收集在刷题笔记里。以上。

一、lambda表达式(C++11)

第一次听说lambda表达式,是在高中搞oi时,在刘汝佳神犇写的大蓝书附录中看到的。蓝书是在介绍Java(还是Python来着,忘了)中的一些东西的时候顺带提出了这个东西。我当时以为和C++没有什么关系,所以仅仅觉得很神奇但却并没有深入研究和使用(其实NOIP并不能使用C++11的各种特性,所以当时我的反应也情有可原)。

前几天的洛谷日报上看到C++11竟然也支持lambda表达式,惊讶之余赶紧学习了学习。真的很好用啊(而且逼格十足)

基础定义和使用

Lambda表达式是一种匿名函数,基于数学中的λ演算而得名,直接对应其中的lambda抽象匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(即定义在函数内部的函数,函数内外交流的窗口)。

ISO C++11标准中引入了lambda表达式并且定义了其在C++中的基本语法:

其中各项的具体含义如下:

  1. capture list:捕获外部变量列表 可空不可省
  2. parameter list:形参列表 可空不可省
  3. mutable指示符:说明是否可以修改捕获变量 可省
  4. return type:返回类型 可省
  5. function body:函数体 可空不可省

实际写题应用中,lambda表达式可以省略的东西很多,其余的东西编译器会帮我们补全。

比如给一个vector<int> v;排序的话,通过lambda表达式,我们就可以这么写:

sort(v.begin(), v.end(), [](int a, int b) -> bool {return a < b;});

通过给一个lambda表达式命名可以重复使用同一个lambda表达式:

关于捕获变量-值捕获

值捕获和函数传参中的值转递相似,被捕获的值在lambda创建时通过值拷贝的方式传入,以局部变量的形式存在,之后修改该变量不会影响到lambda内部的值。但注意的是,不能在lambda表达式内修改值捕获变量的值。

若要修改值捕获变量的值,则需要在函数体前加上上边格式中的mutable关键字。修改值捕获变量的值不会影响到表达式外。

关于捕获变量-引用捕获

引用捕获和用法和值捕获相似,但是修改外部变量的值的时候,lambda内部的变量值也会被修改。

关于捕获变量-隐式捕获

我太懒了以至于不想在捕获列表一个一个写上捕获谁,这时候就需要隐式捕获了。编译器会为我们推断需要捕获哪些变量。

关于捕获变量-混合捕获

分三种,分别写成:

其他语言中的Lambda表达式基础语法

二、printf()场宽问题

这个问题其实很早之前刚学习C艹的时候就在用了。但是因为需要设置输出场宽的问题很少所以一直没怎么用过。前两天做题的时候遇到了一道需要设置场宽的题,竟然一时间没想起来。所以在这儿稍微记一下。

printf()中,形如%d的占位符,百分号后的数字正/负表示数字在场宽内的右/左侧,小数点前表示场宽,小数点后表示保留多少位小数。比如%-5.2lf就表示靠左/场宽5/保留两位小数的double。

三、重载自定义类内运算符的const

前几天做题的时候遇到了一个玄学bug:一个类一直编译不通过:

最后发现把重载运算符部分改成了这样:

才编译通过。在网上找了找原因,这里的const是为了给编译器表示函数中不会修改变量的值。(之前不加也没事儿啊orz)

四、类中的析构函数

了解到析构函数的起因是我正在使用的Sublime Text在创建类的时候在自动补全的时候会生成一个类似这样的东西:

我一直很疑惑这个~rua();是干什么用的,每次写都默默删掉它也不会报错,不删它也好像没什么影响。终于,我按耐不住心中的欲火在网上查了查,原来这个东西叫析构函数。析构函数和构造函数相反。构造函数是负责在新建一个对象的时候执行,而析构函数则是在删除一个对象的时候执行。它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(如关闭文件,释放内存等)前释放资源。而如果类中没有显式定义析构函数,编译器会自动定义一个啥都是空的析构函数(说白了就是算法竞赛里基本不用管)

最近做的题数量有限,遇到的值得记下来的东西也不是很多。就先记这么多,过一段时间再整理之后的刷题笔记。

以上,冻葱Tewi

于2018/08/09

转载原创文章请注明,转载自: 冻葱Tewi » 刷题笔记01
Not Comment Found