学而不思则罔,思而不学则殆

有其事必有其理, 有其理必有其事

  IT博客 :: 首页 :: 联系 :: 聚合  :: 管理
  85 Posts :: 12 Stories :: 47 Comments :: 0 Trackbacks

2013年9月27日 #

这两个类对Winsock API进行了封装,CAsyncSocket是一个异步非阻塞套接字类,CSocket是继承于CAsyncSocket的同步阻塞套接字类。使用这两个类编程无需自己处理Winsock的I/O模型。

CAsyncSocket类提供的唯一抽象就是将与套接字相连的windows消息以回调函数的形式完成,在创建程序时只需要重载这几个函数就可以实现Winsock的I/O操作。

异步模型效率更高,使用起来更灵活,当然也比较难,因为你要手动检测会显得错误或者阻塞的具体情况。当你需要通信的对端系统可能只允许你建立一个SOCKET连接时,就用CAsyncSocket。

CAsyncSocket用于在少量连接时,处理大批量无步骤依赖性的业务。CSocket用于处理步骤依赖性业务,或在可多连接时配合多线程使用。

CAsyncSocket事件处理

当你使用CAsyncSocket::Create创建一个指定兴趣事件的异步套接字时,这些消息究竟是怎么接收和处理的呢?

MFC定义了一个内部的类CSocketWnd,当调用Create函数创建一个套接字时,就会将该套接字连接到一个窗口(CSoketWnd的对象),并且使用WSAAsyncSelect(Winsock I/O模型)将套接字和此窗口对相关联。CAsyncSocket的DoCallBack函数为该窗口的回调函数。这样,当一个网络事件发生时,经过MFC的消息循环,DoCallBack函数会根据不同的事件调用相应的消息处理函数。MFC将这些消息处理函数定义为虚函数,在编程时必须重载需要的消息处理函数CAsyncSocket::OnReceive(),CAsyncSocket::OnSend(),CAsyncSocket::OnAccept(),CAsyncSocket::OnConnect(),CAsyncSocket::OnClose(),CAsyncSocket:OnOutOfBandData()。

客户方在使用CAsyncSocket::Connect()时,往往返回一个WSAEWOULDBLOCK的错误(其它的某些函数调用也如此),实际上这不应该算作一个错误,它是Socket提醒我们,由于你使用了非阻塞Socket方式,所以(连接)操作需要时间,不能瞬间建立。既然如此,我们可以等待呀,等它连接成功为止,于是许多程序员就在调用Connect()之后,Sleep(0),然后不停地用WSAGetLastError()或CAsyncSocket::GetLastError()查看Socket返回的错误,直到返回成功为止。这是一种错误的做法,断言,你不能达到预期目的。事实上,我们可以在Connect()调用之后等待CAsyncSocket::OnConnect()事件被触发,CAsyncSocket::OnConnect()是要表明Socket要么连接成功了,要么连接彻底失败了。至此,我们在CAsyncSocket::OnConnect()被调用之后就知道是否Socket连接成功了,还是失败了。
类似的,Send()如果返回WSAEWOULDBLOCK错误,我们在OnSend()处等待,Receive()如果返回WSAEWOULDBLOCK错误,我们在OnReceive()处等待,以此类推。

总之,尽量使用这些回调函数处理事件,而不要自己查询处理。

CSocket事件处理

主要是要了解他继承了CAsyncSocket之后,如何从异步非阻塞编程同步阻塞模式的。

CSocket在Connect()返回WSAEWOULDBLOCK错误时,不是在OnConnect(),OnReceive()这些事件终端函数里去等待。你先必须明白Socket事件是如何到达这些事件函数里的。这些事件处理函数是靠CSocketWnd窗口对象回调的,而窗口对象收到来自Socket的事件,又是靠线程消息队列分发过来的。总之,Socket事件首先是作为一个消息发给CSocketWnd窗口对象,这个消息肯定需要经过线程消息队列的分发,最终CSocketWnd窗口对象收到这些消息就调用相应的回调函数(OnConnect()等)。
   所以,CSocket在调用Connect()之后,如果返回一个WSAEWOULDBLOCK错误时,它马上进入一个消息循环,就是从当前线程的消息队列里取关心的消息,如果取到了WM_PAINT消息,则刷新窗口,如果取到的是Socket发来的消息,则根据Socket是否有操作错误码,调用相应的回调函数(OnConnect()等)。
