自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 如何理解Linux下的文件描述符 ?以及Linux下的重定向与缓冲区这一概念???

开始正式内容之前,会先大致描述一下我们在说些什么。所有是内容都是围绕文件描述符这一概念进行展开,但是并不会直接切入这一概念,因为这一概念并不是很难,但是因为文件描述符而涉及的周边概念是很广泛的,我会由周边涉及到的知识逐步递进,逐渐引入文件描述符。首先我们先解答下面的疑问。1.文件是什么?请参考C语言文件操作,总结一下就是,文件 = 内容 + 属性(属性也是数据)2.文件的相关操作是什么?无外乎两种:a.对内容的操作 b.对属性的操作3.访问文件本质是谁在访问?进程。为什么?

2024-04-25 15:07:52 824 2

原创 关于Linux下的进程替换(进程篇)

其实这里还涉及到一个写时拷贝的问题:在之前的博客中提及过,父进程创建子进程,代码是共享的,地址空间也是共享的,因为代码是不能更改的,而数据写时拷贝。-----------------------------------------------测试代码process_replace.c (下面的测试代码脚本都是这个)-------------------------------------官方的说法是:程序替换,是通过特定的接口,加载磁盘上的一个权限的程序(代码和数据),加载到调用进程的地址空间中!

2024-04-12 10:12:23 756

原创 关于Linux下的进程等待(进程篇)

最后思考一下:既然进程是具有独立性的,进程退出码,不也是子进程的数据吗?如果子进程已经退出,调用wait/waitpid时,wait/waitpid会立即返回,并且释放资源,获得子进程退出信息。waitpid/wait可以在存在多个子进程的情况下,让子进程退出具有一定的顺序性,将来让父进程进行更多的收尾工作。因为如果子进程退出,父进程不接收子进程的退出状态,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。只有子进程退出的时候,父进程才会调用waitpid函数,进行返回(注意,父进程依旧在运行)

2024-04-10 14:09:57 813 1

原创 关于父进程中的环境变量无法传递给子进程

这里是没有进入if语句的,因为第二次切割子串在 if 语句之后, g_argv[1] 为空,条件不成立,未进入语句,继续执行下面的代码,创建子进程进行程序替换,但是替换时export这样的命令是不存在的(我们编写的shell脚本内),所以出现了报错。今天在写shell脚本的时候,遇到一个棘手的问题,是关于环境变量,当时父进程的环境变量是无论如何也无法传递给子进程,重重排查,才找到问题所在,所以心血来潮,想写一下关于Linux下的环境变量具有全局属性的这个问题。环境变量是否具有全局属性?

2024-04-10 09:41:52 744

原创 关于Linux中的环境变量

环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数不知道各位小伙伴会不会有疑问,为什么我们在Linux下运行自己写的程序前面需要加上./, 而而运行系统的指令是不需要加上./。这是为什么呢?return 0;total 20可以看到,执行a.out的时候前面需要加上 ./ , 而系统的指令ls是不需要的,这是为什么?

2024-04-09 17:14:31 1038

原创 详解简单的shell脚本 --- 命令行解释器【Linux后端开发】

原因是因为,当前我们自己写的shell,无论我们写的任何指令,都是交给了子进程 , 子进程进行进程替换帮助我们来完成的指令,那么指令就只会影响子进程,而不会影响父进程。那么我们想要的是shell脚本所在的路径发生变化,所以我们想要进行判断命令,如果是所谓cd这样的命令,那么我们不能创建子进程,而是直接交给父进程。这是一个需要注意的小细节的地方,因为在输入的时候,当我们最终输入字符结束的时候,会输入一个“回车”键盘,它会被缓冲区拿到并被识别为“\n”。如果字符串中不存在更多的标记,则返回 NULL 指针。

2024-04-08 16:22:50 1168

原创 关于Linux下的进程创建与终止(进程篇 - 涉及写时拷贝,fork函数)

是可以自定义设置的所以:我们自己可以使用这些退出码和含义,但是,如果你想自己定义,也可以自己设计一套退出方案!

2024-04-07 11:05:55 920

原创 关于Linux下的进程状态(进程篇)

