自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 【无标题】基于Huffman和LZ77的GZIP压缩

Gzip压缩

2022-08-07 08:49:39 329 1

原创 基于TCP的聊天系统

基于TCP的聊天系统

2022-08-05 19:33:55 1134

原创 多种智能指针

智能指针的作用实现原理加指针指针的种类

2022-06-29 12:55:38 199

原创 线程安全---->互斥

线程安全 什么是线程不安全 1.多个线程并行或者并发运行时,会导致结果的二义性 2.假设有两个线程,线程A和线程B有一个cpu.同时++ 怎么解决二义性 互斥锁 线程不安全的代码演示 例子:内存->寄存器->cpu->寄存器->内存,这个过程没有原子性,不能一步执行完,可能会被打断...存在二义性,所以就存在线程不安全.线程A刚拿到一个全局变量100,放在寄存器里.还没到写回内存这一步,被剥离处来了.线程B在内存里拿的话还是100,--之后是99,但

2022-04-18 17:55:24 207

原创 qsort和sort的比较器

c语言的qsort函数包含头文件#include<stdlib.h>函数原型:void qsort(void*base,size_t num,size_t size,int(*cmp)(const void*,const void *))base:待排序的数组num:数组长度size:数组元素的大小注意:qsort函数的参数必须是void*,必须是void*,必须是void*#include<stdio.h>#include<stdlib.h&.

2022-04-14 22:23:57 742

原创 c++ list

