- 博客(38)
- 收藏
- 关注
原创 C语言内存函数总结
memcpy的差别就是memmove函数处理的src内存块和dest内存块是可以重叠的。该函数主要的作用是将两个不同地址的变量按照字节数进行拷贝,如果变量的地址相同,那么就会发生不安全的隐患,所以程序员必须知道该函数底层实现!使用void*进行接收dest和src,将dest和src强转成char*型方便按字节进行操作。memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。⽐较从ptr1和ptr2指针指向的位置开始,向后的num个字节。
2024-05-29 19:23:42
313
原创 socket编程
用来创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)第一个参数代表了作用域,常用的一般就这三个第二个参数是类型,用什么样的方式发送,选择udp或者tcp第三个参数在这我们可以先忽略填0就ok。
2024-02-28 16:37:42
1255
原创 linux多线程
1.加锁保护:加锁的时候,一定要保证加锁的粒度,越小越好。2.加锁就是串行执行了吗?加锁了之后,线程在临界区中,是否会切换,会有问题吗?是的,就变成串行了,是会切换,但是由于原子性的体现,数据不会更改,所以没问题。3.要访问临界资源,每一个线程都必须现申请锁,每一个线程都必须先看到同一把锁&&访问它,锁本身是不是就是一种共享资源?是的是共享资源。4.谁来保证锁的安全呢??所以,为了保证锁的安全,申请和释放锁,必须是 原子的!
2023-12-14 12:08:52
59
原创 进程间通信
1.管道是用来进行具有血缘关系的进程进性进程间通信2.管道具有通过让进程间协同,提供了访问控制!3.管道提供的是面向流式的通信服务 -- 面向字节流 --协议4.管道是基于文件的,文件的生命周期是随进程的,管道的生命周期是随进程的!45.管道是单向通信的 ,就是半双工通信的一种特殊情况a.写快,读慢,写满不能在写了b.写慢,读快,管道没有数据的时候,读必须等待c.写关,读到‘\0’位置,标识读到了文件结尾d.读关,写继续写,写满的话OS终止写进程。
2023-11-29 11:23:46
53
原创 动态库和静态库
(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静 态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文 件的整个机器码 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个 过程称为动态链接(dynamic linking) 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。
2023-11-25 13:48:34
67
原创 线程池的实现
进入先上锁,如果total==size则说明队列已满,直接返回,如果没满则在尾部插入data,再另total++和tail++,如果tail==size说明队列已经到了末尾的位置,那么就要回到数组头的位置重新开始,最后等待发送信号signal,wait在等待他发送的信号后解锁。如果没有顾客,理发师就去睡觉;data在数据的头取出,取出后total--,head++,如果head==size,那么则说明head到达了最后一个,就将head指向0号位置,最后解锁,返回给线程池中data数据。
2023-11-17 14:15:47
55
原创 linux进程等待
1.子进程退出,而父进程不退出,则子进程会产生僵尸进程,那么就会导致内存泄漏2.父进程创建了子进程,而子进程的任务有没有做完,父进程需要得知。
2023-11-12 22:19:54
68
原创 map和set
set是按照一定次序存储元素的容器在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。set在底层是用二叉搜索树(红黑树)实现的。
2023-11-06 11:54:38
40
原创 c++二叉搜索树
和普通二叉树一样,一个节点有左子树和右子树,还有key值,因为存在了自定义类型,所以需要使用初始化列表去初始化该Node节点。这边的引用就是代表了上一个节点的位置去插入 ,所以只需要指向到需要插入的位置,递归能自动帮我们生成插入并返回。1 .若它的左子树不为空,则左子树上所有节点的值都小于根节点的值。2. 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值。解决该key在不在二叉树中的问题,如校园卡,该学生号在不在系统中。b. 树不空,按二叉搜索树性质查找插入位置,插入新节点。
2023-11-02 11:03:54
49
原创 c++多态
因为虚函数的必要条件是调用父类的指针或者引用,所以父子类各自都有自己的虚表,父类的虚函数要调用父类的虚表,子类的虚函数要调用子类的虚表,如果不是引用或者指针,那么传值的时候就会子类对象的虚函数值传给父类,就会造成传值覆盖,如果传的是引用或者指针,那么就会进行切割,子调用子的,父调用父的。派生类的虚表需要生成一张新的虚表,那么就需要重写,覆盖成新的虚函数,如果不需要重写的那么就拷贝相同的地址。虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写,达成。多态,继承的是接口。
2023-10-24 22:57:15
49
原创 liunx进程创建与终止
fork创建子进程,系统中多了一个进程,该子进程分配了对应的数据结构,所以子进程有了自己的数据代码。我们没有加载的时候,子进程是没有自己的代码和数据的,所以子进程只能“read only”父进程的的代码和数据,所以代码都是不可以被修改的,只能读取,父子进程共享。但是数是会被修改的,必须各自享有一份。
2023-10-20 09:48:06
52
原创 优先级队列复现
向上调整算法是从一个堆的底层开始走,不管是左孩子还是右孩子都是(child-1)/2,这边假设child的下标是5,那么parent节点的下标就是2,假设child节点下标是6那么parent节点的下标还是5,当child大于0的时候我们就一直执行,因为child有可能比容器里的所有数都大,最坏的情况是调整logn层,我们用child下标的中的数和parent下标中的数进行比较,如果child大于parent就交换,交换完再更新一下child的下标,如果child小于parent那么就break跳出循环。
2023-10-07 14:08:08
55
1
原创 stl中list复现
首先节点先套用一个模版,因为数据的数据类型可能是各种各样的自定义类型,或者是内置类型的一个data存储数据,next节点指向下一个节点,prev指向前一个节点,传一个T数据类型的x,其中x可能是任何数据类型的,可以不填值,只开空间,next和prev都是指向的空迭代器list的迭代器和string,vector的不同,string,vector的的数据存储是在连续的空间里面,而list需要用链接的地址去迭代,所以最好就是封装出一个迭代器去模拟指针的行走过程这边模版包含类型,ref代表引用该参数
2023-10-04 10:48:42
71
1
原创 vector模拟实现
如果n大于capacity再扩容,先定义一个tmp变量,如果start不为空则拷贝,这里需要值得注意,不能够使用memcpy去拷贝,这里涉及到一个深层次浅拷贝到问题,sizeof(T)为T成员变量的使用空间,如果这里是一个int类型的完全ok,如果是一个字符串类型的,这个_start会指向一块堆上的空间,这个空间有多大根据使用情况来定的,如果只用sizeof(T)那么则可能会发生报错的风险。这里的T& val=T()是代表了取的是T数据类型的空值,int的话可能是0,string可能是空。
2023-09-21 09:55:40
40
原创 string模拟实现
append在逻辑上是和push_back相同的,一个是打印的字符,一个是打印的字符串,首先要给出str的长度,这里的if判断中的reserve不能是扩二倍的关系,因为len的长度有可能远远的大于2*capacity,假如len的长度是10,而capacity的长度是3,capacity即使扩了二倍也无法满足所需要的。str为空或者不设置变量的时候,在初始化的时候我们不能将指针指向空,指向空是一个大坑,因为即使是空的时候,我们识别字符串的时候需要指向\0结束,指向空就无法识别出什么时候结束。
2023-09-16 15:29:46
79
1
原创 linux vim的使用
显示行号后找到第100行,将第100行的文字yy复制一下,按p插入到101行,将root的名字改成自己需要提权的用户名,再强制写入:w!,再保存退出:wq!在早期的键盘中并没有上下左右移动的按键,vim中在命令模式下引入移动光标的方式就是h表示左边,j表示下,k表示上,l表示右。在命令模式下,yy对于win中ctrl+c,p对应ctrl+v,u代表撤销,其中p可以前面加数字代表复制多少行,在命令模式下我们输入R命令代表了进入一个叫替换模式的模式,就是说从光标当前的位置安字符去替换你想替换的内容。
2023-09-10 21:53:42
977
1
原创 关于linux下gcc和g++
头文件提供声明,库文件提供链接。是c/c++或者其他第三方库所有方法的集合,被所有程序以拷贝的方式,将所要的代码,拷贝到自己的可执行文件中。库中所有的函数,都有入口地址,所谓的动态链接,就是把要链接的的函数地址拷贝到我们可执行文件的特定位置。你所写的代码变成xxx.o,切系统中大部分的指令都是c/c++写的,都是依赖的各种动静态库。1.我们现在所有写的代码,已经有人给我们写好了对应的可以直接使用的接口,就是所说的库函数。如下分别建立静态链接和动态链接的文件,可以清晰的看到静态链接的所消耗的内存比。
2023-09-09 18:01:16
90
1
原创 c++string
,因为c++迭代器设计的时候考虑了连续存储和链式存储,如果是链式存储,begin指针的地方可能本身就大于end指针的地址。4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits。3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信。2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作。
2023-08-01 23:45:51
48
1
原创 C++类和对象
1. public修饰的成员在类外可以直接被访问2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止4. 如果后面没有访问限定符,作用域就到 } 即类结束。5. class的默认访问权限为private,struct为public(因为struct要兼容C)注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别。
2023-07-23 12:00:38
87
原创 函数重载,引用,内联函数,c++新关键字
首先编译器里面有一个叫符号表的东西去存储函数名,本质是同样的函数名转换成两句指令,如果类型不同修饰出来的名不同,返回值不同也不能构成函数重载,先不谈编译能否通过,在符号表翻译成的代码就不一样,名字不一样自然不能构成函数重载了。在使用了引用的情况下,相当于给原链表娶了给别名,不需要取地址了,看上去更加简单。test.cpp中预处理首先是头文件展开,宏替换,去掉注释,条件编译。只有声明没有定义就可能找不到,c语言直接用函数名去,c++用的修饰名。全局对象or静态对象or堆上动态,出了作用域还在,提高效率,
2023-07-18 22:02:41
61
1
原创 1.1c++命名空间,输入&输出, 缺省参数
3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。假设有a,b两个文件,用的同一快namespace,那么编译的时候合成一个。在c++中,命名空间是对标识符的空间进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。使用using namespace 命名空间名称 引入。使用using将命名空间中某个成员引入。加命名空间名称及作用域限定符。2. 命名空间可以嵌套。
2023-07-16 22:43:46
61
1
原创 常见的排序
堆排序:先构造一个大堆,大堆就是最大的在上面,然后将最大的和最后一个数交换,每次向下调整,end--代表最后的数值不动了。排序是数据结构中一种非常重要的算法,不同的排序时间复杂度也不一样。选择排序:选择出最大和最小的值依次放入起点和终点。插入排序:每次和前面一个数比较。希尔排序:每次和gap差比较。
2023-07-07 23:33:27
34
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人