自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(55)
  • 资源 (1)
  • 收藏
  • 关注

原创 动态链接(二)

5. 动态链接相关结构 首先装载方面和静态链接下的装载基本无异,唯一不同的是装载完之后控制权交给动态链接器,而不是可执行文件的入口。系统加载完动态链接器之后将控制权交给动态链接器的入口地址,接着动态链接器进行一系列的初始化及链接工作,完成之后将控制权交给可执行文件的入口,开始执行。 5.1 .interp段 在动态链接的ELF可执行文件中,存在.interp段,专门说明需要用到的动态链接器的...

2018-12-05 15:04:02 608

原创 动态链接(一)

1. 为什么要动态链接 静态链接的缺点: (1)内存和磁盘空间: 比如有两个程序,目标文件分别为Program1.o,Program2.o,并且都用到Lib.o这个模块。静态链接生成可执行文件Program1,Program2时,它们都分别存有Lib.o模块的一个副本。当同时运行Program1和Program2时,Lib.o在磁盘和内存中都有两个副本。可见会造成内存和磁盘空间的浪费。 (...

2018-12-04 12:13:46 692

原创 可执行文件的装载与进程

1. 进程虚拟地址空间 每个进程拥有自己独立的虚拟地址空间,这个虚拟地址空间由cpu位数决定,硬件决定了地址空间的最大理论上限,即硬件的寻址空间大小。比如32位的硬件平台决定了虚拟地址空间的地址为0到2^32-1,即0x00000000~0xFFFFFFFF,共4GB。而64位的硬件平台具有64位寻址能力,虚拟地址空间达到2^64字节,即17179869184GB。 从程序角度,比如可以判断C...

2018-11-29 10:43:29 531

原创 Windows PE/COFF

1.Windows的二进制文件格式PE/COFF 在32位Windows平台下,微软引入了一种叫PE(Protable Executable)的可执行格式。PE文件格式和ELF都是由COFF格式发展而来的。而对于VISUALC++编译器产生的目标文件仍然使用COFF格式。由于PE是COFF的一种扩展,所以它们的结构在很大程度上相同,甚至跟ELF文件的基本结构也相同。即Windows下目标文件默认...

2018-11-20 21:14:55 1049

原创 静态链接

链接就是指将多个目标文件链接在一起并最终形成一个可执行文件。 两个示例源码: a.c extern int shared; int main() { int a=100; swap(&a,&shared); }   b.c int shared=1; void swap(int *a,int *b) { int c; c=*a; *a=*b; *b=...

2018-11-15 20:39:05 2996

原创 解析目标文件

1.目标文件是什么 编译阶段分为预处理,编译,汇编,链接。Linux下汇编之后生成的.o文件就是目标文件,此时的目标文件经过链接之后才会生成最后的可执行文件。实际上,目标文件和可执行文件的结构基本上是相同的,区别就是目标文件中对一些符号的引用和地址还没有确定,只有等到链接之后才能确定。可以把目标文件和可执行文件看成是同一类型的文件。 2.目标文件的格式 Windows下可执行文件的格式是PE...

2018-11-08 15:55:46 576

原创 Windows下线程的同步

内核对象首先介绍内核对象的概念。应用程序在运行过程中会创建各种资源,如进程,线程,文件,互斥量等等。这些资源均由操作系统管理。操作系统管理这些资源的方式就是:记录这些资源的相关信息,会在其内部生成数据块。每种资源需要维护的信息不同,因此每种资源拥有的数据块格式也不同。这类数据块就是“内核对象”。即使资源的创建请求是在进程内部完成的,但内核对象的所有者并不是该进程,而是内核即操作系统。内核对象的创建...

2018-04-02 14:49:14 316

原创 Linux下多线程服务器端的实现

Linux下多线程编程时,编译命令需要加上-lpthread选项。g++ test.cpp -o test -lpthread线程的创建线程具有单独的执行流,所以会有自己的main函数。创建线程的函数如下:int pthread_create(pthread_t * restrict thread,const thread_attr_t * restrict attr,void *(* start...

2018-03-27 15:00:36 493 1

原创 epoll讲解

实现I/O复用技术除了可以使用select,还可以使用epoll。先说一下select的缺点,每次调用完select之后,一般都会有一个循环,遍历全部文件描述符,找出发生事件的那一个,可见时间效率并不高。因此,select函数一般适用于服务器端接入者少,要求有兼容性的情况下。兼容性是因为各大操作系统都支持select函数。相反,epoll则可以将发生事件的所有文件描述符都集中在一起,因此遍历这个集...

2018-03-22 20:56:49 367

原创 select()函数用法

select()函数是实现服用服务器端的一种方法。这里介绍Linux环境下select()函数的用法,Windows下的大同小异。select函数的功能select函数可以同时监视多个文件描述符,并且可以监视三种事件。一旦某个文件描述符所指的对象发生了相应事件,就可以进行相应的处理。监视的三种事件:(1)是否有对象需要接受数据。(2)是否有对象需要传输数据。(3)是否有对象发生了异常。select...

2018-03-20 11:51:15 3658

原创 Ubuntu16.04编译Linux内核

本文介绍在Ubuntu中编译Linux内核并添加新的启动项信息。第一步:下载内核源码并解压内核源码可以在官网下载:点击打开链接笔者用的内核版本是4.14的。把下载好的内核源码放在/usr/src/kernel目录下,没有这个目录的话可以自己创建。通过以下命令把内核源码解压,后面跟的是源码文件名。tar xvJf xxxxxx.tar.xz第二步:配置编译选项配置编译选项有多种方法:(1)make...

2018-03-14 23:47:33 5406

原创 Codeforces 946D Timetable

题意:有n天,每天有m个小时,“1”代表有课,“0”代表没课。Ivan可以选择性地逃掉k节课,问如何逃课才能使得Ivan呆在学校的总时间最短。每天呆在学校的时间为第一节课到最后一节课的时间,例:0011010,则呆在学校的时间为4个小时。输入:n,m,k,接着是一个n行m列的矩阵。1<=n,m<=500,0<=k<=500。题解:注意到数据量很小,可以想到进行三层循环都不会...

2018-03-12 11:42:08 446

原创 用Java实现文本编辑器

源码里有注释:import java.awt.*; import java.awt.event.*; import java.io.*; import javax.swing.*; import javax.swing.text.*; //简单的文本编辑器 public class Editor extends JFrame { public JTextPane textPane = new...

2018-02-14 10:25:06 22532 4

原创 socket()函数介绍

socket函数创建套接字:SOCKET socket(int af, int type, int protocol); 成功时返回套接字句柄,失败时返回INVALID_SOCKET。句柄其实就是标识符,唯一地标识某个东西。第一个参数套接字通信中的协议有一些分类。第一个参数传递套接字中使用的协议分类信息,此协议分类信息称为协议族。下面列出几个协议族:(1)PF_INET。IPv4互联网协议族。(2...

2018-02-13 22:47:30 1864 1

原创 window套接字编程

套接字什么是套接字?套接字(socket)是操作系统提供的用来进行网络数据传输的软件设备。即使对网路数据传输原理不太熟悉,也可以通过套接字完成数据传输。操作系统提供相应的函数,windows和linux提供的函数有一些差异,但大致思想是一样的。下面介绍windows的几个函数:socket函数创建套接字:SOCKET socket(int af, int type, int protocol);成...

2018-02-12 21:31:58 1916

原创 C++输入输出迭代器

C++输入输出可以使用cin,cout,也可以使用C语言的scanf和printf。这里介绍使用输入输出迭代器进行输入输出。 迭代器 迭代器代表广义指针,可以完成常规指针的所有操作。C++的STL定义了5中迭代器:(1)输入迭代器。(2)输出迭代器。(3)正向迭代器。(4)双向迭代器。(5)随机访问迭代器。这些包含在头文件iterator中。 输入迭代器 输入迭代器指向某个输入流,因此可以

2018-02-06 14:36:22 2922

原创 C++智能指针

对于常规指针,如果指向的是动态分配的内存,则必须要记得使用delete。智能指针模板类正是用来解决这个问题的,解决程序员”不记得“的毛病。智能指针是行为类似于常规指针的类对象。既然是类对象,就会有析构函数,智能指针的析构函数就是执行了delete操作。所以一当智能指针无效时,会自动调用它的析构函数,把它指向的内存也一并释放掉。这里介绍三个智能指针模板类:(1)auto_ptr。(2)unique_

2018-02-04 16:10:45 638

原创 C++异常

调用abort() 调用abort()将使程序异常终止。因此可以在程序中添加异常测试代码,如果检测到了异常,就调用abort()使程序终止。 以下这个例子是输入a和b,输出a/b的结果。在函数中检测除数是0的情况,如果除数是0,代表异常。 #include #include using namespace std; const double esp = 1e-20; double myDi

2018-02-03 16:51:31 464

原创 C++类的三种继承

各种继承方式   公有继承  保护继承 私有继承 公有成员变成 派生类的公有成员 派生类的保护成员 派生类的私有成员 保护成员变成 派生类的保护成员 派生类的保护成员 派生类的私有成员 私有成员变成 还是基类的私有成语,只能通过基类接口访问 还是基类的私有成语,只能通过基类接口访问 还是基类的私有成语,只能通过基类接口访问

2018-02-01 16:03:22 310

原创 C++静态联编和动态联编

所谓联编就是:程序调用函数时,编译器通过某种方法确定具体要执行的代码块的过程。分为静态联编和动态联编。在C语言中,这显得很简单,因为每个函数名对应于不同的函数,所以根据函数名就可以确定具体要执行的代码块。而在C++中,有了函数重载,类继承中的虚函数等特性之后,这个过程就变得很复杂了。 在编译过程中进行联编的就是静态联编,在程序运行时才确定要执行哪个代码块的话就是动态联编。 在类继承中指针和引用

2018-01-31 16:57:51 500

原创 win32汇编窗口中添加第一个按钮

.386 .model flat,stdcall option casemap:none include windows.inc include gdi32.inc includelib gdi32.lib include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib .data hI

2017-12-29 11:27:06 740

原创 Codeforces 899D Shovel Sale

题意: 给一个数n(2 题解: 令sum代表n+n-1,如果sum是99999...99这种形式的话,则答案是1。 如果不是,假设sum有len位,则x是len-1,x是上面提到的x。则此时枚举最高为从0到8,分别得到09999..9,19999..9,29999...9。。。。。89999...9。令这些数是p。 如果p 如果p>n+1&&p 否则如果p>n+n-1,对答案无贡献。

2017-12-26 11:48:55 340

原创 C++类的自动转换和强制类型转换

通过构造函数来转换 如果有这样的构造函数: Node(int _x); 则可以有这样的语句: Node a=2; 这条语句实际上将使用2作为构造函数的参数创建临时变量,然后将该变量复制到a中,由于这一步是自动进行的,所以称为隐式转换。注意只有一个参数的构造函数(或者有多个参数,但除了第一个,其他的参数都有默认值)才能用来转换。 可以用于隐式转换的情况(前提是有满足条件的构造函数):

2017-12-18 21:10:57 615

原创 C++随机数

头文件cstdlib中包含了rand()和srand()的原型。而ctime包含了time()的原型。 rand()函数返回从0到某个数的随机数。如果将它模一个数,即rand()%x,得到的是从0到x-1的随机数。这种方法得到是伪随机数,因为在其内部的算法作为seed(种子)的数总是不变的,因此每次运行程序得到的随机数序列都相同。 x=rand()%360; srand()函数提供设置种子的

2017-12-18 20:15:22 441

原创 win32汇编第一个窗口程序

窗口程序的运行过程(1)得到应用程序的句柄(GetModuleHandle)。(2)注册窗口类(RegisterClassEx),在注册之前,要填写RegisterClassEx的参数WNDCLASSEX结构。(3)建立窗口(CreateWindowEx)。(4)显示窗口(ShowWindow)。(5)刷新窗口客户区(UpdateWindow)。(6)进入无限的消息获取和处理的循环。首先获取消息(...

2017-12-17 20:06:03 856

原创 Codeforces 903D Almost Difference

题意: 定义一个函数 给定一个含有n个数的数组a,要求求出所有d(ai,aj)的和,其中1 其中1 题解: 最然ai最大为1e9,但最多也就只有2e5个数,因此可以先离散化再建线段树。线段树里每个节点存有数的和还有数的个数。遍历每个数,对于当前的这个数ai,求出比它小的数的和sum和个数count,则count*ai-sum加到结果里,其中注意ai在线段树的前一个叶子节点是不是a

2017-12-15 13:15:56 328

原创 运算符重载

C++可以通过运算符重载来完成用户定义类型的运算。具体语法就是把函数名换成operator@,其中@代表特定的运算符。 #include #include using namespace std; class NODE { private: int x, y; public: NODE(int _x = 0, int _y = 0) { x = _x; y = _y; }

2017-12-10 12:10:22 294

原创 类里定义常量和枚举

作用域为类的常量 如果要在类里定义常量 #include #include using namespace std; class NODE { private: int val; const int p = 1; }; int main() { return 0; } 这样是编译会报错(在C++11中是可允许的,但早期的版本不支持)。因为类声明只是描述了对象的形式,并没有创建对象

2017-12-09 11:56:49 1382

原创 名称空间

传统的C++名称空间 先说以下三个基本概念:声明区域,潜在作用域,作用域。 声明区域:即变量可以声明的区域。如全局变量的声明区域就是全局的,代码块里的变量的声明区域就是该代码块。 潜在作用域:在该变量的声明区域中,从该变量声明的位置起,到声明区域结束,都是该变量的潜在作用域。 作用域:变量并非在起潜在作用域的所有地方都可见,比如会被另一个被嵌套的代码块中的同名变量给覆盖掉。因此,变量可见的

2017-12-05 11:54:26 306

原创 变量的存储持续性,作用域和链接性

存储持续性 存储持续性分为自动存储持续性,静态存储持续性,动态存储持续性。 自动存储持续性:在函数中或者代码块中定义的变量的存储持续性是自动的。执行函数或代码块时,变量被创建,执行完之后,该变量使用的内存被释放。 静态存储持续性:在函数外定义的或者用static关键字定义的变量的存储持续性是静态的。它在整个程序运行过程中都存在。 动态存储持续性:用new分配的内存,直到用delete才会被

2017-12-03 21:11:53 412

原创 Codeforces896A Nephren gives a riddle

题意 字符串f0是"What are you doing at the end of the world? Are you busy? Will you save us?"。 字符串 fi 是 "What are you doing while sending "fi - 1"? Are you busy? Will you send "fi - 1"?" 。 先输入q(1

2017-12-03 14:10:01 353

原创 Codeforces897B Chtholly's request

题意 给你k和p,k最大是1e5,p最大是1e9。问你前k小的偶数长度的回文数的和,再模p。例如,11,22,1221,就是偶数长度的回文数。 思路 很容易想到,从1枚举到k,把每个数反向复制拼接起来,就是前k小的偶数长度的回文数。 比如前10小是:11,22,33,44,55,66,77,88,99,1001。这分别是1 2 3 4 5 6 7 8 9 10前10个数反向复制拼接起来得到

2017-12-03 13:59:50 360

原创 函数模板

#include #include using namespace std; template T add(T a, T b); int main() { int a, b; cin >> a >> b; double c, d; cin >> c >> d; cout << add(a, b) << endl; //根据实参的具体类型创建相应的函数 cout << add(

2017-11-30 20:00:47 313

原创 引用类型

创建引用变量 引用是C++新增的特性,它能实现在函数调用指针能实现的功能,即通过修改参数的值从而修改实参的值。创建引用的语句: int a = 1; int &b = a; &在这里不是取地址的意思,而是类型标识符的一部分。表示变量b是一个引用。这样声明的结果是a和b指向相同的内存单元,即b是a的别名。两者完全等效。另外,引用变量必须初始化。 int a = 1; int &b =

2017-11-28 09:40:47 225

原创 内联函数

浅谈程序内部 编译的最终产品是可执行程序,由一堆机器指令组成。运行程序时,操作系统将这些机器指定载入内存,每条指令都有自己的地址,随后操作系统逐步执行这些指令。执行遇到分支或者循环等其他条件时,将会跳到特定指令地址处。常规函数调用也是使程序跳到特定的指令处(被调用函数的首地址),并在函数结束时返回。更详细的过程是,遇到函数调用指令时,程序在函数调用后,立即存下当前指令地址,如果还需要传参数,则参

2017-11-25 11:40:44 358

原创 C++指针和const

指针指向的值为常量 int a = 1; const int *p = &a; //指针p指向的值为常量,不能通过指针p来修改值 *p = 2; //这是错误的 a = 2; //a本身为普通变量,这是允许的 值得一提的是,非const变量的地址可以同时赋给const指针和非const指针,而const变量的地址只能赋给const指针不能赋给非const指针。 int a

2017-11-23 08:48:09 272

原创 C++函数原型

函数原型即在调用某个函数前,需事先声明的一条语句,它和函数定义的头部一致,参数变量名可以省略。 首先说一下C++函数是如何返回值的。通常,函数通过将返回值复制到指定的cpu寄存器或内存单元中。然后调用程序或调用函数(是指调用了该函数的函数)将查看该内存单元。函数原型将返回值类型告知调用程序,而函数定义确定具体返回值的类型,显然这两者应该保持一致。 为什么需要原型 原型描述了函数到编译器的接口

2017-11-21 11:24:19 1258

原创 C++简单文件输入输出

简单文件输入输出 使用文件输入输出需要包括头文件fstream。该头文件里有用于处理输入的类ifstream和输出的类ofstream。以下给个例子: #include #include using namespace std; int main() { ifstream in; //in可以用cin的所有方法 ofstream out; //out可以用cout的所有方

2017-11-15 19:42:30 501

原创 cin读取数字时遇到字符的情况

cin读取数字时遇到字符 当定义一个int变量,用cin输入时,如果输入的是一个字符,会发生以下4中情况: 1.n的值变成0 2.不匹配的输入被留在输入流中 3.cin对象的一个错误标记被设置,即cin.fail()返回true 4.对cin的方法调用返回false,即(cin>>n)返回的是false #include using namespace std; int main()

2017-11-14 12:11:36 7329 4

原创 字符函数库cctype

字符函数库cctype 该函数库里包含了一些与字符相关的,非常方便的一些函数,可以简化程序员的工作。 例如,当判断一个字符是否是字母时,以下两条语句是等价的,其中第二条语句用到了字符函数库里的函数。 #include using namespace std; int main() { char ch; cin>>ch; if(ch>='a'&&ch='A'&&ch

2017-11-14 11:17:09 314

java写视频播放器用到的jar包

用java写视频播放器用到的jar包,jna-3.5.2.jar,platform-3.5.2.jar等等

2018-01-29

空空如也

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

TA关注的人

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