自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(335)
  • 收藏
  • 关注

原创 1. 单片机时钟与GPIO

本博客用于记录 百问网 7天物联网培训中所学习的知识STM32时钟分类:HSE:高速外部时钟HSI:高速内部时钟LSI:低俗内部时钟LSE:低俗外部时钟外部时钟精度高,低俗外部时钟通常给看门狗用。查看时钟引脚后,可以通过CubeMX设置时钟:STM32的GPIOSTM32F103C8T6一共有48个引脚按A、B、C分组,每组16个引脚,编号0~15,STM32F103C8T6有两组GPIO,每组16个引脚,即32个GPIO引脚GPIO支持八种工作模式输出模式:推挽输出、开漏输出

2022-05-11 17:07:54 790

原创 3.类型转换

static_caststatic_cast:静态转换,理解成“正常转换”,编译时就会进行类型转换的检查。c风格的强制类型转换、编译器能够进行的隐士类型转换,都可以用static_cast显示完成。//1.整型和实型之间转换double f = 100.34f;int i = static_cast<int>(f);//2.子类转成父类(继承关系)class A{};class B : public A{};B b;A a;A a = static_cast<A&g.

2022-04-27 23:37:38 160

原创 2. 函数后置返回类型、内联函数

函数后置返回类型//前置返回类型void func1(int a,int b){}//后置返回类型 C++11auto func2(int a,int b)->void{}内联函数//函数定义前加上inline 就成了内联函数inline int myfunc(){ return 1;}/*1. 频繁地调用简单地函数,需要频繁地分配内存、压栈、出栈等,不划算inline影响编译器,在编译阶段对这种函数进行处理,系统尝试将调用该函数地动作替换为函数本体(如上:retu

2022-04-27 22:17:18 252

原创 1. const、constexpr浅谈

var和var2表面上是一个东西,实际上不是的。C++中,当碰见const声明时在符号表中放入常量,编译过程中发现使用常量则直接以符号表中的值替换,编译过程中若发现:对const常量使用extern对const常量使用&操作符则给对应的常量分配存储空间例如:const int c = 0;编译器编译到这里时,将常量c放入符号表。int* p = (int*)&c;到这里时会给c分配空间,上一步只是放入符号表!C++11新关键字:constexpr也是个常量的概念,.

2022-04-27 21:12:27 759

原创 43. 设计模式2

结构性模式:关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。代理模式Proxy:/*代理Proxy模式 : 通过代理类,来控制实际对象的访问权限客户 助理Proxy 老板 委托类*/class VideoSite // #1 抽象类{public: virtual void freeMovie() = 0; // 免费电影 virtual void vipMovie() = 0; // vip电影 virtual void ticketMov

2022-03-03 14:43:14 344

原创 42.设计模式1