大致的简化代码为:

BOOL CSocket::Connect( ... )
{
   if( !CAsyncSocket::Connect( ... ) )
   {
    if( WSAGetLastError() == WSAEWOULDBLOCK ) //由于异步操作需要时间,不能立即完成,所以Socket返回这个错误
    {
     //进入消息循环,以从线程消息队列里查看FD_CONNECT消息,直到收到FD_CONNECT消息,认为连接成功。
     while( PumpMessages( FD_CONNECT ) );
    }
   }
}

CAsyncSocket、CSocket编程

在MFC中进行socket编程需要在应用程序类的Initlnstance中调用AfxSocketlnit初始化套接字。如果使用AppWizard创建应用程序的基本框架时,选中了“WindowsSockets”复选框,那么将自动添加初始化代码。

if (!AfxSocketInit())
    {
        AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
        return FALSE;
    }

CSocket不需要bind(),在Create()时会调用bind()函数绑定此套接字。

CSocket一个重要的用处是可用于串行化技术,要结合CSocketFile 和 CArchive。

服务器端程序:

CSocketFile file(&sockRecv);
CArchive arin(&file,CArchive::load);
CArchive arout(&file,CArchive::load);
arin>>dwValue;   //发送数据
arout <<dwValue;//接收数据

客户端程序:
CSocketFile file(&sockClient);
CArchive arin(&file,CArchive::load);
CArchive arout(&file,CArchive::load);
arin>>dwValue;   //发送数据
arout<<dwValue;//接收数据

posted @ 2013-09-27 17:41 易道 阅读(514) | 评论 (0)编辑 收藏

2013年9月5日 #

 QImage ————》 cv::Mat
 cv::Mat mat = cv::Mat(m_leftQimage->height(), m_leftQimage->width(), CV_8UC4, (uchar*)m_leftQimage->bits(), m_leftQimage->bytesPerLine()); 
 cv::Mat _small_mat ;// = cv::Mat(cv::Size(320,240),CV_8UC3);
 cv::resize(mat,_small_mat, cv::Size(320, 240)) ;
 cv::cvtColor(_small_mat, _small_mat, CV_BGR2RGB);
 cv::Mat  ————》  QImage

 QImage img = QImage((const unsigned char*)_small_mat.data,  _small_mat.cols, _small_mat.rows,  _small_mat.cols * _small_mat.channels(),   //new add   
QImage::Format_RGB888);
posted @ 2013-09-05 10:33 易道 阅读(3783) | 评论 (1)编辑 收藏

2013年5月15日 #

1、Linux进程间的通信方式?两个进程是如何来共享内存的?两个进程如何通过信号量通信?

(1)Linux下进程间通信的方式有: 管道(有名/无名) 、消息、信号、信号量、共享内存、邮箱、socket。

(2)Linux下共享内存是进程间通信的方式之一,共享内存允许两个或多个进程访问同一块内存,比如像 malloc函数 向不同的进程返回执行同一块物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其他拥有这块物理内存指针的进程也会察觉到这个更改。在进程间的通信方式中,共享内存是通信效率最高的,访问共享内存区域和访问进程独有的内存区域一样快,并不需要通过系统调用或者其他通过内核的过程来完成,同时也避免了各种不必要的复制。对共享内存的操作涉及到多个进程间的同步问题,数据应该先写,在读,通常采用用信号量来协调这个过程。


进程与线程的区别?回答方式:

线程是进程中的一个逻辑执行单元,也是进程中可调度的实体;一个进程中可以包含多个线程,但是一个线程只能隶属于一个进程

与进程的区别:

1、CPU调度方面:CPU调度是以线程为基本单位进行的;

2、拥有资源方面:进程是拥有资源的基本单位,线程不拥有系统的资源,但是可以使用隶属于进程的资源;

3、并发方面: 线程 和 进程都支持并发;

4、系统开销方面: 创建进程的时候需要为进程分配资源,销毁进程时需要回收资源,所以使用进程的开销要大于使用线程的开销。


