自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

转载 c++多态性之虚函数与虚表指针

1. 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。2. 存在虚函数的类都有一个一维的虚函数表叫做虚表。类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。3. 多态性是一个接口多种实现,是面向对象的核心。分为类的多态性和函数的多态性。4. 多态用虚函数来实现,结合动态绑定。5. 纯虚函数是虚函数再加上= 0。6. 抽象类是指包括至少一个纯

2017-09-21 01:40:26 546

转载 全排列

全排列在很多程序都有应用,是一个很常见的算法,常规的算法是一种递归的算法,这种算法的得到基于以下的分析思路。  给定一个具有n个元素的集合(n>=1),要求输出这个集合中元素的所有可能的排列。        一、递归实现        例如,如果集合是{a,b,c},那么这个集合中元素的所有排列是{(a,b,c),(a,c,b),(b,a,c),(b,c,a),(c,a,b),(c,b,a)},

2017-09-15 11:58:34 350

原创 c语言模拟实现c++的继承和多态

因为c++的继承和多态是面向对象的,需要用类实现,而c语言没有类,所以就只能选择结构体。但是结构体中不能定义函数,所以可以使用函数指针来实现c++的成员函数。typedef void (*FUN)();struct A{ FUN fun; int a;};struct B{ A _a; int b;};void fA() { cou

2017-08-01 22:56:47 341

原创 将搜索二叉树转化为双向链表

用二叉树的_pLeft表示_prev,用二叉树的_pRight表示_next。 用中序遍历的方式遍历整棵二叉树。Node* BothwayList() { if(!_pRoot) return NULL; stack<Node*> s; s.push(_pRoot); Node* pCur = NULL

2017-08-01 22:45:45 304

原创 创建一个不能被继承的类和只能在堆上(或栈上)创建对象

创建一个不能被继承的类法一: 要创建一个不能被继承的类,我们容易想到的方法是:将构造函数私有化,重新编写create()函数,创建对象,同时为了对称可以将析构函数也私有化,重新编写destory()。class Base{public: static Base* Create(int b) { Base* ba = new Base; ba->_

2017-07-19 16:26:09 446

原创 带环链表的处理

先给出几个要用的函数。1.Begin():Node* Begin(pNode pHead){ return pHead;}2.End():Node* End(pNode pHead){ pNode pCur = pHead; if(!pCur) { return NULL; } while(pCur->_pNext) {

2017-07-19 09:37:37 329

原创 不用‘+’的Add函数

实现一个Add函数,让两个数相加,但是不能使用+、-、*、/等四则运算符。 可以用位运算符实现:int Add(int num1, int num2){ return ((num1&num2)<<1) | (num1^num2);}void AddFun(){ cout<<"32 + 45 = "<<Add(32, 45)<<endl;}

2017-07-14 17:48:28 356

原创 单链表的逆序和倒数第n个节点

单链表的逆序: Node* reverse() { if(_pHead == NULL) return NULL; if(_pHead->_pNext == NULL) return _pHead; Node* pCur = _pHead; Node* pPre = NULL;

2017-07-14 17:22:32 332

原创 实现1+2+3...+n的不同解法

实现1+2+3…+n,要求不能使用乘除法、循环、条件判断、选择相关的关键字。 方法一:使用构造函数。 在构造函数中对静态成员变量++,创建n个对象,就能++n次。class Sum{public: Sum() { n++; sum += n; } static int GetSum() { return

2017-07-14 15:46:29 1286

原创 合并两个有序链表

合并两个有序链表,合并以后的链表依旧有序。 代码:#include <windows.h>#include <iostream>using namespace std;typedef struct Node{ Node(const int& value) :_or(value) ,_pNext(NULL) {} int _or;

2017-07-14 15:41:05 313

原创 shell脚本实现字符串截取

shell脚本截取字符串有8种方法: 1.# 号截取,删除左边字符,保留右边字符。代码: ch=abcd1234 echo ${ch#*d}其中 ch 是变量名,# 号是运算符,*d 表示从左边开始删除第一个 字符d 及左边的所有字符 结果是 :1234 2.## 号截取,删除左边字符,保留右边字符。 代码:echo ${ch##*,} ##*, 表示从左边开始删除最后(最右边)一个

2017-07-05 17:26:01 9642

原创 Linux下的crond和crontab

定时任务软件种类at:适合仅执行一次就结束的调度命令,需要启动一个后端的atd服务。 crontab:需要启动一个服务crond才行,crond服务通过crontab命令实现。anacron:无法周期性执行,只能以天为周期,但有个特点,在关机状态下未>执行的任务,下次开机时可以补上执行。crond 与crontab的区别crond:crond是Linux系统用来定期执行命令或指定程序的服务的

2017-07-05 16:33:01 873

原创 Linux下的sed、awk、cut、sort、uniq工具

sedsed:流式编辑器,在shell脚本中作为过滤器,即将前一个程序的输出作为sed的输入,经过一系列编辑命令转换为另一种格式输出。 sed的基本格式: sed ‘pattern(正则表达式)/action(动作)’ file(文件名) sed -f scriptfile(脚本文件) file sed处理的文件既可以由标准输入重定向,也可以当命令行参数传入,一次传入多个文件,sed会依次

2017-07-04 17:15:27 857

原创 Linux下正则表达式的使用及grep工具

正则表达式规定一些特殊语法表示字符类、数量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式。字符类 例如: 匹配电话号码的正则表达式:1[3578][0-9]{9}。 表示第一位是1,第二位是3、5、7、8中的一个,后面9位都是0-9中的一位。 2. 数量限定符3.位置限定符 4.其他特殊字符 grepgrep是一种查找过滤工具,正则表达式在grep中用来查找符合模式的字符

2017-06-30 17:12:39 603

原创 poll服务器与客户端

与select服务器相比,poll服务器有两个显著地优点: 其一是poll服务器的文件描述符值fd理论上没有上限; 其二是poll服务器的参数不需要每次都设置,因为它不是输入输出型参数。int poll(struct pollfd*fds, nfds_t nfds, int timeout);struct pollfd结构如下 struct pollfd { int fd;

2017-06-29 17:20:02 646

原创 shell脚本编写小程序

求1-100的加法,并输出1+2+3+4+5+6+7+…+100?#!/bin/bashsum=1str='1'i=2for (( i; i<=100; i++))do str=$str'+'$i let sum+=idoneecho $str=$sum因为‘+’不好处理,所以从2开始。 2.输入n个数字,判断最大最小值#!/bin/bashfunction m

2017-06-29 16:03:09 5337

原创 Linux下的eval、` `与$()

1.eval cmdlineeval会对cmdline进行两遍扫描,第一遍扫描后,如果cmdline是一条普通命令,则执行该命令;如果cmdline中含有变量的间接引用,则保证间接引用的语义。 例如: 如果没有eval: shell第1次扫描命令行时,它替换出pipe的值|,接着eval使它再次扫描命令行,这时shell把|作为管道符号了。2.eval echo $$#取得最后一个参数

2017-06-27 16:57:19 545

原创 进程池和线程池

用new、malloc申请内存时,由于每次申请的大小不同,最后可能导致会有许多内存碎片无法使用,造成内存浪费和不好管理的问题。内存池则是在真正使用内存之前,先申请分配一定数量的、大小相等的内存块留做备用。当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够则继续申请新的内存。这样做有效的避免了内存碎片,提高了内存使用效率。而进程池(线程池与进程池的概念基本一致)就引用了内存池的思想,由服务

2017-06-27 15:25:44 343

原创 TCP通信

在tcp协议中,建立连接的两个进程就分别由一个socket来标识,这两个socket组成的socket pair就唯一标识一个连接。所以用来描述网络连接中的一对一关系。 socket:网络套接字,IP地址+端口号就组成了socket。 socket数据结构: TCP协议通信流程: 服务器调用socket(), bind(), listen()初始化,调用accept()阻塞等待,处于

2017-06-23 17:38:11 281

原创 TCP定时器

TCP使用四种定时器(Timer,也称为“计时器”):重传计时器:Retransmission Timer坚持计时器:Persistent Timer保活计时器:Keeplive Timer时间等待计时器:Time_Wait Timer。 (1)重传计时器:重传定时器:为了控制丢失的报文段或丢弃的报文段,也就是对报文段确认的等待时间。当TCP发送报文段时,就创建这个特定报文段的重传计时器,可能发

2017-06-22 19:49:34 391

原创 TCP首部分析及三次握手

TCP首部格式要解析TCP报文,首先要了解它的首部格式: TCP协议的可靠性就体现在首部的序号和确认序号。可以保证数据的按序到达,和数据丢包后的重传机制。 (1)序号:TCP是面向字节流的,在一个TCP连接中传送的字节流中的每一个字节都按顺序编号,整个要传送的字节流的起始序号必须在建立连接时设置。假设某一报文段的序号字段值为301,而数据长度为100字节,那么下一个报文应该从401开始。

2017-06-22 18:40:23 789

原创 端口分类调研

计算机中的进程都是用进程标识符来标志的,但在网络环境下,计算机系统所指派的这种进程标识符用来标志运行在应用层的各种应用进程是不行的。这是因为在因特网上使用的计算机的操作系统种类很多,而不同的操作系统有使用不同格式的进程标识符。为了使运行不同操作系统的计算机的应用进程能够互相通信,就必须用统一的方法对TCP/IP体系的应用进程进行标志。所以就引入了端口的概念。端口虽然通信的终点是应用进程,但我们只要把

2017-06-21 16:24:23 291

原创 路由生产算法

路由路由 是指路由器从一个接口上接收数据报,根据数据报的目的地址进行定向并转发到另一个接口的过程。 路由结点 一个具有路由能力的主机或路由器,它维护一张路由表,通过查询路由表来决定向那个接口发送数据报。 接口 路由结点与某个网络相连的网卡接口。 路由表 由很多路由条目组成,每个条目都指明去往哪个网络的数据报应该经由那个接口发送。其中最后一条是缺省路由条目。 路由条目 路由表中的每一

2017-06-21 15:57:24 375

原创 NAT技术与代理服务器

NAT技术NAT,网络地址转换,当在专用网内部的一些主机本来已经分匹配到了本地IP地址(即仅在本专用网内部使用的专用地址),但现在又想和因特网上的其他主机进行通信(并不需要加密)时,可使用NAT方法。 NAT方法通过使用少量的公有IP地址代表较多的私有IP地址的方式,将有助于减缓可用的IP地址枯竭的问题。NAT技术原理NAT能够使由私有IP构成的局域网内所有主机通过一个具有公有IP和NAT技术的主

2017-06-20 16:16:32 567

原创 ARP协议

ARP协议ARP协议叫做地址解析协议,在数据传送到目标网络时,源主机需要将数据发送到对应主机,但源主机只知道目标主机的IP地址,不知道MAC地址,而数据包在接收时是先被网卡接受在递交给上层协议,网卡通过数据包上的MAC地址与主机是否相符,选择是否要丢弃,所以在通讯前必须先获得目标主机的MAC地址。 (1)源主机通过广播的方式,向局域网内的所有主机发送ARP请求,其中包括源主机的IP地址IP1, M

2017-06-19 17:44:58 266

原创 CRC校验

数据在链路层进行传递时,是以MAC帧的形式进行传递的,MAC帧是将上层的IP数据报作为有效载荷加上自己的报头就成了新的MAC帧了。 在MAC帧的报头中有一项叫RCR校验,那么什么是CRC校验?CRC校验CRC又称为循环冗余校验,其特征是信息字段与校验字段的长度可以自己选定。CRC校验原理CRC校验是在要发送的帧后附加上一个数字(CRC校验码)发给接收方,而接收方通过CRC校验码可以判断发送的帧是否

2017-06-19 16:25:01 1306

原创 线程死锁

什么是死锁线程A需要资源X,而线程B需要资源Y,而双方都掌握有对方所要的资源,这种情况称为死锁。死锁产生的4个必要条件是什么1.互斥:存在这样一种资源,它在某个时刻只能被分配给一个执行绪(也称为线程)使用; 2.请求与保持:当请求的资源已被占用从而导致执行绪阻塞时,资源占用者不但无需释放该资源,而且还可以继续请求更多资源; 3.不抢占和不剥夺:执行者执行完成前不可被剥夺资源,只有资源占用者自己才

2017-06-15 18:29:08 238

原创 线程的分离与结合

线程是可结合或分离的。一个可结合的线程能够被其他线程收回资源和杀死。相反,一个分离的线程是不能被其他线程收回或杀死的,它的存储器资源在它终止时由系统自动释放。 默认情况下,线程被创建为可结合的。 线程分离函数:int pthread_detach(pthread_t thread); 由于调用pthread_join后,如果该线程没有运行结束,调用者会被阻塞,但有些情况并不希望如此,所以可以在

2017-06-15 18:03:38 775

原创 Linux下线程的创建与等待

Linux下的进程是在各自独立的地址空间中运行,进程间共享数据需要进程间通信机制,这种机制非常不方便,并且有的时候需要一个进程同时执行多个执行流,这时就引入了线程的概念。 线程是在进程的地址空间内部运行的一个执行分支,它们之间共享进程内部的资源,所以代码段和数据段都是共享的。 那么线程有哪些东西是自己独有的呢? 1.线程id(标识了各个不同的线程); 2.上下文信息(离开CPU时的信息,方便

2017-06-15 17:47:09 367

原创 信号屏蔽与信号递达

信号递达(handler):实际执行信号的处理动作, 信号未决(pending):信号从产生到递达之间的状态, 信号阻塞(block):被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。 【注意】:阻塞和忽略是不同的,只要信号被阻塞,就不会递达,而忽略是在递达之后会选择的一种动作。 对于信号1:没有阻塞,也没有产生过,如果递达则执行默认动作; 对于信号2

2017-06-15 16:30:44 364

原创 可重入函数

重入:是指被两个或多个执行流重复进入。 假设在链表向头结点_pHead插入节点_Node1时,插入动作分两步,一是将_Node1->_pNext = _pHead->_pNext,二是_pHead->_pNext = _Node1,如果在完成第一步后,因为硬件中断使进程切换到内核,再次回到用户态前检查到有信号要处理,于是切换到sighandler()函数,sighandler()也调用insert

2017-06-14 17:32:03 184

原创 线程安全

假设一种情况,编写mysleep()函数。#include <stdio.h>#include <unistd.h>#include <signal.h>void myhandler(int sig){ printf("%d signal\n", sig);}int mysleep(int timeout){ struct sigaction act, oact;

2017-06-14 17:13:20 247

原创 父进程异步等待子进程

父进程自定义SIGCHLD信号的处理函数,并采用非阻塞方式等待,当子进程退出时,会向父进程发送信号,父进程会进行回收。 当有10个子进程退出时,会给父进程发送10个信号,但由于只会记录一次,所以只能回收一次,我们让父进程一直回收,当子进程全部被回收,waitpid()返回-1,跳出循环。#include <unistd.h>#include <stdio.h>#include <std

2017-06-14 16:17:18 395

原创 子进程退出时会给父进程发信号吗?

父进程创建一个子进程,那么子进程退出时,会不会告诉父进程它要退出了?其实在子进程退出时,会给父进程发送一个SIGCHLD,17号信号。 那么下面用代码来验证一下: 首先要捕捉SIGCHLD信号,输出 i am %d signal ; 再创建子进程,在子进程中输出 i am child,然后退出; 在父进程中每隔1s输出 i am father。#include <unistd.h>#in

2017-06-14 15:56:08 7719

原创 匿名管道的四种情况

匿名管道的4种情况: 1.如果所有指向管道写端的文件描述符都关闭了(管道写端的引用计数等于0),而仍有进程从管道的读端读取数据,那么管道中剩余的数据都被读取后,再次read会返回0,就像读到文件末尾一样。 1 #include <sys/types.h> 2 #include <sys/w

2017-06-12 16:52:45 1626

原创 进程通信之管道

管道通信分为两种,一种是匿名管道,另一种是命名管道,对于这两种管道有什么区别呢? 匿名管道,顾名思义就是没有名字,他只能让拥有血缘关系的两个进程进行通信,它是让两个进程分别连接管道的读端和写端,将数据保存在该管道内,两个进程就都能看到这些信息了。 因为匿名管道不能让两个没有血缘关系的进程通信,那么这些进程想要通信要怎么办呢?所以命名管道就出现了。 命名管道可以让两个毫无关系的进程进行通信,它是

2017-06-12 15:55:35 239

原创 二叉树之红黑树迭代器

红黑事的性质: 1.每个节点不是红色就是黑色。 2.根节点一定是黑色。 3.没有两个连续的红色节点。 4.每个叶子结点道根的路径上,黑色结点的个数都相等。 5.每个叶子结点的空指针域都是黑色的。 通过这些条件的设定,可以保证最长路径上结点的个数不会超过最短路径上节点个数的两倍。 这是一种极限情况,但是这种情况不可能出现,因为正在插入每个节点时都需要调整。 红黑树插入时要考虑的几种

2017-05-29 22:14:07 525

原创 AVL树的删除

AVL数的删除前面的操作和二叉搜索树的删除操作相同,只是在删除时顺便修改pParent的平衡因子,在删除完后,根据pParent的平衡因子,向上调整平衡因子直到平衡。 当pParent->_bf == 0时,需要向上调整; 当pParent->_bf == 1时,不需要修改,直接退出即可; 当pParent->_bf == 2时,需要进行左旋或右旋。bool Destory(const K&

2017-05-29 14:49:24 377

原创 AVL树之插入与判断

二叉搜索树是为了降低遍历的时间复杂度,但是对于单支情况并不能很好的解决,要遍历一个左单支或右单支的二叉树,时间复杂度和链表相同,所以就引入了—>AVL树。 AVL树和一般的搜索二叉树相比有什么不同呢? AVL树在搜索二叉树的基础上每个节点都加了一个平衡因子。 平衡因子的计算方法就是:右子树的深度 - 左子树的深度,或者也可以是,左子树的深度 - 右子树的深度。 当平衡因子的值 >= 2或<=

2017-05-28 14:51:46 1441

原创 将二叉搜索树转换成链表

二叉搜索树与双向链表的相同点是: 二叉搜索树右左右指针域,而双向链表也有前去与后继,这样只要按照中序遍历的方法,将二叉树遍历一遍,改变原来的左右指针域的指向,就能变成双向链表。首先将搜索二叉树写成迭代器,迭代器的本质就是指针,用指针++或–的方式,依次获得链表的节点。template<class K, class V>struct BSTNode{ BSTNode(const K& k

2017-05-25 18:05:33 387

空空如也

空空如也

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

TA关注的人

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