原始字符串(Raw String Literals)
C++ 11特性
一种所见即所得的东西,可以完美返回你想要的字符串,包括换行等等
大体长这样
R"()"
使用方式如
string k = R"(asdfasd sd gf a)";
cout << k << endl;
输出
asdfasd sd gf a
其中"(
和)"
叫做定界符,是用来说明你需要返回的字符串范围的,将返回字符串之内的字符串。如果想输出"(
和)"
可以自定义定界符。
很简单就是在"
与(
中间,和,)
与"
中间加上相同的任意字符即可
如下
R"#%()#%";
定界符就为"#%(
和#%)"
如下
#include <iostream>using namespace std;int main()
{string k = R"#%(asdfhhh )#%";cout << k << endl;}
输出
asdf
hhh
可以看出来在这之内的都会输出,可以换行,而且所见即所得。
多测
关于多测一般不要用 memset 特别是 T 很大的时候。
优先队列
priority_queue 默认大根堆,而一般我们用小根堆,这时候就需要使用 priority_queue<int, vector<int>, greater<int>> q;
这样定义使他变为小根堆。也可以把存入的权值变成它的相反数,但要注意取出时变回来。
注意
函数内传入形参数组,无法直接知道其长度无法使用sizeof (它以字节计位)
浮点数和memset
如 double 清最大值 一般用 0x42,这个大小为1e11,43 为 1e16,44为1e20。
40 32.502
41 2.26163e+06
42 1.56842e+11 *
43 1.0844e+16 *
44 7.47708e+20
45 5.14291e+25
46 3.52954e+30
而极小值
bf -0.12402
c0 -8577.51
c1 -5.95821e+08
c2 -4.12554e+13 *
c3 -2.84839e+18 *
c4 -1.96154e+23
而 long double,使用 %Lf 格式输出输入,但不可 memset。
不知道为什么在 P11290 【MX-S6-T2】「KDOI-11」飞船 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) long double 搞了我好久(最起码1.5h),改成double就对了。发现 long double 在 memset 后极易爆 nan,本身就成nan虽然还能正常输出。正常还是别用 memset 清 long double,循环吧。
而 double memset 后不容易爆 nan (兼容性好?),可以memset,一般没事。
经测试,[1, 0x7f]
,与 0xff 都会使 long double memset后变成 nan,因此memset不要对long double使用(目前不知道原因)。不要使用。通过 isnanf(),位于 cmath 里的一个函数可以检测nan(是nan返回 true 否则 false)。
isnan函数、isinf函数c语言实现-CSDN博客 估计是那些初始化刚好使其变成了NaN。
浮点异常值:NAN,QNAN,SNAN - konlil - 博客园 (cnblogs.com)
而 double 除了 0xff 以外 memset 后都不是 nan。可以放心使用。注意 nan \(\not =\) nan,这里表示两nan不相等,\(a + nan = nan\) 这里的nan表示还是非数字, 所以 \(a + nan \not = a + nan\)。
fill
fill可以给数组赋值,而非 memset 的每位填充。但效率较低。甚至不如直接 for。但确实简单,和 sort 这类函数一样的用法,只不过形参三个,前两个是指针,最后是赋值。
这是下面博客里的图
关于循环赋值、memset与fill的效率测试 - ViKyanite - 博客园 (cnblogs.com)
二维数组传参
为了代码表示,下面数组都写成代码块形式。
把二维数组传入函数时,可以使用简单的 \(auto\) 类型直接搞定指针,也可以使用 int (*a)[5]
把一个 g[3][5]
数组传入函数,当然,也可以直接使用 int a[][5]
此时需要直到第二维的大小。
总结一下,如果要简单一点,可以直接使用 \(auto\) 类型,自动而省心,如果想学习可以使用后两种。
二维数组的变量名本质上也是一个地址,但是有的不一样,它包含了捆绑的数组大小,如 g[3][5]
中的存储本质是:
int g[3][5] = {{1, 2, 3, 4, 5},{6, 7, 8, 9, 10},{11, 12, 13, 14, 15},
};
对于 g[3][5]
中第二维的 [5]
代表了 5 个一组,实际上就是这样,而 int a[][5]
中可以写 []
是因为对于第一维来说长度可以无限增加,而后面的限制必须存在,因此第一维可以空,而后面的维度缺一不可。
除此之外,我们还可以使用 int *a[]
来传递二维数组,一维的指针数组等于二维数组。
void find(int a[][5])
{
}void find(auto a)
{
}void find(int (*a)[5])
{
}void find(int *a[])
{
}
调用主函数
即调用主函数通过主函数自调用实现一些循环。少用,但可能有妙用。
主函数的参数
详细见这个文章:C语言main函数中的argc和argv参数有什么用? - C语言中文网
注意:其中的 \(argc\) 和 \(argv\) 本身都只是普通变量名而已,不是特殊变量名。
\(getline\) 和 \(stringstream\)
getline
auto 的妙用
实现函数多类型参数调用和多类型返回
如果写一个判断函数,要给 int,double 是两中类型使用,通常会写两个函数,分别判断,或者只写一个 double 的,给两个使用,第一种麻烦,第二种类型变化,但仍可以使用。
更好的是使用 auto 作为参数,自动识别,利于使用,而且 auto 的识别是类型的识别,而非数值。这就可以实现一个函数的多类型参数。
int smp(auto a, auto b)
{cout << a + b << endl;return a < b;
}
同时,你也可以吧返回值写成 \(auto\),这样可以实现一个函数,返回多种类型。