进程控制块?

操作系统通过进程控制块来对进程控制和管理的。PCB通常在系统内存中占用一块连续的分区,它存放着操作系统用于描述进程情况以及控制进程运行情况所需的全部信息,

为什么要CPU调度?

CPU调度的目标是在任何时候都有某些进程在运行,是CPU使用率最大化。  同一时刻 只有一个进程占有CPU资源,但一个进程在等待IO时等等一些阻塞进程的动作时,CPU就回空闲出来,这时候,我们应该让这个阻塞的进程让出CPU资源,让其他已经处于就绪状态的进程执行。这样就可以使CPU使用率最大化。

什么是死锁?

在多道程序环境下,多个进程可能竞争一定数量的资源,某个进程申请资源,如果这时这个资源不可用,那么这个进程就进入等待状态。如果所申请的资源被其他等待进程占有,那么该等待进程可能再也无法改变其状态,一直等待下去,这种情况称之为 死锁。


cache的作用?

cache是处于 CPU寄存器 和 内存之间的一层缓存,用来加快CPU的取指速率, 使用时: CPU需要数据时,首先会查找cache中有没有需要的数据,如果有,则取走,如果没有,则查询内存,并将数据更新到缓存中,以供下次取指。


2、DNS (Domain name system)域名系统,简单描述其工作原理。

DNS客户机需要在程序中使用名称时,它会查询DNS服务器来解析该名称。客户机发送的每条查询信息包括三条信息:包括:指定的DNS域名,指定的查询类型,DNS域名指定的类别。它是基于UDP的服务,端口是53,该应用一般不直接为用户使用,而是为其他应用服务 如 HTTP、SMTP等在其中需要完成主机名到IP地址转换。


在浏览器地址栏内敲 www.baidu.com 到这个页面显示在浏览器上,这个过程中都发生了什么?

(1) 当我们在浏览器上敲入一个url是, 浏览器会解析出该url的域名,接下来的动作,是将域名转化为 ID 地址,依次查询 浏览器DNS缓存、系统缓存、路由器缓存、如果没有找到 则一直查询到 根域名服务器缓存,找到域名所对应的的 IP地址。

(2)向IP所对应的的服务器发送请求数据,

(3)服务器响应请求,发回网页内容;

(4)客户端浏览器获取网页内容,解析,并显示在浏览器上。

这就是我们所看到的的 百度页面显现的过程。


3、TCP/UDP的区别?

(1)TCP是面向连接的、可靠数据传输协议,UDP是不面向连接的,非可靠数据传输协议;(2) 从传输速度上考虑: TCP 由于要建立连接、保证数据传输的可靠性等造成数据传输速度比较慢,UDP不需要这些,数据传输速度相对比较快;(3)从安全方面考虑,TCP的安全性能更高,UDP的安全性能比较低 (4)从传输数据的格式来比较,TCP传输的单位称为报文段,UDP传输的数据单位被称为 数据报

4、ICMP协议

ICMP (Internet Control Message Protocol) ,因特网控制消息协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传输控制消息。控制消息包括:网络不同、主机是否可达、路由器是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但对用户数据的传递起着很重要的作用。ICMP报文格式两种: 差错报告报文和询问报文。


5、数据库

数据库 一个 逻辑执行单元 如何才能被称的上是一个事务? 必须满足的性质?

数据库的事务是指 一个逻辑单元,这个逻辑单元可包含一系列的执行操作, 一个逻辑单元要想成为一个事务,必须满足所谓的 ACID (原子性、隔离性、一致性、持久性);

原子性:指的是 一个事务执行,要么全部执行成功,要么执行失败回滚到执行之前的状态;

一致性:事务执行过后,数据库中数据的状态都必须是一致的,必须遵从数据库的完整性约束;

隔离性:对于多个事务并发的时候,

持久性: 事务的完成后对系统的影响是持久的,任何一个事务的操作不会对其他事务造成干扰;比如一个事务在读数据库,一个事务在写数据库,读数据库的这个事务读到的数据,要么是这个写数据库事务 写前的状态,要么为写后的状态,不存在 读到的数据是 另一个事务写的过程中的一个状态。

数据库索引?


