自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Linux线程

该系统调用成功返回0,失败返回错误码,传统的一些函数是,成功返回0,失败返回-1,并且对全局变量errno赋值以指示错误,但pthreads函数出错时不会设置全局变量errno(而大部分其他POSIX函数会这样做),而是将错误代码通过返回值返回,尽管pthreads同样也提供了线程内的errno变量,以支持其它使用errno的代码,对于pthreads函数的错误,建议通过返回值业判定,因为读取返回值要比读取线程内的errno变量的开销更小。通常而言,在读的过程中,往往伴随着查找的操作,中间耗时很长。

2024-08-02 00:26:36 816

原创 算法1--双指针

由于给定一个int型数字,其各位的平方和一定有一个最大值(不会超过int最大值,可以自己验证)和一个最小值0,即数字的各位的平方和得到的数据的个数是有限的,如果我们不停的将数字的各位进行平方和操作,其一定会出现2个相同的数据,即对数据的平方和操作一定是存在循环的,因此可以使用快慢指针解决问题。如果arr[pos1]+arr[pos2]>arr[pos3],那么pos1右边的元素加上arr[pos2]一定大于arr[pos3],此时可以直接计算出当前可以获得的三角形的个数,接着–pos2。

2024-07-22 20:08:00 643

原创 Linux信号

采用第一种方式,父进程阻塞了就不能处理自己的工作了;block位图与pending位图之间互不影响,即使进程没有接收到信号,block位图也可以将该信号对应位置置1阻塞该信号,如果在进程解除某个信号的阻塞之前,该信号多次产生,Linux的处理方法为:对标准信号无论在这期间产生多少次,都只计一次,对实时信号,其会被依次放到一个队列里面。:pending位图位置表示信号的编号,内容表示该信号是否到来,1表示产生了该信号,此时该信号处于未决状态,直到信号递达才会消除该标志(先置0,再递达),0表示未产生该信号。

2024-07-14 23:55:01 742

原创 Linux进程间通信

数据传输:一个进程需要将他的数据发送给另一个进程资源共享:多个进程之间需要共享某一个资源通知事件:一个进程需要向另一个或一组进程发送消息,通知他们出现了某种情况,如子进程终止需要通知父进程进程控制:一个进程希望完全控制另一个进程的执行(如debug进程),此时就需要控制进程可以拦截另一个进程的所有陷入和异常,并能够及时地知道被控制的进程的状态的改变在内存中有交换数据的空间该空间应该由OS提供,而不能是由通信进程的任何一方提供。

2024-06-21 18:31:03 882

原创 c++类型转换

我们发现&i和p的地址明明是一样的,但值却不一样,这是因为编译器进行了优化认为const变量i既然不能改变,就将i直接放到了寄存器中,我们的p是指向内存中存放的i,在打印i时是到内存中到寄存器取值,而打印*p时是到内存中取值,因此导致了数据不一致的问题。强制类型转换关闭或挂起了正常的类型检查,每次使用强制类型转换前,程序员应该仔细考虑是否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会,因此特别建议避免使用强制类型转换。

2024-05-31 21:35:02 573

原创 c++特殊类的设计

由于m_pInstance是一个指针,编译器在释放资源时不会调用Singleton类的析构函数,因此我们需要实现一个垃圾回收类对开辟的资源进行释放:我们定义了一个内部类MyDelete,由该内部类的析构函数对开辟的资源进行释放,利用该内部类定义一个静态成员变量md,当程序退出释放md时调用其析构函数就完成了对资源的释放。在全局中实例化出该对象是因为我们希望该类预先实例化出对象。一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。

2024-05-28 15:51:58 795

原创 异常与智能指针

我们的想法是:既然是由于A节点里的next或pre指针指向另一个节点B时,调用了share_ptr的赋值拷贝函数后,使得B节点的计数增加了,最后在循环中导致内存无法释放,那我们只需要控制若是next或者pre指针指向节点B时,节点B的引用计数不增加,最后资源不就正常释放了吗,因此我们对pre或者next进行包装另一个类,使其可以正常指向节点,同时在复制拷贝中不增加计数。版本的智能指针,其支持指针的拷贝,原理也较为简单,就是每一份资源都用一个引用计数记录资源的拥有者的个数,只有当引用计数为0时才释放资源。

