自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 函数调用栈

但是,跳转到目标函数并执行指令后如何返回调用者的位置继续执行调用者函数剩余的指令?最主要的问题是,在执行程序的整个过程中怎么区分局部变量等栈上的数据是属于那个函数的?对于代码中的函数调用来说,会被翻译为跳转指令(跳转到存放目标函数的指令区域)。如果在调用函数之前寄存器有值,那么调用者会把寄存器的值保存在自己的函数栈里,等到调用结束,调用者就读取他们以恢复寄存器的值。被调用者通过ebp-n来访问调用者传给它的参数,函数的返回值通过寄存器返回给调用者。,至于调用栈如何工作,是我们这篇文章讨论的。

2025-12-23 08:58:31 453

原创 互斥和同步(生产者消费者模型)

注:该类型的生产者消费者模型将缓冲区当作局部使用(但也不是完全局部,至少没有实现生产者之间的并发(并行)放入,只实现了生产者和消费者之间的并发(并行)访问)。被挂起的执行流的PCB/TCB会被放到内核中的某等待队列中,并且PCB/TCB的状态会被修改为睡眠,所以本执行流不再被调度。对条件变量进一步的叙述需要结合接口的使用来进行,所以在这里先来介绍一下条件变量接口的使用,希望读者不要感到突兀。当然,互斥的实现方式多种多样,比如中断屏蔽,比如OS提供的原子操作接口,而我给读者介绍的只是其中一种——互斥锁。

2025-12-19 15:24:41 725

原创 项目自动化构建工具: make(以linux为例)

makefile推导。

2025-12-03 10:03:55 621

原创 网络层次划分—深入理解传输层

拥塞控制并不是单纯的提高网络承受上限的问题,比如说,当我们发现由于路由器缓存不足而导致网络拥塞,如果直接把路由器缓存扩大,那么也不能解决问题,因为太多的数据包在路由器缓存队列中排队,发送发迟迟收不到确认也会触发超时重传,结果就是发送更多的数据包,导致路由器缓存中的队列更长,还是会拥塞。在发送端,滑动窗口前面的数据是已经发送了并且收到确认的数据,滑动窗口后面是不能发送的数据(可能由于没有数据要发送,可能由于B的可接收的数据量的限制),而滑动窗口内部则是可发送但是未发送的包括已发送但未确认的数据。

2025-11-28 18:14:10 1092

原创 网络层次划分-网络层

两相对比之下,第二种方式承认了通信的不可靠性,而让通信双方维护可靠性。使用第二种方式部署网络造价大大降低,而且使得网络运行方式灵活(第一种方式要预留出线路资源)。而计算机上层具有很强的处理能力,就算出错了也能有效处理,因此第二种方式就比较适合了。,它总是路由项目表中的第一位,不难看出,这个地址块的地址掩码是全1,也就是说任何目的IP和它按位与都等于目的IP本身,这可以为发往特定的目的地址的数据包开辟一个专用的接口,即把目标网络设置为想要使用专用接口的目的IP,地址掩码是全1,接口设置为专用接口的名字)。

2025-10-16 18:46:11 1065

原创 网络层次划分-数据链路层

这样的话帧定界作用就会消失,帧会被胡乱截断,导致的结果就是,帧包裹的IP数据报也四分五裂了,即IP数据报看到了干扰,而且这可不是重传能解决的问题,因为再次发送,IP数据报的内容也不能变。简单讲这个协议做的事情,就是让网卡不断进行碰撞检测:当两个站点同时发出信息时,总线上的信号电压变化幅度会变大,而网卡一但检测到这个幅度超出了一定的门限值,就认为在发送消息的过程中发生了碰撞,并停止继续发送消息,等待一段时间。限制帧的最小长度,如果帧太小,就填充字节进去(因此,帧长度不仅有最大值,也有最小值)

2025-10-02 15:13:50 547

原创 网络层次划分-物理层

这里的带宽不是用带宽一词形象化的描述数据传送速率(bit/s),而是真实的带宽定义(HZ),可以看出带宽限制了数据在信道的传输速率不能太高(太高会导致信号失真),从而限制了数据传送速率,除此之外码元的信息量也限制了数据传送速率,当然还有很多,比如频分复用增大了数据传输速率等等,而带宽(bit/s)大小是这些因素导致的结果,即带宽(HZ)是因,带宽(bit/s)是果。要想提高信息在信道上的传输速率,就要增大一个码元携带的信息量,但也不能无限增大,码元太多识别起来技术上也有困难。频分多址接入,时分多址接入。