6、内存管理

内存的段页式管理的优缺点?

分段:

在段式存储管理中,将程序的地址空间(进程地址空间)划分为若干个段(segment),这样每个进程都有一个二维的地址空间,相互独立,互不干扰。程序通过分段来划分为多个模块,如代码段、数据段、共享段等,这样做的优点是:可以分别编译源程序的一个文件,并且可以针对不同类型的段采取不同的保护,也可以按段为单位进行共享。段式存储管理的优点是:没有内碎片,外碎片可以通过内存紧缩来消除,便于实现内存共享。


分页:将程序的逻辑地址空间划分为固定大小的页 (page),而物理内存划分为同样大小的页框(pageframe)。程序加载时,可以将任意一页放入内存中的任意一个页框,这些页框不必连续,从而实现了离散分配。这种管理的优势是:没有外碎片,且一个程序不必连续存放,这样就便于更改程序占用的空间大小。

页式 和 段式系统有许多相似之处,比如,两者都采用离散的分配方式,都通过地址映射机构来实现地址变换。但概念上两者是有很多区别的,主要表现在:

[1]、页是信息的物理单位, 段是信息的逻辑单位,每个逻辑单元分为一个段。

[2]、页大小固定由系统决定,把逻辑地址划分为页号和页内地址两部分,段的长度不固定,且决定于用户编写的程序

[3]、页式系统地址空间是一维的,即为单一的线性地址空间,程序员只需利用一个标识符,即可表示一个地址。分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。

http://dongxicheng.org/os/linux-memory-management-basic/


内存:

(1)虚拟内存: 计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续可用的内存(一块连续完整的地址空间),而实际上,他/她通常被分割成多个物理内存碎片,还有部分占时存储在外部磁盘存储器上,在需要时进行交换数据。与没有虚拟内存技术的系统相比,使用这种技术的系统使得大型程序编写变得更容易,对真正的物理内存使用的更有效率。

(2)物理内存:实际的内存,物理地址被分成离散的单元,称为页,页面大小是跟操作系统的位数有关系,一般为4K


7、程序内存分区

5个分区:

堆区:用户在这进行动态内存分配区,

栈区:系统自动分配,自动回收,速度快,效率高,但是栈区比较小,小心 栈溢出

全局区:  存储全局变量和静态变量,

文字常量区:常量字符串就存储在这,程序结束后,由系统同一释放。

程序代码区:存放程序的二进制代码。

posted @ 2013-05-15 10:52 易道 阅读(401) | 评论 (0)编辑 收藏

2013年4月20日 #

     摘要: databases , appdir , node , paper颜开 , v0.2 , 2010.2 序思想篇 CAP最终一致性 变体 BASE其他 I/O的五分钟法则不要删除数据RAM是硬盘,硬盘是磁带Amdahl定律和Gustafson定律万兆以太网 手段篇 一致性哈希 亚马逊的现状算法的选择 Quorum NRWVector clockVirtual nod...  阅读全文
posted @ 2013-04-20 20:30 易道 阅读(407) | 评论 (0)编辑 收藏

2013年3月22日 #

     摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->  1#include     <stdio.h>      ...  阅读全文
posted @ 2013-03-22 11:57 易道 阅读(567) | 评论 (0)编辑 收藏

转自 http://www.cnblogs.com/rootq/articles/1377355.html

TCP(Transmission Control Protocol) 传输控制协议

TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:

位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)

Sequence number(顺序号码) Acknowledge number(确认号码)

第一次握手:主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;

第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包

第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。

完成三次握手,主机A与主机B开始传送数据。


在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。 完成三次握手,客户端与服务器开始传送数据.

实例:

IP 192.168.1.116.3337 > 192.168.1.123.7788: S 3626544836:3626544836
IP 192.168.1.123.7788 > 192.168.1.116.3337: S 1739326486:1739326486 ack 3626544837
IP 192.168.1.116.3337 > 192.168.1.123.7788: ack 1739326487,ack 1

第一次握手:192.168.1.116发送位码syn=1,随机产生seq number=3626544836的数据包到192.168.1.123,192.168.1.123由SYN=1知道192.168.1.116要求建立联机;

