自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Linux文件系统中的软硬链接

在文件系统中,链接(Link)是一个重要的概念,它允许用户或系统通过不同的路径名访问同一文件或目录。链接分为硬链接(Hard Link)和软链接(Soft Link)两种。硬链接允许一个文件拥有多个文件名。这些文件名指向同一个inode,而该inode节点包含了文件的元信息(如文件大小、权限、所有者等)以及指向文件数据的指针,且文件所在的目录的inode与block的容量不发生改变。与硬链接不同,软链接不直接指向文件的inode节点,而是通过路径名来访问文件。

2024-05-01 19:45:59 297

原创 C++类型转换攻略

在C++编程中,类型转换(Type Conversion)是一个核心概念,它指的是将一个数据类型的值转换为另一个数据类型的值的过程。这种转换可能是隐式的(由编译器自动执行),也可能是显式的(由程序员通过特定的语法明确指示)。类型转换在编程中至关重要,因为它允许程序员灵活地处理不同数据类型的数据,并能够在需要时将它们转换为兼容的类型,以便进行进一步的计算或操作。

2024-04-30 16:45:02 1280 1

原创 Linux下的进程管理:创建、终止、切换与等待

进程管理是操作系统中不可或缺的核心功能之一,它负责控制和协调系统中各个进程的执行,确保它们能够高效、安全地并发运行。进程的创建、终止、切换与等待更是管理的关键环节。这些操作不仅影响单个进程的生命周期,更直接关系到系统资源的分配与利用效率。

2024-04-24 21:16:26 4209 8

原创 Linux进程地址空间及其页表

进程地址空间是指每个进程在计算机内存中所占用的地址空间。它本质上是一种虚拟地址空间,是进程看待内存的方式,抽象出来的一个概念,由操作系统提供。这种地址空间不是物理地址,而是由内核中的结构体mm_struct表示,用于在进程控制块中完成各个数据区域的划分,并通过页表映射到物理内存上。每个进程都有自己独立的地址空间,意味着每个进程都有自己的内存地址范围,不会与其他进程冲突。这种独立性有助于防止地址的随意访问,保护物理内存与其他进程。同时,将进程管理和内存管理进行解耦合,保证进程的独立性。

2024-04-23 19:13:08 1200 2

原创 Linux环境变量深度解析

在Linux操作系统中,环境变量是一种特殊的变量,用于存储系统或用户配置的信息。它们以键值对(key-value pair)的形式存在,可以在整个系统中被不同的程序和脚本访问和使用。环境变量通常用于存储路径、系统设置、语言环境等关键信息,以便程序能够正确地运行和交互。环境变量具有全局性,一旦设置,就可以被当前用户或整个系统的所有进程所访问。这使得环境变量成为了一种非常有效的配置和管理系统资源的方式。

2024-04-20 19:44:55 2025 4

原创 Linux进程状态深度解析:探索进程的生命周期

在Linux系统中,进程状态是多种多样的,它们各自代表了进程的不同执行阶段和资源占用情况。这些状态可以大致分为几类:为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在 Linux内核里,进程有时候也叫做任务)。"X (dead)"可执行状态(R):进程正在运行或准备在CPU上运行。这通常表示进程处于可执行状态,等待获得CPU资源以执行其代码。可中断的睡眠状态(S):进程处于可中断的睡眠状态。这意味着进程正在等待某个条件成立,比如等待I/O操作完成。

2024-04-07 16:44:43 2707 9

原创 std::function与std::bind:C++中的函数包装与绑定

std::function是一个通用的、多态的函数包装器,它可以保存、复制和调用任何Callable目标——函数、lambda表达式、bind表达式或其他函数对象。这使得我们能够以统一的方式处理各种可调用对象,无需关心它们的具体类型或签名。通过`std::function`,我们可以将函数作为参数传递给其他函数,或者将函数存储在容器中,实现更为灵活和模块化的代码设计。而std::bind则是一种生成可调用对象的方式,它可以将一个可调用对象与其参数绑定在一起,生成一个新的可调用对象。这个新的可调用

2024-04-07 12:40:48 789

原创 深入理解C++ lambda表达式:用法、特性与最佳实践

在C++中,lambda表达式是一种可以定义匿名函数的语法结构,允许在需要函数作为参数的地方直接定义和传递函数,从而提高了代码的简洁性和可读性。如果lambda表达式的体只有一个返回语句,并且该语句的类型是明确的,那么编译器可以自动推断出lambda的返回类型。其次,lambda表达式可以作为参数传递给其他函数,特别是在STL算法中,lambda表达式可以作为谓词(Predicate)使用,实现更加灵活的功能。在C++的lambda表达式中,返回类型可以是隐式推断的,也可以显式指定。

