- 博客(36)
- 收藏
- 关注
原创 C++移动语义与智能指针笔记
本文主要介绍了C++中的移动语义与智能指针。移动语义通过右值引用实现,能够减少不必要的内存分配和复制操作,提升性能。右值引用可以绑定到右值,区分出临时对象,从而支持移动构造函数。移动构造函数通过浅拷贝复用临时对象的内存空间,避免重复申请和释放内存。智能指针则用于自动管理动态内存,防止内存泄漏。通过移动语义和智能指针的结合,C++程序可以更高效、安全地管理内存资源。
2025-05-10 12:02:56
610
原创 C++模板笔记
像C/C++/Java等语言,是编译型语言,先编译后运行。它们都有一个强大的类型系统,也被称为强类型语言,希望在程序执行之前,尽可能地发现错误,防止错误被延迟到运行时。所以会对语言本身的使用造成一些限制,称之为静态语言。与之对应的,还有动态语言,也就是解释型语言。如javascript/python/Go,在使用的过程中,一个变量可以表达多种类型,也称为弱类型语言。因为没有编译的过程,所以相对更难以调试。强类型程序设计中,参与运算的所有对象的类型在编译时即确定下来,并且编译程序将进行严格的类型检查。
2025-05-08 15:04:13
1055
原创 C++多态笔记
如果一个类只定义了protected型的构造函数而没有提供public构造函数,无论是在外部还是在派生类中作为其对象成员都不能创建该类的对象,但可以由其派生出新的类,这种能派生新类,却不能创建自己对象的类是另一种形式的抽象类。Base类只定义了protected属性的构造函数,不能创建Base类的对象,但是可以定义Base类的指针—— Base类是抽象类如果Derived类也只定义了protected属性的构造函数,Derived类也是抽象类,无法创建对象,但是可以定义指针指向派生类对象。
2025-05-07 14:51:53
914
原创 C++运算符重载笔记
C++ 预定义中的运算符的操作对象只局限于基本的内置数据类型,但是对于自定义的类型是没有办法操作的。当然我们可以定义一些函数来实现这些操作,但考虑到用运算符表达含义的方式很简洁易懂,当定义了自定义类型时,也希望这些运算符能被自定义类类型使用,以此提高开发效率,增加代码的可复用性。所以,可以将运算符重载理解成函数调用,只不过调用的形式是以运算符的形式。为了实现这个需求,C++提供了运算符重载。希望自定义类类型在操作时与内置类型保持一致。!
2025-05-04 12:56:45
428
原创 C++输入输出流
比如我们从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度。又比如,我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的 CPU 可以处理别的事情。,这种方式是兼容C的写法。IO 操作与生俱来的一个问题是可能会发生错误,一些错误是可以恢复的,另一些是不可以的。
2025-04-26 22:15:28
819
原创 C++类与对象
C++用类来描述对象,类是对现实世界中相似事物的抽象,比如同是“双轮车”的摩托车和自行车,有共同点,也有许多不同点。“车”类是对摩托车、自行车、汽车等相同点的提取与抽象。类的定义分为两个部分:数据,相当于现实世界中的属性,称为数据成员;对数据的操作,相当于现实世界中的行为,称为成员函数。从程序设计的观点来说,类就是数据类型,是用户定义的数据类型,对象可以看成某个类的实例(某类的变量)。所以说类是对象的抽象,对象是类的实例。由对象抽象出类由类实例化出对象。
2025-04-22 23:07:39
797
原创 C++与C
在引用的使用中,单纯给某个变量取个别名没有什么意义,引用的目的主要用于在函数参数传递中,解决大块数据或对象的传递效率和空间不理想的问题。用引用传递函数的参数,能保证参数传递中不产生副本,提高传递的效率,还可以通过const的使用,保证了引用传递的安全性。引用与指针的区别。
2025-04-22 20:13:54
810
原创 Linux进程间通信
进程间通信,即,在现代操作系统中起着至关重要的作用。在计算机系统中,每个进程都拥有独立的地址空间,这意味着它们不能直接访问彼此的数据。然而,在许多实际应用场景中,不同的进程需要进行数据交互和协同工作,这就需要进程间通信机制来实现。
2025-04-21 21:15:37
619
原创 Linux进程
操作系统最初的原型是一种批处理系统(batch):在最开始我们把正在执行的程序称为作业,操作员将所有的作业放在一起,由批处理系统进行读取并交给计算机执行,当一个作业执行完成以后,批处理系统会自动地取出下一个作业。在批处理系统中,存在的最严重的问题是任务执行的过程,会经常需要等待IO操作,这会导致CPU经常性地空闲。为了充分提高CPU的利用率,一种解决方案是引入多道程序设计,在内存当中划分多个区域,每个区域存储一个作业的指令和数据,当其中一个作业在等待IO操作时,另外一个作业可以使用CPU。
2025-03-07 10:51:24
371
原创 Linux文件操作
函数成功返回时,目标描述符将变成旧描述符的复制品,此时两个文件描述符现在都指向同一个文件,并且是函数第一个参数(也就是oldfd)指向的文件(执行完成以后,如果newfd已经打开了文件,该文件将会被关闭)a和a+为追加模式,在此两种模式下,在一开始的时候读取文件内容是从文件起始处开始读取的,而无论文件读写点定位到何处,在写数据时都将是在文件末尾添加(写完以后读写点就移动到文件末尾了),所以比较适合于多进程写同一个文件的情况下保证数据的完整性。的mode参数是一个字符串,决定了以什么样的方式打开文件。
2025-03-03 14:21:26
833
原创 Linux目录操作
使用目录流,可以查看目录中的内容。在讲目录流之前,我们一起来回顾一下流模型:“流"类似"水流”,顺序访问流中的数据时,程序员是不需要 care 位置的。现在我们来学习目录流,目录流中的基本单位是目录项。接下来这一章,我们就来学习和目录相关的库函数和系统调用。可以打开一个目录,得到一个指向目录流的指针 DIR*。,填入当前工作目录的绝对路径,然后返回。:重置目录流,即移动到目录流的起始位置。读目录流,得到指向下一个目录项的指针。函数可以改变当前工作目录。:返回目录流中现在的位置。可以移动目录流中的位置。
2025-02-27 19:52:38
893
原创 Linux编译工具链
库是写好的现有的,成熟的,可以复用的代码 (库有时候也被称为轮子,不要重复造轮子~)。现实中每个程序都要依赖很多基础的底层库,不可能所有的代码都从零开始编写,因此库的存在意义非同寻常。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行 (说得更通俗易懂点,就是目标文件的集合库有两种:静态库和动态库。在类 Unix 系统上,静态库一般是以 .a 结尾,Windows 上一般是以 .lib 结尾;
2025-02-25 21:45:40
781
原创 Linux常用命令
管理用户 即我们俗称的 sudoers,他们可以临时提升权限(使用sudo命令),安装Ubuntu过程中创建的用户默认就是 sudoers。删除 text1 或 h_link 只会减少硬链接数,当硬链接数为 0 的时候,才会真正删除磁盘上的文件。第二卷是用来查看系统调用相关信息的;这个文件的内容是一个一个目录项(directory entry),在逻辑上,目录项之间是用链表的方式链接起来的。Linux是按功能进行划分的,将功能相似的文件放到同一个目录下进行管理,所以一个程序的文件是分散在各个目录上面的。
2025-02-23 21:27:42
712
原创 IEEE 会议论文作者信息Latex模板
官网提供的模板在作者数量>3时,会产生换行后难以对齐,作者信息区域占用空间太大的问题。在conference撰写中,需基于作者数量选择合适的模板,作者数量≤3时选择多栏格式,作者数量>3时选择长条模式。基于IEEE官网提供的Latex会议论文模板进行修改,官网上为更新至2024年6月的版本。
2025-02-22 20:36:49
1665
1
原创 Vim编辑器常用命令
例如在 Vim 中,“d” 表示删除,“j” 移动到下一行,组合 “dj” 表示删除当前行和下一行;而且我们还可以指定命令重复的次数:“dd” 表示删除光标所在行,“2dd” 或 “d2d” 表示连续删除两行,效果和 “dj” 一致。Vim 有多种模式, 最常用的是:普通(命令)模式、插入(编辑)模式和视图模式。视图模式是用来选择内容的。Vim 中的删除类似 Windows 中的剪切,会将删除的内容复制到 Vim 的"剪切板"中。普通模式又叫命令模式,顾名思义,这种模式就是用来执行各种命令的。
2025-02-19 21:57:59
874
原创 C语言中的文件
Ctrl+Z不是必需的,但如果存在,它就标志着文件的结束,其后的所有字节都会被忽略。每个流都有相关联的文件位置。,就是将程序中的对象转换成一种可以保存的格式(二进制或文本),从而方便存储(存储到文件或数据库中)或传输(通过网络传输给另一台机器)。标准库中有些函数 (比如与文件相关的一些函数),如果在调用过程中发生了错误,它会设置 errno 的值,以表明发生 了何种类型的错误。遇到换行符’\n’,或者文件的末尾就会终止(也就是说,读取的字符数可能不足 count - 1 个),并且会存储换行符’\n’。
2025-02-15 22:16:13
829
原创 排序与查找算法(C语言实现)
接着,再从剩余未排序的元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。每比较一轮(冒泡一次),最大的元素就会"沉"到数列的末尾,而较小的元素会慢慢"浮"到数列的前面。数据集中"相等"的元素,如果排序前和排序后的相对次序不变,那么这个排序算法就是稳定的。如下图所示,每一层的所用的时间为 cn (归并操作所用的时间,其中 c 为常数项),总共有 log2n 层。快速排序也是分治思想的一种典型应用。当左边区间最前面的元素和右边区间最前面的元素相等时,我们放入的是左边区间的元素,因此归并排序是稳定的。
2025-02-15 22:06:34
929
原创 二叉树(C语言版)
如果为2-结点,3-结点,4-结点分别编写不同的结点类型,则处理起来会非常麻烦,我们不得不处理各个结点类型之间得转换。:若 BST 为空,则创建结点,将其作为根结点。如果要删除结点有两个孩子,那么我们可以找到这个结点的右子树中最小结点 (或者左子树中最大结点),把它替换到要删除的结点上,然后再删除右子树的最小结点 (或左子树的最大结点)。完全二叉树:若二叉树的深度为 h,除第 h 层外,其它各层(1~h-1)的结点数目都达到最大值,第 h 层的结点都连续排列在最左边,这样的二叉树就是完全二叉树。
2025-02-15 21:53:05
737
原创 位图(C语言版)
为什么需要构建一个专门的数据结构来表示位的数组?:因为计算机最小的寻址单位是字节,而不是位。位图要求尽可能少地使用内存空间,所以实际使用多少内存,就申请多少内存。的数据结构,即位图在内存资源紧张的设备中更多使用,如嵌入式设备等。位图是“位”的数组。比如,存储10亿 (
2025-02-15 21:37:05
967
原创 哈希表(C语言版)
在现实生活中,我们经常需要存储键值对(key-value)数据,比如上面的 ‘a’:10, ‘b’:6,再比如账号:个人信息,关键字:网页等等。在哈希函数保证 key 平均分布的前提下,那么哈希表的性能就取决于链表的平均长度 (L)。 先对 key 进行哈希,找到对应的链表,然后遍历链表,判断是添加结点还是更新结点。 先对 key 进行哈希,找到对应的链表,然后遍历链表,找到对应的结点。 先对 key 进行哈希,找到对应的链表,然后遍历链表,删除对应的结点。哈希表的应用很广,比如 C++ 中的。
2025-02-15 21:31:30
2151
原创 栈与队列(C语言版)
队列是另一种操作受限的线性结构。操作受限体现在,队列只能在一端添加元素,在另一端删除元素,符合**先进先出(FIFO)**的特性。栈是一种操作受限的线性结构。操作受限体现在,栈只能在一端添加和删除元素,
2025-02-15 21:21:25
722
原创 链表(C语言版)
我们很容易验证,单向链表的基本操作,双向链表也是支持的,并且时间复杂度也是一样。但是在工程实践上,我们往往更倾向于使用双向链表,而不是单链表,比如 C++ 中的 list,Java 中的 LinkedList 底层的数据结构都是双向链表。该对象中有数据域和指针域,数据域顾名思义存放的就是数据,指针域存放的是结点(可以是另一个结点,也可以是自身)的地址。合并两条有序的单向链表,使得合并后的链表也是有序的 (要求: 不能额外申请堆内存空间)【leetcode 21题】。添加 (在某个结点后面添加) O(1)
2025-02-15 21:08:44
928
原创 C语言的结构体和枚举
这一章我们主要介绍 2 种新类型:结构体和枚举。结构体是一系列值(成员)的集合,这一系列值可以有不同的数据类型。枚举本质上是一种整数类型,只不过我们给这些整数值起了一些名称。
2025-01-31 13:08:46
656
原创 C语言中的字符串
这块内存空间将用来存储字符串字面值中的字符,以及一个用来标志字符串末尾的标记字符 (空字符)。而且,这样的存储方式很灵活,对字符串数组进行排序的时候,我们只需要交换指针即可,不需要复制整个字符串。比如,对这一组字符串进行排序,就需要复制整个字符串里面的内容。设计一个输入函数:它不会跳过前面的空白字符,并且在第一个换行符 (不存储到字符串中) 处停止读取,如果输入的字符串太长,那么就忽略额外的字符。而且,这样的存储方式很灵活,对字符串数组进行排序的时候,我们只需要交换指针即可,不需要复制整个字符串。
2025-01-30 23:09:32
602
原创 C语言:指针与数组
如果 p 指向 a[i],q 指向 a[j],那么 p - q 就等于 i - j。C 语言中指针和数组的关系非常紧密,理解指针和数组之间的关系对于熟练掌握 C 语言非常关键。指针的算术运算是数组和指针关联的一种方式,但这不是两者之间唯一的关联。虽然可以把数组名当作指针,但是不能给数组名赋新的值,也就是说数组名是一个常量指针。既然传递数组时,只是传递一个指针,那么就可以把数组类型的形式参数声明为指针类型。函数时,会把指向数组 b 第一个元素的指针赋值给 a,数组本身并没有复制。但是,通过对指针 p 执行。
2025-01-29 22:46:53
750
原创 C语言中的指针
由于指针的重要性,我们将用3个章节对其进行讨论:指针的基础、指针与数组的关系以及指针的高级应用。程序中的每一个变量占一个或多个字节的内存,我们把第一个字节的地址称为是变量的地址。*p 不仅拥有和 i 相同的值,而且对 *p 的改变也会改变 i 的值。如果指针变量 p 未被初始化或者指向了一个未知的区域,这样的指针我们称为。如果 p 是指针,那么 *p 就表示 p 当前指向的对象。当指针变量 p 存储变量 i 的地址时,我们就说 p 指向了 i。我们不仅可以为函数传递指针,还可以编写返回指针的函数。
2025-01-29 21:28:19
882
原创 C语言中的函数
statements函数不能返回数组,除此之外,函数可以返回任意类型的值。如果函数的返回值类型为 void,则函数没有返回值。如果省略返回值类型,C89 会假定返回值类型为 int;但在 C99 中这是不合法的。double如果返回值类型很长,比如,那么这种方法是很有用的。函数名的后面是形式参数列表。我们需要在每个形式参数前面指定它的类型,并且参数之间用逗号分隔。如果函数没有形式参数,那么应该标明为 void。函数体内包含声明和语句。
2025-01-29 14:59:14
1025
原创 C语言中的数组
到目前为止,我们见过的变量都只能存储单个数据项,这样的变量称为标量 (scalar)。C 语言也支持聚合变量,这类变量可以存储多个数据项。C 语言提供两种类型的聚合变量:数组和结构体。本章主要介绍数组。数组是含有多个数据项的数据结构,并且这些数据项都具有相同的数据类型。这些数据项称为数组的元素,我们可以根据元素在数组中的位置来选取元素。最简单的数组就是一维数组。数组元素在内存中是依次排列的,如下图所示:声明一个数组,我们需要指定数组元素的类型和数量。如:数组元素可以是任何类型,数组的长度则必须是常量表达
2025-01-27 23:11:43
808
原创 C语言中的表达式
如果运算符是从左向右结合的,那么这种运算符是左结合的。首先,我们讨论两个移位运算符,然后再讨论其他 4 个按位运算符 (按位取反,按位与,按位异或,按位或)。: 会对 i 和 j 的每一位进行异或运算,如果对应的位相同则为0,如果对应的位不同则结果为 1。C 语言拥有异常丰富的运算符:算术运算符,赋值运算符,关系运算符,判等运算符,逻辑运算符,位运算符…按位位运算符包含:按位取反,按位与,按位异或,按位或。执行这条语句时,首先会计算表达式 ++i 的值,之后这个值会被丢弃,然后执行下一条语句。
2025-01-26 22:54:50
799
原创 C语言中的语句
这种非顺序控制流的使用,使得理解代码的逻辑变得异常困难,尤其是对于复杂的程序。条件表达式的求值步骤是:首先计算 expr1 的值,如果该值不为 0,则计算 expr2 的值,并且把 expr2 的值当作整个表达式的值;如果 expr1 的值为 0,那么计算 expr3 的值,并把 expr3 的值当作整个表达式的值。break 和 continue 语句都是受限制的,break 只能跳出到 switch 语句或者循环语句后面的那一点,而 continue 语句只能跳转到循环体的末尾。
2025-01-26 14:12:11
974
原创 C语言基本数据类型
但是更好的做法是使用 typedef注意:我们定义的别名是放在最后的,而且类型定义是一条语句,后面需要加分号。使用 typedef 定义别名 Bool,编译器会把 Bool 加入它所能识别的类型名列表中。现在我们可以像使用 C 语言内置类型一样使用 Bool 类型了。Bool flag;编译器会把 Bool 看作 int 的同义词;因此,flag 其实就是一个普通的 int 类型变量。增加代码的可读性 (前提是选择合适的类型名)。增加代码的可移植性我们举个例子来说明这一点。
2025-01-24 17:41:46
966
原创 C语言格式化输入输出
虽然计算机的硬件设备(CPU、内存、I/O设备)都在不断迭代,但在快速发展的过程中,有一个核心矛盾一直存在,那就是。我们可以形象地描述为:CPU 一天,内存一年;内存一天,IO 设备十 年。(假设 CPU 执行一条普通指令需要一天,那么 CPU 读取内存就需要一年;假设内 存之间传递单位数据需要一天,那么内存与 IO 设备之间传递单位数据就需要十年)。为了平衡这三者之间的鸿沟,一个有效的手段是引入。
2025-01-23 22:42:35
938
原创 C语言概述
用C语言编写的hello world程序。// 凡是以#开头的,都是预处理指令#include <stdio.h> // 预处理指令int main (void) { // 在C语言里,如果函数没有参数。一律加上void// "\"表示转义序列return 0;当程序含有一些有特殊意义的常量时 (比如32.0f),建议给这些常量定义名字,以免 别人在阅读程序不知道这个常量的含义。32.0f5.0f9.0f注意:宏定义只是执行简单的文本替换,不会进行类型检查和参数传递的检查。
2025-01-23 13:55:58
787
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人