2025-09-26 11:02:12 684

原创 了解交换机,集线器,中继器,路由器

中继器:集线器(hub):交换机(switch):路由器(router):

2025-09-24 19:43:21 453

原创 计算机网络有哪些类别

用来把用户接入网络的网络。按照网络作用范围分类。按照网络作用范围分类。

2025-09-23 17:41:46 298

原创 网络协议与层次划分

PDU(协议数据单元):注:PDU = SDU(由上层PDU组成的内容,也是本层服务的对象,叫做服务数据单元)+PCI(由控制信息组成的头部)

2025-09-23 09:23:49 226

原创 计算机网络的性能

k(千) = 10^3,M(兆) = 10^6,G(吉) = 10^9,T(太) = 10^12......(40Gbit/s就是4*10^10bit/s)发送时延 = 数据帧长度(bit)/发送速率(bit/s)。传播时延 = 信道长度(m)/电磁波在信道上的传播速率(m/s)。k(千) = 2^10B,M(兆) = 2^20B,G(吉) = 2^30B,T(太) = 2^40B。其次带宽不等于传播速率,传播速率的单位是每秒传播多少公里,而带宽的单位是bit/s。bit/s(也记作b/s,bps)。

2025-09-22 20:19:34 610

原创 网络数据交换方式

信号的两种类型电路交换。

2025-09-21 11:20:45 681

原创 C/C++类型转换(C++四大强制类型转换)

总是一个“与指针类型占用字节数相同,却是一个整型类型”的数据类型的重命名,也就是说,在32位系统下(指针大小是4字节),他两分别是usigned long和long;进行上行转换(把派生类的指针或引用转换成基类表示)是安全的,进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。在者,在某些位数的操作系统中,指针与小数类型数据的字节数可能不同(比如16位系统下),强行转换会有丢失数据的风险,这是兼容性的考虑。没问题吧,基础类型之间的转换,那我把。

2025-08-10 22:21:07 1156

原创 C++-特殊类设计

在申请锁之前就先进行一重检验,这可以有效减少线程申请锁的次数:如果指针不为空就不申请锁了。将类的构造函数定义为私有,这样继承该类的类不可见该类的构造函数,也就无法正确构造对象,继承无法进行。直接使这个类无法被new,其也就无法通过new和拷贝构造来创建一个动态空间的类对象了。阻止类外使用构造函数定义对象。而我们提供一个统一的接口供于创建对象。将拷贝构造函数和赋值运算符重载只声明而不定义。将拷贝构造函数和赋值运算符重载声明为私有。阻止类外使用构造函数定义对象。将拷贝构造函数只声明而不定义。

2025-08-05 12:52:25 754

原创 揭秘C++对象模型:虚表与内存布局

而子类新定义的虚函数的地址追加了到了第一个父类子对象中的vfptr指向的虚函数表的末尾。并且如果子类重写了父类的某虚函数,那么会将原本虚函数表中的该虚函数的地址覆盖成子类重写的虚函数的地址,不再是父类的该虚函数的地址,当然如果没有重写,那就还是父类的。首先可以看到,在Left对象中,有一块区域被称为Base子对象,所以我来啰嗦一下:实际上,在继承体系中,不管继承了几个类,继承的层次有多深,在子类对象中,属于同一个父类的成员总是集中在一块的,所以我们可以把子类对象中属于父类的一块叫做该子类对象的子对象。

2025-07-26 22:17:03 1274

原创 函数返回值问题,以及返回值的使用问题(c/c++)

有意思的是,如果返回值是常量,并且返回类型是引用,那么系统会开辟一个临时空间把常量拷贝进去,而rax存放的就是临时空间的地址!-----其实,这就是我们所说的。优化就是根据调用,直接告诉被调用的函数,你应该把临时对象返回值存在我的(即调用者)函数栈的哪个位置,这样就直接把临时对象构造在调用者函数栈里,节省了一次拷贝。虽然是传值返回类型,但因为返回的是大型对象,所以返回的是地址而不是把值直接拷贝到寄存器。虽然是传值返回类型,但因为返回的是大型对象,所以返回的是地址而不是把值直接拷贝到寄存器。

2025-07-18 23:31:29 1147

原创 c++列表初始化

【代码】c++列表初始化。

2025-07-17 20:53:19 366

原创 C/C++-qsort和sort函数