2024-04-06 17:20:42 1010 2

原创 C++11中auto与decltype的区别与联系深入解析

auto是C++11中引入的一个关键字,它用于在声明变量时让编译器自动推导出变量的类型。在这里,是一个表达式,编译器会根据该表达式的类型来推导的类型。decltype的主要功能是允许编译器在编译时期根据给定的表达式来推断其类型,而不仅仅是基于变量的初始化表达式。

2024-04-06 15:41:17 953

原创 C语言中的数组与函数指针:深入解析与应用

从字符串数组的基础知识出发,逐步探讨函数指针的概念与应用。我们将首先回顾字符串数组的基本概念和应用场景,然后逐步引入函数指针的概念,并详细阐述其在编程中的高级应用和灵活性。通过这个过程,我们希望读者能够深入理解从处理数据(字符串数组)到处理代码(函数指针)的思维转变,并学会将这两种强大的工具结合起来,实现更复杂、更灵活的编程逻辑。

2024-04-03 21:32:19 1396 5

原创 深入C语言:探究static关键字的奥秘

当用于不同的上下文环境时,`static`关键字具有不同的意思。当用于函数定义时,或用于代码块之外的变量声明时,`static`关键字用于修改标识符的链接属性(从 `external` 变为 `internal` ),但标识符的存储类型和作用域不受影响。用这种方式声明的函数或变量只能在声明它们的源文件中访问。当用于代码块内部的局部变量的声明的时候,`static`用于修改变量的存储类型,从自动变量修改为静态变量,但变量的链接属性和作用域不受影响。用这种方式声明的变量在程序执行之前创建,并在程序的整个

2024-04-03 20:02:20 646 1

原创 布隆过滤器:基于哈希函数的原理、应用解析

布隆过滤器(Bloom Filter) 是一种空间效率极高的概率型数据结构,它利用位图和哈希函数来快速判断一个元素是否属于某个集合。布隆过滤器不是传统意义上的过滤器,它不能完整地存储数据,而是以一种紧凑的方式表示数据可能存在的集合。

2024-04-01 19:34:53 1062 6

原创 深入探索位图技术:原理及应用

虽然位图在图形处理中也常被提及,但在此上下文中,我们需要明确区分两种不同类型的“位图”:一种是数据结构中的位图,如上所述,它主要用于数据的高效存储和检索;当我们要标记第n个数据元素是否存在时,我们只需要找到对应的整数(通过n除以32得到整数索引),然后在该整数中找到对应的二进制位(通过n对32取余得到位索引),并将其设置为0或1。在上面的例子中,如果使用一个整型数组来存储集合中的元素,每个整数需要4个字节(假设是32位系统),那么存储1亿个整数需要大约400MB的空间。如果是1,表示该整数存在于集合中;

2024-03-31 21:10:18 896 15

原创 C++运算符重载中的引用返回

在C++中,对于自定义类型,重载运算符时返回引用是一个常见的做法,特别是针对类似+=、-=等复合赋值运算符。通过返回左侧操作数的引用,可以实现链式调用和保持与内置类型相似的行为,增强代码的可读性和一致性。这不仅增加了内存分配和释放的开销,还可能导致不必要的对象复制,降低了代码的效率。通过返回引用,我们可以直接修改并返回原始对象,避免了这些额外的开销。对于自定义类型,重载这些运算符以返回引用可以保持与内置类型相似的行为,这有助于保持代码的语义一致性和可读性。类重载了赋值运算符,使其返回自身的引用。

2024-03-26 16:27:33 1176 15

原创 红黑树进阶:正向与反向迭代器的实现及map、set的封装实践

map和set是两种常见的数据结构,它们分别用于存储键值对和无序集合。红黑树作为一种高效的平衡搜索树,非常适合用于封装这两种数据结构。通过红黑树的特性,我们可以保证map和set在插入、删除和查找操作时的性能稳定且高效。此外,红黑树的有序性也使得map和set在遍历元素时能够按照特定的顺序进行,满足了更多实际应用的需求。迭代器是一种设计模式,它允许我们顺序访问容器中的元素。对于红黑树来说,设计高效的迭代器是实现其封装Map和Set的关键之一。通过迭代器,我们可以方便地遍历红黑树中

2024-03-25 18:27:19 1180 17

原创 从哈希桶角度看 unordered_map 与 unordered_set 的实现