当系统中存在着大量的进程,那么一定会消耗大量的内存资源,此时,系统不得不通过把内存中的进程(对应的代码和数据)交换到磁盘,从而保证内存中仍有空余的空间,此时,对于被交换的进程来说,状态就被称为挂起。所以为了防止这样情况的发生,才有了D状态,他的意思是告诉系统,我是不可以被干掉的,只能等我传输成功,从睡眠中醒来才可以干掉我这个进程。或者来说c语言中的scanf,c++中的cin,在系统中不也是在等待键盘资源的输入嘛,当我们的程序存在这些命令的时候,如果此时不在键盘上输入,那么此时的进程就处于阻塞状态。

2024-04-06 16:54:32 890

原创 关于Liunx下的进程概念

的方式运行一个程序的时候,本质上,就是在系统层面上创建一个进程,Linux是可以同时加载多个可执行程序的,意味着系统中是会出现同时存在大量进程的情况。I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。通过对进程对应的PCB结构的增删查改,也就实现了对进程的管理。标示符: 描述本进程的唯一标示符,用来区别其他进程。

2024-04-06 14:52:48 409

原创 简单聊聊冯诺伊曼体系结构

小a:键盘输入(制造产品)--- > 加载到内存 --- > 内存交给cpu(进行打包,封装,填写收件人信息)--- > 加载到内存 --- > 输出设备(通过网卡发出快递)小b:网卡输入(收到产品)--- > 加载到内存 --- > 内存交给cpu(拆掉快递,撕开包装)--- > 加载到内存 --- > 输出设备(显示器打印信息)b.如果没有存储器参与进来,那么cpu就没有操作的空间,只能与外设直接交互,有存储器的话,可以让软件(系统)参与进来,进行更加合理的分配。为什么不能直接让cpu与外设直接交互?

2024-04-03 19:06:43 311

原创 哈希表以及哈希表的底层结构 --- 万字解说【c++11】

-(常用)取关键字的某个线性函数为散列地址:Hash(Key)= A*Key + B优点:简单、均匀缺点:需要事先知道关键字的分布情况使用场景:适合查找比较小且连续的情况。

2024-03-29 16:42:53 651

原创 浅谈linux下的进程地址空间(虚拟地址/线性地址)

示例:运行之后发现:同一个变量,同一个地址,在运行一段时间后,竟然会在同一时间出现两个不同的值?这是完全违背常理的,按道理来说一个 int类型 ,只能存储一个整数,为什么这里会出现两个完全不同的值呢???要想了解这个问题,我们需要先了解一些东西。linux下的地址空间:注意,这里指的是虚拟地址空间【说明】1.栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

2024-03-25 17:04:38 1062

原创 linux环境基础开发工具3(git 、 gdb)

注:这个可以理解为是执行完当前函数,vs是没有这一功能的,vs一般是在函数的开头与结尾处设置断点。list/l 行号:显示程序源代码,接着上次的位置往下列,每次列10行。print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数。注:开始调试,如果没有设置断点,程序就直接结束 - 相当于vs中的f5。注:可以理解为vs中运行至下一个断点,如果中途没有断点,程序直接结束。:显示程序源代码,接着上次的位置往下列,每次列10行。注:删除的时候不能输入行号,只能输入编号才可以删除成功。

2024-03-14 19:31:44 757

原创 linux环境基础开发工具2(gcc/g++ 、 make/ Makefile)

static。

2024-03-14 16:35:31 589

原创 linux环境基础开发工具1(vim 、 yum)

在Linux下安装软件一个通常的办法是下载到程序的源代码并进行编译得到可执行程序但是这样太麻烦了,于是有些人把一些常用的软件提前编译好做成软件包可以理解成windows上的安装程序)放在一个服务器上通过包管理器可以很方便的获取到这个编译好的软件包直接进行安装软件包和软件包管理器就好比"App"和应用商店这样的关系是Linux下非常常用的一种包管理器主要应用在Fedora, RedHat,Centos等发行版上。

2024-03-14 16:35:24 1105

原创 数据结构中的平衡搜索树 --- 红黑树 (如何旋转与变色)