简单来说,qsort将基准元素(二分法)左边的一个元素作为fcmp的第一个参数,右边的一个元素作为fcmp的第二个参数,调用fcmp。如果fcmp返回大于0的数,那么传入函数的两个参数就进行交换,反之则不进行交换。(greater,less对象是标准库提供的函数对象,greater实现了a<b的比较逻辑(升序),less实现了a>b的比较逻辑(降序))注意,comp返回true,表示前一个参数应该在后一个参数前面,返回false表示前一个参数应该在后一个参数前面。如果不传这个参数,默认是从小到大排序。

2025-07-15 16:26:05 325

原创 c/c++-extern

当在一个文件中使用另一个文件中定义的函数(函数默认具有外部链接属性。

2025-07-13 17:10:42 299

原创 c/c++拷贝函数

1.不像strcpy(),strncpy()不会向dest追加结束标记'\0',这就引发了很多不合常理的问题。被复制的数据类型,只是逐字节地进行复制,这给函数的使用带来了很大的灵活性,可以面向任何数据。,如果src长度大于dest,就从后往前复制,这样就可以保证内存区域重叠时正确复制。的实际内存边界,它只是机械地复制,在vs2022中超出边界会程序。2.如果n大于src的长度,会用"/0"填充dest。src的长度都不会阻止),在vs2022会报警告。的实际内存边界,它只是机械地复制。

2025-07-11 21:27:42 560

原创 c99-柔性数组

柔性数组的大小不计算在结构体大小之内.

2025-07-11 17:58:31 221

原创 析构函数抛异常问题(栈展开)

但这样做法的缺点是可能会给程序的稳定运行带来隐患,因为当某些比较严重或者不能处理的异常发生时,我们继续让程序运行,就可能导致程序的未知行为。当然如果能保证所有异常都能被正确处理,程序能继续稳定运行,就可以使用这个方法。

2025-07-11 14:23:07 412

原创 c++-内部类

【代码】c++-内部类。

2025-07-10 18:34:42 244

原创 c++-友元函数和友元类

【代码】c++-友元函数和友元类。

2025-07-10 17:59:23 323

原创 c-union联合体

联合体大小能被其包含的所有基本数据类型的大小所整除。

2025-07-09 13:10:00 193

原创 c++--大小端

判断机器大小端的方式。判断机器大小端的方式。

2025-07-09 11:33:35 91

原创 c++-内存对齐

数据结构(尤其是栈)应该尽可能地在自然边界上对齐原因在于,为了访问未对齐的内存,处理器需要做两次内存访问;而对齐的内存访问只需要一次访问。注意:非自定义成员变量的对齐数 = min(编译器默认的一个对齐数 ,该成员的。大小),char x[5]的对齐数是1而不是5,因为比较的是。修改编译器默认对齐数。

2025-07-09 11:27:32 168

原创 c++--typedef和#define的用法及区别

typedef与#define的区别。typedef的用法。typedef的用法。

2025-07-08 18:57:20 492

原创 c++-引用(包括完美转发,移动构造,万能引用)

区别左值和右值的标准就是是否可以取地址。,一个是赋值之前程序放在寄存器里的字符串,它用来给p指向的空间赋值,它是右值。一个是赋值后p指向的内存空间里的字符串,它是左值。通过这个深刻理解了,左值和右值的区分就是依据是否有固定可取的地址。表达式。

2025-07-07 22:11:54 1193

原创 c++-名称查找

形如func(a,b,c)这样没有作用域限定符(例如x::)的函数调用被称为非限定的函数调用。当C++代码以非限定方式使用一个函数时,编译器会查找与之匹配的函数声明,除了调用者的词法域,查找范围还会包括函数参数类型所在的命名空间。这个额外的查询被称作参数依赖查找(Argument-Dependent Lookup ,简称ADL)。这件事儿就发生在你的代码里,所以你最好对它有个基本的了解。

2025-07-07 13:34:00 1211

原创 图解函数调用过程(函数栈帧)

正在被执行push x指令:先将esp -"1"(1代表的不是数字1,而是一个最小单元),然后把x的值复制到esp指向的内存块中。pop x 指令:先将esp指向的内存块的内容赋值给x,然后esp+"1"。

2025-07-07 09:41:07 509

原创 c++11-function包装器

3.既然this是指针类型,为什么第二种包装方法把参数写成对象也可以,这是因为包装器底层其实是把可调用对象作为成员变量存起来,使用包装器时先调用包装器的operator()重载,把参数传给operator(),然后operator()利用参数调用这个对象,所以实际上,这里是operator()用Plus*或者Plus()调用被包装的可调用对象,而不论是对象还是对象指针都可以调用成员函数,所以两种都可以。bind是一个函数模版,他可以在一个可调用对象的基础上改变其的参数个数,参数顺序,并返回一个新函数对象。