第二次握手:192.168.1.123收到请求后要确认联机信息,向192.168.1.116发送ack number=3626544837,syn=1,ack=1,随机产生seq=1739326486的包;

第三次握手:192.168.1.116收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,192.168.1.116会再发送ack number=1739326487,ack=1,192.168.1.123收到后确认seq=seq+1,ack=1则连接建立成功。

 

图解:
一个三次握手的过程(图1,图2)

 

(图1)

(图2)
 

 

第一次握手的标志位(图3)
我们可以看到标志位里面只有个同步位,也就是在做请求(SYN)
3 
 (图3)

第二次握手的标志位(图4)
我们可以看到标志位里面有个确认位和同步位,也就是在做应答(SYN + ACK)
4 
(图4)

第三次握手的标志位(图5)
我们可以看到标志位里面只有个确认位,也就是再做再次确认(ACK)
5 
 
(图5)

一个完整的三次握手也就是 请求---应答---再次确认

posted @ 2013-03-22 11:53 易道 阅读(194) | 评论 (0)编辑 收藏

2013年3月18日 #

char*--strlen()返回的是字节数(对中英文不一致,中文占两个字节,不包括'/0'),
wchar_t--wcslen返回的是字符数(对中英文一致)。
sizeof返回的是字节数(包含'/0',而'/0'在Unicode下也是占两个字节的)。

// 测试代码待写
posted @ 2013-03-18 23:36 易道 阅读(357) | 评论 (0)编辑 收藏

1、重载:
方法名相同,参数列表不同
2、重写:
也叫覆盖,指在子类中定义一个与父类中方法同名同参数列表的方法。因为子类会继承父类的方法,而重写就是将从父类继承过来的方法重新定义一次,重新填写方法中的代码

// 待写
posted @ 2013-03-18 17:01 易道 阅读(240) | 评论 (0)编辑 收藏

       主要参考 Effective C++  第四条款  确定对象被使用前一辈初始化 
       Make sure that Objects are initialized before they're used

  • 成员初始化列表 member initialization list ,是用逗号分开的程序以及初始值的列表。
  • 对于大多数类型而言,只调用一次Copy 构造函数, 比起来先调default 构造函数后,在调用copy assignment 操作符,有时候高效很多。对于内置的类型,其实初始化和赋值的成本是相同。但是为了一致性也通过程序初值来初始化。
  • 对于Const  和 reference 他们一定是要有初值, 不能被赋值。 所以只能在这里了 。见代码。
      

       // 编译vc++ 2010 错误提示
      // error C2758: “CK::CNoOrderMemeberInitialization::a_ref”: 必须在构造函数基/成员初始值设定项列表中初始化
      //int & a_ref ;

      // 编译vc++ 2010 错误提示
      // error C2758: “CK::CNoOrderMemeberInitialization::MAX_LEN”: 必须在构造函数基/成员初始值设定项列表中初始化
      //const int  MAX_LEN ;

  •  class 的成员变量的总是以其声明的顺序初始化。

    #include "stdafx.h"
    #include 
    <iostream>

    //////////////////////////////////////////////////////////////////////////
    // 一个不按照 内部声明顺序 进行member initialization
    namespace CK
    {
        
    class CNoOrderMemeberInitialization
        
    {
        
    public:
            CNoOrderMemeberInitialization(
    int x, int y)
                : n_second(x) , n_first( n_second )   
    //这里先初始化n_second, 然后再给n_first赋值  ??会怎么样
            {

            }

            
    ~CNoOrderMemeberInitialization()
            
    {

            }


        
    public:
            
    int  n_first ;
            
    int  n_second ; 

            
    // 编译vc++ 2010 错误提示
            
    // error C2758: “CK::CNoOrderMemeberInitialization::a_ref”: 必须在构造函数基/成员初始值设定项列表中初始化
            
    //int & a_ref ;

            
    // 编译vc++ 2010 错误提示
            
    // error C2758: “CK::CNoOrderMemeberInitialization::MAX_LEN”: 必须在构造函数基/成员初始值设定项列表中初始化
            
    //const int  MAX_LEN ;
        }
    ;
    }




    int _tmain(int argc, _TCHAR* argv[])
    {
        CK::CNoOrderMemeberInitialization  test(
    2 ,10) ;
        
    //期盼着 test.n_first=2  test.n_second=2
        
    //程序的输出test.n_first=-858993460  test.n_second=2
        std::cout << "test.n_first=" << test.n_first  <<"  test.n_second=" << test.n_second << std::endl ;
        
    return 0;
    }



     




