自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 C++语法——右值引用、移动构造和赋值、万能引用和转发、move和forward底层实现

是的,因为to_string内部会生成一个string对象,而该对象是局部变量,出了函数作用域就销毁,因此只能调用拷贝构造to_string内部的对象。因为右值作为“暂时存在的数据”,把数据交给目标对象,目标对象把“舍弃”的数据交给右值,正好可以“延续”目标数据且消除原本数据。通过remove_reference源码可以看到,不管传入的是左值引用还是右值引用,它都只会返回这个值去掉引用后的类型。即当模板的参数是右值引用的形式,如果实参是左值就是左值引用,右值就是右值引用。

2022-11-21 17:00:00 2123 10

原创 如何处理海量数据文件以及大文件数据查找

同样,一个数据只会映射一个比特位,在两个位图中会映射同样的比特位,这两个比特位正好可以用于记录数据出现的次数。数据第一次映射时置为0 1,第二次为1 0,第三次为1 1。如果是40亿个数据,最多就需要40亿个比特位,即476MB。当找寻数据时,只需要在位图中找到该数据对应的比特位,如果为1说明有,0说明没有。当然,前提是数据进文件时就已经建立位图了,否则查找时再建立位图还是要遍历数据。这时一个位图已经无法满足需求,因为一个位图只能通过0和1判断数据是否存在。不管是哪种,面对40亿个数据其效率都不会太高。

2022-11-18 18:45:00 1576 6

原创 C++语法——make_heap、push_heap、pop_heap、sort_heap使用介绍

这个函数用于建立堆。前两个参数为迭代器类型,最后一个为仿函数,用于确定建堆方式。默认使用大堆排序。可以调用官方仿函数greater,构建小堆排序,也可以自定义仿函数给参数comp。使用方式如下:这个用于将堆底数据加入堆结构中。因为nake_heap只能建堆,如果当前堆数据发生改变,就需要使用push_heap重回大堆/小堆。值得注意:first-last之间的元素必须满足堆结构。它仅仅是将last之后元素插入堆中。意思就是,如果一次性插入多个元素,它只会把最后一个元素(堆底)加入堆结构中

2022-11-15 10:30:00 3308 7

原创 手把手教你实现红黑树

手把手教你实现AVL树、平衡二叉树红黑树是在1972年由发明的。其特点是从根到叶子节点的所有路径中,最长路径不大于最短路径的2倍。可以说红黑树是AVL树的plus版,因此,红黑树查找时间与AVL树相同,都为O(log N)。同时,红黑树没有做到AVL树那种绝对平衡,因此其旋转次数少于AVL树。当数据量大时,其效率要优于AVL树。正因如此,在实际应用中往往采取红黑树而非AVL树。

2022-11-12 15:15:00 2400 3

原创 《Effective C++》学习笔记——区分接口继承和实现继承

当然,这种方法也不是万全之策,因为它要求defaultFly函数应该是非虚(non-virtual)函数,任何一个派生类都不应该重定义它。但此时如果需要新上线一款飞机,它与前两种的不同就在于飞行方式,又因为时间原因急于上架而忘记了对fly函数重定义,那灾难就发生了。实现基类函数时,我们需要考虑基类该函数与派生类该函数关系后,再给予具体的实现方式。我们先定义一个基类飞机,它会实现一个飞行方法,因为所有的飞机都能飞。,这样当派生类定义时,可以直接调用基类函数,也就是缺省实现继承。

2022-11-06 15:45:00 159 5

原创 学懂如何计算结构体内存大小

结构体内存对齐方式需要同时满足数据内存对齐与结构体整体内存对齐两个限制要求。数据内存对齐数 = min(数据所占字节数,默认对齐数)。默认对齐数是编译器所规定的。在32位机器下是4字节,64位机器下是8字节。各常用类型数据对齐数如下:结构体整体内存对齐数 = min(最大数据类型字节,默认对齐数)最大数据类型字节就是这个结构体中所有数据类型中所占字节最大的类型。默认对齐数与文一致,32位下是4字节、64位下是8字节。

2022-11-06 09:15:00 1696 5

原创 Linux——gdb调试时多进程切换方法(attach/follow-fork-mode)

当在linux下运行的代码中有创建子进程的操作时,当进行gdb调试时会默认选择父进程进行调试,假如需要对子进程进行调试就需要使用特殊方法。共有两种方法可供选择:这个方式就是当进程运行时,获取进程PID然后在进入gdb调试时,通过attach指令调试PID对用的进程。本质就是指定PID然后调试,并不是真正的进程切换调试。示例代码:过程如下: mode的可供选择值有两个parent与child,对应父进程与子进程。这个只能选择fork的第一个子进程作为child进行调试。还是使用上述示例代码,过程如