饿汉单例模式:(是线程安全的)一个类不管创建多少次对象,永远只能得到该类型一个对象的实例!class Singleton{public: static Singleton* getInstance()//获取类的唯一实例对象接口方法 { return &instance; }private: static Singleton instance;//定义一个唯一的类的实例对象 Singleton() { } Singleton(const Singleton&amp

2022-03-03 12:30:51 293

原创 41. 线程间同步通信-生产者消费者模型

std::mutex mtx;std::condition_variable cv;//条件变量,线程间的同步通信操作//生产者生产一个物品,通知消费者消费一个;消费完了,消费者再通知生产者生产!class Queue{public: void put(int val) { while(!que.empty()) { unique_lock<std::mutex> lck(mtx); //que不空,通知消费者消费,消费完了再继续生产 //下面两行代码实

2022-03-02 19:45:36 94

原创 40.C++11多线程

语言级别的多线程=》代码跨平台 Windows、linux、macosthread/mutex/condition_variableatomic原子类型,基于CAS操作的原子类型(线程安全)sleep_for本质上都是在调用系统的API一、如何创建启动线程?std::thread定义一个线程对象,传入线程所需要的线程函数和参数,线程自动开启!void threadHandler(int time){ std::this_thread::sleep_for(std::chrono::sec

2022-03-02 15:58:37 232

原创 39. C++11常用知识点总结

auto可以根据右值,推导出右值的类型,然后左边变量的类型也就已知了!nullptr指针专用(和整数进行区别)#define NULL 0(NULL其实是个宏定义)foreachfor(Type val : container) => 底层就是指针或者迭代器实现的右值引用:少了内存开辟,拷贝构造。move移动语义构造和forward类型完美转发函数模板新特性:typename… A 表示可变参(类型参数)函数对象function:函数对象bind绑定器 bind1st和bin.

2022-03-01 21:44:14 388

原创 38. lambda表达式实现原理、实践

函数对象的缺点使用在泛型算法参数传递,比较性质/自定义操作,优先级队列,智能指针删除器lambda表达式的语法:[捕获变量](形参列表)->返回值{操作代码}template<typename T=void>class TestLambda01{public: TestLambda01(){} void operator()()const { cout << "hello world!" << endl; }};template&lt

2022-03-01 20:59:53 338

原创 37.bind和function实现mini线程池

bind绑定器返回的结果还是一个函数对象bind是函数模板,可以自动推演模板类型参数class ThreadPool{public: ThreadPool(){} ~ThreadPool(){} void startPool(int size) { for(int i=0;i<size;++i) { _pool.push_back(new Thread(bind(&Thread::runInThread,this,i))); } }private: v

2022-03-01 12:25:11 79

原创 36. function实现原理

void hello(string str){ cout << str << endl;}int sum(int a,int b){ return a+b;}template<typename FTy>class myfunction{};template<typename R,typename A1>class myfunction<R(A1)>{public: using PFUNC = R(*)(A1);

2022-02-28 17:14:16 139

原创 35. function函数对象类型的应用实例、模板完全/部分特例化

function:绑定器,函数对象,lambda表达式本质上都是函数对象,只能使用在一条语句中!function作用?

2022-02-28 15:54:00 120

原创 34.绑定器、bind1st、bind2nd、my_find_if实现

C++ STL中的绑定器bind1st:operator()的第一个形参变量绑定成一个确定的值bind2nd:operator()的第二个形参变量绑定成一个确定的值int main(){ vector<int> vec; srand(time(nullptr)); for(int i=0;i<20;++i) { vec.push_back(rand()%100+1); } sort(vec.begin(),vec.end());//默认从小到大排序 retur.

2022-02-28 13:32:19 300

原创 33. 自定义删除器

智能指针能够保证资源绝对的释放!template<typename T>class MyDeletor{public: void operator()(T* ptr)const { delete[] ptr; }};template<typename T>class MyFileDeletor{public: void operator()(T* ptr)const { fclose(ptr); }};int main(){ unique

2022-02-28 09:58:22 78

原创 32.shared_ptr交叉引用问题

shared_ptr:强智能指针 可以改变资源的引用计数weak_ptr:弱智能指针 不会改变资源的引用计数交叉引用:造成new出来的资源无法释放,资源泄露问题!定义对象的时候,用强智能指针!引用对象的地方使用弱智能指针!改进:就可以了,weak_ptr不会+1;他本身没有提供* ->的重载,只会观察资源,不能访问资源!那他有什么用???:把他提升成强智能指针!多线程共享对象的线程安全问题!:...

2022-02-27 21:39:21 270

原创 31. 智能指针

template<typename T>class CSmartPtr{public: CSmartPtr(T* ptr = nullptr) :mptr(ptr) {} CSmartPtr(const CSmartPtr<T>& src) { mptr = new T(*src.mptr); } ~CSmartPtr() { delete mptr; mptr = nullptr; } T& operator*() {

2022-02-27 20:17:29 369

原创 30. 右值引用、move、forward

/*CMyString(const char*)CMyString(const char*)CMyString(const char*)CMyString(const CMyString&) => tmpStr拷贝构造main函数栈帧上的临时对象~CMyStringoperator=(const CMyString&) => main函数栈帧上的临时对象给t2赋值~CMyStringaaaaaaaaaaaaaaaaaaaa~CMyString~CMyStr..

2022-02-27 15:21:31 197

原创 29. 高效编程

2022-02-27 12:55:52 130

原创 28.面经(一)

多个进程用户空间是单独的隔离的,而内核空间是共享的!程序的内存布局堆栈函数调用参数如何传递(汇编层面)函数调用参数为什么从右向左压栈?(C、C++支持可变参函数,所以要从右向左压栈)内存的最小单位为1...

2022-02-26 20:29:55 283

原创 27.泛型算法和绑定器

#include <iostream>#include <vector>#include <algorithm> // 包含了C++ STL里面的泛型算法#include <functional> // 包含了函数对象和绑定器using namespace std;#if 0/*五、泛型算法 = template + 迭代器 + 函数对象特点一:泛型算法的参数接收的都是迭代器特点二:泛型算法的参数还可以接收函数对象(C函数指针)sort

2022-02-26 15:25:33 77

原创 26. 迭代器iterator、函数对象

#include <iostream>#include <vector>using namespace std;/*容器的迭代器const_iterator:常量的正向迭代器 只能读,而不能写了iterator:普通的正向迭代器reverse_iterator:普通的反向迭代器const_reverse_iterator:常量的反向迭代器*/#if 0int main(){ vector<int> vec; for (int i = 0;.

2022-02-26 14:33:43 261

原创 25. 无序关联容器、有序关联容器

// 不会存储key值重复的元素(插入50个,可能元素个数只有18,好多重复) unordered_set<int> set1; for (int i = 0; i < 50; ++i) { set1.insert(rand()%20+1); // vector/deque/list insert(it, val) } //哈希表元素的个数! //cout << set1.size() << endl; //值为15的元素的个数! //...

2022-02-26 13:20:41 333

原创 24. 详解容器适配器

标准容器-容器适配器如何理解适配器?适配器底层没有自己的数据结构,他是一个容器的封装,他的方法全部由底层依赖的容器进行实现的!没有实现自己的迭代器!template<typename T,typename Container=deque<T>>class Stack{public: void push(const T&val) { con.push_back(val); } void pop() { con.pop_back(); }

2022-02-26 00:28:29 96

原创 23. STL::deque、vector、list对比

deque:双端队列容器!底层是2倍扩容的动态数组!动态开辟的二维数组,一维数组从2开始,以二倍的方式扩容!每次扩容后,原来的第二维从新的第一维数组oldsize/2开始存放,上下都预留空行,方便支持deque的首位元素添加!deque<int> deq;deq.push_back(20);从末尾添加元素O(1)deq.push_front(20);从首部添加元素O(1)vector从首部添加:vec.insert(vec.begin(),20) O(n)deq.insert

2022-02-25 23:32:44 330

原创 22.STL::vector

vector:向量容器底层数据结构:动态开辟的数组,每次以原来大小的2倍进行扩容!vector<int> vec增加:vec.push_back(20);时间复杂度O(1) 可能导致容器扩容。容器中进行对象的构造析构,内存的开辟释放,都是通过allocator空间适配器实现的!allocate deallocate construct construct四个函数!vec.insert()时间复杂度O(n)删除:vec.pop_back()末尾删除元素O(1)vec.e

2022-02-25 00:05:17 338

原创 21.四种类型转换方式

C++语言级别的四种类型转换方式:const_cast:去掉常量属性的一个类型转换!<>里面必须是个指针或者引用!!!汇编层面是一样子的!static_cast:提供编译器认为安全的类型转换!没有任何联系的类型之间的转换就会被否定!!reinterpret_cast:类似于C风格的强制类型转换!dynamic_cast:主要用于继承结构中,可以支持RTTI类型识别的上下转换!class Base{public: virtual void func() = 0;

2022-02-24 20:42:07 181

原创 20.菱形继承

虚继承可以解决菱形继承带来的数据重复、浪费资源的情况!C++多重继承-菱形继承的问题:派生类有多个间接基类的数据!如何解决?虚继承!

2022-02-24 19:38:45 56

原创 19.理解虚基类虚继承

抽象类:有纯虚函数的类virtual:修饰成员方法是虚函数可以修饰继承方式,是虚继承。被虚继承的类,叫做虚基类!如果不是虚继承,那么内存分配:A::mamb如果虚继承的话:vbptrmbA::ma0:向上的偏移量!8:到虚基类数据的偏移量!class A{public: virtual void func() { cout << "call A::func" << endl; } void operator delete(void *ptr)

2022-02-24 19:10:19 264

原创 18.继承多态笔试题实战分析

class Animal{public: Animal(string name) :_name(name) {} // 纯虚函数 virtual void bark() = 0;protected: string _name;};// 以下是动物实体类class Cat : public Animal{public: Cat(string name) :Animal(name) {} void bark() { cout << _name << " bar

2022-02-24 15:08:33 205

原创 17. 虚析构函数、再谈动态绑定、多态到底是啥、抽象类

虚函数能产生函数地址!存储在虚函数表对象必须存在,因为只有对象,才存在虚函数指针、表、虚函数地址构造函数完成,对象才产生!构造函数不能是virtual,构造函数调用虚函数,不会发生静态绑定!(构造函数中,调用的任何函数都是静态绑定的!)派生类对象构造过程:先调用父类构造函数,再调用子类构造函数!virtual+static是不行的,因为静态方法不依赖对象!(联想到第二点!)//如果父类析构函数不是虚函数:Base *pb = new Derive(10);pb->show(); /.

2022-02-24 13:24:21 184

原创 16. 虚函数、静态绑定、动态绑定

改一波(改成虚函数):总结一:如果类里面定义了虚函数,那么在编译阶段,编译器给这个类类型产生一个唯一的vftable虚函数表,虚函数表中主要存储的内容就是==RTTI指针和虚函数的地址!==当程序运行时每一张虚函数表都会加载到内存的.rodata区!(只读数据区)RTTI:run-time type information 运行时的类型信息。此时虚函数表是Base,所以Base vftable的RTTI指针指向代表“Base”这个字符串!上述代码加了虚函数关键字之后,sizeof大小变成了.

2022-02-23 22:26:30 230

原创 15. 继承、重载、覆盖、隐藏

继承的本质和原理本质:a.代码复用 b.子类父类相同的变量名字是没有关系的!派生类怎么初始化从基类继承来的成员变量呢?解答:通过调用基类相应的构造函数来初始化,不允许用派生类初始化列表的方法初始化基类成员变量(报错!),只能像这样子(调用构造函数):派生类的构造函数和析构函数,负责初始化和清理派生类部分派生类从基类继承来的成员,的初始化和清理由谁负责呢?是由基类的构造和析构函数来负责派生类优先在自己作用域查找函数,没有才去基类找!上面的代码:d.show()没有问题,但是d.s.

2022-02-23 19:02:32 160

原创 14. 对象池、new、new[ ]、delete、delete[ ]混用

new和deletemalloc和new区别malloc按字节开辟内存;new开辟内存时需要指定类型new int[10]所以malloc开辟内存返回的都是void* ,上面的operator new返回的是int*malloc只负责开辟空间,new不仅仅有malloc的功能,可以进行数据的初始化new int(20);new int20;(20个元素初始化为0)malloc开辟内存失败返回nullptr指针;new抛出来的是bad_alloc类型的异常free和delete区别?de.

2022-02-22 23:43:21 179

原创 13. 迭代器失效问题、迭代器失效底层原理及实现

上述程序很大可能报错!这就叫迭代器失效!(扩容也失效!)当容器调用erase方法后,当前位置到容器末尾元素所有迭代器全部失效当容器调用insert方法后,当前位置到容器末尾元素所有迭代器全部失效迭代器失效后,如何解决?对插入删除点的迭代器进行更新操作!:erase后返回erase元素的下一个元素的迭代器!insert后返回的是插入的元素的迭代器迭代器失效如何实现?#include <iostream>using namespace std;#if 0// 定义容器..

2022-02-22 15:10:52 410

原创 13. vector容器迭代器iterator自实现

以下是上一篇博客实现的带空间适配器alloctor的vector代码!template<typename T>struct Allocator{ //负责内存开辟 T* allocate(size_t size) { return (T*)malloc(sizeof(T)*size); } //负责内存释放! void deallocate(void* p) { free(p); } //负责对象构造! void construct(T* p,const T&a

2022-02-22 13:02:49 748

原创 12.复数类、重载<< >>、string类、iterator迭代器

class CComplex{public: CCOmplex(int r=0,int i=0) :mreal(r),mimage(i) {} //指导编译器如何做CComplex类对象的加法操作 CComplex operator+ (const CComplex& com) { CComplex comp; comp.mreal = this->mreal + src.mreal; comp.mimage = this->mimage + src.mim

2022-02-22 12:12:37 443

原创 11. 函数模板、类模板、实现vector顺序容器、空间适配器

// 模板的声明template<typename T> bool compare(T a, T b){ return a>b;}int main(){ compare<int>(20,30); //模板的实参推演! compare(20,30);}编译器优先把函数名看成普通函数,找不到的话,才考虑是个函数模板!:compare (“aaa”,“bbb”);模板不能分开文件定义(一个文件定义,一个文件使用)!因为编译产生符号,链接时找不到符号,出

2022-02-21 13:48:51 587

原创 10. 静态成员变量、静态成员方法、指向类成员的指针

静态成员变量初始化只能在类外初始化静态成员变量,在类大小计算时,不计算大小!(不考虑)不属于对象,而是属于类级别(全局对象)static 静态成员方法和普通成员方法区别:静态方法调用使用作用域调用(类名),他不需要依赖对象,所以不产生this指针!它不需要接受对象的地址而普通方法会产生this指针!所以必须用对象来调用!类的静态成员方法不能调用类的普通成员对象,因为它不会生成this指针!但是可以调用静态成员变量(static)!const 常对象不能调用非const成员函数!为..

2022-02-20 22:31:40 238

原创 9.类和对象实践、初始化列表

class String{public: String(const char* str = nullptr) { if(str!=nullptr) { m_data = new char[strlen(str) + 1]; strcpy(this->m_data,str); } else { m_data = new char[1]; *m_data = '\0'; } } String(const String& other) {

2022-02-20 18:51:17 242

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除