posted @ 2013-03-18 15:56 易道 阅读(479) | 评论 (0)编辑 收藏

  •  C  说到底C++仍然是个C为基础,区块(blocks),语句(statements),预处理(preprocessor),内置数据类型(built-in data types),数组 (arrays) , 指针(points) 等统统是来自C,很多时候C++对问题的解法不过是较高基本的C的接法, (条款2的预处理之外的另外选择,12 的对象资源的管理) ,但是当你以C++内的C成分工作时候,搞笑的编程守则映照出C的局限,没有模板templates, 没有异常 ,没有重载。
  •  Object-Orented C++  这部分也就是C with Class所诉求 
     Classes (包括构造函数和析构函数)
     封装(encapsulation)
     继承(inheritance)
     多态(polymorphism)[运行时多态是动态多态,其具体引用的对象在运行时才能确定。编译时多态是静态多态,在编译时就可以确定对象使用的形式。]
    virtual 函数(动态绑定) 这一部分是面向对象的设计古典守则在C++直接实施
  • Template C++ 是C++ 泛型编程部分,
    还带来的崭新的编程泛型 template metaprogramming (TMP 模板元编程) ---参照C++ 新思维
  • STL 是个template 程序库,他对容器(containers)  迭代器(iterators)  算法(algorithms)  以及函数对象
    function objects
posted @ 2013-03-18 14:36 易道 阅读(228) | 评论 (0)编辑 收藏

2013年3月15日 #

gcc的不定参数
#define debug(x, arg...)  printf((x), ##arg)
C99不定参数
#define debug(...)  printf( __VA_ARGS__)
posted @ 2013-03-15 14:49 易道 阅读(400) | 评论 (0)编辑 收藏

2012年6月20日 #

从大的方面来说,排序可以分成内排序和外排序——内排序是外排序的基础。我们常用的内排序又可以粗略分成下面的类型:

    1.经典算法:如冒泡排序;

    2.插入排序及希尔排序;

    3.选择交换排序;

    4.堆排序;

    5.归并排序;

    6.快速排序。

别看排序有那么多种类型,但它们都离不开这样的核心思想   

 

一个待排序列总是被不断从无序序列转变为有序序

一。经典算法:冒泡排序
     
原理 :在每一遍历中,通过相邻元素的比较 (“冒泡”的比较形象),找到这趟遍历的最小值(或者最大值),并且放到合适的位置
     时间复杂度 O(n^2)


//////////////////////////////////////////////////////////////////////////
///// 冒泡排序
template
<typename T>
inline void my_swap(T
& l , T& r)
{
    T  tmp 
= l ;
    l 
=r ;
    r 
= tmp ;
}
 
template
<typename T>
void BubbleSort(T Arr[] ,
int N)
{    
    
for (int i= 0 ; i < N  ; i++ )
    {
        
for(int j= N-1 ; j > i ; j--)
        {
            
if (Arr[j] < Arr[j -1])
            {
                my_swap(Arr[j] , Arr[j 
-1])   ;
            }
        }
    }
}

 

 

二。插入排序:

   原理  每一趟处理一个元素,将该元素放于该元素之前的子数组(有序)中的正确位置,共需n-1趟。    时间复杂度 O(n^2)
   (思想来源玩扑克的时候,插牌)

 



template
<typename T>
void InsertSort(T Arr[] ,
int N)
{
    
int j ;
    
for (int p =1 ; p < N ;p++)
    {
        T tmp 
= Arr[p] ;
        
for (j = p ;j> 0 && tmp < Arr[j -1] ; j--)
        {
            Arr[j] 
= Arr[j-1]  ;
        }

        Arr[j] 
= tmp ;
    }
}

 
三 希尔排序

       