红黑树和AVL树都是高效的平衡二叉树,增删改查的时间复杂度都是O($log_2 N$),红黑树不追求绝对平衡,其只需保证最长路径不超过最短路径的2倍,相对而言,降低了插入和旋转的次数,所以在经常进行增删的结构中性能比AVL树更优,而且红黑树实现比较简单,所以实际运用中红黑树更多。这时会发现违反性质3比违反性质4的代价要更小,而事实上也的确是这样做的,可能会有疑问,这样还是红黑树嘛,其实新增节点之后是需要通过变色来达到红黑树的结构的。此时我们会发现,最后的结构是符合红黑树的:没有出现连续的红色节点;

2024-03-13 15:43:42 764

原创 数据结构中的平衡搜索树 --- AVL树是怎样进行旋转处理的?(平衡因子版本)

树做一些结构修改的操作,性能非常低下,比如:插入时要维护其绝对平衡,旋转的次数比较多,更差的是在删除时,有可能一直要让旋转持续到根的位置。):第一次单旋会把30节点 、60节点 的平衡因子置成 0,第二次单旋会把60节点 、90节点 的平衡因子置成 0 ,这显然是不对的,因为90节点最后的平衡因子应该是1。因为AVL树也是二叉搜索树,可按照二叉搜索树的方式将节点删除,然后再更新平衡因子,只不错与删除不同的时,删除节点后的平衡因子更新,最差情况下一直要调整到根节点的位置。什么时候右旋,什么时候双旋呢?

2024-03-12 17:49:09 651

原创 二叉搜索树 - c++实现

对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度的函数,即结点越深,则比较次数越多。a、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。若它的左子树不为空,则左子树上所有节点的值都小于根节点的值。若它的右子树不为空,则右子树上所有节点的值都大于根节点的值。b、最多查找高度次,走到到空,还没找到,这个值不存在。,统计成功后,给定单词就可快速找到其出现的次数,

2024-01-22 15:09:40 812

原创 关于c++的三大特性 --- 多态(底层原理)

建议看下面的内容之前,先看一下这里我们先来看一个笔试题:请问 sizeof(Base)是多少?为什么呢?按照内存对齐的规则,这里应该是4byte,为什么是8byte呢?调试一下:通过观察测试我们发现,。一个含有虚函数的类中都至少都有一个虚函数表指针,因为虚函数的地址要被放到虚函数表中,虚函数表也简称虚表。

2024-01-19 13:01:02 816

原创 c++三大特性之多态

从上面可以看出,C++对函数重写的要求比较严格,但是有些情况下由于疏忽,可能会导致函数名字母次序写反而无法构成重载,而这种错误在编译期间是不会报出的,只有在程序运行时没有得到预期结果才来debug会得不偿失,因此:C++11提供了。),所以就算是子类不加 virtual 关键字,也认为是虚函数,因为父类就是虚函数,子类继承也是虚函数,当然,也可以认为是个例外。,派生类继承的是基类虚函数的接口,目的是为了重写,达成多态,继承的是接口。但是在这个地方,我们认为子类重写了这个虚函数,重写体现的是。

2024-01-09 16:58:40 850

原创 关于linux权限的相关操作

文件和文件目录的所有者:u(User)文件和文件目录的所有者所在的组的用户:g(Group)其它用户:o(Others)

2024-01-05 18:36:12 847

原创 c++的三大特性之关于继承

Person是父类,也称作基类。Student是子类,也称作派生类。

2024-01-03 20:33:51 829

原创 linux常见基础指令

指令用于复制文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则它会把前面指定的所有文件或目录复制到此目录中。起别名并不是一直有效,只在本次登陆上上有效,如果退出,下次登录就会失效,如果想要一直有效,就需要将这条指令放进启动脚本里面。命令完成文件重命名,此时,源文件只能有一个(也可以是源目录名),它将所给的源文件或目录重命名为给定的目标文件名。在显示方面,使用者可以设定欲显示的格式,格式设定为一个加号后接数个标记,其中常用的标记列表如下。对于文件,将列出文件名以及其他信息。

2023-12-30 14:14:09 1171