2022-11-03 08:45:00 2917 2

原创 C++语法——详细剖析多态与虚函数

所谓虚函数就是当通过指针或引用调用该函数时,编译器不会在编译时确定该函数地址,而是在运行时通过指针或引用的具体对象类型进行。正因为虚函数的这种特性,可以说它“天生”就是为多态准备的。多态是OOP的核心思想,含义是“多种形式”。当我们通过父类的指针或引用调用父类定义的虚函数时,并不会在编译时就清楚它的地址,只有当运行时确定了具体的对象类型,才会根据该对象类型调用该类型重写的该函数。换一种说法,假设人是一种父类,其中皮肤是虚函数,派生出了黑人、白人、黄种人三个子类,各自重写了皮肤函数为黑色、白色、黄色。

2022-10-30 11:15:00 463 4

原创 带你彻底搞懂缓冲区

所谓缓冲区,就是当我们在编程向文件中输入数据时,数据无法直接写入文件,而是先写入一个名为缓冲区的区域,经过对缓冲区的刷新后才能写入文件中。可以通过此例作以证明:下例中,我们打开一个文件,使用fwrite向其中输入数据,第一次采用直接使用close关闭文件,第二次采用刷新缓冲区fflush后close关闭文件。//代码一int main(){//系统调用接口,fileno:即文件描述符fdreturn 0;}//代码二int main(){//刷新缓冲区return 0。

2022-10-26 08:45:00 4008 5

原创 C++语法——详解虚继承

一.什么是虚继承所谓虚继承(virtual)就是子类中只有一份间接父类的数据。该技术用于解决多继承中的父类为非虚基类时出现的数据冗余问题,即菱形继承问题。,那么,当我们用D实例化对象调用a时,编译会报错,因为发生了混淆。除非指定类域B或C。当然指定A也可以,因为默认会从第一个父类中找。此时,D的实例化对象内部结构如下:而当我们使用虚继承时,结构是下图这样,D中只有一份父类A,当我们调用A中数据时,并不会发生冗余。

2022-10-23 16:15:00 24226 23

原创 C++语法——详细剖析类成员函数在内存中存储形式(包括静态)

先说结论,不管对于静态还是非静态成员,其都是。我们发现,。而地址空间中,代码区就在常量区下方(低地址处)。因为上述发现,更加佐证了类成员函数存放在代码区。当我们通过同一个类实例化出多个对象时,为了最大化的节省空间资源,。

2022-10-21 17:00:00 2183 6

原创 C++语法——超详细模拟实现list源代码

这篇小编将以SGI版的list为例进行模拟实现。这里小编做了一张图,它足以表明list的大致框架:对于节点node而言,我们可以按照c语言中的双向链表节点结构进行创建。首先node设为一种类由于list属于泛型编程,我们不知道链表数据类型,因此使用template将node变成泛型类。内部参数分别是node* next,node* prev,T value。通过代码我们可以发现,在结构上list_node与c语言的结构体链表节点基本无异。但是C++特性赋予了链表节点泛型编程的强大功能。当

2022-10-18 15:00:00 1873 11

原创 STL中list如何实现普通迭代器隐式类型转换成const迭代器

不要以为int可以隐式转化成const int,list所使用的是template泛型编程,当我们定义一种泛型时,更加需要确保其与模板匹配。要不然会更加乱套了。因此,编译器才会报错说iterator无法转化为iterator所以这里原因很清楚了,当我们定义一个const_iterator时,其默认拷贝构造的参数也是const_iterator。这时就会非常困惑,我们明明没有对权限进行放大,为什么编译器还会报错呢?

2022-10-14 08:00:00 810 7

原创 LeetCode题解——42.连续子数组的最大和(动态规划思想)

这份代码中,并没有使用最大值数组。因为实际上我们只需记录前一位存储的最大值以及目前为止的最大值。下标1对应值为1,与前一位最大值-2相加为-1,是小于本身值的,因此下标1处最大值为1。在这道题中,数组连续是一个很重要的信息。我们可以创建一个数组用于记录每一位对应的最大值。同理,下标2处: -3 + 1 = -2 > -3,因此最大值为-2。从下标0处出发,该下标处没有前一位,因此-2所对应最大值即本身。按上述推导,我们在最大值数组中找到的最大值即是答案。因为题目要求连续,所以。