//////////////////////////////////////////////////////////////////////////
/// shell 发明者Donald Shell 该算法是冲破2次时间障碍的第一批算法,
///  通过比较一定间隔的元素工作,距离随着算法的进行而减小
//// 直到比较相邻元素最后一趟位置   ----》 也叫缩减增量排序
//// 最坏 Θ(O^2)  不同的增量最坏的时间复杂度 不一样                 
template<typename T>
void ShellSort(T Arr[] ,
int N)
{
    
for(int gap = N /2 ; gap > 0 ; gap /=2)
        
for(int i =gap ; i < N ; i++)
        {
            T tmp
= Arr[i] ;
            
int j= i ;
            
for( ; j>= gap && tmp<Arr[j -gap] ;j -= gap)
                Arr[j]  
=Arr[j -gap] ;
        
            Arr[j] 
=tmp  ;
        }
}

 

posted @ 2012-06-20 11:58 易道 阅读(233) | 评论 (0)编辑 收藏

2011年12月26日 #

#pragma once

 


typedef struct _VC_BITMAPINFO {
 BITMAPINFOHEADER    bmiHeader;
 //union {
 // VC_RGB565_MASKS  rgbMasks;
 DWORD    bwPalette[ 256 ];
 //};
} VC_BITMAPINFO, *PVC_BITMAPINFO;


// CIRImageView

class CIRImageView : public CStatic
{
 DECLARE_DYNAMIC(CIRImageView)

public:
 CIRImageView();
 virtual ~CIRImageView();

private:
 HBITMAP   hStillBitmap ;
 PUCHAR   pStillImageData;
 PUCHAR   p_tmpMem  ;

 VC_BITMAPINFO bmiStill  ;
protected:
 DECLARE_MESSAGE_MAP()
public:

 int UpdateIrisImage(BYTE* pData);
 int ClearIrisImage();
 afx_msg void OnPaint();
 int InitBmpStruct(void);


};


 

// IRImageView.cpp : 实现文件
//

#include "stdafx.h"
#include "IRImageView.h"
#include "applib.h"

//////////////////////////////////////////////////////////////////////////

#define ES_RZ_WIDTH 2560
#define ES_RZ_HIGH  800

//#define ES_RZ_WIDTH 640
//#define ES_RZ_HIGH  480

//////////////////////////////////////////////////////////////////////////
// CIRImageView

IMPLEMENT_DYNAMIC(CIRImageView, CStatic)

CIRImageView::CIRImageView()
{
 hStillBitmap =  NULL ;
 p_tmpMem  = NULL  ;
 InitBmpStruct() ;
}

CIRImageView::~CIRImageView()
{
 if ( hStillBitmap != NULL )
 {
  DeleteObject( hStillBitmap );
  hStillBitmap = NULL;
 }
}


BEGIN_MESSAGE_MAP(CIRImageView, CStatic)
 ON_WM_PAINT()
END_MESSAGE_MAP()

// CIRImageView 消息处理程序

 


int CIRImageView::ClearIrisImage()
{
 memset(pStillImageData , 0 ,  ES_RZ_WIDTH * ES_RZ_HIGH ) ;
 Invalidate(true) ;
 return 0;
}

int CIRImageView::UpdateIrisImage(BYTE* pData)
{
 int ImageHeight = ES_RZ_WIDTH;
 int ImageWidth = ES_RZ_HIGH;
 //For test preview update

 int j=0 ; 
 for(int iY = (INT32)(ImageHeight - 1); iY >= 0; iY--)
 {                               
  for(int iX = 0; iX < ImageWidth; iX++)
  {                              
   pStillImageData[( ( ImageHeight -1 - iY ) * ImageWidth) +  ( ImageWidth -1 - iX) ] = (UINT8)pData[(iY * ImageWidth) + iX] ;
  }  
 }

 Invalidate(FALSE) ;
 return 0;
}

void CIRImageView::OnPaint()
{
 CPaintDC dc(this); // device context for painting
 // TODO: 在此处添加消息处理程序代码
 // 不为绘图消息调用 CStatic::OnPaint()

 int   imageWidth;
 int   imageHeight;
 RECT    rect ,win ;
 ::GetClientRect(m_hWnd, &rect);

 imageWidth = ES_RZ_WIDTH;
 imageHeight = ES_RZ_HIGH;

 int   i   =   SetStretchBltMode(dc.m_hDC,COLORONCOLOR);

 StretchDIBits( dc.m_hDC,
 0,0,rect.right, rect.bottom,
 0,0,imageWidth, (UINT)imageHeight,
 pStillImageData,
 (BITMAPINFO*)&bmiStill,  DIB_RGB_COLORS , SRCCOPY
 );
}