2024-05-24 12:59:12 991

原创 c++的io流

C++系统实现了一个庞大的类库,其以ios_base为基类,其他类都是直接或间接派生自ios_base类。

2024-05-17 00:09:40 952

原创 C++11

在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字取代了C++98称为C++11之前的最新C++标准名称。不过由于C++03(TC1)主要是对C++98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合并称为C++98/03标准。从C++0x到C++11,C++标准10年磨一剑,第二个真正意义上的标准珊珊来迟。

2024-05-09 18:58:15 920

原创 哈希思想及其常见应用

哈希或者散列是一种思想:即通过某个转换函数在某两种数据之间建立映射关系,利用这种思想建立的数据结构都可以看作是哈希结构,这个转换函数就被称为哈希函数。这种思想在计算机中的一大应用就是哈希表:利用哈希函数建立数据的关键字和数据存储位置之间的映射关系,这样就可以快速地对某个数据进行查找。一般是先将数据关键字输入到哈希函数中得到一个哈希函数值,然后在哈希表中把数据存放到以该哈希函数值为下标的位置即可。

2024-04-22 20:38:04 783 1

原创 Linux文件

现在还有一个问题,文件的属性部分的block[15]只有15个元素,那它是怎么存储大文件的呢?实际上,block数组只有0-11号元素是直接存储数据块的编号,12-13号元素也是指向对应的数据块,但这些数据块不存放文件内容,而是存放其他数据块的编号,这些编号存放的才是文件的内容,14号元素也类似,指向的数据块存放的是其他数据块的编号,这些编号对应的数据块存放的还是其他数据块的编号,这时的数据块存的才是文件的内容,这有点类似于多级指针,这样一个文件就可以拥有十分巨大的体积了(可能导致文件跨越多个分组)。

2024-04-12 16:02:57 1197

原创 unordered_set和unordered_map基本使用

STL提供了4个unordered系列关联式容器,分别是:unordered_set、unordered_map、unordered_multiset、unordered_multimap,这4个容器的使用与底层为红黑树的关联式容器是十分类似的,只不过现在这4个容器的底层机构都是哈希结构,因此其查询效率比底层为红黑树的关联式容器的要高一些。

2024-04-09 15:55:51 787

原创 AVL树和红黑树

当我们插入的新结点时,我们需要对插入结点到根结点路径上的平衡因子进行调整,平衡因子的调整方法为:左子树高度增加,则当前结点平衡因子减1,右子树高度增加,则当前结点平衡因子加1,接着对其父结点也进行以上操作,直至根结点或者某个祖先结点的平衡因子变为0为止(当前结点平衡因子变为0说明新结点的插入并不影响以当前结点为根的子树的高度,那么自然就不会影响其到根结点路径上的祖先结点的平衡因子)。红黑树结点的删除这里也不进行讨论。,如果新插入结点的父结点的颜色是黑色的,则红黑树不需要进行任何调整,否则就需要调整。

2024-04-02 20:50:26 651

原创 map和set基本使用

使用二叉搜索树,其数据的插入、删除、查找成本都较低,是良好的数据结构,但当其变为单支时,查找效率会大大下降,从而导致插入和删除的效率也下降,由此改进就产生了平衡搜索二叉树,使进行结点插入删除时这棵树依然接近完全二叉树,经典的平衡搜索二叉树有AVL树和红黑树。在要删除结点的左子树找到键值最大的结点L或在要删除结点的右子树找到键值最小的结点R,只需要将L或R的键值赋值给要删除的结点,然后删除L或R结点即可,因为L一定没有右孩子,R一定没有左孩子,所以L或R结点的删除一定属于1、2、3情况中的某一种。

2024-03-05 19:55:58 820

原创 c++多态

在不同继承关系的类对象去调用同一函数,产生了不同的行为,这就是多态。在继承中构成多态需要满足两个条件1.必须通过基类的指针或者引用调用虚函数2.被调用的虚函数必须是虚函数,且派生类必须对基类的虚函数进行重写满足条件以上2个条件的函数调用是多态调用,多态调用的函数只与对象相关,否则就是普通调用,普通调用的函数与类型相关。如果是普通调用,则调用哪个函数看的是指针或者引用或者对象的类型,如果是多态调用,则看的是指针或者引用指向的对象。

