自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 find和find_if

STL

2022-09-09 16:50:19 362 1

原创 初试完成端口

1.完成端口写的好的博客地址博客1博客22.简易服务器实现代码#include <iostream>#include <winsock2.h>#include <ws2def.h>using namespace std;#define MAX_SIZE 1024#define LISTEN_SOCK_PORT 5060#pragma comment( lib, "ws2_32.lib" ) //代表参数完成键 CompletionPortty

2022-05-05 10:40:47 266

原创 初探重叠IO

个人学习总结笔记 对于这一块也不算很通透,如果大家发现错误,一定要及时告诉我1.基于重叠IO的网络异步模型有两个写法,一个是基于完成例程的,一个是基于事件的,用完成例程的复杂而且效率不如完成端口,所以在此只介绍基于事件的。2.windows下的事件就是你创建一个事件对象,一般来说初始都是将该事件对象设置为无信号的,然后在该事件对象上绑定上你感兴趣的一个操作,然后调用事件等待函数等待该事件的发生,等待过程中线程是被挂起的(也就是说阻塞在了等待处),不耗费CPU的资源,当感兴趣的操作发生的时候,会将事件

2022-05-05 10:35:13 712 2

原创 快速初始化成员变量和sizeof

1.快速初始化成员变量①在C++98的标准可以在类中使用 “=初始值” 的方式来对类中的成员进行初始化,但是是十分严格的,,如果静态成员不满足常量性,且成员不是整型或枚举类型,是无法初始化的非静态成员的初始化,在构造函数中进行②在c++11当中,可以使用= {} 来对非静态成员变量来进行初始化class Test{ int a = 10; double b{ 1.3 }; vector<int> c{ 1,2,3,4,5 }; };

2022-01-28 10:30:16 143

原创 noexcept修饰符和noexcept操作符

1. 弃用throw我们可能见过的异常处理 长这个样子void except_fun() throw(int, double) { }但是由于该特性很少被使用到,所以被弃用了表示函数不会抛出异常的throw() 也已经被新的关键字noexcept关键字代替2.noexcept表示其修饰的函数 不会抛出异常,在西皮皮11中,如果noexcept修饰的函数抛出了异常,那么编译器会调用std::terminate()直接终止运行了,从语法上面讲 有两种形式①void fun() noexce

2022-01-24 10:51:50 181

原创 Chapter 4 How to Benefit from Move Semantics

1. Avoid Objects with Names①如果编译器检测到一个值 来自于一个生命周期即将结束的对象,那么他便会自动的去选择移动语意传递临时对象返回一个局部变量 return local object by value②除此之外我们还可以显示标记一个对象 std::move()尽量避免给对象命名MyType x{42, "hello"};foo(x); // x not used afterwards这个x对象,以后就没有使用过了,那么我们就可以用另一种方式代替foo(MyT

2022-01-21 10:45:40 115

原创 Chapter3 Move Semantics in Classes