迭代器失效:erase会导致失效,resize()把list的长度减少,可能就会失效..解决方式就是用之前重新赋值 底层为非连续空间,erase之后当前迭代器失效,但是后面的迭代器不会失效 list的构造和析构 list( ) | list(size_t n,const T& value=T()) | list(const list<T>& L) | list(Iterator first,Iterator last) | list<int> L{1,2,3,5

2022-04-14 17:27:11 62

原创 linux-->多线程

线程概念 进程中的主线程在执行代码,执行流. 线程只是在进程虚拟地址空间中拥有相对独立的一块空间,线程包含cpu现场,但是线程只是进程中的一个执行流,进程是资源分配的基本单位,线程是调度的基本单位,每个线程在进程虚拟地址空间中拥有独立的栈空间,线程有自己的独立栈空间且共享数据,,,由于线程没有独立的地址空间.进程比线程安全的原因是每个进程由独立的虚拟地址空间,具有独立性 同一个进程中线程的切换不会引起进程的切换,由一个进程的线程切换到另一个线程的进程时才引起进程的切换 其中有一个主线程来调用本进程中

2022-04-13 19:39:40 849

原创 c++--->string的细节加模拟实现string

namespace A{ class string { public: //迭代器 typedef char* iterator;//string里的迭代器本质指针,以后迭代器就不一定是指针了 typedef const char* const_iterator;//const类型的迭代器 const_iterator begin()const { return _str; } iterator begin() { return _str; }...

2022-04-06 20:48:59 943

原创 [c++]new和malloc的细节

New和malloc的区别 new是操作符,malloc是函数 New不需要包含头文件,不需要判空,不用强转,new出来的空间直接初始化 在类里:Malloc不会调构造,只是开辟一块类类型大小的空间,free也不会调用析构.new会调构造函数,指针会指向堆上的一个对象.delete会调析构 New里调用了malloc,如果没申请成功,会循环申请. New先调用operator new函数,这个函数里调用了malloc,申请成功后返回指针,然后调用类的初始化函数,这是申请一个类.要是申请多个类,调用

2022-03-30 09:23:19 462

原创 进程信号的深度剖析

1.信号量概念 临界资源:供多个进程访问的资源(例如:管道,共享内存,消息队列) 临界区:访问临界资源时的代码 信号量:本质是资源计数器(资源计数器为1表示可以访问,为0表示不能访问) 互斥访问:同一个时刻,多个进程当中只有一个进程可以访问临界区资源 多个进程通过信号量保证互斥的时候需要先获取信号量,如果能够获取信号量,才能访问支援,如果获取不了,则阻塞等待. 如果不互斥访问导致的结果:复习:(程序计数器(保存下一步执行的指令),上下文信息(保存寄存器中的内容))会产生二义性:如果两..

2022-03-27 23:47:39 199

原创 所有的运算符重载

class Date{ friend ostream& operator<<(ostream& _cout, const Date& d); //设置<<重载运算符为友元函数public: //获取某年是不是闰年 bool GetYear(int year) { if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { return true; }.

2022-03-24 08:54:30 208 1

原创 c++类和对象-----成员函数和注意事项

1.c++类里默认生成的成员函数(特性:用户没有定义,编译器自动生成) 构造函数: 1. 函数名与类名相同。 2. 无返回值。 3. 对象实例化时编译器自动调用对应的构造函数。 4. 构造函数可以重载。 5. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成. 6.用户自定义的构造函数可以有参数也可以没有参数,无参的构造函数和全缺省的构造函数都称为默认构造函数(编译器自己能调用),并且默认构造函数只能有一个。注意:..

2022-03-21 22:53:13 1376

原创 进程间通信 消息队列基础

1.消息队列的介绍1.1消息队列是采用链表的形式实现的队列,该链表由系统内核进行维护1.2系统中[有很多个消息队列,每个消息队列用消息队列描述符(消息队列的ID:qid)来区分,qid是唯一的,用来区分不同的消息队列1.3在进行进程间通信的时候,一个进程将消息加到队列的尾端,另一个进程从队列头部读(不一定是只能读取队列的头部消息,只是从头部开始读,通俗来讲就是从头部开始往下挑)2.消息队列的接口函数2.1创建消息队列key:消息队列的标识符msgflg:创建的标志,例如 IP

2022-03-19 21:25:34 540

原创 c实现力扣95题(不同的搜索二叉树)

二叉树递归的基本思想:无论什么二叉树都先看作是只有根左右三个节点,先找出对这三个节点的操作规律,然后再递归.

2022-03-17 19:21:47 785 6

原创 内联函数的用法,,,auto注意事项

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销, 内联函数提升程序运行的效率。inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的函数不适宜 使用作为内联函数。 inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等 等,编译器优化时会忽略掉内联。1. 在release模式下,查看编译器生成的汇编代码中是否存在call Add(这个就

2022-03-14 14:42:58 1191

原创 进程间通信(命名管道)(共享内存)

1.命名管道1.1,命名管道的创建命令创建命名管道:mkfifo+命名管道的文件名函数创建:int mkfifo(const char *pathname,mode_t mode);参数:pathname:要创建的命名管道文件的路径以及文件名mode:命名管道文件的权限,八进制数组(例如0644)0是八进制数的起手式特点:升级了匿名管道,支持不同进程间通信,不再依赖亲缘关系.命令创建和函数创建都是生成一个文件,这个文件就能代表内核里的缓冲区.代码验证:生成代表管道

2022-03-12 22:45:38 746

原创 预处理编译汇编链接(程序运行过程中的细节)

1.预处理过程2主要处理那些源代码文件中的以“#”开始的预编译指令。如“#include”、“#define”等,主要处理规则如下:将所有的“#define”删除,并且展开所有的宏定义。处理所有条件预编译指令,比如“#if”、“#ifdef”、“#elif”、“#else”、“#endif”处理“#include”预编译指令,将被包含的文件插入到该预编译指令的位置。注意,这个过程是递归进行的,也就是说被包含的文件可能还包含其他文件。删除所有的注释“//”和“/* */”。添加行号和文件名标识,

2022-03-09 23:15:55 445

原创 页表和多级页表

我们在c和c++里看到的地址都是操作系统虚拟出来的,%p打印出来的也是虚拟地址,物理内存由操作系统统一管理.操作系统负责把虚拟地址映射到物理内存.那么为什么要用到虚拟内存呢:1,因为如果每个进程都访问物理内存的话,造成不可控性.如果进程有访问内存的权力,他就会把自己的数据存到内存上,但是他并不知道哪片内存被使用,那一片未被使用.所以在多个进程的情况下,数据会混乱,所以物理内存由操作系统管理,进程没有权限访问.2,操作系统并不能预先知道这个进程有多大,这个进程运行多少时间,应该给他分配多少空间(如

2022-03-08 09:19:47 2991

原创 文件流指针和文件描述符

1.文件流指针和文件描述符的产生fopen函数打开文件成功后会返回文件流指针,open函数打开文件成功后返回的是文件描述符.他俩的相同点是通过文件流指针和文件描述符都可以对文件进行操作.2.fopen函数和open函数的介绍fopen函数(库函数)path:带有的路径的文件名,如果没有路径默认在当前文件下.mode:'r' 只读方式打开,将文件指针指向文件头,如果文件不存在,则返回空。'r+' 读写方式打开,将文件指针指向文件头,如果文件不存在,则返回空。'w' 写入方式打开

2022-03-06 21:26:44 1331 1

原创 进程间通信(匿名管道)pipe函数

1.进程间通信简单来说就是让两个或者两个以上的进程能够相互交换数据2.一般的进程是独立的,一个进程的PCB(struct task_struct结构体)也叫进程控制块里只保存了本进程的信息,虚拟地址空间通过页表映射的物理内存也是只有自己通过操作系统能访问到,他只是能访问到,他自己是不知道数据存储在物理内存的什么位置.而操作系统只会让他访问到属于他自己的空间,不会让他访问到别的进程所保存的数据的地方.3.为了让进程之间能交流,就有了管道,下面是有关管道的介绍1.管道符号 | ;管道的本质是

2022-03-05 09:49:04 495

原创 【exec函数簇】进程程序替换

exec类函数的作用:在执行完fork函数之后,希望子进程可以执行其他现有的代码(不用再写一遍),就可以用exec类型函数替换子进程里的代码.exec类函数把当前进程映像替换成新的进程文件,而且该新程序通常从main函数处开始执行。进程ID并不改变。六个exec函数的区别在于:(a)待执行的程序文件是由文件名还是由路径名指定;(b)新程序的参数是一一列出还是由一个指针数组来引用;(c)把调用进程的环境传递给新程序还是给新程序指定新的环境。替换过程:1.首先用磁盘中已有的代码和数据2.然后

2022-03-02 14:36:11 292

原创 插入排序,选择排序,冒泡排序

1.插入排序插入排序的基本思路:一串无序的数据,第一个数据本身一定是有序的,直接判断第二个数据,如果第二个数据比第一个数据大,判断第三个,如果小,将第一个数据保存到第二个数据的位置,将第二个位置本来的数据放在第一个位置.对每一个数据都进行这样的比较就能得到一组有序的数void InsertSort(int* array,int size){ for (int i = 1; i < size; i++) { //待排序元素的前一个下标 int a = i - 1; /

2022-02-22 17:57:25 192

原创 make和makefile的应用

1.make和makefile的作用就是为了避免想要多次gcc,每次都得输入gcc指令.make是一个命令,makefile是一个文件:输入make指令就会执行当前文件下的makefile文件,makefile文件里的内容就是gcc.格式如下1.1简单的makefile文件内容第一行分别是生成对象:依赖对象(生成对象只能是一个,但是依赖对象可以依赖多个,因为想要得到的结果不一定是只依赖一个文件)第二行是编译指令 gcc前面是一个tab键,不能以空格代替1.2也可以在makefile文

2022-01-14 16:36:21 314

原创 对文件的操作

1.文件的分类 :文件分为二进制文件和文本文件首先,所有的数据在内存中都是以二进制形式存在的.只是存二进制之前的状态有所不同二进制文件就是在内存中什么样子,在文件中就是什么样子,例如数字在内存中以二进制存储,如果将他写进文件里就是以二进制形式放进了外存,也就是所谓的文件,但是咱们电脑上文件的打开方式比较单一,例如用记事本打开,就会出现乱码,因为记事本在读取是会将存入的二进制序列当成assic码,然后翻译assic码...

2021-11-15 13:19:12 64

原创 结构体大小的计算

结构体所占的字节在内存中并不是各成员所占简单之和实际计算方式为,结构体第一个元素放在内存中,这个元素的首地址定义为偏移量为0;其他成员不一定是接着上一个元素末尾地址存放,定义VS默认对齐数为8;除第一个元素外,其他元素存放在哪和需要用自身的大小和VS默认的对齐数进行比较,取较小值.这个数据在内存中存放的地址是从偏移量为0的地方算起,他放在比较出来的最小值的整数倍地址处.结构体的总大小为最大对齐数的整数被.每个数都有自己的对齐数(就是是和8比较后的最小值)如果嵌套了结构体,嵌套的结构体对其到自

2021-11-08 18:35:11 51

原创 类型的转换

在进行大的转小的的时候会发生截断,将高位字节去掉,剩下的内容存放在小内存里例如:int 型转char型,只会保留低地址的一个字节,高地址的三个字节被舍弃例题:char a='1';char只能保存00000001这八个bite位.指针类型进行转换时不会舍弃,要注意指针是指向一块内存空间将指针类型进行强转之后只会改变这个指针所指向的内存空间的大小.例如:int arr[10]=0; int*p=arr 这个表示p可以代表整个数组并且指向数组arr的首地址,如果进行指针+1操作,p指向的...

2021-11-07 22:48:55 150

原创 字符函数和字符串函数内存函数

1.求字符串长度size_tstrlen(const char* str)用指针接收一个字符串,strlen函数作用是找传入字符串末尾的\0,找一次就+1,找到\0后就返回一个int.2.字符串拷贝函数char*strcpy(char*destination,const char*source)将course中的字符拷入destination,包括字符串本身和末尾的\0;要求destination足够大.返回destination的地址.char*strncpy(char*desti

2021-11-03 21:57:37 69

空空如也

空空如也

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

TA关注的人

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