原创 c++ - 模板特化

模板特化中分为与。注意:以下示例均已日期类为例函数模板的特化步骤:1.必须要先有一个基础的函数模板2.关键字template后面接一对空的尖括号3.函数名后跟一对尖括号,尖括号中指定需要特化的类型4.函数形参表必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误。该种实现简单明了,代码的可读性高,容易书写,因为对于一些参数类型复杂的函数模板,特化时特别给出,因此函数模板不建议特化。

2023-12-28 22:27:49 415

原创 关于标准库中的反向迭代器

迭代器(iterator)有时又称光标(cursor)是程序设计的软件设计模式,可在容器对象(container,例如list或vector)上遍历访问的接口,通常来说就是访问容器(数据结构中保存)的元素。并且迭代器是分类型的,STL中的名字是类型的暗示(比如Inputiterator),迭代器的使用属性是正向访问以及反向访问;还有特性属性,严格来说还分单向双向随机,单链表的迭代器特性就是一个单向的,它只能++,不能--,双向链表的迭代器特性就是双向的,不仅能++,还能--。

2023-12-25 14:31:25 892

原创 关于标准库中的 stack / queue / 优先级队列(涉及部分仿函数,deque)

双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。

2023-12-24 12:51:47 715

原创 关于标准库中的list(涉及STL的精华-迭代器的底层)

因为这里的const修饰的是*this 也就是指向的内容,*this 是这个节点的指针,const修饰的是这个指针的本身不能被改变,也就是_head不能被改变,但是可以拷贝。所以回过头来也能发现,c++新增运算符重载,而不是继续使用printf函数,是因为printf函数有局限性,printf只能打印内置类型,%d,%lf等等。其次,关于下面这句代码,我们并没有实现拷贝构造,编译器会默认生成,默认生成的拷贝构造是浅拷贝,那么,这里可以使用浅拷贝嘛?这里不仅可读,并且可写,显然程序是有些不正确的。

2023-12-13 15:40:16 1061

原创 关于标准库中的vector - (涉及迭代器失效,深浅拷贝,构造函数,内置类型构造函数,匿名对象)

回答是不会,如果使用 iterator 就把这里的构造函数写死了,以后使用必须要传vector的迭代器来运行,迭代器区间的构造不一定要使用vector,一个容器使用迭代器区间去初始化,只要存储的类型符合,就可以使用任意类型的迭代器。说明什么,说明拷贝构造还不够完善呗,原因其实出在赋值上面,因为 vector 我们并没有写赋值 ,所以使用的是编译器默认生成的赋值,默认生成的赋值来进行拷贝,也就是浅拷贝。但是由于vs22的优化,导致我们看起来好像还是浅拷贝,其实不是,怎么样,看起来不正常,实际上是正常。

2023-12-02 22:32:52 890

原创 关于标准库中的string类 - c++

流提取并未在输入中获取字符,而是在缓冲区获取字符,而空格或者换行未进入缓冲区,c++/c 规定,值与值之间的区分必须是空格或者换行,所以输入空格或者换行会被认为是多个字符之间的间隔,不会被cin 或者 scanf 拿到。答:因为_capacity是容量字符,指的是能够存取多少个有效字符,而vs认为 '\0'属于标识符,不属于有效字符的范畴,所以+1是为了给'\0'预留空间。的时候,会导致缩容的问题,对程序的安全造成隐患,因此要加个判断,避免出现缩容的情况。操作时,如果能够大概预估到放多少字符,可以先通过。

2023-11-21 17:55:44 495

原创 c++中的动态内存管理

答:malloc 与 calloc 都是申请内存空间,只不过calloc 会对空间进行初始化,而 realloc 是对已有空间进行扩展。malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new。总结:new 的底层是operator new ,operator new 是 malloc 的封装。基本类似,不同的地方是:new/delete申请和释放的是单个元素的空间,

2023-10-04 16:02:01 251

原创 (c++)类和对象 下篇

内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。,不属于任何类,但需要在类的内部声明,声明时需要加。

2023-10-03 11:08:36 127

原创 (c++)类和对象中篇