2024-02-28 20:06:48 849

原创 c++继承

class 派生类类名 : 继承方式 基类类名 {//... }其中继承方式有3种:public继承、protected继承、private继承。需要注意的是,如果我们不显示写继承方式,使用关键字class的派生类默认的继承方式是private继承,使用关键字struct的派生类默认的继承方式是pubilc继承,不过我们建议显示写出继承方式。

2024-02-24 22:59:05 1066

原创 c++模板2

在test.cpp中,只有模板函数的定义,没有模板函数的实例化,因此编译器不会生成具体的函数,也就不存在该模板函数实例化后的函数地址,main.cpp调用fun(int.int)函数,但在链接期间找不到函数地址,因此出错。作为模板的参数,在模板中可以直接使用该参数,需要注意的是,浮点数、类对象和字符串常量是不允许作为模板的非类型参数的,同时该参数必须在编译期间就可以确认结果。通过使用模板,我们可以实现一些与类型无关的代码,但对于一些特殊的类型,我们可能需要进行特殊处理,这就需要用到模板的特化。

2024-02-19 13:28:54 290

原创 stack和queue基本使用

中控即指针数组从中间位置开始使用,以保证其头插头删尾删的高效性,但该结构却导致了下标访问的高效性与中间元素插入删除的高效性之间是互斥的:如果为每个指针开辟的空间大小都是相同的,那么如果需要进行下标访问时,只要简单的计算就行了,其效率可以保证,但删除和插入中间元素其效率确实极低的;如果不进行指定,其底层容器默认也是deque。总之,deque在头部插入和删除元素的效率是比vector高的,其空间利用率也比list高,其缺陷也非常明显,在遍历和中间元素插入删除效率非常低。7.返回优先级队列元素个数;

2024-02-11 21:17:50 671

原创 list基本使用

list容器底层是带头双向链表结构,可以在常数范围内在任意位置进行输入和删除,但不支持任意位置的随机访问(如不支持[ ]下标访问),下面介绍list容器的基本使用接口。

2024-02-04 21:46:09 1267

原创 vector基本使用

vector是表示可变大小数组的序列容器,其大小可以可以动态改变,与数组一样采用连续的存储空间来存储元素。下面介绍vector的基本使用接口。

2024-02-01 16:16:09 280

原创 Linux进程

底层硬件以冯诺依曼体系结构组合,同时每种硬件都有自己对应的驱动程序,驱动程序一般由硬件生产商提供,通过其可以对硬件进行对应操作,驱动程序将自己操作硬件的接口提供给操作系统,以供操作系统调用和管理硬件,操作系统又向上提供了一些接口(本质上是有输入和返回的函数),称为系统调用接口以供用户使用,由于使用系统调用接口对用户有一定的要求,于是又对系统调用接口进行一定的封装,产生了用户操作接口,如c标准库等,上层用户通过指令或开发操作操作用户操作接口,就可以较为容易的使用底层硬件。

2024-01-27 18:05:52 926

原创 Linux开发工具及其安装

make是一个命令,makefile是一个文件,在一个工程中,源文件数量众多,其会按类型、功能、模块放在若干个目录下,makefile文件则定义了一系列规则来指定哪些文件先编译,哪些文件后面编译,哪些文件要重新编译以及进行一些更复杂的操作,再通过make命令工具解释makefile中的指令,从而完成项目的自动化构建。在目录/etc/下的vimrc文件,是属于系统中公共的vim配置文件,修改该文件,对所有用户都有效,而在用户的家目录下,也有个名为.vimrc的vim配置文件,修改该文件,只对当前用户有效。

2024-01-23 14:56:17 1105

原创 Shell命令和Linux权限

由前面的写权限可知,只要用户拥有文件所处目录的写权限,那么用户就有权删除该目录下的所有文件,而不管该文件的所有者是谁,换句话说,一个文件本身能否被删除,取决于文件所处的目录而不是文件本身的权限。②w:写权限,对普通文件来说,具有修改该文件内容的权限,对目录来说,具有删除和移动该目录内的文件及在该目录下创建新文件的权限。①r:读权限,对普通文件来说,具有读取该文件的内容的权限,对目录来说,具有查看该目录的内容的权限。③x:执行权限,对普通文件来说,具有执行该文件的权限,对目录来说,具有进入该目录的权限。

2024-01-21 14:57:22 917

原创 Linux基本指令与操作

cat指令默认是从键盘读取内容,接着输出到屏幕上,因此如果我们直接输入cat指令,后面不加cat要读取的文件,其就要从键盘读取内容并输出到屏幕上,直到我们按ctrl+z终止该指令。“*”表示可执行的普通文件,“/”表示目录,“@”表示符号链接文件,“|”表示FIFOs文件,“=”表示套接字文件。如果第二个参数是不存在的文件或目录,则移动并进行重命名操作,如果第二个参数是已经存在的目录,则进行移动操作。显示指定文件的末尾内容,不指定文件时,作为输入信息进行处理,可以不断刷新,从而看到最新内容。

2024-01-16 22:24:09 946

原创 string基本使用

string是表示字符串的字符串类,为basic_string模板类的一个实例,支持流插入和流提取。在使用时,要包含头文件string并使用命名空间std。

2024-01-01 22:42:44 888 1

原创 c++模板1

函数模板本身并不是函数,在编译阶段,编译器通过用户传参自动识别参数类型,从而推导出模板函数参数列表的类型,得到一个函数供用户使用,这样就可以通过用户传递的参数类型的不同,得到一批仅仅只是类型不同的函数,相当于把重复做的事情交给了编译器,从而提升了开发效率。要注意在显式实例化中里面的类型个数要与template的中的typename的个数相同,同时是自左向右依次匹配typename的类型。①一个非模板函数与一个同名的模板函数同时存在,且该模板函数可以实例化出这个非模板函数时,优先使用非模板函数。

2023-12-10 20:56:36 475

原创 C++内存管理

operator new和operator delete是系统提供的全局函数,new在底层调用了operator new函数来开辟空间,delete在底层调用operator delete函数来实现释放空间。由于c++兼容c,因此c的内存管理方式在c++中依旧可以使用,但其不能解决自定义类型的初始化问题,new在为一个自定义类型开辟空间时会调用其构造函数进行初始化,delete在释放自定义类型的空间时也会调用其析构函数来对其内容进行清理。1.malloc和free是函数,new和delete是操作符。

2023-12-02 12:10:29 971 1

原创 类和对象学习笔记

/... };在类的内部可以定义变量和函数,c++可以通过3个访问限定符来限制类的成员的访问权限:pubilc:在该作用域的成员在类外可以直接访问private和protected:在该作用域内的成员在类外不能直接访问c++为了兼容c,就将c的结构体提升成了类,使用struct和class定义类的唯一区别是:class的成员的默认访问权限为private,struct的成员的默认访问权限是public,其他的并无区别。