在C++中,当使用等无序容器时,哈希函数起着至关重要的作用。默认的哈希函数对于许多类型都工作得很好,但有时对于自定义类型或特殊需求,默认的哈希函数可能不是最优的,甚至可能导致性能下降或哈希冲突过多。为特定类型设计哈希函数对于自定义类型,需要提供一个哈希函数,该函数接受自定义类型的对象作为参数,并返回一个足够大的整数值。不同的对象尽可能映射到不同的哈希值。相同的对象总是映射到相同的哈希值。哈希函数的计算应该尽可能快。

2024-03-19 20:24:48 2631 2

原创 哈希技术解析:从哈希函数到哈希桶及其迭代器的全面指南

哈希表(Hash Table)是一种非常重要的数据结构,它基于哈希函数将键(Key)映射到值(Value)上,从而实现对数据的快速存储、查找和删除。在哈希表中,数据并不是按顺序存储的,而是根据哈希函数计算出的键的哈希值,确定数据在表中的位置。由于哈希函数的设计使得键与位置之间存在直接对应关系,因此哈希表在查找、插入和删除操作上的平均时间复杂度可以达到O(1),即常数时间复杂度。这使得哈希表在处理大规模数据时具有极高的效率。

2024-03-19 18:15:41 1172 1

原创 深入解析红黑树(RB-Tree):原理、操作及应用

红黑树作为一种自平衡的二叉搜索树,在计算机科学领域中占据着重要的地位。它的设计旨在在维持树的平衡性的同时,保证各种操作的时间复杂度始终稳定在较低水平。红黑树的灵活性和高效性使得它成为众多编程语言和系统实现中不可或缺的数据结构之一。本文将带领读者深入探究红黑树的结构与原理。(c++实现)

2024-03-17 20:28:28 1282 2

原创 细说C++反向迭代器:原理与用法

通常,反向迭代器在内部持有一个指向容器末尾之后位置的迭代器,或者一个指向容器第一个元素之前的迭代器,这取决于容器的具体实现。本文将详细介绍C++中反向迭代器的概念、原理和使用方法,并通过模拟实现一个简单的反向迭代器来加深读者对反向迭代器的理解。通过本文的学习,读者将能够掌握反向迭代器的基本用法,并能够在实际编程中灵活运用反向迭代器来处理各种需要逆向遍历容器的场景。在C++中,反向迭代器是一种特殊的迭代器,它允许我们按照相反的顺序遍历容器中的元素。在标准库中的迭代器类型中,这通常是成立的。

2024-03-15 20:48:31 1353 6

原创 探索仿函数(Functor):C++中的灵活函数对象

仿函数(Functor)是一种行为类似函数的对象,它可以被用作函数并接受参数。在C++中,仿函数通常是重载了函数调用运算符operator()的类对象。通过重载operator(),仿函数可以像函数一样被调用,并且可以保存状态信息。按照操作数划分:假定某个类有一个重载的operator(),而且重载的operator()要求获取一个参数,我们就将这个类称为一元仿函数(unary functor);如果重载的operator()要求获取两个参数,就将这个类称为二元仿函数(binary functor)。

2024-03-15 18:48:28 980 3

原创 深入解析C++树形关联式容器:map、set及其衍生容器的使用与原理

关联式容器是C++标准库中的一种重要数据结构,它允许我们存储键值对(key-value pair)或单独的元素,并基于键(key)来快速访问或检索对应的值(value)或元素。关联式容器在多种场景下发挥着至关重要的作用,特别是在需要高效查找、插入和删除元素时。它们为程序员提供了便捷的工具,可以简化复杂的操作,并优化程序性能。

2024-03-13 18:34:47 1541 12

原创 深入探索AVL树:优雅的自平衡二叉搜索树

AVL树是一种自平衡的二叉搜索树,其在每个节点上维护一个平衡因子(Balance Factor),用于确保树的高度保持在较低水平( 即保持在O(log n) )从而提高性能。定义每个节点的平衡因子(Balance Factor)是 -1、0 或 1。左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1)。左子树和右子树都是AVL树。// 该节点的左孩子// 该节点的右孩子// 该节点的双亲int _bf;

2024-03-12 19:12:49 1024 17

原创 深入了解二叉搜索树:原理、实现与应用

在计算机科学中,数据结构是构建算法和程序的基础。其中,二叉搜索树(Binary Search Tree,简称 BST)作为一种常见的数据结构,在很多应用中发挥着重要作用。它具有以下特点:每个节点最多有两个子节点,左子节点的值小于父节点的值,右子节点的值大于父节点的值。这一特性使得二叉搜索树具有快速的查找、插入和删除操作。

2024-03-10 20:12:40 1442 37