2022-10-12 17:30:00 380

原创 Linux——详细模拟实现shell(进程控制综合运用)

因为虽然子进程确实进行了路径切换,但是在切换后进程就终止了,当再创建子进程时还是继承自父进程所在的原路径,相当于路径没变。因此我们想要改变路径就要让父进程改变路径,但是父进程又不能够用进程替换,又因为进程替换成功不会返回原有进程,我们需要一个子进程来执行每次具体的系统命令,父进程来完成shell的“轮回”——当子进程(系统命令)执行完毕后父进程重开一个新shell接收新指令。还有我们输入的ls指令是无色的,但是真正的shell是有颜色的,这个只需要我们在命令行参数中再加入"--color=auto"即可。

2022-10-10 07:45:00 1767 6

原创 Effective C++学习笔记——宁以传引用替换传值

那么在函数内部,Print()就是按照Human中的定义进行调用。比如一个由int组成的对象,某些编译器并不会把它放入缓存器中。一个小小的传值,竟然会引发这么多次的构造析构,着实令人惊讶,不可忽视。这种情况下,就应该使用引用传参,因为指针是会放入缓存器中的。我们的预期是它会打印 "I am Man",但实际上不是。同时定义一个函数打印对象信息(传值传参),并调用。,毕竟当我们传值传参时一般不希望实参发生改变。因此,我们同样需要进行引用传参。这是因为,当我们传值的时候,,这并不是我们希望的。

2022-10-07 09:00:00 842 4

原创 Effective C++学习笔记——确定对象被使用前已先被初始化

不同编译单元(源文件)内的对象如果其中一方要使用另一方,那么一定要注意初始化的次序,倘如被借用的一方尚未初始化,那么会发生意想不到的错误。小编将《Effective C++》中代码示例做了调整,以便讲解展示:下面有两个类Par、Child分别位于不同的编译单元内。我们所期待的结果是当Child对象B定义时,调用自己构造函数打印Par对象A中的Hello world。//头文件class Par{public:Par(){}};//源文件Par A。

2022-10-04 08:00:00 1178 7

原创 Linux——详解进程控制之终止

在CPU运行完我们编写的代码后,执行到return 0时,就会结束当前进程。因此,main函数中的return 0的含义就是代码正确执行完毕,进程终止。,将0值(return值)作为参数status给exit(),在exit()内部清空缓冲区后,调用_exit终止进程,记录退出码status。由此,我们引来问题,为什么return在main中会终止进程而其他函数中不会呢,为什么return 0能结束进程呢。,作用是标志一个函数结束,即函数栈的返回。此外,_Exit与_exit是等价的,但头文件不同。

2022-09-30 15:24:44 2506 4

原创 Linux——详解进程控制之替换

与之前execl、execv相同,环境变量传链式结构或指针数组。filename传入文件绝对/相对路径+文件名。*envp[]传入带有环境变量的指针数组。当然最后应以NULL结尾。当创建失败时,函数会返回-1并在errno中记录该错误原因。errno是一个系统参数,由操作系统直接维护,会记录最新的错误。除此之外,execl、execv、execlp、execvp、execle都是在第三手册中,只有execve在第二手册中。

2022-09-29 09:44:12 956 2

原创 Linux——详解进程控制之等待

进程等待是进程控制中非常重要的一环,这关系着多进程之间的联动。进程等待是父进程等待子进程退出的过程。在等待中父进程可以选择阻塞或非阻塞状态。阻塞状态:父进程等待过程中不进行任何操作,进入挂起状态,本质是将父进程PCB放入等待队列(wait_queue)。非阻塞状态:父进程在等待过程中继续执行自己代码,即父进程一直处于运行状态。进程等待常用的两个函数接口是wait与waitpid。本质上,在waitpid内部会对options进行判断。当值为0时,将进程挂起,从而父进程进入阻塞状态,然后死循环判断子进程是

2022-09-26 15:11:39 1884 10

原创 Linux——详解进程控制之创建

创建进程是编程的常见操作。本节我们将对创建进程进行学习。

2022-09-23 16:20:13 1348 6

原创 为什么STL中List的实现其迭代器iterator是类模板?

试想一下,你是使用者,创建的iterator一定想当然的认为是代指自己的list参数。再清晰一些,for(auto)时,本质使用的是迭代器,你的auto对象是不是代指节点的参数?由此,我们需要创建一个类模板来作为迭代器,其要包含整个节点,让++/--能够重载,发挥node = node->next/prev的作用。因此,当我们进行++操作时,是对list_node里的参数进行++,这显然不是我们要的下一个参数值。因此我们就会发现,单纯的T* iterator已经满足不了我们的需求了——我们无法重载++。

