欢迎关注我的大众号 [极智视界],获取我的更多经历共享

大家好,我是极智视界,本文介绍一下 从数组求和来看C++的开展。

邀您参加我的常识星球「极智视界」,星球内有超多好玩的项目实战源码下载,链接:t.zsxq.com/0aiNxERDq

从一个事例来看 C++ 的开展。

定义一个数组 {4, 2, 6, 7},求数组里所有数的和,并将之打印

如果是 python 的话,完成十分简练 (但你要清楚的是,代码简练并不代表程序效率高):

  • python
arr = [4, 2, 6, 7]
print(sum(arr))

那用 C++ 该如何完成呢。大家知道 C++ 是由 C言语开展而来,所以先来看一下 C言语的完成。

  • 古代:C言语
#include <stdlib.h>
#include <stdio.h>
int main(){
    size_t nums = 4;
    int *arr = (int *)malloc(nums * sizeof(int));
    arr[0] = 4;
    arr[1] = 2;
    arr[2] = 6;
    arr[3] = 7;
    int sum = 0;
    for(size_t i = 0; i < nums; i++){
        sum += arr[i];
    }
    printf("%d\n", sum);
    free(v);
    return 0;
}

C言语看起来显着要比 python 费事不少吧,多了 malloc内存管理、指针逐个赋值、循环加和的进程。

再来看 C++98。

  • 近代:C++98 引进了 STL 容器库
#include <iostream>
#include <vector>
int main(){
    std::vector<int> arr(4);
    arr[0] = 4;
    arr[1] = 2;
    arr[2] = 6;
    arr[3] = 7;
    int sum = 0;
    for(size_t i = 0; i < arr.size(); i++){
        sum += arr[i];
    }
    std::cout << sum << std::endl;
    return 0;
}

C++98 引进了 vector 这个模板类,自带内存管理,所以相比C言语不需求自己进行手动管理内存了。输出函数这里采用了运算符重载的特性,不必像C言语 printf 那样需求显式指定是要用 %d 仍是 %f 了,便利挺多。不过在数组赋值那一块仍是和C言语相同的。

接着来看 C++11。

  • 近现代:C++11 引进了 {} 初始化表达式
#include <iostream>
#include <vector>
int main(){
    std::vector<int> arr = {4, 2, 6, 7};
    int sum = 0;
    for(int i = 0; i < arr.size(); i++){
        sum += arr[i];
    }
    std::cout << sum << std::endl;
    return 0;
}

这样,经过花括号就把 C++98 中对数组的初始化给优化地愈加简练了。

别的,C++11 还引进了一个很便利的、根据规模的 for循环,来看看经过根据规模的 for循环怎样来进一步做简化。

  • 近现代:C++11 引进了 range-based for-loop
#include <iostream>
#include <vector>
int main(){
    std::vector<int> arr = {4, 2, 6, 7};
    int sum = 0;
    for(int a: arr){
        sum += a;
    }
    std::cout << sum << std::endl;
    return 0;
}

很显着,for 循环变得愈加简练了。

接着经过 C++11 的 for_each 还能够继续改造。

  • 近现代:C++11 引进了 for_each 算法模板
#include <iostream>
#include <vector>
#include <algorithm>
int sum = 0;
void func(int a){
    sum += a;
}
int main(){
    std::vector<int> arr = {4, 2, 6, 7};
    std::for_each(arr.begin(), arr.end(), func);
    std::cout << sum << std::endl;
    return 0;
}

for_each 是一个算法模版,能够套用到任何支持迭代器的容器。而 for_each 有个不太便利的地方,就是它的 func 是一个外部函数,需求去声明一个大局的 sum 就比较费事。对此,C++11 又引进了 lambda 表达式,这样就能够把 func 写在局部了,这样 sum 就能够为一个局部变量。

  • 近现代:C++11 引进了 lambda 表达式
#include <iostream>
#include <vector>
#include <algorithm>
int main(){
    std::vector<int> arr = {4, 2, 6, 7};
    int sum = 0;
    std::for_each(arr.begin(), arr.end(), [&] (int a){
        sum += a;
    });
    std::cout << sum << std::endl;
    return 0;
}

接着来到了 C++14,在 C++14 中答应 lambda 运用 auto 主动揣度类型了。

  • 现代:C++14 的 lambda 答应用 auto 主动揣度类型
#include <iostream>
#include <vector>
#include <algorithm>
int main(){
    std::vector<int> arr = {4, 2, 6, 7};
    int sum = 0;
    std::for_each(arr.begin(), arr.end(), [&] (auto a){
        sum += a;
    });
    std::cout << sum << std::endl;
    return 0;
}

运用了 auto 后,优点就在于 既能够用于 int 类型,也能够用于 float 类型等,要是哪天 arr 的数据类型改变了,auto 也不需求改就能够习惯,这样就愈加通用了。

继续,来到了 C++17,参加了编译期参数揣度,什么意思呢,来看。

  • 今世:C++17 CTAD / compile-time argument deduction / 编译期参数揣度
#include <iostream>
#include <vector>
#include <algorithm>
int main(){
    std::vector arr = {4, 2, 6, 7};
    int sum = 0;
    std::for_each(arr.begin(), arr.end(), [&] (auto a){
        sum += a;
    });
    std::cout << sum << std::endl;
    return 0;
}