2024-09-03 20:04:48 576

原创 c++11--lambda表达式及仿函数

注意: 在lambda函数定义中,参数列表和返回值类型都是可选部分,而捕捉列表和函数体可以为 空。事实上,lambda的底层与仿函数,即函数对象很相似,lambda捕捉到的变量就是以成员变量的方式存储的,捕捉的本质是用构造函数初始化。捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉。在该函数体内,除了可以使用其参数外,还可以使用所有捕获 到的变量。也可以混用捕捉,传值捕捉所有变量,只有b是传引用捕捉。没有返回值时此部分可省略。

2024-09-03 17:37:46 593

原创 C++-智能指针(RAII)

delete是删除器。智能指针指向的资源不光是一个动态开辟的变量(用delete释放),也有可能是FILE类型(用fclose释放),还有可能是动态数组类型,用delete[]释放,总之释放资源的方式是不同的,但我们写的模版要使用所有类型,所以我们在用智能指针管理资源的时候需要传入一个可调用对象(删除器),通过传入不同的删除器,实现资源的正确释放。如果计数器成为0,说明这个智能指针是唯一的管理者,此时如果它析构,我们就把资源也释放了。是D,但问题是,D是函数模版参数,类模版没有这个模版参数,它不认识D,

2024-09-03 16:00:37 1276

原创 C++—异常

我上面说throw对象的类型与catch参数的类型必须是强匹配,但这儿有个例外,就是。

2024-09-01 18:43:53 1321

原创 c++-多态

这样引用和指针就有机会找到没有转换成person之前student和solider重写的同名函数,所以虽然在Ticket中对象类型都是person,但是指向的分别是student和solider的空间,调用的自然可以是不同对象的同名函数。a传入函数后,x指向的是a中属于父类的一部分,但是子类继承父类后,由于sound这个虚函数被重写,其指针p所指向的指针数组里的sound的地址不是父类的sound而是子类重写的sound1。如果重写了却没有构成多态,比如直接用s调用func,打印的就是0。

2024-07-27 14:27:59 1109

原创 C++--继承

摘要:继承是面向对象编程中实现代码复用的重要机制,通过创建父类(基类)包含公共成员,子类(派生类)继承父类特性并添加特有成员。继承方式包括public、protected和private三种,决定基类成员在派生类中的访问权限。继承中存在隐藏机制,子类同名成员会覆盖父类成员。派生类默认成员函数的处理遵循"先父后子"原则,需通过基类构造函数初始化继承部分。复杂的菱形继承问题可通过虚拟继承解决。相较于继承,组合(has-a关系)能降低耦合度,应优先考虑使用组合,但在需要实现多态等场景下仍需使用

2024-07-25 22:05:33 1661

原创 c++-模版

摘要:模板编程是C++中实现代码复用的重要技术。函数模板通过隐式或显式实例化自动生成不同参数类型的函数重载,处理相同逻辑但类型不同的需求。类模板则通过显示实例化生成不同类型的类。文章详细介绍了模板的基本语法、使用场景和匹配原则,并对比了函数模板与类模板的异同。此外,还探讨了非类型模板参数、模板特化(全特化和偏特化)等高级特性,以及模板声明和定义不能分离的原因。模板编程能显著提高开发效率,但需要注意类型推导、匹配优先级等技术细节。

2024-07-23 20:46:11 1255

原创 关于std::vector::at 和 std::vector::operator[] 的越界检查

operator[]在不同编译器下可能会检查,也可能不检查。在VS下是用assert强制检查的。at在任何编译器下都进行越界检查,如果越界就抛出异常。

2024-07-15 12:51:00 235

原创 c++-关于delete和delete[ ]混用的未定义问题解释

(2)如果此时我们没写析构函数,他就会调用编译器生成的析构函数,不用记录次数(可能涉及更底层,我也不太清楚,望指正),也就不用多开一个整形。),那么调用几次就是个问题,这四个字节恰好是一个整形的大小,这个整形用以记录这块空间的对象个数,从而确定需要调用几次构造和析构函数。但是实际上,如果你自己写了析构函数那么总共分配了44个字节,如果没写析构函数那么才总共分配40个字节。不用调用析构函数也就不用计录对象个数,也就不多开空间,因此可以从指针指向位置释放空间,所以不会报错。为什么写了析构函数就多了4个字节?

2024-07-11 22:50:21 679

空空如也

空空如也

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

TA关注的人

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