2023-11-21 18:00:36 431

原创 初识c++

为了避免命名冲突和污染,c++提出了命名空间的概念,一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中,其用法为:当我们想要使用某个已经定义好的变量或函数时,编译器默认是不会到命名空间中去寻找的,若我们想要用命名空间中的成员时,有三种方法:①成员前加上命名空间名称及作用限定符:②使用using将命名空间的某个成员引入:③使用using namespace将命名空间引入:第②和③种方法本质都是将命名空间里面的成员暴露出来,使其暴露在using位置开始直至所在作用域结束的空间

2023-11-15 17:06:29 145

原创 常用字符串函数拓展

因此要包含头文件<errno.h>。

2023-10-28 20:38:37 174 1

原创 八大排序详解

下面给出常见排序的复杂度和稳定性表格:如果本文有什么不对的,恳请指正。

2023-10-08 21:47:19 1657 3

原创 堆排序详解

堆排序在生活中主要有两大应用场景:一是大数据排序,二是优先队列。其中典型的实例就是解决Topk问题。堆的创建优先选用向下调整建堆,无论是从空间复杂度还是时间复杂度来说,堆排序的性能都是非常不错的。

2023-10-05 22:35:14 294

原创 指针的进阶--从入门到入土

掌握指针这块知识的重要性不言而喻,当你觉得自己已经差不多掌握指针的时候,不妨看看下面8道面试题(题目从简单到困难,读者根据自己水平选择题目难度),答案在文末公布,如果你都做对了,那说明你对指针这一块知识的掌握还是非常不错的,当然了,如果你的表现还欠那么一点点,不妨看看这篇文章对指针的详解。其实就是指向内存某个地方的地址,尽管该地址处的数据不变,但由于指针类型不一样,读取数据的方式就不同,结果就不一样,如整型指针解引用会在该地址处向后读取4个字节的数据,而字符型指针解引用只会在该地址处向后读取一个字节的数据。