看 arr 的声明,在 vector 后能够省掉 的类型定义了,由于右值都是整型,所以会主动揣度为整型。

别的,在 C++17 里边还引进了一些常用的数值算法,放在 这个头里边,比方这里能够用 reduce 归约来求和。

  • 今世:C++17 引进了常用的数值算法
#include <iostream>
#include <vector>
#include <numeric>
int main(){
    std::vector arr = {4, 2, 6, 7};
    int sum = std::reduce(arr.begin(), arr.end());
    std::cout << sum << std::endl;
    return 0;
}

当然,reduce 不只能够用于加法,还能够用于乘法,如果我们是要求 arr 中每个数的乘积,运用 reduce 的话能够是这样:

#include <iostream>
#include <vector>
#include <numeric>
int main(){
    std::vector arr = {4, 2, 6, 7};
    int sum = std::reduce(arr.begin(), arr.end(), 1, std::plus{});
    std::cout << sum << std::endl;
    return 0;
}

愈加拓展一点,reduce 内的函数还能够自定义,而自定义函数能够用 lambda 表达式来完成,比方仍是要求 arr 中每个数的和,运用 reduce 内自定义函数,能够是这样:

#include <iostream>
#include <vector>
#include <numeric>
int main(){
    std::vector arr = {4, 2, 6, 7};
    int sum = std::reduce(arr.begin(), arr.end(), 0, [] (int x, int y){
        return x + y;
    });
    std::cout << sum << std::endl;
    return 0;
}

继续进化,在 C++20 中引进了区间 ranges,来看看 ranges 将带来什么样的完成改变。

  • 未来:C++20 引进区间 ranges
#include <iostream>
#include <vector>
#include <numeric>
#include <ranges>
#include <cmath>
int main(){
    std::vector arr = {4, 2, 6, 7, 0, -2, -5};
	int sum = 0;
    for(auto &&a: arr
        | std::views::filter([] (auto &&x) {return x >= 0;})){
            sum += a;
        }
    std::cout << sum << std::endl;
    return 0;
}

经过 ranges 能够有一个挑选的功能在里边,甚至还能够经过 ranges 对挑选出来的元素再直接做一些操作再抛出来用,比方如果想要对以上数组 arr 中大于等于 0 的元素开个根号再求和,经过 ranges 能够这样写:

#include <iostream>
#include <vector>
#include <numeric>
#include <ranges>
#include <cmath>
int main(){
    std::vector arr = {4, 2, 6, 7, 0, -2, -5};
	int sum = 0;
    for(auto &&a: arr
        | std::views::filter([] (auto &&x) {return x >= 0;})
        | std::views::transform([] (auto &&x) {return sqrtf(x);})){
            sum += a;
        }
    std::cout << sum << std::endl;
    return 0;
}

别的,不得不说 C++ 一直也在学习一些 python 的特性,在往 python 挨近,原本 C++ 中是经过 include 来包含头文件的,而在 C++ 20 中引进了模块 module 的概念。

  • 未来:C++20 引进模块 module
import <iostream>;
import <vector>;
import <numeric>;
import <ranges>;
import <cmath>;
int main(){
    std::vector arr = {4, 2, 6, 7, 0, -2, -5};
	int sum = 0;
    for(auto &&a: arr
        | std::views::filter([] (auto &&x) {return x >= 0;})){
            sum += a;
        }
    std::cout << sum << std::endl;
    return 0;
}

看到这里,是不是会让你有一种错觉:我是在写 C++ 吗?[捂脸]

在 C++20 中,还对 auto 进行了再次的升级,答应函数参数为 auto 了。

  • 未来:C++20 答应函数参数为主动揣度 auto
import <iostream>;
import <vector>;
import <numeric>;
import <ranges>;
import <cmath>;
int func(auto &&a){
	int sum = 0;
    for(auto &&a: arr
        | std::views::filter([] (auto &&x) {return x >= 0;})){
            sum += a;
        }
    return sum;
}
int main(){
    std::vector arr = {4, 2, 6, 7, 0, -2, -5};
	int sum = func(arr);
    std::cout << sum << std::endl;
    return 0;
}

这里,是不是感觉会有一点了解呢?func 是不是看起来是和模板函数 template 的作用比较像。

别的在 20 里边还引进了一些多线程的特性,比方 std::future、协程之类的。虽然 C++20 挺香的,但是还没有遍及落地,甚至连 CMake 对 C++20 modules 的支持也不够好,所以暂时仍是能够把 C++20 作为拓展来进行学习,项目中仍是用 C++17 及以下的较多。

好了,以上共享了 从数组求和来看 C++ 的开展,希望我的共享能对你的学习有一点协助。



 【大众号传送】

《极智开发 | 从数组求和来看C++的开展》


畅享人工智能的科技魅力,让好玩的AI项目不难玩。邀请您参加我的常识星球, 星球内我精心整备了很多好玩的AI项目,皆以工程源码方式敞开运用,包括人脸、检测、切割、多模态、AIGC、主动驾驶、工业等。不敢说会对你学习有所协助,但一定十分好玩,并继续更新愈加有趣的项目。 t.zsxq.com/0aiNxERDq

极智开发 | 从数组求和来看C++的发展