美文网首页
C++学习四:高级

C++学习四:高级

作者: 芳心之纵火犯 | 来源:发表于2021-04-08 15:15 被阅读0次

    STL容器相关

    一、vector向量

    // Java的集合框架 非常强大  相当于  C++  STL(标准模板库) #include <iostream>
    // TODO STL 是“Standard Template Library”的缩写,中文译为“标准模板库”。STL 是 C++ 标准库的一部分,不用单独安装。
    // STL 有很多很多的容器
    // C ++ vector 向量 容器 (内部:封装动态大小数组作为容器,能够存放任意的动态数组【数据结构】)
    #include <iostream>
    #include <vector> // 引入 vector 容器的支持
    using namespace std;
    int main() {
        vector<int> vector1;
        vector<int> vector2(10); // 指定10的空间大小
        vector<int> vector3(10, 0); // 有了10个值了 每个值都是0
        vector<int> vector4;
        // vector4.begin() 迭代器 插入到前面
        // vector4.end() 迭代器 插入到后面
        // 插入数据
        vector4.insert(vector4.begin(), 40);
        vector4.insert(vector4.begin(), 60);
        vector4.insert(vector4.begin(), 80);
        vector4.insert(vector4.begin(), 100);
        vector4.insert(vector4.begin(), 200);
    
        // 第一个  200 100 80 60 40
        cout << " 修改前:vector4.front():" << vector4.front() << endl;  
        vector4.front() = 99; // 默认修改第一个
        cout << " 修改后:vector4.front():" << vector4.front() << endl; 
    
        // 最后一个
        cout << " 修改前:vector4.back():" << vector4.back() << endl;
        vector4.back() = 777; // 默认修改最后 99 100 80 60 777
        cout << " 修改后:vector4.back():" << vector4.back() << endl;
    
        vector4.erase(vector4.begin()); // 移除第一个元素(内部:通过迭代器的位置 进行移除)  删除 100 80 60 777
    
        // 循环打印,默认 从大到小输出
        for (int i = 0; i < vector4.size(); ++i) { 
            cout << "item:" << vector4[i] << endl; //100 80 60 777
        }
    
        // KT的类型推到  相当于 C++ auto
        /*var a = 10;
        var b = 30.4f;
        var c = "";*/
    
        // 迭代器 循环遍历
        // auto Kotlin自带类型推导
        // for (vector<int>::iterator iteratorVar = vector4.begin(); iteratorVar != vector4.end(); iteratorVar++) {
        for (auto iteratorVar = vector4.begin(); iteratorVar != vector4.end(); iteratorVar++) {
            // 迭代器 当中指针操作  iteratorVar++
            cout << "迭代器:" << *iteratorVar << endl;
        }
        return 0;
    }
    
    

    二、stack栈

    //  先进后出
    #include <iostream>
    #include <stack>
    using namespace std;
    // NDK开发者 几乎用不到
    int main() {
        stack<int> stackVar;
    
        // 压栈(注意:stack无法指定那个位置去压栈)
        stackVar.push(30);
        stackVar.push(60);
        stackVar.push(90);
        //90 60 30
    
        // [] 角标是不行的,内部没有重载此运算符
        /*for (int i = 0; i < stackVar.size(); ++i) {
            // cout << stackVar[i] << endl;
            // cout << stackVar.at() << endl;
        }*/
    
        // 他根本就没有迭代器
        // 开发者 自己组装 迭代器 遍历
        /*for (stack<int>::iterator; i < ; ++i) {
        }*/
    
        // 慎用,为什么? 元素被弹完了
        // 这种方式是可以的,手枪把子弹全部打完【会把元素清空】
        while (!stackVar.empty()) {
            int top = stackVar.top(); // top == 获取栈顶的元素
            cout << "获取栈顶的元素:" << top << endl; // 永远拿 90
            stackVar.pop(); // 把栈顶的元素 弹出去  【删除】
        }
        /*int top = stackVar.top();
        cout << top << endl;*/
        return 0;
    }
    

    三、队列queue

    //先进先出
    #include <iostream>
    #include <queue> // 队列支持(内部:基本上 链表 、 数组 )
    using namespace std;
    int main() {
        queue<int> queueVar;
    
        queueVar.push(20);
        queueVar.push(40);
        queueVar.push(60);
        //20 40 60 
        // 第一个元素是谁 20  FIFO 原则
        cout << " 修改前: queueVar.front():" << queueVar.front() << endl;
        queueVar.front() = 88;  //88 40 60 
        cout << " 修改后: queueVar.front():" << queueVar.front() << endl;
    
        // 最后一个
        cout << " 修改前: queueVar.back():" << queueVar.back() << endl;
        queueVar.back() = 88; // 88 40 88
        cout << " 修改后: queueVar.back():" << queueVar.back() << endl;
    
        // 没有找到 角标
        /*for (int i = 0; i < 9; ++i) {
            queueVar[i];
        }*/
    
        // 他根本就没有迭代器
        /*for (queue<int>::iterator; i < ; ++i) {
        }*/
    
        // 慎用,为什么? 前面的元素全部被消费完了
        while (!queueVar.empty()) {
            cout << "while1:" << queueVar.front() << endl;
            queueVar.pop(); // 把前面的元素 给消费掉  【删除】
        }
        return 0;
    }
    

    四、list

    / / Java:ArrayList采用Object[]数组,   C++的list 内部:采用链表
    #include <iostream>
    #include <list> // list容器的支持
    using namespace std;
    int main() {
        list<int> listVar;
    
        // 插入操作
        listVar.push_front(50); // 插入到前面   明确
        listVar.push_back(60); // 插入到后面
        listVar.insert(listVar.begin(), 70); // 插入到前面  灵活
        listVar.insert(listVar.end(), 80); // 插入到后面
        //70 50 60 80
        // 修改操作
        listVar.back() = 88;
        listVar.front() = 55;
    
        // 删除
        listVar.erase(listVar.begin()); // 删除最前面的 55
        listVar.erase(listVar.end()); // 删除最后面的 88
    
        // list 迭代器
        // 不用通过角标去访问,也不能修改   遍历
        for (list<int>::iterator it = listVar.begin(); it != listVar.end() ; it ++) {
            cout << *it << endl;
        }
        return 0;
    }
    

    五、set

    // set(内部:红黑树结构),会对你存入的数据进行排序,但是绝对不允许元素相同
    
    #include <iostream>
    #include <set>
    using namespace std;
    int main() {
        set<int, less<int>> setVar; //  __x < __y 从小到大,默认情况下 就是 less
        // 添加参数,不需要用迭代器,也不需要指定位置
        setVar.insert(1);
        setVar.insert(3);
        setVar.insert(2);
        setVar.insert(4);
    
        // 重复插入,并不会报错  std::pair<iterator, bool>
        pair<set<int, less<int>>::iterator, bool> res = setVar.insert(8);
    
        // res.first 获取第一个元素 迭代器   当前迭代器   最后一个位置
        // res.second 获取第二个元素 bool
        bool insert_success = res.second;
        if (insert_success) {
            cout << "恭喜你,插入成功" << endl;
        } else {
            cout << "哎,插入失败.." << endl;
        }
    
        // 全部遍历  auto 自动推到
        for (auto it = setVar.begin(); it != setVar.end() ; it ++) {
            cout << *it << endl;
        }
        return 0;
    }
    

    六、谓词

    // 谓词 设计对象的排序
    #include <iostream>
    #include <set>
    using namespace std;
    class Person {
    public:
        string name;
        int id;
        Person(string name, int id) : name(name), id(id) {}
    };
    
    // C++ 都是一些常规的 谓词  不能满足功能, 模仿C++源码的谓词 自定义谓词 解决这个问题
    
    // C++缔造者写的这个源码 没有对象比较的功能 【系统源码谓词 做不到对象比较功能】
    // bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; }
    
    // 我们就自定义这个功能  【自定义谓词 没有达到谓词的标准】
    bool doCompareAction(const Person& person1, const Person& person2) {
        return person1.id < person2.id;
    };
    
    // 真正的谓词
    struct doCompareAction2 {
    public:
        bool operator() (const Person& __x, const Person& __y) {
            return __x.id < __y.id;
        }
    };
    
    struct doCompareAction3 {
    public:
        bool operator() (const Person& __x, const Person& __y) {
            return __x.id > __y.id;
        }
    };
    
    int main() {
        // 默认是 less  return 对象1 < 对象2;
    
        set<Person, doCompareAction2> setVar;
    
        // set<Person, doCompareAction3> setVar;
    
        // 构建对象
        Person p1 ("Snake", 1);
        Person p2 ("kevin", 2);
        Person p3 ("Derry", 3);
    
        // 把构建的对象 插入到 set 容器里面去
        setVar.insert(p1);
        setVar.insert(p2);
        setVar.insert(p3);
    
        // name string  ---  c_str() ---->   char *
        for (set<Person>::iterator it = setVar.begin(); it != setVar.end() ; it ++) {
            cout << it->name.c_str() << " , " << it->id << endl;
        }
        return 0;
    }
    
    

    七、线程

    1、基础
    #include <iostream>
    #include <pthread.h> 
    using namespace std;
    
    // void *(*)(void *)
    void * customPthreadTask(void * pVoid) { // 异步线程  相当于Java的Thread.run函数一样
        // C++转换static_cast  转换指针操作的
        int * number = static_cast<int *>(pVoid); // pVoid==number int的地址,所以我用int*接收,很合理
        cout << "异步线程执行了:" << *number << endl;
    
        return 0; // 必须返回
    }
    
    int main() {
        int number = 9527;
        /**
          int pthread_create (pthread_t *,  // 参数一:线程ID
                            const pthread_attr_t *, // 参数二:线程属性
                            void *(*)(void *), // 参数三:函数指针的规则
                            void *); // 参数四:给函数指针传递的内容,void * 可以传递任何内容
         */
        pthread_t pthreadID; // 线程ID,每个线程都需要有的线程ID
    
        pthread_create(&pthreadID, 0, customPthreadTask, &number);
    
        return 0;
    }
    

    2、pthread的3种情况

    //  第一种情况,main函数只要结束,不等异步线程,全部结束
    //  第二种情况,我们开发者,千万不要让 main函数睡眠的方式,去等待异步线程
    //  第三种情况,main函数一直等待 异步线程,只有异步线程执行完成后,我在执行 join后面的代码
    #include <iostream>
    #include <pthread.h> // Derry Cygwin 有 pthreads支持
    #include <unistd.h>
    using namespace std;
    // void *(*)(void *)
    void * runTask(void * pVoid) { // 异步线程  子线程
        int number = *static_cast<int *>(pVoid);
        cout << "异步线程执行了:" << number << endl;
    
        for (int i = 0; i < 10; ++i) {
            cout << "run:" << i << endl;
            sleep(1);
        }
        return 0;
    }
    
    int main() {
        int number = 999;
    
        pthread_t  pthreadID;
        pthread_create(&pthreadID, 0, runTask, &number);
    
        // 为了演示第二种情况
        // sleep(3); // main函数只 异步线程三秒钟
    
        // 异步线程在执行的过程中,我们的main函数 相当于 阻塞在这里不动了,只有异步线程执行完成后,我才开始执行join后面的代码
        pthread_join(pthreadID, 0);
    
        cout << "main函数即将弹栈..." << endl;
        return 0;
    }
    

    3、锁

    // C++ 互斥锁 == Java版本(synchronize) 多线程操作的安全  持有内置锁
    #include <iostream>
    #include <pthread.h>
    #include <queue>
    #include <unistd.h> // sleep(秒)
    using namespace std;
    
    queue<int> queueData; // 定义一个全局的队列,用于 存储/获取
    
    pthread_mutex_t mutex; // 定义一个互斥锁
    
    // void *(*)(void *)
    void * task(void * pVoid) {
        /*synchronize(锁) {
            // code
        }*/
    
        pthread_mutex_lock(&mutex); // 锁住
    
        cout << "异步线程-当前线程的标记是:" << *static_cast<int *>(pVoid) << "异步线程" << endl;
    
        if (!queueData.empty()) { // 有元素
            printf("异步线程-获取队列的数据:%d\n", queueData.front());
            queueData.pop(); // 把数据弹出去,删除的意思
        } else { // 没有元素
            printf("异步线程-队列中没有数据了\n");
        }
        // sleep(0.2);
        pthread_mutex_unlock(&mutex); // 解锁
        return 0;
    }
    
    int main()
    {
        // 初始化 互斥锁
        pthread_mutex_init(&mutex, NULL);
    
        // 给队列 初始化数据 手动增加数据进去
        for (int i = 10001; i < 10011; ++i) {
            queueData.push(i);
        }
    
        // 一次性定义10个线程
        pthread_t pthreadIDArray[10];
        for (int i = 0; i < 10; ++i) {
            pthread_create(&pthreadIDArray[i], 0, task, &i);
    
            // 不能使用 join,如果使用(就变成顺序的方式,就没有多线程的意义了,所以不能写join)
            // pthread_join(pthreadIDArray[i], 0);
        }
    
        // main函数等 异步线程
        sleep(12);
        // 销毁 互斥锁
        pthread_mutex_destroy(&mutex);
        cout << "main函数即将弹栈..." << endl;
        // 每次运行 效果都不同:1,8,9,10,3,2,5,8
        // 每次运行 效果都是错乱
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:C++学习四:高级

          本文链接:https://www.haomeiwen.com/subject/kdrghltx.html