原创 【C++私房菜】序列式容器的迭代器失效问题

在实际编程中,当对listvector以及string进行插入或删除操作时,需要格外小心,避免在迭代器失效的情况下继续使用迭代器。如果需要在循环中对容器进行插入或删除操作,可以考虑使用迭代器的insert和erase方法,并注意更新迭代器的位置,以避免迭代器失效问题。一句话就能总结解决迭代器失效问题:在使用前,对迭代器重新赋值即可。

2024-02-28 20:04:47 1423 66

原创 【C++私房菜】面向对象中的多态

在C++中,重载、覆盖(重写)和隐藏(重定义)都是面向对象编程中的概念,用于处理函数的多态性。重载(Overloading)定义:重载是指在同一个作用域内,使用相同的函数名但具有不同的参数列表的情况。函数重载可以根据参数的类型、顺序和个数进行区分。特点:函数名相同,参数列表不同。返回值类型可以相同也可以不同。发生在同一个类或命名空间中。覆盖(重写,Override)定义:覆盖是指在派生类中重新实现基类中已经存在的虚函数。

2024-02-24 21:06:06 1348 37

原创 【C++私房菜】面向对象中的多重继承以及菱形继承

多重继承(multiple inheritance)是指从多个直接基类中产生派生类的能力。多重继承的派生类继承了所有父类的属性。尽管看上去与单继承没有什么区别,但是多个基类交织混合产生的细节会带来错综复杂的设计问题与实践问题。菱形继承是多继承的一种特殊情况。

2024-02-23 18:20:39 1306 38

原创 【C++私房菜】面向对象中的简单继承

一个派生类对象包含多个组成部分:一个含有派生类自己定义的(非静态)成员的子对象,以及一个与该派生类继承的基类对应的子对象,如果有多个基类,那么这样的子对象也有多个。如果基类对象不是派生类对象的一部分,则它只含有基类定义的成员,而不含有派生类定义的成员。类似的,如果我们将一个派生类对象赋值给一个基类对象,则实际运行的赋值运算符也是基类中定义的那个,该运算符同样只能处理基类自己的成员。表达式的静态类型是编译时总是已知的,它是变量声明时的类型或表达式生成的类型:动态类型则是变量或表达式表示的内存中的对象的类型。

2024-02-23 14:42:06 1195 33

原创 【Linux】make和makefile详解

当谈论到 Linux 中的软件构建工具时,不得不提到 Makefile。Makefile是一种文件,它包含了一组规则,用于指导构建系统在源代码中生成可执行文件或库。它是使用GNU Make软件的标准格式。Makefile 的主要目的是描述代码文件之间的依赖关系以及如何构建以达到特定目标。通过定义规则和命令,开发人员可以轻松地管理项目的复杂构建过程。Makefile 带来的好处就是——“自动化编译”,一旦写好,只需要一个 make 命令,整个工程 完全自动编译,极大的提高了软件开发的效率。

2024-02-01 17:30:52 1411 4

原创 【C++私房菜】类和对象详解

在 C++中,我们通过定义一个类(class)来定义自己的数据结构。一个类定义了一个类型,以及与其关联的一组操作。类机制是 C++最重要的特性之一。实际上,C++最初的一个设计焦点就是能定义使用上像内置类型一样自然的类类型(class type)。类是 C++中面向对象编程(OOP)的核心概念之一。

2024-02-01 17:29:16 923 4

原创 【 C++私房菜】模板的入门与进阶

函数模板(function template)是通用的函数描述,也就是说,它们使用泛型来定义函数,其中的泛型可用具体的类型(如 int、double) 替换。通过将类型作为参数传递给模板。可使编译器生成该类型的函数。由于模板允许以泛型(而不是具体类型)的方式编写程序。因此有时也被称为通用编程,由于类型是用参数表示的,因此模板特性有时也被称为参数化类型(parameterized types)。下面介绍为何需要这特性以及其工作原理。

2024-01-27 22:15:39 1153 7

原创 【C++私房菜】new/delete、定位new及内存分配

C++内存管理以及new delete ,定位运算符……

2023-11-12 12:24:24 608 17

原创 【Linux】Shell基本命令——操作系统

命令行和sheill这两个概念常常是令人困惑的,在很多不正式的场合,这两个名词代表着相同的概念,即命令行解释器。然而从严格意义上讲,命令行指的是供用户输入命令的界面,其本质只是接受输入,然后把命令传递给命令解释器。后者就是shell。从本质上讲,shell是一个程序,它在用户和操作系统之间提供了一个面向行的可交互接口。用户在命令行中输入命令,运行在后台的Shell把命令转换成指令代码发送操作系统。shell提供了很多高级特性,使得用户和操作系统间的交互变得简单。