2022-09-19 17:44:22 455 9

原创 Linux——进程地址空间

在我们刚学习计算机时,就知道栈区、堆区、常量区...的概念。那时候总以为计算机内存(物理内存)就是按这样排序的。但是,这不是物理内存,这是进程地址空间!(一).进程地址空间内部结构这里小编选择用一张图来表示其内部结构:(二).进程地址空间的产生当程序运行时,操作系统不仅将文件加载进进程、创建PCB结构体,还会创建一个mm_struct结构体。mm_struct结构体就是我们所谓的进程地址空间。我们在写代码时的那些所谓地址,其实都是mm_struct结构体规定的地址。这些地址并不真实存在。

2022-09-15 17:14:07 1618 8

原创 LeetCode题解——36.二叉搜索树与双向链表(中序遍历)

这样讲可能还有些不清楚,换一个说法:我们在操作一个节点时,只需要先递归左节点,找到本节点的前驱。完成前驱与本节点对接后,将本节点作为前驱,递归右子树,与右子树中本节点的后继对接即可。

2022-09-09 16:38:21 353

原创 Leetcode题解——30. 包含min函数的栈(辅助栈思想)

这样就可以利用同步栈的特性,完美的解决了当出栈值就是最小值时,回溯到上一个最小值的问题。此时st中入了三个元素,但后两个元素都比st_min的栈顶元素1大,所以st_min依旧入自己栈顶元素。这里的难点就是在st出栈后,假如出栈元素就是最小值,那么怎么回溯到上一个最小值。但如果st入栈值大,那st_min继续入自己的栈顶元素,即最小值。即,如果此时st入栈值小于st_min,那st_min入该值。但当-3入栈st后,-3小于1,所以st_min开始入栈-3。当st入栈出栈时,st_min同时入栈出栈。

2022-09-01 17:45:50 1200 1

原创 Leetcode题解——26.树的子结构

如果False,再开始将B树顶与A剩下节点匹配,直到True或A全部匹配结束False。当A中节点与B的树顶匹配时,再匹配B中剩下节点,全部一致True;该函数的中心思想是查看此时AB节点是否匹配,若匹配就继续判断A左B左以及A右B右。当B节点到空时,此时说明B中某一分支已经匹配完毕且与A完全一致,直接返回True。需要注意的是,递归时,左右子树的关系是或,当左或右有一个能有B树匹配即可。当A节点空时(B不空),此时说明A与B并不匹配,返回False。②此时节点与B树顶不匹配,直接递归A节点左右子树。...

2022-08-31 15:30:04 307 1

原创 Linux指令——crontab

crontab指令安装和具体使用

2022-08-30 17:47:27 3497 8

原创 LeetCode题解—260.只出现一次的数字Ⅲ

但是,这道升级题中有两个单独的数字,只是异或遍历一遍的话就相当于让这两个数字异或。这一位上是1的放一组,是0的放一组。在Ⅰ中,我们只需要把所有的数字异或一遍即可,因为只有一个数字是唯一的。异或两个数字,实际上就是二进制里它俩哪一位不同就是1,哪一位相同就是0。于是,问题就回到了最初的情况,一组里只有一个数字是单独的,其他都是两个。因为是两个不同的数字,所以注定它们至少有一位是不同的,该位的数值是1。第二步,取任意一位为1的位数,这里我们选第一位。也是一种解法,但哈希的空间复杂度太高,是O(N)。...

2022-08-15 15:21:42 348

原创 LeetCode题解—15.三数之和

从头开始固定一个数字,让另外两个一前一后与固定的数字相加,直到两个数字相遇,然后固定数字向后移动。1.因为要求是三数之和,所以固定一个数不动,让另外两个数移动搜索求和为0。2.因为题目要求不能有重复的数组,且基于第1点,所以要提前。这是一道很好的算法题。思考:如果用哈希表怎么解决,以及方不方便呢?在本题中,我们首先要理清思路。如果和等于0,记录此次三个数。如果和小于0,前头的向后移动。如果和大于0,后头的向前移动。3. 在进行搜索移动时,要。时间复杂度:O(n^2)空间复杂度:O(n)...

2022-08-07 15:29:58 249 7

原创 linux—常用gdb调试命令汇总