2023-08-12 19:40:34 256 18

原创 2个办法解决头文件重复包含的问题

在一些大型项目中,各种头文件会相互包含,关系就显得错综复杂,同时由于文件的包含就是复制粘贴,那些重复包含的头文件就会使代码长度大大增加,那有没有什么办法解决这个问题呢?答案肯定是有的,这就涉及到条件编译了。

2023-08-07 13:31:09 1848 13

原创 #define预处理详解--宏和函数的7大区别

我们经常会使用#define定义一个常量,但对#define这个标识符的了解并不多,总会有如#define使用时有没有什么坑、#define怎么定义宏、定义的宏和函数有什么区别等一堆疑问,今天这篇文章就带你走近科学,走进#define。#define的语法为:#define name(名称) stuff(内容)当stuff过长时,为了代码的美观,需要分几行来写,方法为:除了最后一行,每一行的后面都加上续行符 ’ / ’如welcome \to my \world!

2023-08-06 14:13:34 159 7

原创 程序的翻译环境和运行环境

在ANSI C(标准C语言版本)的任何一种实现中,存在两种不同的环境,第一种是翻译环境,在这个环境中源代码被转化为可执行的机器指令,第二种是运行环境,用于实际执行代码。本篇文章就带大家了解这两种环境,帮助我们更好的理解程序是怎么运行起来的。

2023-08-03 22:39:36 79 2

原创 论动态内存的正确开辟

使用动态内存开辟可以让我们对内存空间的使用更加灵活,但如果使用不当就可能让整个程序崩溃。下面通过4道经典面试题来测试一下你以前使用动态内存的方法是否正确,答案在文末公布,如果每道题你都能讲出个所以然来,恳请指出我有没有什么讲得不到位的地方。函数原型malloc函数是向内存申请一块连续可用的空间,并返回这块空间地址如果空间开辟失败会返回一个空指针,所以malloc的返回值一定要做检查返回的指针类型是void型,使用者要根据自己需求进行强制类型转换如果size为0,malloc的行为是未定义的,取决于编译器。

2023-08-02 16:08:22 55 6

原创 结构体、位段、枚举、联合体大小的正确计算方式

对于结构体、位段、枚举、联合体大小的计算,这里先给出四道题目,答案在文末公布,如果你都做对了,说明你对自定义类型大小的计算没什么问题了,就没有继续看这篇文章的必要了。注:对齐数默认为8(一)结构体 struct s1 {double d1;char c1;int i;char c2;double d2;(二)位段 struct s3 {char a : 2;char b : 4;char c : 5;char d : 4;0 };s3 . c = 3;

2023-07-31 21:23:20 150 3

原创 EasyPlane小游戏,C语言初学者练习项目

对于C语言初学者来说,练习一些小项目来检验自己的学习成果还是很有必要的,今天我就为大家带来了一个简单小游戏----EasyPlane,适合初学者来学习。这个小游戏时比较简单的,各位可以自己尝试写出来,当然了,如果你还想练习其他的C语言游戏,可以关注我,我还写了简单的扫雷、三子棋游戏的制作。

2023-06-21 20:48:44 107 7

原创 270行代码,实现简单的三子棋人机对弈

三子棋是一个比较有意思的益智游戏,玩家通过在棋盘上放子占据位置,使自己的子在棋盘上连成一条大于或等于规定长度的直线后即可获胜,这需要玩家具备一点的判断力和远见意识。下面我们就通过C语言实现和电脑进行三子棋的对弈。以上就是全部代码了,有兴趣的可以复制粘贴来玩。

2023-06-17 18:37:56 207 6

空空如也

空空如也

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

TA关注的人

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