int CIRImageView::InitBmpStruct(void)
{
 // create the still dib
 bmiStill.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
 bmiStill.bmiHeader.biWidth = ES_RZ_WIDTH;
 bmiStill.bmiHeader.biHeight = ES_RZ_HIGH;
 bmiStill.bmiHeader.biPlanes = 1;
 bmiStill.bmiHeader.biSizeImage = 0;
 bmiStill.bmiHeader.biXPelsPerMeter = 0;
 bmiStill.bmiHeader.biYPelsPerMeter = 0;
 bmiStill.bmiHeader.biClrUsed = 0;
 bmiStill.bmiHeader.biClrImportant = 0; 

 bmiStill.bmiHeader.biBitCount = 8;
 bmiStill.bmiHeader.biCompression = BI_RGB;

 int  stillImageSize = ES_RZ_WIDTH  * ES_RZ_HIGH;

 // initialize the black and white palette
 for ( int i=0; i < 256; i++ ) {
  bmiStill.bwPalette[i] = i | ( i << 8 ) | ( i << 16 );
 }

 if (NULL == hStillBitmap)
 {
  HDC hDc  = ::GetDC( m_hWnd );
  hStillBitmap = CreateDIBSection( hDc, (LPBITMAPINFO) &bmiStill, DIB_RGB_COLORS, (PVOID *) &pStillImageData, NULL, 0 );
 }
 
 return 0;
}

posted @ 2011-12-26 11:15 易道 阅读(1413) | 评论 (0)编辑 收藏

2011年12月5日 #

{9699EED2-BE87-9ee4-9996-9BAE4-FW71-DAWA-VG5W-4RUQ-C0}
{880300E9-20C2-18c4-A5C0-4D322-FW70-E936-8362-4EQA-C0}
{4B2DEEBC-C889-653a-3158-3545C-FW70-A5CM-UU9K-NGK3-C0}
{27B034BE-E297-d84e-02B5-C05D1-FW71-C70N-QO3O-E0AO-C0}
------------------------
低版本的也能用,而且,7.0的keygen生成的key也能用在8.0.864上面。

在官网下载的试用版无法使用这些key,请从下面的链接进行下载。

下载:115网盘下载 
posted @ 2011-12-05 11:56 易道 阅读(3510) | 评论 (0)编辑 收藏

2011年11月10日 #

include <stdio.h>
#include <string.h>
#define N 40
#define M 100
int res[M];

/*****
* Function: 大整数相乘算法
* 参数:
*  a: 乘数,字符串,一个字符代表整数的一位,左侧是最高位,右侧是最低位
*  b: 乘数,同上
*  n: a的长度
*  m: b的长度
* 没有返回值,结果直接放到全局变量res数组中,如果不想要全局变量,也可以在函数中多加一个参数,保存结果。
  res中每一位存放相乘结果的各个位,跟输入不同,右侧放的是高位,即高位的对应的数组索引也是高的。
*****/

void Multiply(char *a,char *b,int n,int m)            // 大整数相乘
{
 int i,j,temp,t,tt;
 int num=0;
 memset(res,0,sizeof(res));
 for(i=0;i<m;i++)
 {
  temp=0;
  for(j=0;j<n;j++)
  {   
   t=(a[n-1-j]-'0')*(b[m-1-i]-'0')+temp;//从最低位开始计算
   if(0 == t)   
    continue;               
   num = j+i;       
   tt = res[num]+(t);   
   res[num] = tt%10;   
   temp = tt/10;
  }
  if( temp > 0 )
  {
   res[++num] += temp;
  }
 }
 for(i=num;i>=0;i--)                    // 输出结果
  printf("%d",res[i]);
 printf("\n");
}

posted @ 2011-11-10 10:13 易道 阅读(375) | 评论 (0)编辑 收藏