如果是函数递归调用,当还没开始递归时,finish会执行完整个函数,自动走完全部递归过程(前提无断点)。因为在linux系统下,默认生成的可执行程序是release版,但是调试需要debug版本。*gdp会自动记录最近的命令,如果没有输入其他命令,可以按enter键继续执行最近命令。需要注意的是,不能直接写变量名,变量编号使用infodisplay即可知道。如果我们需要在调试中一直显示某个变量的值,那么就需要display命令了。需要注意的是,这种方法只能显示一次变量值,当继续调试时变量不再显示。...

2022-07-30 17:18:09 19984 13

原创 C++语法——详解运算符重载

运算符重载是C++的一个重要特性。有了运算符重载,在代码编写时能更好的实现封装。一.运算符重载介绍运算符重载,就是让原本已经存在的运算符有了新的用法和意义。比如我们熟知的减号(-),原本是用来进行数字的相减处理。但经过运算符重载后,它可以用来进行其他类型的相减,像时间相减、日期相减、字符相减等等。只要是你能想到的,通过运算符重载基本都能够实现。对于C++而言,运算符重载一般是作为类的成员函数出现。因为当我们需要运算符重载时,往往是类中一种特殊的类型需要处理或者类本身需要处理。就像我们可能会把.

2022-07-28 10:33:42 37220 20

原创 详解析构函数、拷贝构造函数

在销毁对象时,编译器会自动调用析构函数。因此析构函数不写参数。①析构函数不是销毁对象,而是清理对象内定义的空间。比如malloc、new空间的释放之类②定义多个对象时,先定义的后调用析构函数,后定义的先调用析构函数。这符合栈先入后出的原则。当然在静态区存放的对象是在局部变量后析构的,例如static和全局变量。③析构函数一般不必自定义,编译器有默认生成。但如果有malloc、new之类自定义类型,需要手动写。④析构函数的意义就是便于对象空间的释放,当有多个对象时,不必再每个都free/delet...

2022-07-26 12:35:02 2521 8

原创 vim基础操作汇总(模式转换、普通模式下操作、分屏)

vim是linux下一款文件编辑器,本篇文章小编将重点普通模式下的操作以及模式之间的转换和分屏切换。

2022-07-23 18:43:24 1668 9

原创 详解linux权限操作(概念、chown、chmod、chgrp、umask、粘滞位)

本文介绍了权限的概念和chmod,chown,chgrp,umask,粘滞位的概念和使用方式

2022-07-21 15:47:53 1146 7

原创 C++ 详解构造函数

就比如我们创建的这个类a里还包含了另一个类b,假如被包含的那个类b有构造函数,那么在我们创建的这个类a被定义时,里面的类b会调用自己的构造函数进行初始化。

2022-07-20 11:58:30 431 9

原创 Leetcode力扣题解 - 30.串联所有单词的子串

一名优秀的程序员,在穿越单行道时也会确认双向的来车情况。假设字符串="barfoothefoobarman",关键词=["foo","bar"]。当关键词遍历完成后,如果哈希表中所有值都为0说明此时的字符串与关键词都匹配上了,否则就是没有匹配上。如果匹配成功,在返回的数组中保存起始位置即可。直到走到(字符串长度-关键词总长)的位置停止,这里都是3,所以把此时的字符串barfoo分成bar、foo两个部分装入哈希表中,在第一趟中,需要匹配的是barfoo,此时我们创建一个哈希表。...

2022-07-19 11:59:02 376 5

原创 C++ this指针

今天,我们一起来了解关于this指针的使用。在C++中,类可以分成变量和函数,它们各自占有一块区域,而所有实例化对象在另一块区域。假如我们定义了同类的多个对象,那么当一个对象去调用该函数时,程序怎么判断此时函数是被哪个对象调用的呢?这时,程序是用this指针来判断的。...

2022-07-18 16:24:22 721 6

原创 extern 、static 作为全局变量的使用与差异

同一项目中,不同文件间的同名同类型全局变量是不能互相使用的,那这时我们就可以使用extern、static来解决。同时,虽然extern、static均可以修饰全局变量,但他们的意义却是大不相同。

2022-07-17 17:11:26 2056 7

原创 利用哈希来解决问题

在力扣题解中,我们经常能够看到哈希的身影。今天,让我们一起来探寻哈希的算法思路吧。

2022-07-15 10:05:49 272 7

原创 Linux基础命令指南

本次共总结32个常用基础linux命令,包含使用和注意事项。

2022-07-14 12:59:35 391 10

空空如也

空空如也

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

TA关注的人

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