2023-11-12 10:37:26 290 3

原创 【C++私房菜】语法中的static和const

(1)静态成员函数中不能调用非静态成员。(2)非静态成员函数中可以调用静态成员。因为静态成员属于类本身,在类的对象产生之前就已经存在了,所以在非静态成员函数中是可以调用静态成员的。(3)静态成员变量使用前必须先初始化(如。

2023-11-04 18:10:20 172 2

原创 【C++私房菜】入门基础语法

内联展开是在编译时进行的,只有链接的时候源文件之间才有关系。所以内联要想跨源文件必须把实现写在头文件里。如果一个内联函数会在多个源文件中被用到,那么必须把它定义在头文件中。内联函数的定义不一定要跟声明放在一个头文件里面:定义可以放在一个单独的头文件中,里面需要给函数定义前加上inline 关键字,原因看下面第 2.点;然后声明 放在另一个头文件中,此文件include上一个头文件。这种用法 boost里很常见:优点1. 实现跟API分离封装。优点2. 可以解决有关inline函数的循环调用问题。

2023-10-24 21:24:01 101 1

原创 【Linux】用户切换及文件权限详解

Linux是一个基于Unix的操作系统内核,由芬兰程序员Linus Torvalds于1991年开发。Linux内核是开源的,这意味着任何人都可以查看、修改和重新分发它。Linux操作系统则是由Linux内核与其他软件组件(如GNU工具和图形界面)组成的完整操作系统。但Linux只是操作系统内核本身,但通常采用“Linux内核”来表达该意思。而Linux则常用来指基于Linux内核的完整操作系统, 它包括GUI组件和许多其他实用工具。

2023-10-24 21:16:50 61

原创 【排序详解】快排、归并、希尔

具体实现中,每次循环时,对于当前的gap,从左到右将相邻的两个长度为gap的区间进行合并,如果右边区间不足长gap,则将右边区间长度调整为剩余元素个数。快排的思想是任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。当 left 和 right 相遇时,将基准值和 left 指向的元素互换位置,并且此时基准值左侧都是小于它的元素,右侧都是大于它的元素。

2023-10-11 21:31:20 62

原创 【排序详解】TOP-K问题与基于完全二叉树的堆排序

然后判断选定的子节点的值是否小于父节点的值,如果是,则交换两个节点的值,并更新parent和child的值继续向下调整,直到到达叶子节点或不需要再进行交换。一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。3、用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

2023-09-24 21:11:07 58 1

原创 【排序详解】冒泡、选择、插入

外层循环从索引0开始,依次遍历数组中的元素,内层循环从外层循环位置的下一个索引开始,找到未排序部分的最小元素,并将其索引赋值给变量min。它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找最小(大)元素,将其放到已排序的序列的末尾。此算法从小到大排序的基本原理是:每一趟排序讲待排续空间中每一个元素与后一个进行比较,若存在小于关系,则进行冒泡(交换),一趟排序下来以后,待排序空间中的最后一个元素最大。借助从网上流传最广的图片理解。

2023-09-18 19:53:51 105

原创 【数据结构】使用C语言实现的栈和队列

接收一个指向栈结构的指针和要插入的元素作为参数。首先释放动态分配的内存,将栈的指针(ps)赋值为NULL,容量(capacity)和栈顶(top)都设为0。函数返回栈的top成员变量的值,即栈中元素的个数。它将栈的指针(ps)赋值为NULL,容量(capacity)为0,栈顶(top)为0。这段代码实现了一个动态扩容的栈,可以方便地进行入栈、出栈、获取栈顶元素等操作,并且具备栈空判断和销毁栈的功能。获取栈中有效元素个数(StackSize):该函数返回栈中有效元素的个数,即栈的栈顶位置(top)。

2023-08-07 20:28:09 82

原创 【C语言】预定义符号,#define关键字及条件编译详解

在C语言中,有一些预定义符号(Predefined Symbols)是由编译器提供的,它们具有特殊的含义和功能。以下是C语言中的一些常见预定义符号:__LINE__: 表示当前代码所在的行号。__FILE__: 表示当前源文件的文件名。__DATE__: 表示当前编译的日期,格式为"MMM DD YYYY",例如"Jul 29 2023"。__TIME__: 表示当前编译的时间,格式为"HH:MM:SS",例如"10:30:36"。__STDC__: 表示当前编译器是否符合C语言标准。

2023-07-29 18:59:38 893

空空如也

空空如也

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

TA关注的人

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