记录一些有趣的东西
文章目录
- 1. [c] main 函数递归 以及 main函数的参数
- 2. [c++ 17] fold expression 的小栗子
- 3. 递归转非递归
1. [c] main 函数递归 以及 main函数的参数
总所周知,main函数也是函数, 并且它应该是有两个参数的,第一个参数放置的是传入参数的个数,第二个是每一个参数是字符串,一个char*[]类型的指针。
总之,main函数的传参列表可以长这样signed main(int argc, char*argv[])
第二个参数是一个二重指针,根本还是指针,在64位系统下,指针长度为8,所有我们可以用long来代替(不过有警告)
然后,我们就可以写出这种没用的代码:去递归main函数
#include <iostream> int main(int cnt, long ptr) {
if (cnt) {
std::cout << (char*)(*(char**)ptr) << " "; main(cnt - 1, ptr + 8); } return 0;
}
2. [c++ 17] fold expression 的小栗子
在c++ 17啊,推出了一个小东西,来解决c++11引入的
pack
在有些时候只能递归的尴尬场景,这个东西就是折叠表达式,用来简化解包
举个例子,现在我想自己封装一个print函数(老生常谈了属于是)
我们需要一个函数模板。以及一个特化的函数
// std c++ 11
void print(){
}
template<typename T, typename ...U>
void print(T t, U... u) {
std::cout << t << "\n,"[!!sizeof...(u)];print(u...);
}
上面有个特化,看着不舒服,我们换一种方式,损耗一丢丢空间,用另一种方法也可以去实现它
// std c++ 11
template<typename ...T>
void print(T... t) {
int i = sizeof...(t);bool f[sizeof...(t)] = {
(std::cout << t << "\n,"[!!--i], true)...};
}
欸, c++ 17不是有constexpr if 了吗?
那这个就解决了c++11需要特化一个print的情况了
那么就可以写成这种
// std c++ 17 constexpr if
template<typename T, typename ...U>
void print(T t, U... u) {
std::cout << t << ",";if constexpr(sizeof...(u) == 0) std::cout << t << "\n";else print(u...);
}
if else 看着好冗余啊。
可以再短一点吗?
那么,来看看c++ 17我们可以如何写它(利用fold expression)
// std c++ 17 fold expression
template<typename ...T>
void print(T... t) {
int i = sizeof...(t);((std::cout << t << "\n,"[!!--i]), ...);
}
当然,你也可以把它写成lambda表达式
这样子更快吗? (不清楚,也许这样子更modern C++)
// std c++ 17 lambda fold expression
[](auto... a) {
int i = sizeof...(a);((std::cout << a << "\n,"[!!-- i]), ...);
}(1, 2, "2", 3);
3. 递归转非递归
突然想起这个东西了,记录一下
例子就用的是一个斐波那契递归转非递归
思想就是保存当前函数的状态,然后给一个新的函数状态压入栈中
等新的函数状态执行完后,把栈弹掉。
还是利用了栈一样的结构去回复原来的地址
#include <bits/stdc++.h>using namespace std;
const int MOD = 1e9 + 7;int func(int x) {
struct frame {
int pc;int x, sum; /*variable*/};frame st[128];int ret = -1, idx = 0;st[++ idx] = {
.pc = -1, .x = x, .sum = 0};while(idx) {
st[idx].pc++;switch(st[idx].pc) {
case 0: if (st[idx].x <= 1) {
st[idx].sum = 1, st[idx].pc = 4;} break;case 1: st[idx + 1] = {
.pc = -1, .x = st[idx].x - 1, .sum = 0};++ idx;break;case 2: st[idx].sum += ret;break;case 3: st[idx + 1] = {
.pc = -1, .x = st[idx].x - 2, .sum = 0}; ++ idx;break;case 4: st[idx].sum += ret;break;case 5: ret = st[idx].sum; -- idx;break;}}return ret;
}
int main() {
for (int i = 0; i <= 24; i ++)cout << func(i) << " ";return 0;
}