当前位置: 代码迷 >> 综合 >> C/C++ 札记(modern C++11/14/17/20 的东西)
  详细解决方案

C/C++ 札记(modern C++11/14/17/20 的东西)

热度:13   发布时间:2023-11-21 22:23:13.0

记录一些有趣的东西

文章目录

  • 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;
}
  相关解决方案