这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如。注意:在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定。关于编译器生成的默认成员函数,很多童鞋会有疑惑:不实现构造函数的情况下,编译器会。无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如。是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务。

2023-09-23 13:20:20 68

原创 (c++)类和对象 上篇

将一件事情拆分成不同的对象,靠对象之间的交互完成。为什么说c++是基于面向对象的语言,因为c++不仅可以面向对象,还可以面向过程,算是混编,其次c++要兼容c语言。如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。缺陷:每个对象中成员变量是不同的,但是调用同一份函数,如果按照此种方式存储,当一。

2023-09-01 13:29:22 137

原创 c++都补了c语言哪些坑?

中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。c++在形成符号表的时候,会有专门的函数名修饰规则,即使是同一个函数名,参数类型不同,形成的符号表也不会相同。另外如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分。注:如果出了函数作用域,返回对象会销毁的话,那么一定不能使用引用返回,要使用传值返回。相对于编译器而言,是寻找的规则。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

2023-08-23 23:40:37 4638

原创 常见排序集锦-C语言实现数据结构

希尔排序又称缩小增量法,思想 :算法先将要排序的一组数按某个增量 gap 分成若干组,每组中记录的下标相差 gap .对每组中全部元素进行排序,然后再用一个较小的增量对它进行分组,在每组中再进行排序。根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,冒泡排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次 序保持不变,即在原序列中,r[i]=r[j]它是通过堆来进行选择数据。

2023-08-16 20:53:31 604

原创 二叉树的链式结构 - 遍历 - C语言递归实现

思路:也是两种方法,第一种方法是在上一道例题的基础上,创建一个全局变量,用if判断。②是先求出左子树结点的个数再加上右子树结点的个数,最后再加上根。思路:求出左树的深度,再求出右树的深度,加1是加根,然后比较以下,谁大/深返回谁。思路:分治算法,分而治之,把大问题转换成类似规模的小问题。这里有两种方法,①是定义一个全局变量,每递归一次,变量就++一次。注:这里值得注意的一点是,返回值的问题以及跳出递归。用前序遍历一下就行。访问根结点的操作发生在遍历其左右子树之中(间)。由于被访问的结点必是某子树的根,

2023-07-29 00:30:27 198

原创 快慢指针 - 关于链表oj题的思路延申

与fast之间的结点距离为N,这个时候fast才真正开始追击slow,slow每次访问一个结点,fast每次访问两个结点,所以它们之间的距离每次都会缩减1个结点。定义:快慢指针,即慢指针一次走一步,快指针一次走两步,两个指针从链表其实位置开始运行,如果链表带环则一定会在环中相遇,否则快指针率先走到链表的末尾。一个指针从头指针的位置开始向后访问,一个指针从快慢指针相遇的地方开始向后访问,两个指针会在入环的第一个结点相遇。综述,3,4...n步皆是视情况而定,不一定能追上,但是两步是一定能追上。

2023-07-05 13:43:59 59

原创 数据结构单链表 - C语言实现

概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。注:以上概念以及图片均来自比特科技。

2023-06-30 23:47:23 63

原创 数据结构顺序表 - C语言实现接口

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

2023-06-30 20:24:52 42

原创 #define - C语言预处理指令

define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(definemacro)。3. 最后,再次对结果文件进行扫描,看看它是否包含任何由#defifine定义的符号。1. 在调用宏时,首先对参数进行检查,看看是否包含任何由#defifine定义的符号。1. 宏参数和#defifine 定义中可以出现其他#defifine定义的变量。2. 当预处理器搜索#defifine定义的符号的时候,字符串常量的内容并不被搜索。对于宏,参数名被他们的值替换。

2023-06-25 00:00:45 83

C语言 - xmind思维导图

细分C语言知识脉络,全面总结c语言知识点。 内容管理:大致细分函数,指针,数据结构,结构(选择结构,循环结构),字符/字符串,结构体,操作符,数组,变量常量等内容的细节曝光。 观看建议:能够细致的了解C语言实现的底层逻辑,各个知识点看似分散,实则都是紧密相连,值得收藏反复观看。

2023-06-07

空空如也

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

TA关注的人

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