1. Move Semantics in Ordinary Classes①C++11之后,编译器会为简单的类生成 移动构造函数 和 移动赋值运算符(就像生成的默认构造函数和默认赋值运算符)②什么时候会使用移动构造当返回一个局部变量(return local obj by value)按值传递一个无名对象传递一个临时对象(例如 函数的返回值)被std::move 标记的对象③测试代码一个简单的类 只有构造函数和一个重载的运算符class Test{public: Tes

2022-01-20 10:14:31 89

原创 2.5 Passing by Value 2.6 Summary

1.Passing by Value函数形参的声明 是pass by valuevoid foo(std::string str); // takes the object by valuestd::string s{"hello"};...foo(s); // calls foo(), str becomes a copy of sfoo(std::move(s)); // calls foo(), s is moved to strfoo(returnStringByValue())

2022-01-17 11:19:52 63

原创 2.4 Overloading by Different References

1.Overloading by Different References在我们了解完右值引用之后,我们有三种形参可以pass by referencevoid foo(const std::string& arg)void foo(std::string& arg)void foo(std::string&& arg)2. void foo(const std::string& arg)①形参表示 你对传过来的实参 只具有读的权限②将实参作为 c

2022-01-17 10:07:18 58

原创 2.3 Moved-from Objects

1.Moved-from Objects在一个对象被std::move()以后,仍然是有效的一个对象,在其生命周期结束的时候会调用其析构函数。只不过该对象的值变得不确定了。2.Valid but Unspecified StateC++的标准库保证move以后,仍然是有效的对象,但却不能保证他的valuestd::string s;...coll.push_back(std::move(s));foo(std::move(s)); // keeps s in a valid but unc

2022-01-14 11:22:52 128

原创 2.2 std::move()

1. std::move()①我们都知道 对象都有生命周期,当生命周期结束的时候,对象会被销毁释放②我们可以在一个对象生命周期没有结束的时候,我们可以对一个对象使用move标记,来表示 我不在需要这个对象了,仅使用std::move()并没有真的被move,只是作为一个标记void foo(const std::string& lr); // binds to the passed object without modifying itvoid foo(std::string&&

2022-01-14 09:57:42 277

原创 2.1 Rvalue References

1. Rvalue Referencesstd::string returnStringByValue(); // forward declaration...std::string s{"hello"};...std::string&& r1{std::move(s)}; // OKstd::string&& r2{returnStringByValue()}; // OK, extends lifetime of return valuestd::st

2022-01-14 09:31:17 70

原创 1.5 Summary

1.总结①移动语意 可以使我们呢优化数据的拷贝,可以隐式的使用(return by value或者是 右值传参) 或者直接显式 std::move()②std::move()仅仅是代表一个对象是可移动的,该对象仍然存在,但是他的值不确定了,具体看编译器的实现③通过使用 non-const && 作为形参,调用者可以将它不在需要的对象传递进来,此函数将在内部对实参进行任何需要的修改④当没有实现移动语意的时候,你仍然可以使用std::move,因为当编译器找不到移动语意的时候,他便会使

2022-01-13 20:51:55 66

原创 1.4Move Semantics for const Objects

1.Move Semantics for const Objects被const修饰的对象 不能被movemove就是要修改传入的值,去"偷"2.类的定义class MyString{public: MyString(int Len = 0, const char* Str = nullptr) : nLen{ Len } { cout << "默认构造函数" << endl; pStr = new char[

2022-01-13 20:43:49 63

原创 1.2 Implementing Move Semantics

1. Implementing Move Semantics①C++11 以前的push_back()的实现 只有一种template<typename T>class vector {public:...// insert a copy of elem:void push_back (const T& elem);...};也就是说,你只能为该函数传入一个左值②C++11 之后 有了一个重载版本template<typename T>class

2022-01-13 20:25:25 61

原创 1.1后续 Motivation for Move Semantics

1.节约资源通过上一次讲解,我们发现程序做了很多无意义的拷贝,如果能直接将那些要销毁的元素直接给新的元素,那不省去了很多事情吗?没错C++11的移动语义,就是干这个事情的2.C++11①createAndInsert(); 函数#include <string>#include <vector>std::vector<std::string> createAndInsert(){std::vector<std::string> coll;

2022-01-13 11:30:16 58

原创 1.1 Motivation for Move Semantics

1. Motivation for Move Semantics为什么我们需要移动语义呢?节约资源就是这四个字 节约资源2.C++03①函数 createAndInsert();#include <string>#include <vector>std::vector<std::string> createAndInsert(){std::vector<std::string> coll; // 创建了一个元素是string的vector

2022-01-13 10:32:09 84

原创 理解 decltype关键字

1. decltype关键字decltype被称作类型说明符,它的作用是选择并返回操作数的数据类型。例如Test2函数的返回值是std::initializer_list类型std::initializer_list<int> Test2(){ return { 1,2,3 };}我们使用一致化初始列表decltype(Test2()) Arr1 = { 1,2,3 };可以运行,所以decltype关键字得到了Test2返回值的类型2.更多的常规例子cons

2022-01-12 09:40:30 251

原创 理解自动类型推导 auto

1.Understand auto type deduction①auto自动类型推导和模板的类型推导几乎一样,只在少数地方有差别②当一个变量用auto声明的时候template<typename T>void f(ParamType param);auto所扮演的角色 就是T, 类型修饰符扮演的角色 就是param③条款1 对auto仍然适用(我前面的博客写过)• Case 1: The type specifier is a pointer or reference, bu

2022-01-12 09:40:05 200

原创 3.理解模板类型推导 Function Arguments

1. Function Arguments数组不是唯一一个在进行类型推导的时候,会变成指针的东西。函数类型也会被推断成函数指针2.测试void someFunc(int, double); // someFunc is a function; // type is void(int, double) template<typename T>void f1(T param); // in f1, param passed by valuetemplate<typename

2022-01-12 09:39:41 105

原创 2.理解模板类型推导Array Arguments

1. Array Argumentsconst char name[] = "ZZH"; // name's type is // const char[13]const char * ptrToName = name; // array decays to pointer学过C语言的人 都知道 name的真实类型 是const char[13] ,他的目标类型是 const charconst char *的目标类型是 const char 所以他可以指向该数组2. 那么当pass by v

2022-01-12 09:38:55 72

原创 1.理解模板类型推断

1. Understand template type deductiontemplate<typename T>void f(ParamType param);f(expr); 在编译时刻,编译器使用expr的类型去推断出两种类型①是T②是ParamType注意 模板类型和参数类型通常是不一致的 参数类型经常有些修饰template<typename T>void f(const T& param); // ParamType is const T&

2022-01-12 09:37:53 93

原创 初步实现中断处理

1.kernel.S①有些中断处理,会在栈中留下自己的错误码,就很像Linux的errno,所以当中断处理函数退栈的时候,会造成两种不同的处理方式,这里为了简便,直接将两种一起处理,有错误码的我们执行一条空指令,没有错误码的我们手工压入一个0②我们在这里采用了宏汇编,来对所有的中断函数进行处理,就是当中断发生的时候,调用宏汇编的函数,在宏汇编的函数中,它压入自己的中断号,然后在IDT中查找自己的中断处理函数,进行处理[bits 32]%define ERROR_CODE nop ; 若在相关的

2021-12-08 14:59:50 174

原创 实现putchar put_str put_int

1.在lib/kernel/print.S 文件中实现put_char()2.思路①我们前面在全局描述符表GDT中定义的第三个描述符,就是我们的显存段描述符,我们往显存段中写入内容,便会输出到屏幕上。②如果接受到的这个字符是回车/换行/删除键,那么需要特殊处理③如果当前整个屏幕满了,那么需要整体往上挪一行,把最后一行空出来④默认是80*25的⑤每次都需获取光标位置,来进行接下来的操作⑥访问CRT controller寄存器组的的寄存器,先往端口地址为0x03d4的Address Registe

2021-12-08 14:27:18 482

原创 编写MBR

1.MBR 主引导记录①当BIOS对基本的外设进行检查,建立好中断向量表等等以后,BIOS也就完成了他的任务了,下一棒就要交给MBR了②MBR必须放在磁盘的0柱面0磁道的第一个扇区,并且扇区的最后两个字节必须是0x55,0xaa,用来标识他就是MBR。③MBR必须被加载到0x7c002.注意点①SECTION MBR vstart=0x7c00这个参数让编译器将section中的数据的地址以vstart的值开始,不再从整个程序头开始。并不代表写了这个参数 程序就自动加载到这个地址加载到内存中

2021-12-08 11:08:16 551

转载 详解8259A

链接地址

2021-12-03 10:47:07 149

原创 加载内核.

1.ELF文件格式在计算机科学中,是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。详细了解2.加载内核KERNEL_START_SECTOR EQU 0x9 kernel.bin的扇区号KERNEL_BIN_BASE_ADDR EQU 0x70000 从磁盘读入后 写入该地址KERNEL_ENTRY_POINT equ 0xc0001500 内核的入口函数的地址初始化内核;/*****Init Kernel*********/Init_Kernel:

2021-11-21 14:52:25 394

原创 如何在win32控制台下输出wchar_t数组中的中文

1.关键 locale loc("chs"); // 定义“区域设置”为中文方式 wcout.imbue(loc); // 载入中文字符输入方式2.一个例子int __cdecl main(void){ locale loc("chs"); // 定义“区域设置”为中文方式 wcout.imbue(loc); // 载入中文字符输入方式 WSADATA wsaData; if (0 != WSAStartup(MAKEWORD(2, 2), &w

2021-11-17 14:29:47 445

原创 开启分页机制

1. 分页的作用在我们进行程序开发的时候,一般情况下,是不需要管理内存的,也不需要操心内存够不够用,其实,这就是分页机制给我们带来的好处。它是实现虚拟存储的关键,位于线性地址与物理地址之间,在使用这种内存分页管理方法时,每个执行中的进程(任务)可以使用比实际内存容量大得多的连续地址空间。而且当系统内存实际上被分成很多凌乱的块时,它可以建立一个大而连续的内存空间的映象,好让程序不用操心和管理这些分散的内存块。分页机制增强了分段机制的性能。页地址变换是建立在段变换基础之上的。因为,段管理机制对于Intel处理

2021-11-15 14:37:04 564

原创 获取物理内存容量

1.linux获取物理内存的方法0xE820 方法1总共有三种,我们只需要了解一种,因为它一般不会出错2.注意实际物理内存 和 检测出来的结果 之间总是相差1MB的,原因是因为有些老的ISA设备要用到地址15MB以上的内存作为缓冲区,也就是说此缓冲区的大小为1MB,操作系统不可以访问这段内存3.代码Total_Memory_Bytes dd 0 ;以字节形式表示的内存大小 存放在此处MemoryBuf times 244 db 0 ; 获取到的全部的信息 存放在此处ARDS_Count

2021-11-11 11:04:33 1253

原创 迈入保护模式

此时已完成了MBR的任务,MBR将控制权交给了Loader1.步骤①打开A20 gate②加载gdt③将CR0 寄存器的PE位 置12.代码 Loader.S%include "boot.inc"section Loader vstart=LOADER_BASE_ADDR ; 0x900LOADER_STACK_TOP EQU LOADER_BASE_ADDR//栈顶设置为0x900JMP Loader_Start;/**********Init GDT*********

2021-11-10 14:33:24 418

原创 一致性代码段

一致代码段是内核开辟出来的供应用程序访问的段,但是不允许用户程序写入数据。1.CPL(Current Priviliege Level):它代表了当前代码段的特权等级,由CS和SS的第0位和第1位表示。当程序转移到不同的特权等级的代码时处理器将改变CPL。在遇到一致代 码段时,一致代码可以被相同或者更低特权等级(用户程序)的代码访问。当处理器访问一个与CPL特权等级不同的一致代码段时,CPL不会被改变。2.DPL(Descriptor Priviliege Level):表示段或者门的特权等级。它存

2021-11-03 15:32:43 568

转载 CHS和LBA逻辑块地址

转载地址

2021-11-02 13:07:16 147

原创 操作系统的启动流程

1.大致流程1.按下开机键2.BIOS加电自检3.BIOS找到硬盘上的第一个扇区 --> MBR4.MBR在第一个扇区中找到分区表,并发现了活动分区的内核加载器5.内核加载器加载内核2.MBR主引导记录446字节的引导程序及参数64字节的分区表信息2字节的结束标志 0x55 0xaa3.分区表1.一个分区表需要占用16个字节 所以只有四个分区,称为一级分区或者是主分区2.四个分区中只能有一个是活动分区,也就是说只能有一个是被激活的3.活动分区就是这个分区中存放着操作系统

2021-10-29 08:50:20 902

转载 LINUX --- 中断 --- INT 0x10

转载地址

2021-10-29 08:28:33 389

转载 浅谈linux的命令行解析参数之getopt_long函数

转载地址

2021-09-06 15:19:08 78

原创 一个简单的TCP客户/服务器的程序

1.需求①客户从标准输入读入一行文字,并写给了服务器②服务器从网络输入中读取了这个文本,并回射给客户③客户从网络输入中读取这个回射文本,并显示在标准输出上2.server端代码void dosth(int fd){ char szBuf[1024]; while(read(fd, szBuf, 1024) > 0) { write(fd, szBuf, sizeof(szBuf)); }}int main(){ int sd,

2021-09-05 10:26:16 343

原创 一个简单的获取时间的程序

1.server端的代码#define MAXSIZE 100int main(void){ int sd; struct sockaddr_in laddr, raddr;//本地信息 和 客户信息 char buf[MAXSIZE]; int connsd; time_t times;//获取时间 int size; //获取一个socket套接字 //IPV4协议中的TCP的流式套接字 sd = socket(AF_INET, SO

2021-09-02 11:27:54 121

原创 动态报式套接字

1.存在的问题上一次我们在协议中定义了这样一个内容#ifndef __PROTO_H__#define __PROTO_H__#define NAMESIZE 11#include <stdint.h>#define RCVPORT 1989struct msg_st{ uint8_t name[NAMESIZE]; uint32_t math; uint32_t eng;}__attribute((packed));

2021-08-26 11:13:55 111

原创 初探socket 报式

1.socket一般来说socket有一个别名也叫做套接字。socket起源于Unix,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。说白了Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面

2021-08-25 20:39:05 735

空空如也

空空如也

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

TA关注的人

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