C++
文章平均质量分 54
南种北李
这个作者很懒,什么都没留下…
展开
-
AVL树(C++)
插入的元素有序或者接近有序,二叉搜索树就会退化成单支树,时间复杂度会退化成。二叉搜索树有其自身的缺陷,假如往树中。二叉搜索树虽可以缩短查找的效率,但。,即可降低树的高度,从而减少平均。平衡因子=右子树高度-左子树高度。因此,两位俄罗斯的数学家。原创 2023-05-01 18:12:37 · 650 阅读 · 0 评论 -
C/C++数组默认初始化什么时候为零
数组如果定义为局部变量,默认初始化为随机值。数组如果定义为全部变量,默认初始化为0。原创 2023-03-02 17:57:03 · 609 阅读 · 0 评论 -
C语言先往int数组中以%d输入数字和字符后,再向char数组输入字符串会直接跳过。
原因是输入数字的时候,输入了数字字符和字母字符,但是它%d匹配的时候,第一个printf它会拿走缓冲区的数字字符,也就是拿走这里面的23,但是字母字符还在缓冲区留着,所以说下次scanf输入%s字符串的时候,它直接看到缓冲区有数据,它就直接匹配了,就把dsa给了b[0]。这里输入23dsa后,我并没有输入字符串,它就直接如上分别打印数字和字符串了。原创 2023-02-26 11:17:31 · 281 阅读 · 0 评论 -
C++set和map
insert要插入的pair如果不存在就会创建,如果存在则返回创建完的迭代器。第一个箭头获得结构的指针,第二个箭头获得结构的数据。这里面最后一行是先插入后修改的,插入时第二个string插入的是缺省值。s.find是二叉树式的查找,时间复杂度是O(logN)方框的本质是这样的。Key相同,即名字相同,再此插入相同的名字就会失败。因为可能会造成插入的地方的值与该位置 不匹配。multiset中find找到的是中序的第一个。用算法中的find也可以,find是个模板。map是搜索二叉树的KV结构。原创 2023-02-25 16:25:17 · 70 阅读 · 0 评论 -
C++多态
func构成虚函数重写,P调用test函数,实际是A调用的,test函数中的func由this指针调用,这个this指针是A*,所以这个func属于多态调用,由于p是B*,所以它调用的是B中的func,但是重写时,子类接口用的父类,不加virtual也是虚函数,所以它缺省值用的父类,所以打印的是1。调用时,虚函数指针指向父类虚函数表,那么就调用父类的虚函数,指向子类的虚函数表,你们就调用子类的虚函数。初始化列表初始化的顺序和写的顺序没关系,是按声明顺序初始化的,在继承里面就是学先继承,谁先被初始化。原创 2023-02-05 20:54:47 · 83 阅读 · 0 评论 -
C++继承
去掉继承方式,class默认是私有继承,子类外部不能访问继承成员,struct默认是公有继承,子类外部能访问继承成员。子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,上述代码中,Peraon叫父类,也叫基类,Student叫子类也叫派生类。子类对象 可以赋值给 父类的对象 / 父类的指针 / 父类的引用。public叫继承方式,继承方式包括公有保护和继承。子类和父类有同名成员时,子类隐藏了父类成员。赋指针也行,指针指向子类中的父类部分。我们看到父类中拷贝构造函数参数是父类。原创 2023-01-10 14:24:54 · 123 阅读 · 0 评论 -
C++模板进阶
同名的函数模板和普通函数可以同时存在,如果其它条件都相同,调用的时候优先调用普通函数,模板就不会产生对应的实例,如果模板可以产生一个更好匹配的函数,那么就会选择模板,如果模板产生了和普通函数的实例,则是重载的,如果需要调用的参数类型,和普通函数匹配,则函数模板不会实例化生成对应的函数。a.cpp中模板在编译阶段看不懂main.cpp中的代码,不知道是否会被调用,就不会实例化,链接阶段main.cpp中就找不到Add函数的地址,就会出错。这样就能比较日期类的地址了。特化出来的是函数,不是模板。原创 2023-01-09 20:35:03 · 55 阅读 · 0 评论 -
优先级队列
第三个参数虽然有对象的拷贝,,但这个对象因为只有一个成员函数,成员函数不占字节,所以这个对象只有一个字节,拷贝不会有太大影响。而如果我们传Date日期类的地址,我们发现,它会按地址进行比较,而每次运行,new出来的地址都不同,因此每次优先级排序都不同。改成引用的话,形参需要定义为const,类中的成员函数也需要定义为const。优先级队列是用vector适配的容器适配器。这也是之前优先级队列less表示大堆的原因。优先级队列是优先级高的先出队列。每个父亲大于孩子是大堆,小于孩子是小堆。默认是大数优先级高。原创 2023-01-08 11:39:41 · 92 阅读 · 0 评论 -
c++设计模式初步
deque底层是小段小段的数组,叫buffer,一般由多个buffer数组构成。有一个中控指针数组,存放每一个buffer的指针,每一个buffer存满后,就开辟新的buffer。deque随机查找效率较低,如果要随机查找,在第一个buffer中没有找到,就把要查找的第n个数字,的n减去第一个buffer中的数据个数,然后在第二个buffer中查找。如果要头插数据,就在第一个buffer前面新开辟buffer,并在新buffer的末尾插入数据。deque下标随机访问,有一定消耗,没有vector快。原创 2023-01-07 18:43:55 · 64 阅读 · 0 评论 -
vector和list对比
vector优点 链表是不连续的,命中几率会变小。综上,一般大量在中间或头部插入删除会用list链表。vector和list功能互补,相互配合。原创 2022-12-04 12:10:39 · 304 阅读 · 0 评论 -
C++list
list中没有find()模板,需要调用algorithm库中的find。没有reserve和resize了,因为链表是按需要申请和释放空间的。用库里面sort对vector排序要比list中的sort对链表排序快。平时不用头插和头删用vector,不用的话,用list也是可以的。但erase后,pos会失效,因为此时pos位置结点已经没了。元素访问没有[]了,意味着以后大部分需要使用迭代器进行访问。它俩能够相减,需要迭代器是连续的,而链表迭代器不连续。remove一个对象中没有的数,不会报错。原创 2022-12-01 19:04:33 · 1383 阅读 · 0 评论 -
[Linux]操作系统提供的函数和C库函数的区别
操作系统提供的函数,我们称之为叫做系统调用函数,它是由操作系统内核,为我们提供的那个接口(函数),C库函数 ,指的是,有一帮开发C运行时库的大佬,他给我们程序员,将系统调用函数又封装了一层,然后提供出来一些较为简单的一些函数,然后这些函数,都是被放到C运行时库也就是c.so当中的,提供给程序员进行使用,所以这一部分函数,我们称之为C库函数吧。原创 2022-11-21 14:57:17 · 334 阅读 · 0 评论 -
C++类模板
因为此时就不需要链接去找,.h头文件中就有这定义,.h已经被.cpp包含,预处理阶段就会展开,此时.cpp文件有声明和定义,就不存在链接的问题。比如下面T对于st1和st2分别是double和int,可见两个类的大小是肯定不同的,st1和st2是两种不同的类。模板不支持分离编译,会在链接阶段报错,说明不是定义的问题,而是找不到的问题。它们是一个类模板实例化出来的,但是模板参数不同,它们就是不同的类型。用的地方实例化了,实例化的文件只有声明,但此文件没有类的定义。但有定义的文件中却没有实例化。原创 2022-11-19 21:26:54 · 180 阅读 · 0 评论 -
C++函数模板
而且就算它到了强转那步也会有问题,因为模板形参是引用,而转化后的临时对象具有常性,是不能变的,相当于const T型,是不能传给T形的,因为那样此对象权限会飞的,而也不能在形参定义时T&前加const,因为那样函数内就交换不了了。下面这么写并没有报错,说明两个参数的模板,Add只会对第一个参数实例化为int型,因为如果对第二个参数也实例化了,那么e会隐式类型转换,T2前没有const,e的参数权限放大,会报错。下面这样写也不行,因为e是强制类型转换的,同样具有常性,第二个T前也需要加const。原创 2022-11-19 14:14:18 · 365 阅读 · 0 评论 -
c/c++中malloc/free和new/delete区别
malloc/free和new/delete区别。以上内容重在理解,不要死记。原创 2022-11-18 21:15:19 · 241 阅读 · 0 评论 -
C++string深拷贝的进阶写法(现代写法)。
swap前面如果不写std::的话会报错,因为swap会先在局部找,但是在局部类域找到的只有一个参数的swap,所以会报错。s2(s1)需要用到拷贝构造函数,大多数情况下,我们写string拷贝构造函数我们会这样写,创建一个新空间后,把内容依次考入。但是出拷贝构造函数时,tmp要释放,要调用析构函数,此时tmp的_str已经变成和原先this->_str一样的值,上面的第二个,其实是类模板,在上述代码中,T被系统识别为string类型,这里面需要进行三次深拷贝。下面是赋值的进阶写法。这两个都是有意义的。原创 2022-11-18 19:13:17 · 1140 阅读 · 0 评论 -
C++vector
value_type()相当于T(),如果是自定义类型,相当于调用它的构造函数。如果是内置类型,也可以拿构造函数理解。平时只关注第一个参数就行,第一个参数要考虑决定了vector里面存什么类型数组。这里面的int就是下面的T,就是这个类型,val就是value_type这个类型的数据。如果不断扩容,后面不一定有足够空间原地扩容,所以可以用reserve先申请空间。因为2倍通常比较合适,如果扩少了,会导致频繁扩容,扩多了,会造成空间浪费。第二第三是使用迭代器构造,第四个是拷贝构造。Linux上是2倍扩容。原创 2022-11-17 19:24:18 · 520 阅读 · 0 评论