- 博客(67)
- 收藏
- 关注
原创 list、简单的迭代器
头文件#pragma once#ifndef LIST_H#define LIST_H//防止头文件重复引入#include<initializer_list>namespace liujin{ template<class T> void Swap(T& x, T& y) { T tmp = x; x = y; y = tmp; } template<class _Ty> class list { private
2022-02-21 17:15:52
596
原创 5、用C++实现双链表
头文件#include<iostream>using namespace std;class Node{private: int _val; Node* _next; Node* _pre;public: Node(int val = int()) :_val(val),_next(nullptr),_pre(nullptr)//初始化列表 { } Node(const Node& src)//拷贝构造 :_val(src._val),_next(nul
2021-12-12 11:57:31
732
原创 多线程单例模式
ex:设计一个类:1、只能产生一个对象2、在任何地方都能使用到这个对象#include<mutex>#include<iostream>using namespace std;class Sun{public : static Sun* get_sun() { if (nullptr == _only_sun)//双重判断,因为加锁代价有点大 { _lock->lock();//加锁 if (nullptr == _only_sun)
2021-12-11 22:04:19
633
原创 11、信号量(三进程)
三个进程实现ABCABCABC…的有序打印:设置三个信号量:sem.h 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<sys/sem.h> 4 5 #define SEM_NUM 3 6 #define SEM1 0 7 #define SEM2 1 8 #define SEM3 2 9 10 union semun 11 { 12 int val; 1
2021-11-09 11:39:52
314
原创 10、信号量(两进程)
临界资源1、临界资源:同一时刻只允许一个进程来访问的资源。2、临界区:访问临界资源的代码段信号量信号量:为了控制对临界资源的访问。ex:0、1信号量,计数信号量、、、pv操作p操作:资源减一,代表获取资源。v操作:资源加一,代表释放资源。加一和减一都是原子操作。实例:假设有一个打印机,用A、B程序分别打印A和B,打印第一次时表示正在打印,第二次表示打印结束。与信号量相关的几个方法:1、sem_init() 初始化函数2、sem_p() p操作,使用资源,信号量-13、sem_v(
2021-11-09 11:08:04
919
2
原创 9、进程间通信:管道
进程间通信(ipc):管道 信号量 共享内存 消息队列 套接字1、管道管道如果为空,或者管道写满了,写会阻塞。重点:管道文件是在内存中分配空间,管道文件有一个读端,一个写端。管道分为:有名管道和无名管道。有名管道可以在任意两个进程之间通信,无名管道只能在父子进程之间使用;**通信方式:**半双工有名管道:1、mkffo FIFO2、系统调用管道文件 前面有个p prw-rw-r-- 1 stu stu 0 11月 1 19:20 fifo
2021-11-09 11:03:59
115
原创 不借助第三方变量进行两个值交换
void swap1(int* a, int* b){ int temp = 0; temp = *a; *a = *b; *b = temp;}//不引用第三方变量的交换会出现bug,当自身和自身交换,会变成0void swap2(int* a, int* b){ *a = *a + *b; *b = *a - *b; *a = *a - *b;}void swap3(int* a, int* b){ *a = *a ^ *b; *b = *a ^ *b; *a = *
2021-11-04 20:57:58
85
原创 10、算法
八大排序:1、冒泡排序(沉尸排序)**思想:**每次找到一个最大值放在最后面,每次找到一个最大值向后放(升序),两两比较,如果左边大于右边就交换他们的的值,每次比较结束后会得到最大值。降序就反过来。**时间复杂度:**O(n^2)**空间复杂度:**O(1)**优点:**实现简单,稳定,不存在跳跃交换**缺点:**时间复杂度大#include<stdio.h>#include<assert.h>int * Bubble_sort(int* arr, int arrS
2021-11-04 20:56:45
100
原创 8、制作bash
原理:读取指令,然后复制进程,再将要执行的命令/操作替换fork +替换 1 #include<stdio.h> 2 #include<sys/wait.h> 3 #include<stdlib.h> 4 #include<unistd.h> 5 #include<assert.h> 6 #include<string.h> 7 #include<pwd.h> 8 #include<e
2021-11-04 11:15:19
115
原创 7、串(strcpy strcat strcmp strlen)字符串查找 (BF KMP)
1、BF算法(暴力算法)(Brute Force):字符串匹配问题:主串:“ababcabcdabcdeb”子串:“abcd”子串个数:(1+n)*n/2+1真子串个数:(1+n)*n/2目的:在主串中找到子串第一次开始出现的位置。**BF算法难点:**容易出错(i没有回退)1、两两比较,如果相等,i++,j++,接着向后比2、如果匹配到一半发现不相等了,就返回到主串中这趟比较的下一个位置,i=i-j+1,j回退到03、如果主串中的i走出了位置,那么并不能判断是否找到了子串相匹配4、
2021-10-28 11:54:04
151
原创 7、替换进程
所有进程的创建都可以是:fork+execel,先将bash本身赋值,然后替换为要执行的程序。stu@stu-virtual-machine:~/Test/替换举例$ ps PID TTY TIME CMD 3386 pts/0 00:00:00 bash 10948 pts/0 00:00:00 psstu@stu-virtual-machine:~/Test/替换举例$ ps -fUID PID PPID C STIME T
2021-10-24 17:32:31
1886
原创 6、文件操作加系统调用
1、操作文件的系统调用系统调用和库函数的区别:系统调用的实现在内核中(就是在操作系统内实现的函数),库函数的实现在函数库中,属于用户空间。执行系统调用时会产生中断,中断(现场保护,现场恢复)。请求编号存在寄存器中,然后去内核中对照系统调用表,进行调用,将结果返回,存储在寄存器中,然后将值返回给系统调用值。1 代表命令 2代表系统调用 3代表库函数stu@stu-virtual-machine:~/Test/替换举例$ man openOPEN(2) Lin
2021-10-24 17:31:02
208
原创 哈希(hash)
1、哈希 Hash(散列):哈希函数等于散列函数,哈希是一种存储方法,还是一种排序方法,只要算法中用到哈希思想,就可以叫hash算法。将数据自身的值和最终的存储位置形成一个特定关系 这个关系叫做hash函数:ex:y(存储位置)=f(x(关键值key))顺序表:节点之间,物理相邻,逻辑也相邻链表:节点之间,物理可能不相邻,逻辑相邻哈希表:节点之间,节点地址与被存储数据之间存在逻辑关系。2、如何构造哈希(6种)3、如何解决哈希冲突(主要是连地址法)1、开放地址法2、再散列函数法3、链地
2021-10-21 12:44:27
727
原创 5、僵死进程
1、僵死进程僵死进程:子进程先结束,父进程没有调用wait()来获取子进程退出码,那么子进程就会变成僵死进程,当僵死进程的父进程也运行完之后,会称为孤儿进程,此时会由INIT来将其回收,然后父子进程一同结束。 PID TTY TIME CMD 2791 pts/0 00:00:00 bash 3014 pts/0 00:00:00 僵死?程 3015 pts/0 00:00:00 僵死?程 <defunct> 3016 pts
2021-10-18 20:13:51
70
原创 4、fork()复制进程
1、fork复制进程进程:2、父进程子进程stu@stu-virtual-machine:~/Test/Forkex$ vi fork1.cstu@stu-virtual-machine:~/Test/Forkex$ gcc -o fork1 fork1.cstu@stu-virtual-machine:~/Test/Forkex$ ./fork1s=parent,ppid=4067,pid=4390s=child,ppid=4390,pid=4391s=parent,ppid=4067
2021-10-17 13:18:26
130
原创 5、main函数参数
1、argc 参数个数 argv参数名称 1 #include<stdio.h> 2 #include<stdlib.h> 3 int main(int argc,char*argv[],char*envp[])//参数个数,参数内容,环境变 量 4 { 5 printf("argc=%d\n",argc); 6 for(int i=0;i<argc;i++) 7 { 8 printf("argv[
2021-10-16 23:36:48
137
原创 3、库文件
1、什么式库文件:库文件是预先编译好的方法的集合。(相当于一大堆的可执行文件) 存放头文件的标准目录:/usr/include存放库文件的标准目录:/usr/lib比如:printf函数的实现在库文件中 libcs.so声明在/usr/include/stdio.h库分为:静态库 libxx.a共享库 libxx.so2、创建静态库stu@stu-virtual-machine:~/Test$ cd 静态库举例stu@stu-virtual-machine:~/Test/静态
2021-10-16 23:00:58
562
原创 2、gdb调试
再vs中有Debug和Release版本生成解决方案,Debug生成的exe文件比Release生成的exe文件大,原因是Debug版本的带有调试信息可以对程序进行调试,而Release原则上不能进行调试。1、gdb中常用命令调试对象:Windows:exeLinux: main调试程序是对可执行文件进行调试。编译时需要增加调试信息 -g //ex gcc -o main Test.c -gl 显示代码b + 行号 设置断点info break 查看断点信息r 启动程序
2021-10-16 13:22:40
245
原创 队列之链式队列
1、难点要想用链表实现队列,就必须队尾进,队头出,先进先出,后进后出,这些利用链表的头尾节点都可以实现,即:头删(出队)和尾插(入队),那么如何保证入队和出队的**时间复杂度都为O(1)**呢?显然,头删的时间复杂度已经为O(1),因此要让尾插的复杂度为O(1)的话需要将尾节点保存起来。2、结构体设计因此需要进行改进,改进之后的结构体设计如下://有效节点typedef struct LQueue{ ELEM_TYPE data;//用来保存节点数据 LQueue* next;//用来保
2021-10-13 22:14:33
219
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人